[lldb] Add SBFunction::GetBaseName() & SBSymbol::GetBaseName() (#155939)

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
This commit is contained in:
Jonas Devlieghere
2025-08-28 19:10:52 -07:00
committed by GitHub
parent 205d461a19
commit 2a062d6936
9 changed files with 103 additions and 0 deletions

View File

@@ -36,6 +36,8 @@ public:
const char *GetMangledName() const;
const char *GetBaseName() const;
lldb::SBInstructionList GetInstructions(lldb::SBTarget target);
lldb::SBInstructionList GetInstructions(lldb::SBTarget target,

View File

@@ -36,6 +36,8 @@ public:
const char *GetMangledName() const;
const char *GetBaseName() const;
lldb::SBInstructionList GetInstructions(lldb::SBTarget target);
lldb::SBInstructionList GetInstructions(lldb::SBTarget target,

View File

@@ -287,6 +287,17 @@ public:
/// 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".
///
/// \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

View File

@@ -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);

View File

@@ -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);

View File

@@ -556,3 +556,18 @@ void Mangled::Encode(DataEncoder &file, ConstStringTable &strtab) const {
break;
}
}
ConstString Mangled::GetBaseName() const {
const auto &demangled_info = GetDemangledInfo();
if (!demangled_info.has_value())
return {};
ConstString demangled_name = GetDemangledName();
if (!demangled_name)
return {};
const char *name_str = demangled_name.AsCString();
const auto &range = demangled_info->BasenameRange;
return ConstString(
llvm::StringRef(name_str + range.first, range.second - range.first));
}

View File

@@ -0,0 +1,3 @@
CXX_SOURCES := main.cpp
include Makefile.rules

View File

@@ -0,0 +1,36 @@
"""
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):
TestBase.setUp(self)
self.main_source_file = lldb.SBFileSpec("main.cpp")
def test(self):
"""Test SBFunction.GetBaseName() and SBSymbol.GetBaseName()"""
self.build()
_, _, thread, _ = lldbutil.run_to_source_breakpoint(
self, "Set a breakpoint here", self.main_source_file
)
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")

View File

@@ -0,0 +1,16 @@
#include <iostream>
namespace ns {
template <typename T> class MyClass {
public:
void templateFunc() {
std::cout << "In templateFunc" << std::endl; // Set a breakpoint here
}
};
} // namespace ns
int main() {
ns::MyClass<int> obj;
obj.templateFunc();
return 0;
}