Skip to content

Commit 87e6eee

Browse files
committed
[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
1 parent 1213d4e commit 87e6eee

File tree

9 files changed

+126
-0
lines changed

9 files changed

+126
-0
lines changed

lldb/include/lldb/API/SBFunction.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,8 @@ class LLDB_API SBFunction {
3636

3737
const char *GetMangledName() const;
3838

39+
const char *GetBaseName() const;
40+
3941
lldb::SBInstructionList GetInstructions(lldb::SBTarget target);
4042

4143
lldb::SBInstructionList GetInstructions(lldb::SBTarget target,

lldb/include/lldb/API/SBSymbol.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,8 @@ class LLDB_API SBSymbol {
3636

3737
const char *GetMangledName() const;
3838

39+
const char *GetBaseName() const;
40+
3941
lldb::SBInstructionList GetInstructions(lldb::SBTarget target);
4042

4143
lldb::SBInstructionList GetInstructions(lldb::SBTarget target,

lldb/include/lldb/Core/Mangled.h

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -287,6 +287,18 @@ class Mangled {
287287
/// Retrieve \c DemangledNameInfo of the demangled name held by this object.
288288
const std::optional<DemangledNameInfo> &GetDemangledInfo() const;
289289

290+
/// Compute the base name (without namespace/class qualifiers) from the
291+
/// demangled name.
292+
///
293+
/// For a demangled name like "ns::MyClass<int>::templateFunc", this returns
294+
/// just "templateFunc". If the demangled name is not available or the
295+
/// basename range is invalid, this falls back to GetDisplayDemangledName().
296+
///
297+
/// \return
298+
/// A ConstString containing the basename, or nullptr if computation
299+
/// fails.
300+
ConstString GetBaseName() const;
301+
290302
private:
291303
/// If \c force is \c false, this function will re-use the previously
292304
/// demangled name (if any). If \c force is \c true (or the mangled name

lldb/source/API/SBFunction.cpp

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -79,6 +79,15 @@ const char *SBFunction::GetMangledName() const {
7979
return nullptr;
8080
}
8181

82+
const char *SBFunction::GetBaseName() const {
83+
LLDB_INSTRUMENT_VA(this);
84+
85+
if (!m_opaque_ptr)
86+
return nullptr;
87+
88+
return m_opaque_ptr->GetMangled().GetBaseName().AsCString();
89+
}
90+
8291
bool SBFunction::operator==(const SBFunction &rhs) const {
8392
LLDB_INSTRUMENT_VA(this, rhs);
8493

lldb/source/API/SBSymbol.cpp

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -79,6 +79,15 @@ const char *SBSymbol::GetMangledName() const {
7979
return name;
8080
}
8181

82+
const char *SBSymbol::GetBaseName() const {
83+
LLDB_INSTRUMENT_VA(this);
84+
85+
if (!m_opaque_ptr)
86+
return nullptr;
87+
88+
return m_opaque_ptr->GetMangled().GetBaseName().AsCString();
89+
}
90+
8291
bool SBSymbol::operator==(const SBSymbol &rhs) const {
8392
LLDB_INSTRUMENT_VA(this, rhs);
8493

lldb/source/Core/Mangled.cpp

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -556,3 +556,21 @@ void Mangled::Encode(DataEncoder &file, ConstStringTable &strtab) const {
556556
break;
557557
}
558558
}
559+
560+
ConstString Mangled::GetBaseName() const {
561+
const auto &demangled_info = GetDemangledInfo();
562+
if (!demangled_info.has_value())
563+
return GetDisplayDemangledName();
564+
565+
ConstString demangled_name = GetDemangledName();
566+
if (!demangled_name)
567+
return GetDisplayDemangledName();
568+
569+
const char *name_str = demangled_name.AsCString();
570+
const auto &range = demangled_info->BasenameRange;
571+
if (range.first >= range.second || range.second > strlen(name_str))
572+
return ConstString();
573+
574+
return ConstString(
575+
llvm::StringRef(name_str + range.first, range.second - range.first));
576+
}
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
CXX_SOURCES := main.cpp
2+
3+
include Makefile.rules
Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
"""
2+
Test SBFunction::GetBaseName() and SBSymbol::GetBaseName() APIs.
3+
"""
4+
5+
import lldb
6+
from lldbsuite.test.decorators import *
7+
from lldbsuite.test.lldbtest import *
8+
from lldbsuite.test import lldbutil
9+
10+
11+
class GetBaseNameTestCase(TestBase):
12+
13+
NO_DEBUG_INFO_TESTCASE = True
14+
15+
def setUp(self):
16+
# Call super's setUp().
17+
TestBase.setUp(self)
18+
# Find the line number to break on.
19+
self.line1 = line_number(
20+
"main.cpp", "// Find the line number for breakpoint 1 here."
21+
)
22+
23+
def test(self):
24+
"""Test SBFunction.GetBaseName() and SBSymbol.GetBaseName()"""
25+
self.build()
26+
exe = self.getBuildArtifact("a.out")
27+
28+
# Create a target by the debugger.
29+
target = self.dbg.CreateTarget(exe)
30+
self.assertTrue(target, VALID_TARGET)
31+
32+
# Create a breakpoint inside the C++ namespaced function.
33+
breakpoint1 = target.BreakpointCreateByLocation("main.cpp", self.line1)
34+
35+
# Now launch the process, and do not stop at entry point.
36+
process = target.LaunchSimple(None, None, self.get_process_working_directory())
37+
38+
# Get stopped thread and frame
39+
thread = lldbutil.get_stopped_thread(process, lldb.eStopReasonBreakpoint)
40+
frame0 = thread.GetFrameAtIndex(0)
41+
42+
# Get both function and symbol
43+
function = frame0.GetFunction()
44+
symbol = frame0.GetSymbol()
45+
46+
# Test consistency between function and symbol basename
47+
function_basename = function.GetBaseName()
48+
symbol_basename = symbol.GetBaseName()
49+
50+
self.assertEqual(function_basename, "templateFunc")
51+
self.assertEqual(symbol_basename, "templateFunc")
52+
53+
self.trace("Function basename:", function_basename)
54+
self.trace("Symbol basename:", symbol_basename)
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
#include <iostream>
2+
3+
namespace ns {
4+
template <typename T> class MyClass {
5+
public:
6+
void templateFunc() {
7+
std::cout << "In templateFunc"
8+
<< std::endl; // Find the line number for breakpoint 1 here.
9+
}
10+
};
11+
} // namespace ns
12+
13+
int main() {
14+
ns::MyClass<int> obj;
15+
obj.templateFunc();
16+
return 0;
17+
}

0 commit comments

Comments
 (0)