[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