[Lldb-commits] [lldb] [lldb-dap] Add valueLocationReference for member function pointers (PR #186837)

via lldb-commits lldb-commits at lists.llvm.org
Mon Mar 16 09:48:12 PDT 2026


llvmbot wrote:


<!--LLVM PR SUMMARY COMMENT-->

@llvm/pr-subscribers-lldb

Author: Sergei Druzhkov (DrSergei)

<details>
<summary>Changes</summary>

Added `valueLocationReference` for member function pointers. Also changed `GetValueAsAddress`, because original implementation doesn't work for member function pointers. New implementation is inspired by [CXXFunctionPointerSummaryProvider](https://github.com/llvm/llvm-project/blob/main/lldb/source/DataFormatters/CXXFunctionPointer.cpp#L27).

---
Full diff: https://github.com/llvm/llvm-project/pull/186837.diff


6 Files Affected:

- (modified) lldb/include/lldb/API/SBType.h (+4) 
- (modified) lldb/source/API/SBType.cpp (+16) 
- (modified) lldb/source/API/SBValue.cpp (+3-4) 
- (modified) lldb/test/API/tools/lldb-dap/locations/TestDAP_locations.py (+23-3) 
- (modified) lldb/test/API/tools/lldb-dap/locations/main.cpp (+5) 
- (modified) lldb/tools/lldb-dap/JSONUtils.cpp (+3-1) 


``````````diff
diff --git a/lldb/include/lldb/API/SBType.h b/lldb/include/lldb/API/SBType.h
index 9ad3244686328..234f65f4d177b 100644
--- a/lldb/include/lldb/API/SBType.h
+++ b/lldb/include/lldb/API/SBType.h
@@ -158,6 +158,10 @@ class SBType {
 
   bool IsFunctionType();
 
+  bool IsFunctionPointerType();
+
+  bool IsMemberFunctionPointerType();
+
   bool IsPolymorphicClass();
 
   bool IsArrayType();
diff --git a/lldb/source/API/SBType.cpp b/lldb/source/API/SBType.cpp
index f58902dcf44d8..065c954b97090 100644
--- a/lldb/source/API/SBType.cpp
+++ b/lldb/source/API/SBType.cpp
@@ -258,6 +258,22 @@ bool SBType::IsFunctionType() {
   return m_opaque_sp->GetCompilerType(true).IsFunctionType();
 }
 
+bool SBType::IsFunctionPointerType() {
+  LLDB_INSTRUMENT_VA(this);
+
+  if (!IsValid())
+    return false;
+  return m_opaque_sp->GetCompilerType(true).IsFunctionPointerType();
+}
+
+bool SBType::IsMemberFunctionPointerType() {
+  LLDB_INSTRUMENT_VA(this);
+
+  if (!IsValid())
+    return false;
+  return m_opaque_sp->GetCompilerType(true).IsMemberFunctionPointerType();
+}
+
 bool SBType::IsPolymorphicClass() {
   LLDB_INSTRUMENT_VA(this);
 
diff --git a/lldb/source/API/SBValue.cpp b/lldb/source/API/SBValue.cpp
index adc03785602e1..df34bf58b34df 100644
--- a/lldb/source/API/SBValue.cpp
+++ b/lldb/source/API/SBValue.cpp
@@ -46,6 +46,7 @@
 #include "lldb/API/SBTarget.h"
 #include "lldb/API/SBThread.h"
 #include "lldb/lldb-enumerations.h"
+#include "lldb/lldb-private-enumerations.h"
 
 #include <memory>
 
@@ -786,10 +787,8 @@ lldb::addr_t SBValue::GetValueAsAddress() {
   ValueLocker locker;
   lldb::ValueObjectSP value_sp(GetSP(locker));
   if (value_sp) {
-    bool success = true;
-    uint64_t ret_val = fail_value;
-    ret_val = value_sp->GetValueAsUnsigned(fail_value, &success);
-    if (!success)
+    auto [ret_val, type] = value_sp->GetPointerValue();
+    if (type != eAddressTypeLoad)
       return fail_value;
     ProcessSP process_sp = m_opaque_sp->GetProcessSP();
     if (!process_sp)
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 45f836a2fa3c3..12eeeca72da37 100644
--- a/lldb/test/API/tools/lldb-dap/locations/TestDAP_locations.py
+++ b/lldb/test/API/tools/lldb-dap/locations/TestDAP_locations.py
@@ -37,7 +37,7 @@ def test_locations(self):
         )
         self.assertTrue(loc_var1["success"])
         self.assertTrue(loc_var1["body"]["source"]["path"].endswith("main.cpp"))
-        self.assertEqual(loc_var1["body"]["line"], 6)
+        self.assertEqual(loc_var1["body"]["line"], 10)
 
         # func_ptr has both a declaration and a valueLocation
         self.assertIn("declarationLocationReference", locals["func_ptr"].keys())
@@ -49,7 +49,7 @@ def test_locations(self):
         self.assertTrue(
             decl_loc_func_ptr["body"]["source"]["path"].endswith("main.cpp")
         )
-        self.assertEqual(decl_loc_func_ptr["body"]["line"], 7)
+        self.assertEqual(decl_loc_func_ptr["body"]["line"], 11)
         val_loc_func_ptr = self.dap_server.request_locations(
             locals["func_ptr"]["valueLocationReference"]
         )
@@ -67,7 +67,7 @@ def test_locations(self):
         self.assertTrue(
             decl_loc_func_ref["body"]["source"]["path"].endswith("main.cpp")
         )
-        self.assertEqual(decl_loc_func_ref["body"]["line"], 8)
+        self.assertEqual(decl_loc_func_ref["body"]["line"], 12)
         val_loc_func_ref = self.dap_server.request_locations(
             locals["func_ref"]["valueLocationReference"]
         )
@@ -75,6 +75,26 @@ def test_locations(self):
         self.assertTrue(val_loc_func_ref["body"]["source"]["path"].endswith("main.cpp"))
         self.assertEqual(val_loc_func_ref["body"]["line"], 3)
 
+        # member_ptr has both a declaration and a valueLocation
+        self.assertIn("declarationLocationReference", locals["member_ptr"].keys())
+        self.assertIn("valueLocationReference", locals["member_ptr"].keys())
+        decl_loc_member_ptr = self.dap_server.request_locations(
+            locals["member_ptr"]["declarationLocationReference"]
+        )
+        self.assertTrue(decl_loc_member_ptr["success"])
+        self.assertTrue(
+            decl_loc_member_ptr["body"]["source"]["path"].endswith("main.cpp")
+        )
+        self.assertEqual(decl_loc_member_ptr["body"]["line"], 13)
+        val_loc_member_ptr = self.dap_server.request_locations(
+            locals["member_ptr"]["valueLocationReference"]
+        )
+        self.assertTrue(val_loc_member_ptr["success"])
+        self.assertTrue(
+            val_loc_member_ptr["body"]["source"]["path"].endswith("main.cpp")
+        )
+        self.assertEqual(val_loc_member_ptr["body"]["line"], 6)
+
         # `evaluate` responses for function pointers also have locations associated
         eval_res = self.dap_server.request_evaluate("greet")
         self.assertTrue(eval_res["success"])
diff --git a/lldb/test/API/tools/lldb-dap/locations/main.cpp b/lldb/test/API/tools/lldb-dap/locations/main.cpp
index fb7789ffd86fd..d5faf21eb7cb6 100644
--- a/lldb/test/API/tools/lldb-dap/locations/main.cpp
+++ b/lldb/test/API/tools/lldb-dap/locations/main.cpp
@@ -2,9 +2,14 @@
 
 void greet() { printf("Hello"); }
 
+struct test {
+  void foo() {}
+};
+
 int main(void) {
   int var1 = 1;
   void (*func_ptr)() = &greet;
   void (&func_ref)() = greet;
+  auto member_ptr = &test::foo;
   return 0; // break here
 }
diff --git a/lldb/tools/lldb-dap/JSONUtils.cpp b/lldb/tools/lldb-dap/JSONUtils.cpp
index d75b4e23d0e46..40086ef84d67d 100644
--- a/lldb/tools/lldb-dap/JSONUtils.cpp
+++ b/lldb/tools/lldb-dap/JSONUtils.cpp
@@ -338,7 +338,9 @@ std::string VariableDescription::GetResult(protocol::EvaluateContext context) {
 }
 
 bool ValuePointsToCode(lldb::SBValue v) {
-  if (!v.GetType().GetPointeeType().IsFunctionType())
+  lldb::SBType type = v.GetType();
+  if (!(type.IsFunctionPointerType() || type.IsMemberFunctionPointerType() ||
+        type.GetReferenceType().IsFunctionType()))
     return false;
 
   lldb::addr_t addr = v.GetValueAsAddress();

``````````

</details>


https://github.com/llvm/llvm-project/pull/186837


More information about the lldb-commits mailing list