Skip to content

Commit bd47c47

Browse files
committed
[nfc] [lldb] Introduce DWARF callbacks
As requested by @labath in https://reviews.llvm.org/D73206#1949516 providing DWARF index callbacks refactorization. Differential Revision: https://reviews.llvm.org/D77327
1 parent 22e919c commit bd47c47

18 files changed

+586
-528
lines changed

lldb/include/lldb/Core/UniqueCStringMap.h

Lines changed: 16 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,10 @@ template <typename T> class UniqueCStringMap {
3232
T value;
3333
};
3434

35+
typedef std::vector<Entry> collection;
36+
typedef typename collection::iterator iterator;
37+
typedef typename collection::const_iterator const_iterator;
38+
3539
// Call this function multiple times to add a bunch of entries to this map,
3640
// then later call UniqueCStringMap<T>::Sort() before doing any searches by
3741
// name.
@@ -175,6 +179,18 @@ template <typename T> class UniqueCStringMap {
175179
}
176180
}
177181

182+
iterator begin() { return m_map.begin(); }
183+
iterator end() { return m_map.end(); }
184+
const_iterator begin() const { return m_map.begin(); }
185+
const_iterator end() const { return m_map.end(); }
186+
187+
// Range-based for loop for all entries of the specified ConstString name.
188+
llvm::iterator_range<const_iterator>
189+
equal_range(ConstString unique_cstr) const {
190+
return llvm::make_range(
191+
std::equal_range(m_map.begin(), m_map.end(), unique_cstr, Compare()));
192+
};
193+
178194
protected:
179195
struct Compare {
180196
bool operator()(const Entry &lhs, const Entry &rhs) {
@@ -196,9 +212,6 @@ template <typename T> class UniqueCStringMap {
196212
return uintptr_t(lhs.GetCString()) < uintptr_t(rhs.GetCString());
197213
}
198214
};
199-
typedef std::vector<Entry> collection;
200-
typedef typename collection::iterator iterator;
201-
typedef typename collection::const_iterator const_iterator;
202215
collection m_map;
203216
};
204217

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

Lines changed: 45 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -52,57 +52,60 @@ std::unique_ptr<AppleDWARFIndex> AppleDWARFIndex::Create(
5252
return nullptr;
5353
}
5454

55-
void AppleDWARFIndex::GetGlobalVariables(ConstString basename, DIEArray &offsets) {
55+
void AppleDWARFIndex::GetGlobalVariables(
56+
ConstString basename, llvm::function_ref<bool(DIERef ref)> callback) {
5657
if (!m_apple_names_up)
5758
return;
58-
m_apple_names_up->FindByName(basename.GetStringRef(), offsets);
59+
m_apple_names_up->FindByName(basename.GetStringRef(), callback);
5960
}
6061

61-
void AppleDWARFIndex::GetGlobalVariables(const RegularExpression &regex,
62-
DIEArray &offsets) {
62+
void AppleDWARFIndex::GetGlobalVariables(
63+
const RegularExpression &regex,
64+
llvm::function_ref<bool(DIERef ref)> callback) {
6365
if (!m_apple_names_up)
6466
return;
6567

6668
DWARFMappedHash::DIEInfoArray hash_data;
67-
if (m_apple_names_up->AppendAllDIEsThatMatchingRegex(regex, hash_data))
68-
DWARFMappedHash::ExtractDIEArray(hash_data, offsets);
69+
m_apple_names_up->AppendAllDIEsThatMatchingRegex(regex, hash_data);
70+
DWARFMappedHash::ExtractDIEArray(hash_data, callback);
6971
}
7072

71-
void AppleDWARFIndex::GetGlobalVariables(const DWARFUnit &cu,
72-
DIEArray &offsets) {
73+
void AppleDWARFIndex::GetGlobalVariables(
74+
const DWARFUnit &cu, llvm::function_ref<bool(DIERef ref)> callback) {
7375
if (!m_apple_names_up)
7476
return;
7577

7678
DWARFMappedHash::DIEInfoArray hash_data;
77-
if (m_apple_names_up->AppendAllDIEsInRange(cu.GetOffset(),
78-
cu.GetNextUnitOffset(), hash_data))
79-
DWARFMappedHash::ExtractDIEArray(hash_data, offsets);
79+
m_apple_names_up->AppendAllDIEsInRange(cu.GetOffset(), cu.GetNextUnitOffset(),
80+
hash_data);
81+
DWARFMappedHash::ExtractDIEArray(hash_data, callback);
8082
}
8183

82-
void AppleDWARFIndex::GetObjCMethods(ConstString class_name,
83-
DIEArray &offsets) {
84+
void AppleDWARFIndex::GetObjCMethods(
85+
ConstString class_name, llvm::function_ref<bool(DIERef ref)> callback) {
8486
if (!m_apple_objc_up)
8587
return;
86-
m_apple_objc_up->FindByName(class_name.GetStringRef(), offsets);
88+
m_apple_objc_up->FindByName(class_name.GetStringRef(), callback);
8789
}
8890

89-
void AppleDWARFIndex::GetCompleteObjCClass(ConstString class_name,
90-
bool must_be_implementation,
91-
DIEArray &offsets) {
91+
void AppleDWARFIndex::GetCompleteObjCClass(
92+
ConstString class_name, bool must_be_implementation,
93+
llvm::function_ref<bool(DIERef ref)> callback) {
9294
if (!m_apple_types_up)
9395
return;
9496
m_apple_types_up->FindCompleteObjCClassByName(
95-
class_name.GetStringRef(), offsets, must_be_implementation);
97+
class_name.GetStringRef(), callback, must_be_implementation);
9698
}
9799

98-
void AppleDWARFIndex::GetTypes(ConstString name, DIEArray &offsets) {
100+
void AppleDWARFIndex::GetTypes(ConstString name,
101+
llvm::function_ref<bool(DIERef ref)> callback) {
99102
if (!m_apple_types_up)
100103
return;
101-
m_apple_types_up->FindByName(name.GetStringRef(), offsets);
104+
m_apple_types_up->FindByName(name.GetStringRef(), callback);
102105
}
103106

104107
void AppleDWARFIndex::GetTypes(const DWARFDeclContext &context,
105-
DIEArray &offsets) {
108+
llvm::function_ref<bool(DIERef ref)> callback) {
106109
if (!m_apple_types_up)
107110
return;
108111

@@ -122,7 +125,7 @@ void AppleDWARFIndex::GetTypes(const DWARFDeclContext &context,
122125
if (log)
123126
m_module.LogMessage(log, "FindByNameAndTagAndQualifiedNameHash()");
124127
m_apple_types_up->FindByNameAndTagAndQualifiedNameHash(
125-
type_name.GetStringRef(), tag, qualified_name_hash, offsets);
128+
type_name.GetStringRef(), tag, qualified_name_hash, callback);
126129
return;
127130
}
128131

@@ -136,47 +139,46 @@ void AppleDWARFIndex::GetTypes(const DWARFDeclContext &context,
136139
if (!has_qualified_name_hash && (context.GetSize() > 1) &&
137140
(context[1].tag == DW_TAG_class_type ||
138141
context[1].tag == DW_TAG_structure_type)) {
139-
DIEArray class_matches;
140-
m_apple_types_up->FindByName(context[1].name, class_matches);
141-
if (class_matches.empty())
142+
if (!m_apple_types_up->FindByName(context[1].name,
143+
[&](DIERef ref) { return false; }))
142144
return;
143145
}
144146

145147
if (log)
146148
m_module.LogMessage(log, "FindByNameAndTag()");
147-
m_apple_types_up->FindByNameAndTag(type_name.GetStringRef(), tag, offsets);
149+
m_apple_types_up->FindByNameAndTag(type_name.GetStringRef(), tag, callback);
148150
return;
149151
}
150152

151-
m_apple_types_up->FindByName(type_name.GetStringRef(), offsets);
153+
m_apple_types_up->FindByName(type_name.GetStringRef(), callback);
152154
}
153155

154-
void AppleDWARFIndex::GetNamespaces(ConstString name, DIEArray &offsets) {
156+
void AppleDWARFIndex::GetNamespaces(
157+
ConstString name, llvm::function_ref<bool(DIERef ref)> callback) {
155158
if (!m_apple_namespaces_up)
156159
return;
157-
m_apple_namespaces_up->FindByName(name.GetStringRef(), offsets);
160+
m_apple_namespaces_up->FindByName(name.GetStringRef(), callback);
158161
}
159162

160-
void AppleDWARFIndex::GetFunctions(ConstString name, SymbolFileDWARF &dwarf,
161-
const CompilerDeclContext &parent_decl_ctx,
162-
uint32_t name_type_mask,
163-
std::vector<DWARFDIE> &dies) {
164-
DIEArray offsets;
165-
m_apple_names_up->FindByName(name.GetStringRef(), offsets);
166-
for (const DIERef &die_ref : offsets) {
167-
ProcessFunctionDIE(name.GetStringRef(), die_ref, dwarf, parent_decl_ctx,
168-
name_type_mask, dies);
169-
}
163+
void AppleDWARFIndex::GetFunctions(
164+
ConstString name, SymbolFileDWARF &dwarf,
165+
const CompilerDeclContext &parent_decl_ctx, uint32_t name_type_mask,
166+
llvm::function_ref<bool(DWARFDIE die)> callback) {
167+
m_apple_names_up->FindByName(name.GetStringRef(), [&](DIERef die_ref) {
168+
return ProcessFunctionDIE(name.GetStringRef(), die_ref, dwarf,
169+
parent_decl_ctx, name_type_mask, callback);
170+
});
170171
}
171172

172-
void AppleDWARFIndex::GetFunctions(const RegularExpression &regex,
173-
DIEArray &offsets) {
173+
void AppleDWARFIndex::GetFunctions(
174+
const RegularExpression &regex,
175+
llvm::function_ref<bool(DIERef ref)> callback) {
174176
if (!m_apple_names_up)
175177
return;
176178

177179
DWARFMappedHash::DIEInfoArray hash_data;
178-
if (m_apple_names_up->AppendAllDIEsThatMatchingRegex(regex, hash_data))
179-
DWARFMappedHash::ExtractDIEArray(hash_data, offsets);
180+
m_apple_names_up->AppendAllDIEsThatMatchingRegex(regex, hash_data);
181+
DWARFMappedHash::ExtractDIEArray(hash_data, callback);
180182
}
181183

182184
void AppleDWARFIndex::ReportInvalidDIERef(const DIERef &ref,

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

Lines changed: 23 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -32,21 +32,32 @@ class AppleDWARFIndex : public DWARFIndex {
3232

3333
void Preload() override {}
3434

35-
void GetGlobalVariables(ConstString basename, DIEArray &offsets) override;
36-
void GetGlobalVariables(const RegularExpression &regex,
37-
DIEArray &offsets) override;
38-
void GetGlobalVariables(const DWARFUnit &cu, DIEArray &offsets) override;
39-
void GetObjCMethods(ConstString class_name, DIEArray &offsets) override;
40-
void GetCompleteObjCClass(ConstString class_name, bool must_be_implementation,
41-
DIEArray &offsets) override;
42-
void GetTypes(ConstString name, DIEArray &offsets) override;
43-
void GetTypes(const DWARFDeclContext &context, DIEArray &offsets) override;
44-
void GetNamespaces(ConstString name, DIEArray &offsets) override;
35+
void
36+
GetGlobalVariables(ConstString basename,
37+
llvm::function_ref<bool(DIERef ref)> callback) override;
38+
void
39+
GetGlobalVariables(const RegularExpression &regex,
40+
llvm::function_ref<bool(DIERef ref)> callback) override;
41+
void
42+
GetGlobalVariables(const DWARFUnit &cu,
43+
llvm::function_ref<bool(DIERef ref)> callback) override;
44+
void GetObjCMethods(ConstString class_name,
45+
llvm::function_ref<bool(DIERef ref)> callback) override;
46+
void
47+
GetCompleteObjCClass(ConstString class_name, bool must_be_implementation,
48+
llvm::function_ref<bool(DIERef ref)> callback) override;
49+
void GetTypes(ConstString name,
50+
llvm::function_ref<bool(DIERef ref)> callback) override;
51+
void GetTypes(const DWARFDeclContext &context,
52+
llvm::function_ref<bool(DIERef ref)> callback) override;
53+
void GetNamespaces(ConstString name,
54+
llvm::function_ref<bool(DIERef ref)> callback) override;
4555
void GetFunctions(ConstString name, SymbolFileDWARF &dwarf,
4656
const CompilerDeclContext &parent_decl_ctx,
4757
uint32_t name_type_mask,
48-
std::vector<DWARFDIE> &dies) override;
49-
void GetFunctions(const RegularExpression &regex, DIEArray &offsets) override;
58+
llvm::function_ref<bool(DWARFDIE die)> callback) override;
59+
void GetFunctions(const RegularExpression &regex,
60+
llvm::function_ref<bool(DIERef ref)> callback) override;
5061

5162
void ReportInvalidDIERef(const DIERef &ref, llvm::StringRef name) override;
5263
void Dump(Stream &s) override;

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

Lines changed: 3 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -2013,18 +2013,13 @@ bool DWARFASTParserClang::CompleteRecordType(const DWARFDIE &die,
20132013
if (class_language == eLanguageTypeObjC) {
20142014
ConstString class_name(clang_type.GetTypeName());
20152015
if (class_name) {
2016-
DIEArray method_die_offsets;
2017-
dwarf->GetObjCMethodDIEOffsets(class_name, method_die_offsets);
2018-
2019-
const size_t num_matches = method_die_offsets.size();
2020-
for (size_t i = 0; i < num_matches; ++i) {
2021-
const DIERef &die_ref = method_die_offsets[i];
2016+
dwarf->GetObjCMethods(class_name, [&](DIERef die_ref) {
20222017
DWARFDebugInfo &debug_info = dwarf->DebugInfo();
20232018
DWARFDIE method_die = debug_info.GetDIE(die_ref);
2024-
20252019
if (method_die)
20262020
method_die.ResolveType();
2027-
}
2021+
return true;
2022+
});
20282023

20292024
for (DelayedPropertyList::iterator pi = delayed_properties.begin(),
20302025
pe = delayed_properties.end();

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

Lines changed: 14 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -16,42 +16,37 @@ using namespace lldb;
1616

1717
DWARFIndex::~DWARFIndex() = default;
1818

19-
void DWARFIndex::ProcessFunctionDIE(llvm::StringRef name, DIERef ref,
20-
SymbolFileDWARF &dwarf,
21-
const CompilerDeclContext &parent_decl_ctx,
22-
uint32_t name_type_mask,
23-
std::vector<DWARFDIE> &dies) {
19+
bool DWARFIndex::ProcessFunctionDIE(
20+
llvm::StringRef name, DIERef ref, SymbolFileDWARF &dwarf,
21+
const CompilerDeclContext &parent_decl_ctx, uint32_t name_type_mask,
22+
llvm::function_ref<bool(DWARFDIE die)> callback) {
2423
DWARFDIE die = dwarf.GetDIE(ref);
2524
if (!die) {
2625
ReportInvalidDIERef(ref, name);
27-
return;
26+
return true;
2827
}
2928

3029
// Exit early if we're searching exclusively for methods or selectors and
3130
// we have a context specified (no methods in namespaces).
3231
uint32_t looking_for_nonmethods =
3332
name_type_mask & ~(eFunctionNameTypeMethod | eFunctionNameTypeSelector);
3433
if (!looking_for_nonmethods && parent_decl_ctx.IsValid())
35-
return;
34+
return true;
3635

3736
// Otherwise, we need to also check that the context matches. If it does not
3837
// match, we do nothing.
3938
if (!SymbolFileDWARF::DIEInDeclContext(parent_decl_ctx, die))
40-
return;
39+
return true;
4140

4241
// In case of a full match, we just insert everything we find.
43-
if (name_type_mask & eFunctionNameTypeFull) {
44-
dies.push_back(die);
45-
return;
46-
}
42+
if (name_type_mask & eFunctionNameTypeFull)
43+
return callback(die);
4744

4845
// If looking for ObjC selectors, we need to also check if the name is a
4946
// possible selector.
5047
if (name_type_mask & eFunctionNameTypeSelector &&
51-
ObjCLanguage::IsPossibleObjCMethodName(die.GetName())) {
52-
dies.push_back(die);
53-
return;
54-
}
48+
ObjCLanguage::IsPossibleObjCMethodName(die.GetName()))
49+
return callback(die);
5550

5651
bool looking_for_methods = name_type_mask & lldb::eFunctionNameTypeMethod;
5752
bool looking_for_functions = name_type_mask & lldb::eFunctionNameTypeBase;
@@ -61,6 +56,8 @@ void DWARFIndex::ProcessFunctionDIE(llvm::StringRef name, DIERef ref,
6156
// searching for.
6257
if ((looking_for_methods && looking_for_functions) ||
6358
looking_for_methods == die.IsMethod())
64-
dies.push_back(die);
59+
return callback(die);
6560
}
61+
62+
return true;
6663
}

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

Lines changed: 30 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -27,24 +27,35 @@ class DWARFIndex {
2727
/// Finds global variables with the given base name. Any additional filtering
2828
/// (e.g., to only retrieve variables from a given context) should be done by
2929
/// the consumer.
30-
virtual void GetGlobalVariables(ConstString basename, DIEArray &offsets) = 0;
30+
virtual void
31+
GetGlobalVariables(ConstString basename,
32+
llvm::function_ref<bool(DIERef ref)> callback) = 0;
3133

32-
virtual void GetGlobalVariables(const RegularExpression &regex,
33-
DIEArray &offsets) = 0;
34-
virtual void GetGlobalVariables(const DWARFUnit &cu, DIEArray &offsets) = 0;
35-
virtual void GetObjCMethods(ConstString class_name, DIEArray &offsets) = 0;
36-
virtual void GetCompleteObjCClass(ConstString class_name,
37-
bool must_be_implementation,
38-
DIEArray &offsets) = 0;
39-
virtual void GetTypes(ConstString name, DIEArray &offsets) = 0;
40-
virtual void GetTypes(const DWARFDeclContext &context, DIEArray &offsets) = 0;
41-
virtual void GetNamespaces(ConstString name, DIEArray &offsets) = 0;
42-
virtual void GetFunctions(ConstString name, SymbolFileDWARF &dwarf,
43-
const CompilerDeclContext &parent_decl_ctx,
44-
uint32_t name_type_mask,
45-
std::vector<DWARFDIE> &dies) = 0;
34+
virtual void
35+
GetGlobalVariables(const RegularExpression &regex,
36+
llvm::function_ref<bool(DIERef ref)> callback) = 0;
37+
virtual void
38+
GetGlobalVariables(const DWARFUnit &cu,
39+
llvm::function_ref<bool(DIERef ref)> callback) = 0;
40+
virtual void
41+
GetObjCMethods(ConstString class_name,
42+
llvm::function_ref<bool(DIERef ref)> callback) = 0;
43+
virtual void
44+
GetCompleteObjCClass(ConstString class_name, bool must_be_implementation,
45+
llvm::function_ref<bool(DIERef ref)> callback) = 0;
46+
virtual void GetTypes(ConstString name,
47+
llvm::function_ref<bool(DIERef ref)> callback) = 0;
48+
virtual void GetTypes(const DWARFDeclContext &context,
49+
llvm::function_ref<bool(DIERef ref)> callback) = 0;
50+
virtual void GetNamespaces(ConstString name,
51+
llvm::function_ref<bool(DIERef ref)> callback) = 0;
52+
virtual void
53+
GetFunctions(ConstString name, SymbolFileDWARF &dwarf,
54+
const CompilerDeclContext &parent_decl_ctx,
55+
uint32_t name_type_mask,
56+
llvm::function_ref<bool(DWARFDIE die)> callback) = 0;
4657
virtual void GetFunctions(const RegularExpression &regex,
47-
DIEArray &offsets) = 0;
58+
llvm::function_ref<bool(DIERef ref)> callback) = 0;
4859

4960
virtual void ReportInvalidDIERef(const DIERef &ref, llvm::StringRef name) = 0;
5061
virtual void Dump(Stream &s) = 0;
@@ -56,10 +67,11 @@ class DWARFIndex {
5667
/// the function given by "ref" matches search criteria given by
5768
/// "parent_decl_ctx" and "name_type_mask", it is inserted into the "dies"
5869
/// vector.
59-
void ProcessFunctionDIE(llvm::StringRef name, DIERef ref,
70+
bool ProcessFunctionDIE(llvm::StringRef name, DIERef ref,
6071
SymbolFileDWARF &dwarf,
6172
const CompilerDeclContext &parent_decl_ctx,
62-
uint32_t name_type_mask, std::vector<DWARFDIE> &dies);
73+
uint32_t name_type_mask,
74+
llvm::function_ref<bool(DWARFDIE die)> callback);
6375
};
6476
} // namespace lldb_private
6577

0 commit comments

Comments
 (0)