[Lldb-commits] [lldb] [lldb] Add SBFunction::GetBaseName() & SBSymbol::GetBaseName() (PR #155939)
Jonas Devlieghere via lldb-commits
lldb-commits at lists.llvm.org
Thu Aug 28 16:17:53 PDT 2025
https://github.com/JDevlieghere updated https://github.com/llvm/llvm-project/pull/155939
>From 87e6eee01196c924f4fda1093eb961f37bb6088c Mon Sep 17 00:00:00 2001
From: Jonas Devlieghere <jonas at devlieghere.com>
Date: Thu, 28 Aug 2025 15:50:29 -0700
Subject: [PATCH 1/3] [lldb] Add SBFunction::GetBaseName() &
SBSymbol::GetBaseName()
When you are trying for instance to set a breakpoint on a function by
name, but the SBFunction or SBSymbol are returning demangled names with
argument lists, that match can be tedious to do. Internally, the base
name of a symbol is something we handle all the time, so it's reasonable
that there should be a way to get that info from the API as well.
rdar://159318791
---
lldb/include/lldb/API/SBFunction.h | 2 +
lldb/include/lldb/API/SBSymbol.h | 2 +
lldb/include/lldb/Core/Mangled.h | 12 +++++
lldb/source/API/SBFunction.cpp | 9 ++++
lldb/source/API/SBSymbol.cpp | 9 ++++
lldb/source/Core/Mangled.cpp | 18 +++++++
lldb/test/API/python_api/basename/Makefile | 3 ++
.../python_api/basename/TestGetBaseName.py | 54 +++++++++++++++++++
lldb/test/API/python_api/basename/main.cpp | 17 ++++++
9 files changed, 126 insertions(+)
create mode 100644 lldb/test/API/python_api/basename/Makefile
create mode 100644 lldb/test/API/python_api/basename/TestGetBaseName.py
create mode 100644 lldb/test/API/python_api/basename/main.cpp
diff --git a/lldb/include/lldb/API/SBFunction.h b/lldb/include/lldb/API/SBFunction.h
index 0a8aeeff1ea5a..e703ae5dd63c1 100644
--- a/lldb/include/lldb/API/SBFunction.h
+++ b/lldb/include/lldb/API/SBFunction.h
@@ -36,6 +36,8 @@ class LLDB_API SBFunction {
const char *GetMangledName() const;
+ const char *GetBaseName() const;
+
lldb::SBInstructionList GetInstructions(lldb::SBTarget target);
lldb::SBInstructionList GetInstructions(lldb::SBTarget target,
diff --git a/lldb/include/lldb/API/SBSymbol.h b/lldb/include/lldb/API/SBSymbol.h
index a93bc7a7ae074..580458ede212d 100644
--- a/lldb/include/lldb/API/SBSymbol.h
+++ b/lldb/include/lldb/API/SBSymbol.h
@@ -36,6 +36,8 @@ class LLDB_API SBSymbol {
const char *GetMangledName() const;
+ const char *GetBaseName() const;
+
lldb::SBInstructionList GetInstructions(lldb::SBTarget target);
lldb::SBInstructionList GetInstructions(lldb::SBTarget target,
diff --git a/lldb/include/lldb/Core/Mangled.h b/lldb/include/lldb/Core/Mangled.h
index eb9a58c568896..99a0d7c98543c 100644
--- a/lldb/include/lldb/Core/Mangled.h
+++ b/lldb/include/lldb/Core/Mangled.h
@@ -287,6 +287,18 @@ class Mangled {
/// Retrieve \c DemangledNameInfo of the demangled name held by this object.
const std::optional<DemangledNameInfo> &GetDemangledInfo() const;
+ /// Compute the base name (without namespace/class qualifiers) from the
+ /// demangled name.
+ ///
+ /// For a demangled name like "ns::MyClass<int>::templateFunc", this returns
+ /// just "templateFunc". If the demangled name is not available or the
+ /// basename range is invalid, this falls back to GetDisplayDemangledName().
+ ///
+ /// \return
+ /// A ConstString containing the basename, or nullptr if computation
+ /// fails.
+ ConstString GetBaseName() const;
+
private:
/// If \c force is \c false, this function will re-use the previously
/// demangled name (if any). If \c force is \c true (or the mangled name
diff --git a/lldb/source/API/SBFunction.cpp b/lldb/source/API/SBFunction.cpp
index 19861f6af3645..65b02d6b309ca 100644
--- a/lldb/source/API/SBFunction.cpp
+++ b/lldb/source/API/SBFunction.cpp
@@ -79,6 +79,15 @@ const char *SBFunction::GetMangledName() const {
return nullptr;
}
+const char *SBFunction::GetBaseName() const {
+ LLDB_INSTRUMENT_VA(this);
+
+ if (!m_opaque_ptr)
+ return nullptr;
+
+ return m_opaque_ptr->GetMangled().GetBaseName().AsCString();
+}
+
bool SBFunction::operator==(const SBFunction &rhs) const {
LLDB_INSTRUMENT_VA(this, rhs);
diff --git a/lldb/source/API/SBSymbol.cpp b/lldb/source/API/SBSymbol.cpp
index 3b59119494f37..3030c83292127 100644
--- a/lldb/source/API/SBSymbol.cpp
+++ b/lldb/source/API/SBSymbol.cpp
@@ -79,6 +79,15 @@ const char *SBSymbol::GetMangledName() const {
return name;
}
+const char *SBSymbol::GetBaseName() const {
+ LLDB_INSTRUMENT_VA(this);
+
+ if (!m_opaque_ptr)
+ return nullptr;
+
+ return m_opaque_ptr->GetMangled().GetBaseName().AsCString();
+}
+
bool SBSymbol::operator==(const SBSymbol &rhs) const {
LLDB_INSTRUMENT_VA(this, rhs);
diff --git a/lldb/source/Core/Mangled.cpp b/lldb/source/Core/Mangled.cpp
index ce4db4e0daa8b..6e3c36f72155f 100644
--- a/lldb/source/Core/Mangled.cpp
+++ b/lldb/source/Core/Mangled.cpp
@@ -556,3 +556,21 @@ void Mangled::Encode(DataEncoder &file, ConstStringTable &strtab) const {
break;
}
}
+
+ConstString Mangled::GetBaseName() const {
+ const auto &demangled_info = GetDemangledInfo();
+ if (!demangled_info.has_value())
+ return GetDisplayDemangledName();
+
+ ConstString demangled_name = GetDemangledName();
+ if (!demangled_name)
+ return GetDisplayDemangledName();
+
+ const char *name_str = demangled_name.AsCString();
+ const auto &range = demangled_info->BasenameRange;
+ if (range.first >= range.second || range.second > strlen(name_str))
+ return ConstString();
+
+ return ConstString(
+ llvm::StringRef(name_str + range.first, range.second - range.first));
+}
diff --git a/lldb/test/API/python_api/basename/Makefile b/lldb/test/API/python_api/basename/Makefile
new file mode 100644
index 0000000000000..2bb9ce046a907
--- /dev/null
+++ b/lldb/test/API/python_api/basename/Makefile
@@ -0,0 +1,3 @@
+CXX_SOURCES := main.cpp
+
+include Makefile.rules
\ No newline at end of file
diff --git a/lldb/test/API/python_api/basename/TestGetBaseName.py b/lldb/test/API/python_api/basename/TestGetBaseName.py
new file mode 100644
index 0000000000000..c5b208b215800
--- /dev/null
+++ b/lldb/test/API/python_api/basename/TestGetBaseName.py
@@ -0,0 +1,54 @@
+"""
+Test SBFunction::GetBaseName() and SBSymbol::GetBaseName() APIs.
+"""
+
+import lldb
+from lldbsuite.test.decorators import *
+from lldbsuite.test.lldbtest import *
+from lldbsuite.test import lldbutil
+
+
+class GetBaseNameTestCase(TestBase):
+
+ NO_DEBUG_INFO_TESTCASE = True
+
+ def setUp(self):
+ # Call super's setUp().
+ TestBase.setUp(self)
+ # Find the line number to break on.
+ self.line1 = line_number(
+ "main.cpp", "// Find the line number for breakpoint 1 here."
+ )
+
+ def test(self):
+ """Test SBFunction.GetBaseName() and SBSymbol.GetBaseName()"""
+ self.build()
+ exe = self.getBuildArtifact("a.out")
+
+ # Create a target by the debugger.
+ target = self.dbg.CreateTarget(exe)
+ self.assertTrue(target, VALID_TARGET)
+
+ # Create a breakpoint inside the C++ namespaced function.
+ breakpoint1 = target.BreakpointCreateByLocation("main.cpp", self.line1)
+
+ # Now launch the process, and do not stop at entry point.
+ process = target.LaunchSimple(None, None, self.get_process_working_directory())
+
+ # Get stopped thread and frame
+ thread = lldbutil.get_stopped_thread(process, lldb.eStopReasonBreakpoint)
+ frame0 = thread.GetFrameAtIndex(0)
+
+ # Get both function and symbol
+ function = frame0.GetFunction()
+ symbol = frame0.GetSymbol()
+
+ # Test consistency between function and symbol basename
+ function_basename = function.GetBaseName()
+ symbol_basename = symbol.GetBaseName()
+
+ self.assertEqual(function_basename, "templateFunc")
+ self.assertEqual(symbol_basename, "templateFunc")
+
+ self.trace("Function basename:", function_basename)
+ self.trace("Symbol basename:", symbol_basename)
diff --git a/lldb/test/API/python_api/basename/main.cpp b/lldb/test/API/python_api/basename/main.cpp
new file mode 100644
index 0000000000000..17df50b4852e2
--- /dev/null
+++ b/lldb/test/API/python_api/basename/main.cpp
@@ -0,0 +1,17 @@
+#include <iostream>
+
+namespace ns {
+template <typename T> class MyClass {
+public:
+ void templateFunc() {
+ std::cout << "In templateFunc"
+ << std::endl; // Find the line number for breakpoint 1 here.
+ }
+};
+} // namespace ns
+
+int main() {
+ ns::MyClass<int> obj;
+ obj.templateFunc();
+ return 0;
+}
\ No newline at end of file
>From bcb6da2ddf25fb0473a3c0ec2f2246d886d0b221 Mon Sep 17 00:00:00 2001
From: Jonas Devlieghere <jonas at devlieghere.com>
Date: Thu, 28 Aug 2025 16:11:46 -0700
Subject: [PATCH 2/3] Fix missing newlines
---
lldb/test/API/python_api/basename/Makefile | 2 +-
lldb/test/API/python_api/basename/main.cpp | 2 +-
2 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/lldb/test/API/python_api/basename/Makefile b/lldb/test/API/python_api/basename/Makefile
index 2bb9ce046a907..99998b20bcb05 100644
--- a/lldb/test/API/python_api/basename/Makefile
+++ b/lldb/test/API/python_api/basename/Makefile
@@ -1,3 +1,3 @@
CXX_SOURCES := main.cpp
-include Makefile.rules
\ No newline at end of file
+include Makefile.rules
diff --git a/lldb/test/API/python_api/basename/main.cpp b/lldb/test/API/python_api/basename/main.cpp
index 17df50b4852e2..8b33e3a493ef3 100644
--- a/lldb/test/API/python_api/basename/main.cpp
+++ b/lldb/test/API/python_api/basename/main.cpp
@@ -14,4 +14,4 @@ int main() {
ns::MyClass<int> obj;
obj.templateFunc();
return 0;
-}
\ No newline at end of file
+}
>From 2e3bd9f4a114cf7b92fca5b09614bc1c3f4a9349 Mon Sep 17 00:00:00 2001
From: Jonas Devlieghere <jonas at devlieghere.com>
Date: Thu, 28 Aug 2025 16:17:37 -0700
Subject: [PATCH 3/3] Fix Python formatting that only darker cares about
---
lldb/test/API/python_api/basename/TestGetBaseName.py | 1 -
1 file changed, 1 deletion(-)
diff --git a/lldb/test/API/python_api/basename/TestGetBaseName.py b/lldb/test/API/python_api/basename/TestGetBaseName.py
index c5b208b215800..396c062efe566 100644
--- a/lldb/test/API/python_api/basename/TestGetBaseName.py
+++ b/lldb/test/API/python_api/basename/TestGetBaseName.py
@@ -9,7 +9,6 @@
class GetBaseNameTestCase(TestBase):
-
NO_DEBUG_INFO_TESTCASE = True
def setUp(self):
More information about the lldb-commits
mailing list