diff --git a/lldb/tools/lldb-vscode/JSONUtils.h b/lldb/tools/lldb-vscode/JSONUtils.h --- a/lldb/tools/lldb-vscode/JSONUtils.h +++ b/lldb/tools/lldb-vscode/JSONUtils.h @@ -199,13 +199,13 @@ /// Converts breakpoint location to a Visual Studio Code "Breakpoint" /// JSON object and appends it to the \a breakpoints array. /// -/// \param[in] bp_loc -/// A LLDB breakpoint location object to convert into a JSON value +/// \param[in] bp +/// A LLDB breakpoint object to convert into a JSON value /// /// \return /// A "Breakpoint" JSON object with that follows the formal JSON /// definition outlined by Microsoft. -llvm::json::Value CreateBreakpoint(lldb::SBBreakpointLocation &bp_loc); +llvm::json::Value CreateBreakpoint(lldb::SBBreakpoint &bp); /// Create a "Event" JSON object using \a event_name as the event name /// diff --git a/lldb/tools/lldb-vscode/JSONUtils.cpp b/lldb/tools/lldb-vscode/JSONUtils.cpp --- a/lldb/tools/lldb-vscode/JSONUtils.cpp +++ b/lldb/tools/lldb-vscode/JSONUtils.cpp @@ -281,16 +281,21 @@ // }, // "required": [ "verified" ] // } -llvm::json::Value CreateBreakpoint(lldb::SBBreakpointLocation &bp_loc) { +llvm::json::Value CreateBreakpoint(lldb::SBBreakpoint &bp) { // Each breakpoint location is treated as a separate breakpoint for VS code. // They don't have the notion of a single breakpoint with multiple locations. llvm::json::Object object; - if (!bp_loc.IsValid()) + if (!bp.IsValid()) return llvm::json::Value(std::move(object)); object.try_emplace("verified", true); - const auto vs_id = MakeVSCodeBreakpointID(bp_loc); + const auto vs_id = bp.GetID(); object.try_emplace("id", vs_id); + // VS Code DAP doesn't currently allow one breakpoint to have multiple + // locations so we just report the first one. If we report all locations + // then the IDE starts showing the wrong line numbers and locations for + // other source file and line breakpoints in the same file. + auto bp_loc = bp.GetLocationAtIndex(0); auto bp_addr = bp_loc.GetAddress(); if (bp_addr.IsValid()) { auto line_entry = bp_addr.GetLineEntry(); @@ -303,15 +308,7 @@ } void AppendBreakpoint(lldb::SBBreakpoint &bp, llvm::json::Array &breakpoints) { - if (!bp.IsValid()) - return; - const auto num_locations = bp.GetNumLocations(); - if (num_locations == 0) - return; - for (size_t i = 0; i < num_locations; ++i) { - auto bp_loc = bp.GetLocationAtIndex(i); - breakpoints.emplace_back(CreateBreakpoint(bp_loc)); - } + breakpoints.emplace_back(CreateBreakpoint(bp)); } // "Event": { @@ -870,4 +867,3 @@ } } // namespace lldb_vscode - diff --git a/lldb/tools/lldb-vscode/LLDBUtils.h b/lldb/tools/lldb-vscode/LLDBUtils.h --- a/lldb/tools/lldb-vscode/LLDBUtils.h +++ b/lldb/tools/lldb-vscode/LLDBUtils.h @@ -106,46 +106,6 @@ /// The LLDB frame index ID. uint32_t GetLLDBFrameID(uint64_t dap_frame_id); -/// Given a LLDB breakpoint, make a breakpoint ID that is unique to a -/// specific breakpoint and breakpoint location. -/// -/// VSCode requires a Breakpoint "id" to be unique, so we use the -/// breakpoint ID in the lower BREAKPOINT_ID_SHIFT bits and the -/// breakpoint location ID in the upper BREAKPOINT_ID_SHIFT bits. -/// -/// \param[in] bp_loc -/// The LLDB break point location. -/// -/// \return -/// A unique integer that allows us to easily find the right -/// stack frame within a thread on subsequent VS code requests. -int64_t MakeVSCodeBreakpointID(lldb::SBBreakpointLocation &bp_loc); - -/// Given a VSCode breakpoint ID, convert to a LLDB breakpoint ID. -/// -/// VSCode requires a Breakpoint "id" to be unique, so we use the -/// breakpoint ID in the lower BREAKPOINT_ID_SHIFT bits and the -/// breakpoint location ID in the upper BREAKPOINT_ID_SHIFT bits. -/// -/// \param[in] dap_breakpoint_id -/// The VSCode breakpoint ID to convert to an LLDB breakpoint ID. -/// -/// \return -/// The LLDB breakpoint ID. -uint32_t GetLLDBBreakpointID(uint64_t dap_breakpoint_id); - -/// Given a VSCode breakpoint ID, convert to a LLDB breakpoint location ID. -/// -/// VSCode requires a Breakpoint "id" to be unique, so we use the -/// breakpoint ID in the lower BREAKPOINT_ID_SHIFT bits and the -/// breakpoint location ID in the upper BREAKPOINT_ID_SHIFT bits. -/// -/// \param[in] dap_breakpoint_id -/// The VSCode frame ID to convert to a breakpoint location ID. -/// -/// \return -/// The LLDB breakpoint location ID. -uint32_t GetLLDBBreakpointLocationID(uint64_t dap_breakpoint_id); } // namespace lldb_vscode #endif diff --git a/lldb/tools/lldb-vscode/LLDBUtils.cpp b/lldb/tools/lldb-vscode/LLDBUtils.cpp --- a/lldb/tools/lldb-vscode/LLDBUtils.cpp +++ b/lldb/tools/lldb-vscode/LLDBUtils.cpp @@ -79,19 +79,4 @@ frame.GetFrameID()); } -static uint32_t constexpr BREAKPOINT_ID_SHIFT = 22; - -uint32_t GetLLDBBreakpointID(uint64_t dap_breakpoint_id) { - return dap_breakpoint_id >> BREAKPOINT_ID_SHIFT; -} - -uint32_t GetLLDBBreakpointLocationID(uint64_t dap_breakpoint_id) { - return dap_breakpoint_id & ((1u << BREAKPOINT_ID_SHIFT) - 1); -} - -int64_t MakeVSCodeBreakpointID(lldb::SBBreakpointLocation &bp_loc) { - return (int64_t)(bp_loc.GetBreakpoint().GetID() << BREAKPOINT_ID_SHIFT | - bp_loc.GetID()); -} - } // namespace lldb_vscode diff --git a/lldb/tools/lldb-vscode/lldb-vscode.cpp b/lldb/tools/lldb-vscode/lldb-vscode.cpp --- a/lldb/tools/lldb-vscode/lldb-vscode.cpp +++ b/lldb/tools/lldb-vscode/lldb-vscode.cpp @@ -379,27 +379,20 @@ if (event_mask & lldb::SBTarget::eBroadcastBitBreakpointChanged) { auto event_type = lldb::SBBreakpoint::GetBreakpointEventTypeFromEvent(event); - const auto num_locs = - lldb::SBBreakpoint::GetNumBreakpointLocationsFromEvent(event); auto bp = lldb::SBBreakpoint::GetBreakpointFromEvent(event); bool added = event_type & lldb::eBreakpointEventTypeLocationsAdded; bool removed = event_type & lldb::eBreakpointEventTypeLocationsRemoved; if (added || removed) { - for (size_t i = 0; i < num_locs; ++i) { - auto bp_loc = - lldb::SBBreakpoint::GetBreakpointLocationAtIndexFromEvent( - event, i); - auto bp_event = CreateEventObject("breakpoint"); - llvm::json::Object body; - body.try_emplace("breakpoint", CreateBreakpoint(bp_loc)); - if (added) - body.try_emplace("reason", "new"); - else - body.try_emplace("reason", "removed"); - bp_event.try_emplace("body", std::move(body)); - g_vsc.SendJSON(llvm::json::Value(std::move(bp_event))); - } + auto bp_event = CreateEventObject("breakpoint"); + llvm::json::Object body; + body.try_emplace("breakpoint", CreateBreakpoint(bp)); + if (added) + body.try_emplace("reason", "new"); + else + body.try_emplace("reason", "removed"); + bp_event.try_emplace("body", std::move(body)); + g_vsc.SendJSON(llvm::json::Value(std::move(bp_event))); } } } else if (event.BroadcasterMatchesRef(g_vsc.broadcaster)) {