diff options
Diffstat (limited to 'lldb/source/Plugins/SymbolFile/DWARF/DebugNamesDWARFIndex.cpp')
-rw-r--r-- | lldb/source/Plugins/SymbolFile/DWARF/DebugNamesDWARFIndex.cpp | 176 |
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 ®ex, - DIEArray &offsets) { - m_fallback.GetGlobalVariables(regex, offsets); + m_fallback.GetGlobalVariables(basename, callback); +} +void DebugNamesDWARFIndex::GetGlobalVariables( + const RegularExpression ®ex, + 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 ®ex, 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 ®ex, - DIEArray &offsets) { - m_fallback.GetFunctions(regex, offsets); - +void DebugNamesDWARFIndex::GetFunctions( + const RegularExpression ®ex, + 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 ®ex, 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) { |