https://github.com/vogelsgesang updated https://github.com/llvm/llvm-project/pull/104589
>From c6962437499858643b8112bcc1c7d155d3c588a9 Mon Sep 17 00:00:00 2001 From: Adrian Vogelsgesang <avogelsges...@salesforce.com> Date: Mon, 12 Aug 2024 14:53:31 +0000 Subject: [PATCH 1/4] [lldb-dap] Implement value locations for function pointers This commit adds `valueLocationReference` to function pointers and function references. Thereby, users can navigate directly to the pointed-to function from within the "variables" pane. In general, it would be useful to also a similar location references also to member function pointers, `std::source_location`, `std::function`, and many more. Doing so would require extending the formatters to provide such a source code location. There were two RFCs about this a while ago: https://discourse.llvm.org/t/rfc-extending-formatters-with-a-source-code-reference/68375 https://discourse.llvm.org/t/rfc-sbvalue-metadata-provider/68377/26 However, both RFCs ended without a conclusion. As such, this commit now solve the lowest-hanging fruit, i.e. function pointers. If people find it useful, I will revive the RFC afterwards. --- .../API/tools/lldb-dap/locations/Makefile | 2 +- .../lldb-dap/locations/TestDAP_locations.py | 49 +++++++- lldb/test/API/tools/lldb-dap/locations/main.c | 5 - .../API/tools/lldb-dap/locations/main.cpp | 11 ++ lldb/tools/lldb-dap/JSONUtils.cpp | 33 ++++- lldb/tools/lldb-dap/JSONUtils.h | 3 + lldb/tools/lldb-dap/lldb-dap.cpp | 113 +++++++++++++----- 7 files changed, 176 insertions(+), 40 deletions(-) delete mode 100644 lldb/test/API/tools/lldb-dap/locations/main.c create mode 100644 lldb/test/API/tools/lldb-dap/locations/main.cpp diff --git a/lldb/test/API/tools/lldb-dap/locations/Makefile b/lldb/test/API/tools/lldb-dap/locations/Makefile index 10495940055b63..99998b20bcb050 100644 --- a/lldb/test/API/tools/lldb-dap/locations/Makefile +++ b/lldb/test/API/tools/lldb-dap/locations/Makefile @@ -1,3 +1,3 @@ -C_SOURCES := main.c +CXX_SOURCES := main.cpp include Makefile.rules diff --git a/lldb/test/API/tools/lldb-dap/locations/TestDAP_locations.py b/lldb/test/API/tools/lldb-dap/locations/TestDAP_locations.py index 76d938d3908492..45f836a2fa3c39 100644 --- a/lldb/test/API/tools/lldb-dap/locations/TestDAP_locations.py +++ b/lldb/test/API/tools/lldb-dap/locations/TestDAP_locations.py @@ -19,11 +19,11 @@ def test_locations(self): """ program = self.getBuildArtifact("a.out") self.build_and_launch(program) - source = "main.c" + source = "main.cpp" self.source_path = os.path.join(os.getcwd(), source) self.set_source_breakpoints( source, - [line_number(source, "// BREAK HERE")], + [line_number(source, "break here")], ) self.continue_to_next_stop() @@ -36,5 +36,46 @@ def test_locations(self): locals["var1"]["declarationLocationReference"] ) self.assertTrue(loc_var1["success"]) - self.assertTrue(loc_var1["body"]["source"]["path"].endswith("main.c")) - self.assertEqual(loc_var1["body"]["line"], 2) + self.assertTrue(loc_var1["body"]["source"]["path"].endswith("main.cpp")) + self.assertEqual(loc_var1["body"]["line"], 6) + + # func_ptr has both a declaration and a valueLocation + self.assertIn("declarationLocationReference", locals["func_ptr"].keys()) + self.assertIn("valueLocationReference", locals["func_ptr"].keys()) + decl_loc_func_ptr = self.dap_server.request_locations( + locals["func_ptr"]["declarationLocationReference"] + ) + self.assertTrue(decl_loc_func_ptr["success"]) + self.assertTrue( + decl_loc_func_ptr["body"]["source"]["path"].endswith("main.cpp") + ) + self.assertEqual(decl_loc_func_ptr["body"]["line"], 7) + val_loc_func_ptr = self.dap_server.request_locations( + locals["func_ptr"]["valueLocationReference"] + ) + self.assertTrue(val_loc_func_ptr["success"]) + self.assertTrue(val_loc_func_ptr["body"]["source"]["path"].endswith("main.cpp")) + self.assertEqual(val_loc_func_ptr["body"]["line"], 3) + + # func_ref has both a declaration and a valueLocation + self.assertIn("declarationLocationReference", locals["func_ref"].keys()) + self.assertIn("valueLocationReference", locals["func_ref"].keys()) + decl_loc_func_ref = self.dap_server.request_locations( + locals["func_ref"]["declarationLocationReference"] + ) + self.assertTrue(decl_loc_func_ref["success"]) + self.assertTrue( + decl_loc_func_ref["body"]["source"]["path"].endswith("main.cpp") + ) + self.assertEqual(decl_loc_func_ref["body"]["line"], 8) + val_loc_func_ref = self.dap_server.request_locations( + locals["func_ref"]["valueLocationReference"] + ) + self.assertTrue(val_loc_func_ref["success"]) + self.assertTrue(val_loc_func_ref["body"]["source"]["path"].endswith("main.cpp")) + self.assertEqual(val_loc_func_ref["body"]["line"], 3) + + # `evaluate` responses for function pointers also have locations associated + eval_res = self.dap_server.request_evaluate("greet") + self.assertTrue(eval_res["success"]) + self.assertIn("valueLocationReference", eval_res["body"].keys()) diff --git a/lldb/test/API/tools/lldb-dap/locations/main.c b/lldb/test/API/tools/lldb-dap/locations/main.c deleted file mode 100644 index 6a8c86d00cb562..00000000000000 --- a/lldb/test/API/tools/lldb-dap/locations/main.c +++ /dev/null @@ -1,5 +0,0 @@ -int main(void) { - int var1 = 1; - // BREAK HERE - return 0; -} diff --git a/lldb/test/API/tools/lldb-dap/locations/main.cpp b/lldb/test/API/tools/lldb-dap/locations/main.cpp new file mode 100644 index 00000000000000..e3b2e73f9837f8 --- /dev/null +++ b/lldb/test/API/tools/lldb-dap/locations/main.cpp @@ -0,0 +1,11 @@ +#include <cstdio> + +void greet() { printf("Hello"); } + +int main(void) { + int var1 = 1; + void (*func_ptr)() = &greet; + void (&func_ref)() = greet; + __builtin_printf("break here"); + return 0; +} diff --git a/lldb/tools/lldb-dap/JSONUtils.cpp b/lldb/tools/lldb-dap/JSONUtils.cpp index 4f9c9c01cf4b6b..1d3fc110791d2f 100644 --- a/lldb/tools/lldb-dap/JSONUtils.cpp +++ b/lldb/tools/lldb-dap/JSONUtils.cpp @@ -1198,6 +1198,18 @@ std::string VariableDescription::GetResult(llvm::StringRef context) { return description.trim().str(); } +bool HasValueLocation(lldb::SBValue v) { + if (!v.GetType().IsPointerType() && !v.GetType().IsReferenceType()) { + return false; + } + + lldb::addr_t addr = v.GetValueAsAddress(); + lldb::SBLineEntry line_entry = + g_dap.target.ResolveLoadAddress(addr).GetLineEntry(); + + return line_entry.IsValid(); +} + // "Variable": { // "type": "object", // "description": "A Variable is a name/value pair. Optionally a variable @@ -1277,6 +1289,18 @@ std::string VariableDescription::GetResult(llvm::StringRef context) { // Object References' in the Overview section for // details." // }, +// "valueLocationReference": { +// "type": "integer", +// "description": "A reference that allows the client to request the +// location where the variable's value is declared. For +// example, if the variable contains a function pointer, +// the adapter may be able to look up the function's +// location. This should be present only if the adapter +// is likely to be able to resolve the location.\n\nThis +// reference shares the same lifetime as the +// `variablesReference`. See 'Lifetime of Object +// References' in the Overview section for details." +// }, // // "$__lldb_extensions": { // "description": "Unofficial extensions to the protocol", @@ -1390,7 +1414,10 @@ llvm::json::Value CreateVariable(lldb::SBValue v, int64_t var_ref, object.try_emplace("variablesReference", 0); if (v.GetDeclaration().IsValid()) - object.try_emplace("declarationLocationReference", var_ref); + object.try_emplace("declarationLocationReference", var_ref << 1); + + if (HasValueLocation(v)) + object.try_emplace("valueLocationReference", (var_ref << 1) | 1); if (lldb::addr_t addr = v.GetLoadAddress(); addr != LLDB_INVALID_ADDRESS) object.try_emplace("memoryReference", EncodeMemoryReference(addr)); @@ -1416,8 +1443,8 @@ CreateRunInTerminalReverseRequest(const llvm::json::Object &launch_request, llvm::StringRef comm_file, lldb::pid_t debugger_pid) { llvm::json::Object run_in_terminal_args; - // This indicates the IDE to open an embedded terminal, instead of opening the - // terminal in a new window. + // This indicates the IDE to open an embedded terminal, instead of opening + // the terminal in a new window. run_in_terminal_args.try_emplace("kind", "integrated"); auto launch_request_arguments = launch_request.getObject("arguments"); diff --git a/lldb/tools/lldb-dap/JSONUtils.h b/lldb/tools/lldb-dap/JSONUtils.h index 13018458ffe0ad..0e00c0e6bcb8c5 100644 --- a/lldb/tools/lldb-dap/JSONUtils.h +++ b/lldb/tools/lldb-dap/JSONUtils.h @@ -458,6 +458,9 @@ struct VariableDescription { std::string GetResult(llvm::StringRef context); }; +/// Does the given variable have an associated value location? +bool HasValueLocation(lldb::SBValue v); + /// Create a "Variable" object for a LLDB thread object. /// /// This function will fill in the following keys in the returned diff --git a/lldb/tools/lldb-dap/lldb-dap.cpp b/lldb/tools/lldb-dap/lldb-dap.cpp index c7653fed2def4e..b4fd1a00cbbac7 100644 --- a/lldb/tools/lldb-dap/lldb-dap.cpp +++ b/lldb/tools/lldb-dap/lldb-dap.cpp @@ -1542,6 +1542,19 @@ void request_completions(const llvm::json::Object &request) { // client can use this optional information to // present the variables in a paged UI and fetch // them in chunks." +// }, +// "valueLocationReference": { +// "type": "integer", +// "description": "A reference that allows the client to request +// the location where the returned value is +// declared. For example, if a function pointer is +// returned, the adapter may be able to look up the +// function's location. This should be present only +// if the adapter is likely to be able to resolve +// the location.\n\nThis reference shares the same +// lifetime as the `variablesReference`. See +// 'Lifetime of Object References' in the +// Overview section for details." // } // "memoryReference": { // "type": "string", @@ -1628,16 +1641,17 @@ void request_evaluate(const llvm::json::Object &request) { VariableDescription desc(value); EmplaceSafeString(body, "result", desc.GetResult(context)); EmplaceSafeString(body, "type", desc.display_type_name); - if (value.MightHaveChildren()) { - auto variableReference = g_dap.variables.InsertVariable( - value, /*is_permanent=*/context == "repl"); - body.try_emplace("variablesReference", variableReference); - } else { + auto var_ref = g_dap.variables.InsertVariable( + value, /*is_permanent=*/context == "repl"); + if (value.MightHaveChildren()) + body.try_emplace("variablesReference", var_ref); + else body.try_emplace("variablesReference", (int64_t)0); - } if (lldb::addr_t addr = value.GetLoadAddress(); addr != LLDB_INVALID_ADDRESS) body.try_emplace("memoryReference", EncodeMemoryReference(addr)); + if (HasValueLocation(value)) + body.try_emplace("valueLocationReference", var_ref); } } response.try_emplace("body", std::move(body)); @@ -3752,6 +3766,17 @@ void request_threads(const llvm::json::Object &request) { // "description": "The number of indexed child variables. The client // can use this optional information to present the variables in a // paged UI and fetch them in chunks." +// }, +// "valueLocationReference": { +// "type": "integer", +// "description": "A reference that allows the client to request the +// location where the new value is declared. For example, if the new +// value is function pointer, the adapter may be able to look up the +// function's location. This should be present only if the adapter +// is likely to be able to resolve the location.\n\nThis reference +// shares the same lifetime as the `variablesReference`. See +// 'Lifetime of Object References' in the Overview section for +// details." // } // }, // "required": [ "value" ] @@ -3776,7 +3801,6 @@ void request_setVariable(const llvm::json::Object &request) { response.try_emplace("success", false); lldb::SBValue variable; - int64_t newVariablesReference = 0; // The "id" is the unique integer ID that is unique within the enclosing // variablesReference. It is optionally added to any "interface Variable" @@ -3806,14 +3830,17 @@ void request_setVariable(const llvm::json::Object &request) { // so always insert a new one to get its variablesReference. // is_permanent is false because debug console does not support // setVariable request. + int64_t new_var_ref = + g_dap.variables.InsertVariable(variable, /*is_permanent=*/false); if (variable.MightHaveChildren()) - newVariablesReference = - g_dap.variables.InsertVariable(variable, /*is_permanent=*/false); - body.try_emplace("variablesReference", newVariablesReference); - + body.try_emplace("variablesReference", new_var_ref); + else + body.try_emplace("variablesReference", 0); if (lldb::addr_t addr = variable.GetLoadAddress(); addr != LLDB_INVALID_ADDRESS) body.try_emplace("memoryReference", EncodeMemoryReference(addr)); + if (HasValueLocation(variable)) + body.try_emplace("valueLocationReference", new_var_ref); } else { EmplaceSafeString(body, "message", std::string(error.GetCString())); } @@ -4104,10 +4131,13 @@ void request_variables(const llvm::json::Object &request) { void request_locations(const llvm::json::Object &request) { llvm::json::Object response; FillResponse(request, response); - auto arguments = request.getObject("arguments"); + auto *arguments = request.getObject("arguments"); uint64_t reference_id = GetUnsigned(arguments, "locationReference", 0); - lldb::SBValue variable = g_dap.variables.GetVariable(reference_id); + // We use the lowest bit to distinguish between value location and declaration + // location + bool isValueLocation = reference_id & 1; + lldb::SBValue variable = g_dap.variables.GetVariable(reference_id >> 1); if (!variable.IsValid()) { response["success"] = false; response["message"] = "Invalid variable reference"; @@ -4115,21 +4145,50 @@ void request_locations(const llvm::json::Object &request) { return; } - // Get the declaration location - lldb::SBDeclaration decl = variable.GetDeclaration(); - if (!decl.IsValid()) { - response["success"] = false; - response["message"] = "No declaration location available"; - g_dap.SendJSON(llvm::json::Value(std::move(response))); - return; - } - llvm::json::Object body; - body.try_emplace("source", CreateSource(decl.GetFileSpec())); - if (int line = decl.GetLine()) - body.try_emplace("line", line); - if (int column = decl.GetColumn()) - body.try_emplace("column", column); + if (isValueLocation) { + // Get the value location + if (!variable.GetType().IsPointerType() && + !variable.GetType().IsReferenceType()) { + response["success"] = false; + response["message"] = + "Value locations are only available for pointers and references"; + g_dap.SendJSON(llvm::json::Value(std::move(response))); + return; + } + + lldb::addr_t addr = variable.GetValueAsAddress(); + lldb::SBLineEntry line_entry = + g_dap.target.ResolveLoadAddress(addr).GetLineEntry(); + + if (!line_entry.IsValid()) { + response["success"] = false; + response["message"] = "Failed to resolve line entry for location"; + g_dap.SendJSON(llvm::json::Value(std::move(response))); + return; + } + + body.try_emplace("source", CreateSource(line_entry.GetFileSpec())); + if (int line = line_entry.GetLine()) + body.try_emplace("line", line); + if (int column = line_entry.GetColumn()) + body.try_emplace("column", column); + } else { + // Get the declaration location + lldb::SBDeclaration decl = variable.GetDeclaration(); + if (!decl.IsValid()) { + response["success"] = false; + response["message"] = "No declaration location available"; + g_dap.SendJSON(llvm::json::Value(std::move(response))); + return; + } + + body.try_emplace("source", CreateSource(decl.GetFileSpec())); + if (int line = decl.GetLine()) + body.try_emplace("line", line); + if (int column = decl.GetColumn()) + body.try_emplace("column", column); + } response.try_emplace("body", std::move(body)); g_dap.SendJSON(llvm::json::Value(std::move(response))); >From fe2a773d55320e17c516c90e4db140b082c3c2a5 Mon Sep 17 00:00:00 2001 From: Adrian Vogelsgesang <avogelsges...@salesforce.com> Date: Wed, 18 Sep 2024 14:30:13 +0000 Subject: [PATCH 2/4] Address comments --- lldb/tools/lldb-dap/JSONUtils.cpp | 12 ++++++++++-- lldb/tools/lldb-dap/JSONUtils.h | 7 +++++++ lldb/tools/lldb-dap/lldb-dap.cpp | 12 +++++++----- 3 files changed, 24 insertions(+), 7 deletions(-) diff --git a/lldb/tools/lldb-dap/JSONUtils.cpp b/lldb/tools/lldb-dap/JSONUtils.cpp index 1d3fc110791d2f..1a011a50549d9d 100644 --- a/lldb/tools/lldb-dap/JSONUtils.cpp +++ b/lldb/tools/lldb-dap/JSONUtils.cpp @@ -1210,6 +1210,14 @@ bool HasValueLocation(lldb::SBValue v) { return line_entry.IsValid(); } +int64_t PackLocation(int64_t var_ref, bool is_value_location) { + return var_ref << 1 | is_value_location; +} + +std::pair<int64_t, bool> UnpackLocation(int64_t location_id) { + return std::pair{ location_id >> 1, location_id & 1}; +} + // "Variable": { // "type": "object", // "description": "A Variable is a name/value pair. Optionally a variable @@ -1414,10 +1422,10 @@ llvm::json::Value CreateVariable(lldb::SBValue v, int64_t var_ref, object.try_emplace("variablesReference", 0); if (v.GetDeclaration().IsValid()) - object.try_emplace("declarationLocationReference", var_ref << 1); + object.try_emplace("declarationLocationReference", PackLocation(var_ref, false)); if (HasValueLocation(v)) - object.try_emplace("valueLocationReference", (var_ref << 1) | 1); + object.try_emplace("valueLocationReference", PackLocation(var_ref, true)); if (lldb::addr_t addr = v.GetLoadAddress(); addr != LLDB_INVALID_ADDRESS) object.try_emplace("memoryReference", EncodeMemoryReference(addr)); diff --git a/lldb/tools/lldb-dap/JSONUtils.h b/lldb/tools/lldb-dap/JSONUtils.h index 0e00c0e6bcb8c5..a28b1b20cbaf01 100644 --- a/lldb/tools/lldb-dap/JSONUtils.h +++ b/lldb/tools/lldb-dap/JSONUtils.h @@ -461,6 +461,13 @@ struct VariableDescription { /// Does the given variable have an associated value location? bool HasValueLocation(lldb::SBValue v); +/// Pack a location into a single integer which we can send via +/// the debug adapter protocol. +int64_t PackLocation(int64_t var_ref, bool is_value_location); + +/// Reverse of `PackLocation` +std::pair<int64_t, bool> UnpackLocation(int64_t location_id); + /// Create a "Variable" object for a LLDB thread object. /// /// This function will fill in the following keys in the returned diff --git a/lldb/tools/lldb-dap/lldb-dap.cpp b/lldb/tools/lldb-dap/lldb-dap.cpp index b4fd1a00cbbac7..5a11ee1d865a3a 100644 --- a/lldb/tools/lldb-dap/lldb-dap.cpp +++ b/lldb/tools/lldb-dap/lldb-dap.cpp @@ -1641,7 +1641,9 @@ void request_evaluate(const llvm::json::Object &request) { VariableDescription desc(value); EmplaceSafeString(body, "result", desc.GetResult(context)); EmplaceSafeString(body, "type", desc.display_type_name); - auto var_ref = g_dap.variables.InsertVariable( + int64_t var_ref = 0; + if (value.MightHaveChildren() || HasValueLocation(value)) + var_ref = g_dap.variables.InsertVariable( value, /*is_permanent=*/context == "repl"); if (value.MightHaveChildren()) body.try_emplace("variablesReference", var_ref); @@ -4133,11 +4135,11 @@ void request_locations(const llvm::json::Object &request) { FillResponse(request, response); auto *arguments = request.getObject("arguments"); - uint64_t reference_id = GetUnsigned(arguments, "locationReference", 0); + uint64_t location_id = GetUnsigned(arguments, "locationReference", 0); // We use the lowest bit to distinguish between value location and declaration // location - bool isValueLocation = reference_id & 1; - lldb::SBValue variable = g_dap.variables.GetVariable(reference_id >> 1); + auto [var_ref, is_value_location] = UnpackLocation(location_id); + lldb::SBValue variable = g_dap.variables.GetVariable(var_ref); if (!variable.IsValid()) { response["success"] = false; response["message"] = "Invalid variable reference"; @@ -4146,7 +4148,7 @@ void request_locations(const llvm::json::Object &request) { } llvm::json::Object body; - if (isValueLocation) { + if (is_value_location) { // Get the value location if (!variable.GetType().IsPointerType() && !variable.GetType().IsReferenceType()) { >From ae6e7d2e6d3f90f2d99a8d2a63b9b69fe1cde18f Mon Sep 17 00:00:00 2001 From: Adrian Vogelsgesang <avogelsges...@salesforce.com> Date: Wed, 18 Sep 2024 21:19:00 +0000 Subject: [PATCH 3/4] Address comments (2) --- lldb/test/API/tools/lldb-dap/locations/main.cpp | 3 +-- lldb/tools/lldb-dap/JSONUtils.cpp | 7 +++---- lldb/tools/lldb-dap/JSONUtils.h | 2 +- lldb/tools/lldb-dap/lldb-dap.cpp | 6 +++--- 4 files changed, 8 insertions(+), 10 deletions(-) diff --git a/lldb/test/API/tools/lldb-dap/locations/main.cpp b/lldb/test/API/tools/lldb-dap/locations/main.cpp index e3b2e73f9837f8..fb7789ffd86fdf 100644 --- a/lldb/test/API/tools/lldb-dap/locations/main.cpp +++ b/lldb/test/API/tools/lldb-dap/locations/main.cpp @@ -6,6 +6,5 @@ int main(void) { int var1 = 1; void (*func_ptr)() = &greet; void (&func_ref)() = greet; - __builtin_printf("break here"); - return 0; + return 0; // break here } diff --git a/lldb/tools/lldb-dap/JSONUtils.cpp b/lldb/tools/lldb-dap/JSONUtils.cpp index 1a011a50549d9d..7f77f357e25400 100644 --- a/lldb/tools/lldb-dap/JSONUtils.cpp +++ b/lldb/tools/lldb-dap/JSONUtils.cpp @@ -1198,10 +1198,9 @@ std::string VariableDescription::GetResult(llvm::StringRef context) { return description.trim().str(); } -bool HasValueLocation(lldb::SBValue v) { - if (!v.GetType().IsPointerType() && !v.GetType().IsReferenceType()) { +bool ValuePointsToCode(lldb::SBValue v) { + if (!v.GetType().GetPointeeType().IsFunctionType()) return false; - } lldb::addr_t addr = v.GetValueAsAddress(); lldb::SBLineEntry line_entry = @@ -1424,7 +1423,7 @@ llvm::json::Value CreateVariable(lldb::SBValue v, int64_t var_ref, if (v.GetDeclaration().IsValid()) object.try_emplace("declarationLocationReference", PackLocation(var_ref, false)); - if (HasValueLocation(v)) + if (ValuePointsToCode(v)) object.try_emplace("valueLocationReference", PackLocation(var_ref, true)); if (lldb::addr_t addr = v.GetLoadAddress(); addr != LLDB_INVALID_ADDRESS) diff --git a/lldb/tools/lldb-dap/JSONUtils.h b/lldb/tools/lldb-dap/JSONUtils.h index a28b1b20cbaf01..aa3df62ebef7fd 100644 --- a/lldb/tools/lldb-dap/JSONUtils.h +++ b/lldb/tools/lldb-dap/JSONUtils.h @@ -459,7 +459,7 @@ struct VariableDescription { }; /// Does the given variable have an associated value location? -bool HasValueLocation(lldb::SBValue v); +bool ValuePointsToCode(lldb::SBValue v); /// Pack a location into a single integer which we can send via /// the debug adapter protocol. diff --git a/lldb/tools/lldb-dap/lldb-dap.cpp b/lldb/tools/lldb-dap/lldb-dap.cpp index 5a11ee1d865a3a..a7219fa6e6af60 100644 --- a/lldb/tools/lldb-dap/lldb-dap.cpp +++ b/lldb/tools/lldb-dap/lldb-dap.cpp @@ -1642,7 +1642,7 @@ void request_evaluate(const llvm::json::Object &request) { EmplaceSafeString(body, "result", desc.GetResult(context)); EmplaceSafeString(body, "type", desc.display_type_name); int64_t var_ref = 0; - if (value.MightHaveChildren() || HasValueLocation(value)) + if (value.MightHaveChildren() || ValuePointsToCode(value)) var_ref = g_dap.variables.InsertVariable( value, /*is_permanent=*/context == "repl"); if (value.MightHaveChildren()) @@ -1652,7 +1652,7 @@ void request_evaluate(const llvm::json::Object &request) { if (lldb::addr_t addr = value.GetLoadAddress(); addr != LLDB_INVALID_ADDRESS) body.try_emplace("memoryReference", EncodeMemoryReference(addr)); - if (HasValueLocation(value)) + if (ValuePointsToCode(value)) body.try_emplace("valueLocationReference", var_ref); } } @@ -3841,7 +3841,7 @@ void request_setVariable(const llvm::json::Object &request) { if (lldb::addr_t addr = variable.GetLoadAddress(); addr != LLDB_INVALID_ADDRESS) body.try_emplace("memoryReference", EncodeMemoryReference(addr)); - if (HasValueLocation(variable)) + if (ValuePointsToCode(variable)) body.try_emplace("valueLocationReference", new_var_ref); } else { EmplaceSafeString(body, "message", std::string(error.GetCString())); >From aea1c701a2567886683cb409b2c6c9126e422e41 Mon Sep 17 00:00:00 2001 From: Adrian Vogelsgesang <avogelsges...@salesforce.com> Date: Sat, 21 Sep 2024 22:53:30 +0000 Subject: [PATCH 4/4] code formatting --- lldb/tools/lldb-dap/JSONUtils.cpp | 7 ++++--- lldb/tools/lldb-dap/lldb-dap.cpp | 4 ++-- 2 files changed, 6 insertions(+), 5 deletions(-) diff --git a/lldb/tools/lldb-dap/JSONUtils.cpp b/lldb/tools/lldb-dap/JSONUtils.cpp index 7f77f357e25400..d55742e44bd17c 100644 --- a/lldb/tools/lldb-dap/JSONUtils.cpp +++ b/lldb/tools/lldb-dap/JSONUtils.cpp @@ -1210,11 +1210,11 @@ bool ValuePointsToCode(lldb::SBValue v) { } int64_t PackLocation(int64_t var_ref, bool is_value_location) { - return var_ref << 1 | is_value_location; + return var_ref << 1 | is_value_location; } std::pair<int64_t, bool> UnpackLocation(int64_t location_id) { - return std::pair{ location_id >> 1, location_id & 1}; + return std::pair{location_id >> 1, location_id & 1}; } // "Variable": { @@ -1421,7 +1421,8 @@ llvm::json::Value CreateVariable(lldb::SBValue v, int64_t var_ref, object.try_emplace("variablesReference", 0); if (v.GetDeclaration().IsValid()) - object.try_emplace("declarationLocationReference", PackLocation(var_ref, false)); + object.try_emplace("declarationLocationReference", + PackLocation(var_ref, false)); if (ValuePointsToCode(v)) object.try_emplace("valueLocationReference", PackLocation(var_ref, true)); diff --git a/lldb/tools/lldb-dap/lldb-dap.cpp b/lldb/tools/lldb-dap/lldb-dap.cpp index a7219fa6e6af60..bfd65d7dbfa146 100644 --- a/lldb/tools/lldb-dap/lldb-dap.cpp +++ b/lldb/tools/lldb-dap/lldb-dap.cpp @@ -1643,8 +1643,8 @@ void request_evaluate(const llvm::json::Object &request) { EmplaceSafeString(body, "type", desc.display_type_name); int64_t var_ref = 0; if (value.MightHaveChildren() || ValuePointsToCode(value)) - var_ref = g_dap.variables.InsertVariable( - value, /*is_permanent=*/context == "repl"); + var_ref = g_dap.variables.InsertVariable( + value, /*is_permanent=*/context == "repl"); if (value.MightHaveChildren()) body.try_emplace("variablesReference", var_ref); else _______________________________________________ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits