summaryrefslogtreecommitdiff
path: root/lldb/source/Plugins/SymbolFile/DWARF/DebugNamesDWARFIndex.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'lldb/source/Plugins/SymbolFile/DWARF/DebugNamesDWARFIndex.cpp')
-rw-r--r--lldb/source/Plugins/SymbolFile/DWARF/DebugNamesDWARFIndex.cpp176
1 files changed, 99 insertions, 77 deletions
diff --git a/lldb/source/Plugins/SymbolFile/DWARF/DebugNamesDWARFIndex.cpp b/lldb/source/Plugins/SymbolFile/DWARF/DebugNamesDWARFIndex.cpp
index 007ef2e05e59..cb3e662a6cdf 100644
--- a/lldb/source/Plugins/SymbolFile/DWARF/DebugNamesDWARFIndex.cpp
+++ b/lldb/source/Plugins/SymbolFile/DWARF/DebugNamesDWARFIndex.cpp
@@ -1,4 +1,4 @@
-//===-- DebugNamesDWARFIndex.cpp -------------------------------*- C++ -*-===//
+//===-- DebugNamesDWARFIndex.cpp ------------------------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
@@ -10,6 +10,7 @@
#include "Plugins/SymbolFile/DWARF/DWARFDebugInfo.h"
#include "Plugins/SymbolFile/DWARF/DWARFDeclContext.h"
#include "Plugins/SymbolFile/DWARF/SymbolFileDWARFDwo.h"
+#include "lldb/Core/Module.h"
#include "lldb/Utility/RegularExpression.h"
#include "lldb/Utility/Stream.h"
@@ -19,18 +20,14 @@ using namespace lldb;
llvm::Expected<std::unique_ptr<DebugNamesDWARFIndex>>
DebugNamesDWARFIndex::Create(Module &module, DWARFDataExtractor debug_names,
DWARFDataExtractor debug_str,
- DWARFDebugInfo *debug_info) {
- if (!debug_info) {
- return llvm::make_error<llvm::StringError>("debug info null",
- llvm::inconvertibleErrorCode());
- }
+ SymbolFileDWARF &dwarf) {
auto index_up = std::make_unique<DebugNames>(debug_names.GetAsLLVM(),
debug_str.GetAsLLVM());
if (llvm::Error E = index_up->extract())
return std::move(E);
return std::unique_ptr<DebugNamesDWARFIndex>(new DebugNamesDWARFIndex(
- module, std::move(index_up), debug_names, debug_str, *debug_info));
+ module, std::move(index_up), debug_names, debug_str, dwarf));
}
llvm::DenseSet<dw_offset_t>
@@ -53,12 +50,7 @@ DebugNamesDWARFIndex::ToDIERef(const DebugNames::Entry &entry) {
if (!cu)
return llvm::None;
- // This initializes the DWO symbol file. It's not possible for
- // GetDwoSymbolFile to call this automatically because of mutual recursion
- // between this and DWARFDebugInfoEntry::GetAttributeValue.
- cu->ExtractUnitDIEIfNeeded();
cu = &cu->GetNonSkeletonUnit();
-
if (llvm::Optional<uint64_t> die_offset = entry.getDIEUnitOffset())
return DIERef(cu->GetSymbolFileDWARF().GetDwoNum(),
DIERef::Section::DebugInfo, cu->GetOffset() + *die_offset);
@@ -66,10 +58,18 @@ DebugNamesDWARFIndex::ToDIERef(const DebugNames::Entry &entry) {
return llvm::None;
}
-void DebugNamesDWARFIndex::Append(const DebugNames::Entry &entry,
- DIEArray &offsets) {
- if (llvm::Optional<DIERef> ref = ToDIERef(entry))
- offsets.push_back(*ref);
+bool DebugNamesDWARFIndex::ProcessEntry(
+ const DebugNames::Entry &entry,
+ llvm::function_ref<bool(DWARFDIE die)> callback, llvm::StringRef name) {
+ llvm::Optional<DIERef> ref = ToDIERef(entry);
+ if (!ref)
+ return true;
+ SymbolFileDWARF &dwarf =
+ *llvm::cast<SymbolFileDWARF>(m_module.GetSymbolFile());
+ DWARFDIE die = dwarf.GetDIE(*ref);
+ if (!die)
+ return true;
+ return callback(die);
}
void DebugNamesDWARFIndex::MaybeLogLookupError(llvm::Error error,
@@ -83,23 +83,23 @@ void DebugNamesDWARFIndex::MaybeLogLookupError(llvm::Error error,
ni.getUnitOffset(), name);
}
-void DebugNamesDWARFIndex::GetGlobalVariables(ConstString basename,
- DIEArray &offsets) {
- m_fallback.GetGlobalVariables(basename, offsets);
-
+void DebugNamesDWARFIndex::GetGlobalVariables(
+ ConstString basename, llvm::function_ref<bool(DWARFDIE die)> callback) {
for (const DebugNames::Entry &entry :
m_debug_names_up->equal_range(basename.GetStringRef())) {
if (entry.tag() != DW_TAG_variable)
continue;
- Append(entry, offsets);
+ if (!ProcessEntry(entry, callback, basename.GetStringRef()))
+ return;
}
-}
-void DebugNamesDWARFIndex::GetGlobalVariables(const RegularExpression &regex,
- DIEArray &offsets) {
- m_fallback.GetGlobalVariables(regex, offsets);
+ m_fallback.GetGlobalVariables(basename, callback);
+}
+void DebugNamesDWARFIndex::GetGlobalVariables(
+ const RegularExpression &regex,
+ llvm::function_ref<bool(DWARFDIE die)> callback) {
for (const DebugNames::NameIndex &ni: *m_debug_names_up) {
for (DebugNames::NameTableEntry nte: ni) {
if (!regex.Execute(nte.getString()))
@@ -111,17 +111,19 @@ void DebugNamesDWARFIndex::GetGlobalVariables(const RegularExpression &regex,
if (entry_or->tag() != DW_TAG_variable)
continue;
- Append(*entry_or, offsets);
+ if (!ProcessEntry(*entry_or, callback,
+ llvm::StringRef(nte.getString())))
+ return;
}
MaybeLogLookupError(entry_or.takeError(), ni, nte.getString());
}
}
-}
-void DebugNamesDWARFIndex::GetGlobalVariables(const DWARFUnit &cu,
- DIEArray &offsets) {
- m_fallback.GetGlobalVariables(cu, offsets);
+ m_fallback.GetGlobalVariables(regex, callback);
+}
+void DebugNamesDWARFIndex::GetGlobalVariables(
+ const DWARFUnit &cu, llvm::function_ref<bool(DWARFDIE die)> callback) {
uint64_t cu_offset = cu.GetOffset();
for (const DebugNames::NameIndex &ni: *m_debug_names_up) {
for (DebugNames::NameTableEntry nte: ni) {
@@ -133,18 +135,20 @@ void DebugNamesDWARFIndex::GetGlobalVariables(const DWARFUnit &cu,
if (entry_or->getCUOffset() != cu_offset)
continue;
- Append(*entry_or, offsets);
+ if (!ProcessEntry(*entry_or, callback,
+ llvm::StringRef(nte.getString())))
+ return;
}
MaybeLogLookupError(entry_or.takeError(), ni, nte.getString());
}
}
-}
-void DebugNamesDWARFIndex::GetCompleteObjCClass(ConstString class_name,
- bool must_be_implementation,
- DIEArray &offsets) {
- m_fallback.GetCompleteObjCClass(class_name, must_be_implementation, offsets);
+ m_fallback.GetGlobalVariables(cu, callback);
+}
+void DebugNamesDWARFIndex::GetCompleteObjCClass(
+ ConstString class_name, bool must_be_implementation,
+ llvm::function_ref<bool(DWARFDIE die)> callback) {
// Keep a list of incomplete types as fallback for when we don't find the
// complete type.
DIEArray incomplete_types;
@@ -165,84 +169,98 @@ void DebugNamesDWARFIndex::GetCompleteObjCClass(ConstString class_name,
continue;
}
- // FIXME: We should return DWARFDIEs so we don't have to resolve it twice.
DWARFDIE die = m_debug_info.GetDIE(*ref);
- if (!die)
+ if (!die) {
+ ReportInvalidDIERef(*ref, class_name.GetStringRef());
continue;
+ }
if (die.GetAttributeValueAsUnsigned(DW_AT_APPLE_objc_complete_type, 0)) {
// If we find the complete version we're done.
- offsets.push_back(*ref);
+ callback(die);
return;
- } else {
- incomplete_types.push_back(*ref);
}
+ incomplete_types.push_back(*ref);
}
- offsets.insert(offsets.end(), incomplete_types.begin(),
- incomplete_types.end());
-}
+ auto dierefcallback = DIERefCallback(callback, class_name.GetStringRef());
+ for (DIERef ref : incomplete_types)
+ if (!dierefcallback(ref))
+ return;
-void DebugNamesDWARFIndex::GetTypes(ConstString name, DIEArray &offsets) {
- m_fallback.GetTypes(name, offsets);
+ m_fallback.GetCompleteObjCClass(class_name, must_be_implementation, callback);
+}
+void DebugNamesDWARFIndex::GetTypes(
+ ConstString name, llvm::function_ref<bool(DWARFDIE die)> callback) {
for (const DebugNames::Entry &entry :
m_debug_names_up->equal_range(name.GetStringRef())) {
- if (isType(entry.tag()))
- Append(entry, offsets);
+ if (isType(entry.tag())) {
+ if (!ProcessEntry(entry, callback, name.GetStringRef()))
+ return;
+ }
}
-}
-void DebugNamesDWARFIndex::GetTypes(const DWARFDeclContext &context,
- DIEArray &offsets) {
- m_fallback.GetTypes(context, offsets);
+ m_fallback.GetTypes(name, callback);
+}
- for (const DebugNames::Entry &entry :
- m_debug_names_up->equal_range(context[0].name)) {
- if (entry.tag() == context[0].tag)
- Append(entry, offsets);
+void DebugNamesDWARFIndex::GetTypes(
+ const DWARFDeclContext &context,
+ llvm::function_ref<bool(DWARFDIE die)> callback) {
+ auto name = context[0].name;
+ for (const DebugNames::Entry &entry : m_debug_names_up->equal_range(name)) {
+ if (entry.tag() == context[0].tag) {
+ if (!ProcessEntry(entry, callback, name))
+ return;
+ }
}
-}
-void DebugNamesDWARFIndex::GetNamespaces(ConstString name, DIEArray &offsets) {
- m_fallback.GetNamespaces(name, offsets);
+ m_fallback.GetTypes(context, callback);
+}
+void DebugNamesDWARFIndex::GetNamespaces(
+ ConstString name, llvm::function_ref<bool(DWARFDIE die)> callback) {
for (const DebugNames::Entry &entry :
m_debug_names_up->equal_range(name.GetStringRef())) {
- if (entry.tag() == DW_TAG_namespace)
- Append(entry, offsets);
+ if (entry.tag() == DW_TAG_namespace) {
+ if (!ProcessEntry(entry, callback, name.GetStringRef()))
+ return;
+ }
}
+
+ m_fallback.GetNamespaces(name, callback);
}
void DebugNamesDWARFIndex::GetFunctions(
ConstString name, SymbolFileDWARF &dwarf,
const CompilerDeclContext &parent_decl_ctx, uint32_t name_type_mask,
- std::vector<DWARFDIE> &dies) {
-
- std::vector<DWARFDIE> v;
- m_fallback.GetFunctions(name, dwarf, parent_decl_ctx, name_type_mask, v);
+ llvm::function_ref<bool(DWARFDIE die)> callback) {
+ std::set<DWARFDebugInfoEntry *> seen;
for (const DebugNames::Entry &entry :
m_debug_names_up->equal_range(name.GetStringRef())) {
Tag tag = entry.tag();
if (tag != DW_TAG_subprogram && tag != DW_TAG_inlined_subroutine)
continue;
- if (llvm::Optional<DIERef> ref = ToDIERef(entry))
- ProcessFunctionDIE(name.GetStringRef(), *ref, dwarf, parent_decl_ctx,
- name_type_mask, v);
+ if (llvm::Optional<DIERef> ref = ToDIERef(entry)) {
+ if (!ProcessFunctionDIE(name.GetStringRef(), *ref, dwarf, parent_decl_ctx,
+ name_type_mask, [&](DWARFDIE die) {
+ if (!seen.insert(die.GetDIE()).second)
+ return true;
+ return callback(die);
+ }))
+ return;
+ }
}
- std::set<DWARFDebugInfoEntry *> seen;
- for (DWARFDIE die : v)
- if (seen.insert(die.GetDIE()).second)
- dies.push_back(die);
+ m_fallback.GetFunctions(name, dwarf, parent_decl_ctx, name_type_mask,
+ callback);
}
-void DebugNamesDWARFIndex::GetFunctions(const RegularExpression &regex,
- DIEArray &offsets) {
- m_fallback.GetFunctions(regex, offsets);
-
+void DebugNamesDWARFIndex::GetFunctions(
+ const RegularExpression &regex,
+ llvm::function_ref<bool(DWARFDIE die)> callback) {
for (const DebugNames::NameIndex &ni: *m_debug_names_up) {
for (DebugNames::NameTableEntry nte: ni) {
if (!regex.Execute(nte.getString()))
@@ -255,11 +273,15 @@ void DebugNamesDWARFIndex::GetFunctions(const RegularExpression &regex,
if (tag != DW_TAG_subprogram && tag != DW_TAG_inlined_subroutine)
continue;
- Append(*entry_or, offsets);
+ if (!ProcessEntry(*entry_or, callback,
+ llvm::StringRef(nte.getString())))
+ return;
}
MaybeLogLookupError(entry_or.takeError(), ni, nte.getString());
}
}
+
+ m_fallback.GetFunctions(regex, callback);
}
void DebugNamesDWARFIndex::Dump(Stream &s) {