Skip to content

Commit 1fafdee

Browse files
[lldb][[DWARFDeclContext] Add function to extract qualified names as vector
1 parent 80aeb62 commit 1fafdee

File tree

3 files changed

+120
-0
lines changed

3 files changed

+120
-0
lines changed

lldb/source/Plugins/SymbolFile/DWARF/DWARFDeclContext.cpp

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,12 @@ const char *DWARFDeclContext::GetQualifiedName() const {
5555
return m_qualified_name.c_str();
5656
}
5757

58+
llvm::SmallVector<llvm::StringRef>
59+
DWARFDeclContext::GetQualifiedNameAsVector() const {
60+
return llvm::to_vector_of<llvm::StringRef>(
61+
llvm::map_range(m_entries, GetName));
62+
}
63+
5864
bool DWARFDeclContext::operator==(const DWARFDeclContext &rhs) const {
5965
if (m_entries.size() != rhs.m_entries.size())
6066
return false;

lldb/source/Plugins/SymbolFile/DWARF/DWARFDeclContext.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -68,6 +68,11 @@ class DWARFDeclContext {
6868

6969
const char *GetQualifiedName() const;
7070

71+
/// Returns a vector of string, one string per entry in the fully qualified
72+
/// name. For example, for the name `A::B::C`, this methods returns `{"A",
73+
/// "B", "C"}`
74+
llvm::SmallVector<llvm::StringRef> GetQualifiedNameAsVector() const;
75+
7176
// Same as GetQualifiedName, but the life time of the returned string will
7277
// be that of the LLDB session.
7378
ConstString GetQualifiedNameAsConstString() const {

lldb/unittests/SymbolFile/DWARF/DWARFDIETest.cpp

Lines changed: 109 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,8 +7,10 @@
77
//===----------------------------------------------------------------------===//
88

99
#include "Plugins/SymbolFile/DWARF/DWARFDIE.h"
10+
#include "Plugins/SymbolFile/DWARF/DWARFDeclContext.h"
1011
#include "TestingSupport/Symbol/YAMLModuleTester.h"
1112
#include "llvm/ADT/STLExtras.h"
13+
#include "llvm/ADT/StringRef.h"
1214
#include "gmock/gmock.h"
1315
#include "gtest/gtest.h"
1416

@@ -104,3 +106,110 @@ TEST(DWARFDIETest, ChildIteration) {
104106
DWARFDIE no_children_die(unit, die_child0);
105107
EXPECT_TRUE(no_children_die.children().empty());
106108
}
109+
110+
TEST(DWARFDIETest, DeclContext) {
111+
const char *yamldata = R"(
112+
--- !ELF
113+
FileHeader:
114+
Class: ELFCLASS64
115+
Data: ELFDATA2LSB
116+
Type: ET_EXEC
117+
Machine: EM_386
118+
DWARF:
119+
debug_str:
120+
- 'mynamespace'
121+
- 'mystruct'
122+
- 'mytype'
123+
debug_abbrev:
124+
- Table:
125+
- Code: 0x00000001
126+
Tag: DW_TAG_compile_unit
127+
Children: DW_CHILDREN_yes
128+
Attributes:
129+
- Attribute: DW_AT_language
130+
Form: DW_FORM_data2
131+
- Code: 0x00000002
132+
Tag: DW_TAG_structure_type
133+
Children: DW_CHILDREN_yes
134+
Attributes:
135+
- Attribute: DW_AT_name
136+
Form: DW_FORM_strp
137+
- Code: 0x00000003
138+
Tag: DW_TAG_base_type
139+
Children: DW_CHILDREN_no
140+
Attributes:
141+
- Attribute: DW_AT_name
142+
Form: DW_FORM_strp
143+
- Code: 0x00000004
144+
Tag: DW_TAG_namespace
145+
Children: DW_CHILDREN_yes
146+
Attributes:
147+
- Attribute: DW_AT_name
148+
Form: DW_FORM_strp
149+
debug_info:
150+
- Version: 4
151+
AddrSize: 8
152+
Entries:
153+
- AbbrCode: 0x00000001 # compile_unit
154+
Values:
155+
- Value: 0x000000000000000C
156+
- AbbrCode: 0x00000004 # namespace
157+
Values:
158+
- Value: 0x0000000000000000 # DW_ATE_strp
159+
- AbbrCode: 0x00000002 # structure_type
160+
Values:
161+
- Value: 0x000000000000000c # DW_ATE_strp
162+
- AbbrCode: 0x00000003 # base_type
163+
Values:
164+
- Value: 0x0000000000000015 # DW_ATE_strp
165+
- AbbrCode: 0x00000000
166+
)";
167+
168+
YAMLModuleTester t(yamldata);
169+
DWARFUnit *unit = t.GetDwarfUnit();
170+
ASSERT_TRUE(unit != nullptr);
171+
auto &ctx = unit->GetSymbolFileDWARF();
172+
173+
auto top_level_die = unit->DIE();
174+
{
175+
ASSERT_TRUE(top_level_die);
176+
auto top_level_ctx = ctx.GetDWARFDeclContext(top_level_die);
177+
auto top_level_name = llvm::StringRef(top_level_ctx.GetQualifiedName());
178+
ASSERT_EQ(top_level_name, "");
179+
}
180+
181+
auto namespace_die = top_level_die.GetFirstChild();
182+
{
183+
ASSERT_TRUE(namespace_die);
184+
auto namespace_ctx = ctx.GetDWARFDeclContext(namespace_die);
185+
auto namespace_name = llvm::StringRef(namespace_ctx.GetQualifiedName());
186+
ASSERT_EQ(namespace_name, "::mynamespace");
187+
auto namespace_names = namespace_ctx.GetQualifiedNameAsVector();
188+
ASSERT_EQ(namespace_names.size(), 1u);
189+
ASSERT_EQ(namespace_names.front(), "mynamespace");
190+
}
191+
192+
auto struct_die = namespace_die.GetFirstChild();
193+
{
194+
ASSERT_TRUE(struct_die);
195+
auto struct_ctx = ctx.GetDWARFDeclContext(struct_die);
196+
auto struct_name = llvm::StringRef(struct_ctx.GetQualifiedName());
197+
ASSERT_EQ(struct_name, "mynamespace::mystruct");
198+
auto struct_names = struct_ctx.GetQualifiedNameAsVector();
199+
ASSERT_EQ(struct_names.size(), 2u);
200+
ASSERT_EQ(struct_names[0], "mystruct");
201+
ASSERT_EQ(struct_names[1], "mynamespace");
202+
}
203+
auto simple_type_die = struct_die.GetFirstChild();
204+
{
205+
ASSERT_TRUE(simple_type_die);
206+
auto simple_type_ctx = ctx.GetDWARFDeclContext(simple_type_die);
207+
auto simple_type_name = llvm::StringRef(simple_type_ctx.GetQualifiedName());
208+
ASSERT_EQ(simple_type_name, "mynamespace::mystruct::mytype");
209+
auto simple_type_names = simple_type_ctx.GetQualifiedNameAsVector();
210+
ASSERT_EQ(simple_type_names.size(), 3u);
211+
ASSERT_EQ(simple_type_names[0], "mytype");
212+
ASSERT_EQ(simple_type_names[1], "mystruct");
213+
ASSERT_EQ(simple_type_names[2], "mynamespace");
214+
}
215+
}

0 commit comments

Comments
 (0)