diff --git a/lldb/include/lldb/Core/UniqueCStringMap.h b/lldb/include/lldb/Core/UniqueCStringMap.h --- a/lldb/include/lldb/Core/UniqueCStringMap.h +++ b/lldb/include/lldb/Core/UniqueCStringMap.h @@ -13,6 +13,7 @@ #include #include "lldb/Utility/ConstString.h" +#include "lldb/Utility/LLDBAssert.h" #include "lldb/Utility/RegularExpression.h" namespace lldb_private { @@ -98,6 +99,50 @@ return nullptr; } + // Helper iterator for the 'equal_range' method. + class CString_iterator { + public: + CString_iterator(const UniqueCStringMap &map, const Entry *entry_ptr) + : m_map(map), m_entry_ptr(entry_ptr) { + // 'entry_ptr' may be nullptr if the name was not found. + } + CString_iterator(const UniqueCStringMap &map) + : m_map(map), m_entry_ptr(nullptr) {} + CString_iterator &operator++() { + lldbassert(m_entry_ptr); + m_entry_ptr = m_map.FindNextValueForName(m_entry_ptr); + return *this; + } + CString_iterator operator++(int) { + CString_iterator tmp = *this; + operator++(); + return tmp; + } + const Entry &operator*() const { + lldbassert(m_entry_ptr); + return *m_entry_ptr; + } + bool operator==(const CString_iterator &other) const { + lldbassert(&m_map == &other.m_map); + return m_entry_ptr == other.m_entry_ptr; + } + bool operator!=(const CString_iterator &other) const { + return !(*this == other); + } + + private: + const UniqueCStringMap &m_map; + const Entry *m_entry_ptr; + }; + + // Range-based for loop for all entries of the specified ConstString name. + llvm::iterator_range + equal_range(ConstString unique_cstr) const { + return llvm::make_range( + CString_iterator(*this, FindFirstValueForName(unique_cstr)), + CString_iterator(*this)); + }; + // Get a pointer to the next entry that matches "name" from a previously // returned Entry pointer. nullptr will be returned if there is no subsequent // entry that matches "name". @@ -197,9 +242,15 @@ } }; typedef std::vector collection; + collection m_map; + +public: typedef typename collection::iterator iterator; typedef typename collection::const_iterator const_iterator; - collection m_map; + iterator begin() { return m_map.begin(); } + iterator end() { return m_map.end(); } + const_iterator begin() const { return m_map.begin(); } + const_iterator end() const { return m_map.end(); } }; } // namespace lldb_private diff --git a/lldb/source/Plugins/SymbolFile/DWARF/AppleDWARFIndex.h b/lldb/source/Plugins/SymbolFile/DWARF/AppleDWARFIndex.h --- a/lldb/source/Plugins/SymbolFile/DWARF/AppleDWARFIndex.h +++ b/lldb/source/Plugins/SymbolFile/DWARF/AppleDWARFIndex.h @@ -32,21 +32,32 @@ void Preload() override {} - void GetGlobalVariables(ConstString basename, DIEArray &offsets) override; - void GetGlobalVariables(const RegularExpression ®ex, - DIEArray &offsets) override; - void GetGlobalVariables(const DWARFUnit &cu, DIEArray &offsets) override; - void GetObjCMethods(ConstString class_name, DIEArray &offsets) override; - void GetCompleteObjCClass(ConstString class_name, bool must_be_implementation, - DIEArray &offsets) override; - void GetTypes(ConstString name, DIEArray &offsets) override; - void GetTypes(const DWARFDeclContext &context, DIEArray &offsets) override; - void GetNamespaces(ConstString name, DIEArray &offsets) override; - void GetFunctions(ConstString name, SymbolFileDWARF &dwarf, + bool + GetGlobalVariables(ConstString basename, + llvm::function_ref callback) override; + bool + GetGlobalVariables(const RegularExpression ®ex, + llvm::function_ref callback) override; + bool + GetGlobalVariables(const DWARFUnit &cu, + llvm::function_ref callback) override; + bool GetObjCMethods(ConstString class_name, + llvm::function_ref callback) override; + bool + GetCompleteObjCClass(ConstString class_name, bool must_be_implementation, + llvm::function_ref callback) override; + bool GetTypes(ConstString name, + llvm::function_ref callback) override; + bool GetTypes(const DWARFDeclContext &context, + llvm::function_ref callback) override; + bool GetNamespaces(ConstString name, + llvm::function_ref callback) override; + bool GetFunctions(ConstString name, SymbolFileDWARF &dwarf, const CompilerDeclContext &parent_decl_ctx, uint32_t name_type_mask, - std::vector &dies) override; - void GetFunctions(const RegularExpression ®ex, DIEArray &offsets) override; + llvm::function_ref callback) override; + bool GetFunctions(const RegularExpression ®ex, + llvm::function_ref callback) override; void ReportInvalidDIERef(const DIERef &ref, llvm::StringRef name) override; void Dump(Stream &s) override; diff --git a/lldb/source/Plugins/SymbolFile/DWARF/AppleDWARFIndex.cpp b/lldb/source/Plugins/SymbolFile/DWARF/AppleDWARFIndex.cpp --- a/lldb/source/Plugins/SymbolFile/DWARF/AppleDWARFIndex.cpp +++ b/lldb/source/Plugins/SymbolFile/DWARF/AppleDWARFIndex.cpp @@ -52,59 +52,62 @@ return nullptr; } -void AppleDWARFIndex::GetGlobalVariables(ConstString basename, DIEArray &offsets) { +bool AppleDWARFIndex::GetGlobalVariables( + ConstString basename, llvm::function_ref callback) { if (!m_apple_names_up) - return; - m_apple_names_up->FindByName(basename.GetStringRef(), offsets); + return false; + return m_apple_names_up->FindByName(basename.GetStringRef(), callback); } -void AppleDWARFIndex::GetGlobalVariables(const RegularExpression ®ex, - DIEArray &offsets) { +bool AppleDWARFIndex::GetGlobalVariables( + const RegularExpression ®ex, + llvm::function_ref callback) { if (!m_apple_names_up) - return; + return false; DWARFMappedHash::DIEInfoArray hash_data; - if (m_apple_names_up->AppendAllDIEsThatMatchingRegex(regex, hash_data)) - DWARFMappedHash::ExtractDIEArray(hash_data, offsets); + m_apple_names_up->AppendAllDIEsThatMatchingRegex(regex, hash_data); + return DWARFMappedHash::ExtractDIEArray(hash_data, callback); } -void AppleDWARFIndex::GetGlobalVariables(const DWARFUnit &cu, - DIEArray &offsets) { +bool AppleDWARFIndex::GetGlobalVariables( + const DWARFUnit &cu, llvm::function_ref callback) { if (!m_apple_names_up) - return; + return false; DWARFMappedHash::DIEInfoArray hash_data; - if (m_apple_names_up->AppendAllDIEsInRange(cu.GetOffset(), - cu.GetNextUnitOffset(), hash_data)) - DWARFMappedHash::ExtractDIEArray(hash_data, offsets); + m_apple_names_up->AppendAllDIEsInRange(cu.GetOffset(), cu.GetNextUnitOffset(), + hash_data); + return DWARFMappedHash::ExtractDIEArray(hash_data, callback); } -void AppleDWARFIndex::GetObjCMethods(ConstString class_name, - DIEArray &offsets) { +bool AppleDWARFIndex::GetObjCMethods( + ConstString class_name, llvm::function_ref callback) { if (!m_apple_objc_up) - return; - m_apple_objc_up->FindByName(class_name.GetStringRef(), offsets); + return false; + return m_apple_objc_up->FindByName(class_name.GetStringRef(), callback); } -void AppleDWARFIndex::GetCompleteObjCClass(ConstString class_name, - bool must_be_implementation, - DIEArray &offsets) { +bool AppleDWARFIndex::GetCompleteObjCClass( + ConstString class_name, bool must_be_implementation, + llvm::function_ref callback) { if (!m_apple_types_up) - return; - m_apple_types_up->FindCompleteObjCClassByName( - class_name.GetStringRef(), offsets, must_be_implementation); + return false; + return m_apple_types_up->FindCompleteObjCClassByName( + class_name.GetStringRef(), callback, must_be_implementation); } -void AppleDWARFIndex::GetTypes(ConstString name, DIEArray &offsets) { +bool AppleDWARFIndex::GetTypes(ConstString name, + llvm::function_ref callback) { if (!m_apple_types_up) - return; - m_apple_types_up->FindByName(name.GetStringRef(), offsets); + return false; + return m_apple_types_up->FindByName(name.GetStringRef(), callback); } -void AppleDWARFIndex::GetTypes(const DWARFDeclContext &context, - DIEArray &offsets) { +bool AppleDWARFIndex::GetTypes(const DWARFDeclContext &context, + llvm::function_ref callback) { if (!m_apple_types_up) - return; + return false; Log *log = LogChannelDWARF::GetLogIfAny(DWARF_LOG_TYPE_COMPLETION | DWARF_LOG_LOOKUPS); @@ -121,9 +124,8 @@ const uint32_t qualified_name_hash = llvm::djbHash(qualified_name); if (log) m_module.LogMessage(log, "FindByNameAndTagAndQualifiedNameHash()"); - m_apple_types_up->FindByNameAndTagAndQualifiedNameHash( - type_name.GetStringRef(), tag, qualified_name_hash, offsets); - return; + return m_apple_types_up->FindByNameAndTagAndQualifiedNameHash( + type_name.GetStringRef(), tag, qualified_name_hash, callback); } if (has_tag) { @@ -136,47 +138,46 @@ if (!has_qualified_name_hash && (context.GetSize() > 1) && (context[1].tag == DW_TAG_class_type || context[1].tag == DW_TAG_structure_type)) { - DIEArray class_matches; - m_apple_types_up->FindByName(context[1].name, class_matches); - if (class_matches.empty()) - return; + if (!m_apple_types_up->FindByName(context[1].name, + [&](DIERef ref) { return true; })) + return false; } if (log) m_module.LogMessage(log, "FindByNameAndTag()"); - m_apple_types_up->FindByNameAndTag(type_name.GetStringRef(), tag, offsets); - return; + return m_apple_types_up->FindByNameAndTag(type_name.GetStringRef(), tag, + callback); } - m_apple_types_up->FindByName(type_name.GetStringRef(), offsets); + return m_apple_types_up->FindByName(type_name.GetStringRef(), callback); } -void AppleDWARFIndex::GetNamespaces(ConstString name, DIEArray &offsets) { +bool AppleDWARFIndex::GetNamespaces( + ConstString name, llvm::function_ref callback) { if (!m_apple_namespaces_up) - return; - m_apple_namespaces_up->FindByName(name.GetStringRef(), offsets); + return false; + return m_apple_namespaces_up->FindByName(name.GetStringRef(), callback); } -void AppleDWARFIndex::GetFunctions(ConstString name, SymbolFileDWARF &dwarf, - const CompilerDeclContext &parent_decl_ctx, - uint32_t name_type_mask, - std::vector &dies) { - DIEArray offsets; - m_apple_names_up->FindByName(name.GetStringRef(), offsets); - for (const DIERef &die_ref : offsets) { - ProcessFunctionDIE(name.GetStringRef(), die_ref, dwarf, parent_decl_ctx, - name_type_mask, dies); - } +bool AppleDWARFIndex::GetFunctions( + ConstString name, SymbolFileDWARF &dwarf, + const CompilerDeclContext &parent_decl_ctx, uint32_t name_type_mask, + llvm::function_ref callback) { + return m_apple_names_up->FindByName(name.GetStringRef(), [&](DIERef die_ref) { + return ProcessFunctionDIE(name.GetStringRef(), die_ref, dwarf, + parent_decl_ctx, name_type_mask, callback); + }); } -void AppleDWARFIndex::GetFunctions(const RegularExpression ®ex, - DIEArray &offsets) { +bool AppleDWARFIndex::GetFunctions( + const RegularExpression ®ex, + llvm::function_ref callback) { if (!m_apple_names_up) - return; + return false; DWARFMappedHash::DIEInfoArray hash_data; - if (m_apple_names_up->AppendAllDIEsThatMatchingRegex(regex, hash_data)) - DWARFMappedHash::ExtractDIEArray(hash_data, offsets); + m_apple_names_up->AppendAllDIEsThatMatchingRegex(regex, hash_data); + return DWARFMappedHash::ExtractDIEArray(hash_data, callback); } void AppleDWARFIndex::ReportInvalidDIERef(const DIERef &ref, diff --git a/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp b/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp --- a/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp +++ b/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp @@ -2008,18 +2008,13 @@ if (class_language == eLanguageTypeObjC) { ConstString class_name(clang_type.GetTypeName()); if (class_name) { - DIEArray method_die_offsets; - dwarf->GetObjCMethodDIEOffsets(class_name, method_die_offsets); - - const size_t num_matches = method_die_offsets.size(); - for (size_t i = 0; i < num_matches; ++i) { - const DIERef &die_ref = method_die_offsets[i]; + dwarf->GetObjCMethods(class_name, [&](DIERef die_ref) { DWARFDebugInfo &debug_info = dwarf->DebugInfo(); DWARFDIE method_die = debug_info.GetDIE(die_ref); - if (method_die) method_die.ResolveType(); - } + return false; + }); for (DelayedPropertyList::iterator pi = delayed_properties.begin(), pe = delayed_properties.end(); diff --git a/lldb/source/Plugins/SymbolFile/DWARF/DWARFIndex.h b/lldb/source/Plugins/SymbolFile/DWARF/DWARFIndex.h --- a/lldb/source/Plugins/SymbolFile/DWARF/DWARFIndex.h +++ b/lldb/source/Plugins/SymbolFile/DWARF/DWARFIndex.h @@ -27,24 +27,35 @@ /// Finds global variables with the given base name. Any additional filtering /// (e.g., to only retrieve variables from a given context) should be done by /// the consumer. - virtual void GetGlobalVariables(ConstString basename, DIEArray &offsets) = 0; + virtual bool + GetGlobalVariables(ConstString basename, + llvm::function_ref callback) = 0; - virtual void GetGlobalVariables(const RegularExpression ®ex, - DIEArray &offsets) = 0; - virtual void GetGlobalVariables(const DWARFUnit &cu, DIEArray &offsets) = 0; - virtual void GetObjCMethods(ConstString class_name, DIEArray &offsets) = 0; - virtual void GetCompleteObjCClass(ConstString class_name, - bool must_be_implementation, - DIEArray &offsets) = 0; - virtual void GetTypes(ConstString name, DIEArray &offsets) = 0; - virtual void GetTypes(const DWARFDeclContext &context, DIEArray &offsets) = 0; - virtual void GetNamespaces(ConstString name, DIEArray &offsets) = 0; - virtual void GetFunctions(ConstString name, SymbolFileDWARF &dwarf, - const CompilerDeclContext &parent_decl_ctx, - uint32_t name_type_mask, - std::vector &dies) = 0; - virtual void GetFunctions(const RegularExpression ®ex, - DIEArray &offsets) = 0; + virtual bool + GetGlobalVariables(const RegularExpression ®ex, + llvm::function_ref callback) = 0; + virtual bool + GetGlobalVariables(const DWARFUnit &cu, + llvm::function_ref callback) = 0; + virtual bool + GetObjCMethods(ConstString class_name, + llvm::function_ref callback) = 0; + virtual bool + GetCompleteObjCClass(ConstString class_name, bool must_be_implementation, + llvm::function_ref callback) = 0; + virtual bool GetTypes(ConstString name, + llvm::function_ref callback) = 0; + virtual bool GetTypes(const DWARFDeclContext &context, + llvm::function_ref callback) = 0; + virtual bool GetNamespaces(ConstString name, + llvm::function_ref callback) = 0; + virtual bool + GetFunctions(ConstString name, SymbolFileDWARF &dwarf, + const CompilerDeclContext &parent_decl_ctx, + uint32_t name_type_mask, + llvm::function_ref callback) = 0; + virtual bool GetFunctions(const RegularExpression ®ex, + llvm::function_ref callback) = 0; virtual void ReportInvalidDIERef(const DIERef &ref, llvm::StringRef name) = 0; virtual void Dump(Stream &s) = 0; @@ -56,10 +67,11 @@ /// the function given by "ref" matches search criteria given by /// "parent_decl_ctx" and "name_type_mask", it is inserted into the "dies" /// vector. - void ProcessFunctionDIE(llvm::StringRef name, DIERef ref, + bool ProcessFunctionDIE(llvm::StringRef name, DIERef ref, SymbolFileDWARF &dwarf, const CompilerDeclContext &parent_decl_ctx, - uint32_t name_type_mask, std::vector &dies); + uint32_t name_type_mask, + llvm::function_ref callback); }; } // namespace lldb_private diff --git a/lldb/source/Plugins/SymbolFile/DWARF/DWARFIndex.cpp b/lldb/source/Plugins/SymbolFile/DWARF/DWARFIndex.cpp --- a/lldb/source/Plugins/SymbolFile/DWARF/DWARFIndex.cpp +++ b/lldb/source/Plugins/SymbolFile/DWARF/DWARFIndex.cpp @@ -16,15 +16,14 @@ DWARFIndex::~DWARFIndex() = default; -void DWARFIndex::ProcessFunctionDIE(llvm::StringRef name, DIERef ref, - SymbolFileDWARF &dwarf, - const CompilerDeclContext &parent_decl_ctx, - uint32_t name_type_mask, - std::vector &dies) { +bool DWARFIndex::ProcessFunctionDIE( + llvm::StringRef name, DIERef ref, SymbolFileDWARF &dwarf, + const CompilerDeclContext &parent_decl_ctx, uint32_t name_type_mask, + llvm::function_ref callback) { DWARFDIE die = dwarf.GetDIE(ref); if (!die) { ReportInvalidDIERef(ref, name); - return; + return false; } // Exit early if we're searching exclusively for methods or selectors and @@ -32,26 +31,22 @@ uint32_t looking_for_nonmethods = name_type_mask & ~(eFunctionNameTypeMethod | eFunctionNameTypeSelector); if (!looking_for_nonmethods && parent_decl_ctx.IsValid()) - return; + return false; // Otherwise, we need to also check that the context matches. If it does not // match, we do nothing. if (!SymbolFileDWARF::DIEInDeclContext(parent_decl_ctx, die)) - return; + return false; // In case of a full match, we just insert everything we find. - if (name_type_mask & eFunctionNameTypeFull) { - dies.push_back(die); - return; - } + if (name_type_mask & eFunctionNameTypeFull) + return callback(die); // If looking for ObjC selectors, we need to also check if the name is a // possible selector. if (name_type_mask & eFunctionNameTypeSelector && - ObjCLanguage::IsPossibleObjCMethodName(die.GetName())) { - dies.push_back(die); - return; - } + ObjCLanguage::IsPossibleObjCMethodName(die.GetName())) + return callback(die); bool looking_for_methods = name_type_mask & lldb::eFunctionNameTypeMethod; bool looking_for_functions = name_type_mask & lldb::eFunctionNameTypeBase; @@ -61,6 +56,8 @@ // searching for. if ((looking_for_methods && looking_for_functions) || looking_for_methods == die.IsMethod()) - dies.push_back(die); + return callback(die); } + + return false; } diff --git a/lldb/source/Plugins/SymbolFile/DWARF/DebugNamesDWARFIndex.h b/lldb/source/Plugins/SymbolFile/DWARF/DebugNamesDWARFIndex.h --- a/lldb/source/Plugins/SymbolFile/DWARF/DebugNamesDWARFIndex.h +++ b/lldb/source/Plugins/SymbolFile/DWARF/DebugNamesDWARFIndex.h @@ -25,22 +25,34 @@ void Preload() override { m_fallback.Preload(); } - void GetGlobalVariables(ConstString basename, DIEArray &offsets) override; - void GetGlobalVariables(const RegularExpression ®ex, - DIEArray &offsets) override; - void GetGlobalVariables(const DWARFUnit &cu, DIEArray &offsets) override; - void GetObjCMethods(ConstString class_name, DIEArray &offsets) override {} - void GetCompleteObjCClass(ConstString class_name, bool must_be_implementation, - DIEArray &offsets) override; - void GetTypes(ConstString name, DIEArray &offsets) override; - void GetTypes(const DWARFDeclContext &context, DIEArray &offsets) override; - void GetNamespaces(ConstString name, DIEArray &offsets) override; - void GetFunctions(ConstString name, SymbolFileDWARF &dwarf, + bool + GetGlobalVariables(ConstString basename, + llvm::function_ref callback) override; + bool + GetGlobalVariables(const RegularExpression ®ex, + llvm::function_ref callback) override; + bool + GetGlobalVariables(const DWARFUnit &cu, + llvm::function_ref callback) override; + bool GetObjCMethods(ConstString class_name, + llvm::function_ref callback) override { + return false; + } + bool + GetCompleteObjCClass(ConstString class_name, bool must_be_implementation, + llvm::function_ref callback) override; + bool GetTypes(ConstString name, + llvm::function_ref callback) override; + bool GetTypes(const DWARFDeclContext &context, + llvm::function_ref callback) override; + bool GetNamespaces(ConstString name, + llvm::function_ref callback) override; + bool GetFunctions(ConstString name, SymbolFileDWARF &dwarf, const CompilerDeclContext &parent_decl_ctx, uint32_t name_type_mask, - std::vector &dies) override; - void GetFunctions(const RegularExpression ®ex, - DIEArray &offsets) override; + llvm::function_ref callback) override; + bool GetFunctions(const RegularExpression ®ex, + llvm::function_ref callback) override; void ReportInvalidDIERef(const DIERef &ref, llvm::StringRef name) override {} void Dump(Stream &s) override; @@ -68,7 +80,8 @@ ManualDWARFIndex m_fallback; llvm::Optional ToDIERef(const DebugNames::Entry &entry); - void Append(const DebugNames::Entry &entry, DIEArray &offsets); + bool ProcessEntry(const DebugNames::Entry &entry, + llvm::function_ref callback); static void MaybeLogLookupError(llvm::Error error, const DebugNames::NameIndex &ni, diff --git a/lldb/source/Plugins/SymbolFile/DWARF/DebugNamesDWARFIndex.cpp b/lldb/source/Plugins/SymbolFile/DWARF/DebugNamesDWARFIndex.cpp --- a/lldb/source/Plugins/SymbolFile/DWARF/DebugNamesDWARFIndex.cpp +++ b/lldb/source/Plugins/SymbolFile/DWARF/DebugNamesDWARFIndex.cpp @@ -57,10 +57,12 @@ return llvm::None; } -void DebugNamesDWARFIndex::Append(const DebugNames::Entry &entry, - DIEArray &offsets) { +bool DebugNamesDWARFIndex::ProcessEntry( + const DebugNames::Entry &entry, + llvm::function_ref callback) { if (llvm::Optional ref = ToDIERef(entry)) - offsets.push_back(*ref); + return callback(*ref); + return false; } void DebugNamesDWARFIndex::MaybeLogLookupError(llvm::Error error, @@ -74,22 +76,27 @@ ni.getUnitOffset(), name); } -void DebugNamesDWARFIndex::GetGlobalVariables(ConstString basename, - DIEArray &offsets) { - m_fallback.GetGlobalVariables(basename, offsets); +bool DebugNamesDWARFIndex::GetGlobalVariables( + ConstString basename, llvm::function_ref callback) { + if (m_fallback.GetGlobalVariables(basename, callback)) + return true; 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)) + return true; } + return false; } -void DebugNamesDWARFIndex::GetGlobalVariables(const RegularExpression ®ex, - DIEArray &offsets) { - m_fallback.GetGlobalVariables(regex, offsets); +bool DebugNamesDWARFIndex::GetGlobalVariables( + const RegularExpression ®ex, + llvm::function_ref callback) { + if (m_fallback.GetGlobalVariables(regex, callback)) + return true; for (const DebugNames::NameIndex &ni: *m_debug_names_up) { for (DebugNames::NameTableEntry nte: ni) { @@ -102,16 +109,20 @@ if (entry_or->tag() != DW_TAG_variable) continue; - Append(*entry_or, offsets); + if (ProcessEntry(*entry_or, callback)) + return true; } MaybeLogLookupError(entry_or.takeError(), ni, nte.getString()); } } + + return false; } -void DebugNamesDWARFIndex::GetGlobalVariables(const DWARFUnit &cu, - DIEArray &offsets) { - m_fallback.GetGlobalVariables(cu, offsets); +bool DebugNamesDWARFIndex::GetGlobalVariables( + const DWARFUnit &cu, llvm::function_ref callback) { + if (m_fallback.GetGlobalVariables(cu, callback)) + return true; uint64_t cu_offset = cu.GetOffset(); for (const DebugNames::NameIndex &ni: *m_debug_names_up) { @@ -124,17 +135,22 @@ if (entry_or->getCUOffset() != cu_offset) continue; - Append(*entry_or, offsets); + if (ProcessEntry(*entry_or, callback)) + return true; } MaybeLogLookupError(entry_or.takeError(), ni, nte.getString()); } } + + return false; } -void DebugNamesDWARFIndex::GetCompleteObjCClass(ConstString class_name, - bool must_be_implementation, - DIEArray &offsets) { - m_fallback.GetCompleteObjCClass(class_name, must_be_implementation, offsets); +bool DebugNamesDWARFIndex::GetCompleteObjCClass( + ConstString class_name, bool must_be_implementation, + llvm::function_ref callback) { + if (m_fallback.GetCompleteObjCClass(class_name, must_be_implementation, + callback)) + return true; // Keep a list of incomplete types as fallback for when we don't find the // complete type. @@ -163,75 +179,100 @@ if (die.GetAttributeValueAsUnsigned(DW_AT_APPLE_objc_complete_type, 0)) { // If we find the complete version we're done. - offsets.push_back(*ref); - return; + return callback(*ref); } incomplete_types.push_back(*ref); } - offsets.insert(offsets.end(), incomplete_types.begin(), - incomplete_types.end()); + for (DIERef ref : incomplete_types) + if (callback(ref)) + return true; + return false; } -void DebugNamesDWARFIndex::GetTypes(ConstString name, DIEArray &offsets) { - m_fallback.GetTypes(name, offsets); +bool DebugNamesDWARFIndex::GetTypes( + ConstString name, llvm::function_ref callback) { + if (m_fallback.GetTypes(name, callback)) + return true; 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)) + return true; + } } + + return false; } -void DebugNamesDWARFIndex::GetTypes(const DWARFDeclContext &context, - DIEArray &offsets) { - m_fallback.GetTypes(context, offsets); +bool DebugNamesDWARFIndex::GetTypes( + const DWARFDeclContext &context, + llvm::function_ref callback) { + if (m_fallback.GetTypes(context, callback)) + return true; for (const DebugNames::Entry &entry : m_debug_names_up->equal_range(context[0].name)) { - if (entry.tag() == context[0].tag) - Append(entry, offsets); + if (entry.tag() == context[0].tag) { + if (ProcessEntry(entry, callback)) + return true; + } } + + return false; } -void DebugNamesDWARFIndex::GetNamespaces(ConstString name, DIEArray &offsets) { - m_fallback.GetNamespaces(name, offsets); +bool DebugNamesDWARFIndex::GetNamespaces( + ConstString name, llvm::function_ref callback) { + if (m_fallback.GetNamespaces(name, callback)) + return true; 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)) + return true; + } } + + return false; } -void DebugNamesDWARFIndex::GetFunctions( +bool DebugNamesDWARFIndex::GetFunctions( ConstString name, SymbolFileDWARF &dwarf, const CompilerDeclContext &parent_decl_ctx, uint32_t name_type_mask, - std::vector &dies) { + llvm::function_ref callback) { - std::vector v; - m_fallback.GetFunctions(name, dwarf, parent_decl_ctx, name_type_mask, v); + if (m_fallback.GetFunctions(name, dwarf, parent_decl_ctx, name_type_mask, + callback)) + return true; + std::set 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 ref = ToDIERef(entry)) - ProcessFunctionDIE(name.GetStringRef(), *ref, dwarf, parent_decl_ctx, - name_type_mask, v); + if (llvm::Optional ref = ToDIERef(entry)) { + if (ProcessFunctionDIE(name.GetStringRef(), *ref, dwarf, parent_decl_ctx, + name_type_mask, [&](DWARFDIE die) { + if (!seen.insert(die.GetDIE()).second) + return false; + return callback(die); + })) + return true; + } } - - std::set seen; - for (DWARFDIE die : v) - if (seen.insert(die.GetDIE()).second) - dies.push_back(die); + return false; } -void DebugNamesDWARFIndex::GetFunctions(const RegularExpression ®ex, - DIEArray &offsets) { - m_fallback.GetFunctions(regex, offsets); +bool DebugNamesDWARFIndex::GetFunctions( + const RegularExpression ®ex, + llvm::function_ref callback) { + if (m_fallback.GetFunctions(regex, callback)) + return true; for (const DebugNames::NameIndex &ni: *m_debug_names_up) { for (DebugNames::NameTableEntry nte: ni) { @@ -245,11 +286,14 @@ if (tag != DW_TAG_subprogram && tag != DW_TAG_inlined_subroutine) continue; - Append(*entry_or, offsets); + if (ProcessEntry(*entry_or, callback)) + return true; } MaybeLogLookupError(entry_or.takeError(), ni, nte.getString()); } } + + return false; } void DebugNamesDWARFIndex::Dump(Stream &s) { diff --git a/lldb/source/Plugins/SymbolFile/DWARF/HashedNameToDIE.h b/lldb/source/Plugins/SymbolFile/DWARF/HashedNameToDIE.h --- a/lldb/source/Plugins/SymbolFile/DWARF/HashedNameToDIE.h +++ b/lldb/source/Plugins/SymbolFile/DWARF/HashedNameToDIE.h @@ -132,33 +132,36 @@ bool ReadHashData(uint32_t hash_data_offset, HashData &hash_data) const override; - size_t + void AppendAllDIEsThatMatchingRegex(const lldb_private::RegularExpression ®ex, DIEInfoArray &die_info_array) const; - size_t AppendAllDIEsInRange(const uint32_t die_offset_start, - const uint32_t die_offset_end, - DIEInfoArray &die_info_array) const; + void AppendAllDIEsInRange(const uint32_t die_offset_start, + const uint32_t die_offset_end, + DIEInfoArray &die_info_array) const; - size_t FindByName(llvm::StringRef name, DIEArray &die_offsets); + bool FindByName(llvm::StringRef name, + llvm::function_ref callback); - size_t FindByNameAndTag(llvm::StringRef name, const dw_tag_t tag, - DIEArray &die_offsets); + bool FindByNameAndTag(llvm::StringRef name, const dw_tag_t tag, + llvm::function_ref callback); - size_t FindByNameAndTagAndQualifiedNameHash( + bool FindByNameAndTagAndQualifiedNameHash( llvm::StringRef name, const dw_tag_t tag, - const uint32_t qualified_name_hash, DIEArray &die_offsets); + const uint32_t qualified_name_hash, + llvm::function_ref callback); - size_t FindCompleteObjCClassByName(llvm::StringRef name, - DIEArray &die_offsets, - bool must_be_implementation); + bool + FindCompleteObjCClassByName(llvm::StringRef name, + llvm::function_ref callback, + bool must_be_implementation); protected: Result AppendHashDataForRegularExpression( const lldb_private::RegularExpression ®ex, lldb::offset_t *hash_data_offset_ptr, Pair &pair) const; - size_t FindByName(llvm::StringRef name, DIEInfoArray &die_info_array); + void FindByName(llvm::StringRef name, DIEInfoArray &die_info_array); Result GetHashDataForName(llvm::StringRef name, lldb::offset_t *hash_data_offset_ptr, @@ -169,27 +172,28 @@ std::string m_name; }; - static void ExtractDIEArray(const DIEInfoArray &die_info_array, - DIEArray &die_offsets); + static bool ExtractDIEArray(const DIEInfoArray &die_info_array, + llvm::function_ref callback); protected: - static void ExtractDIEArray(const DIEInfoArray &die_info_array, - const dw_tag_t tag, DIEArray &die_offsets); + static bool ExtractDIEArray(const DIEInfoArray &die_info_array, + const dw_tag_t tag, + llvm::function_ref callback); - static void ExtractDIEArray(const DIEInfoArray &die_info_array, + static bool ExtractDIEArray(const DIEInfoArray &die_info_array, const dw_tag_t tag, const uint32_t qualified_name_hash, - DIEArray &die_offsets); + llvm::function_ref callback); - static void + static bool ExtractClassOrStructDIEArray(const DIEInfoArray &die_info_array, bool return_implementation_only_if_available, - DIEArray &die_offsets); + llvm::function_ref callback); - static void ExtractTypesFromDIEArray(const DIEInfoArray &die_info_array, - uint32_t type_flag_mask, - uint32_t type_flag_value, - DIEArray &die_offsets); + static bool + ExtractTypesFromDIEArray(const DIEInfoArray &die_info_array, + uint32_t type_flag_mask, uint32_t type_flag_value, + llvm::function_ref callback); static const char *GetAtomTypeName(uint16_t atom); }; diff --git a/lldb/source/Plugins/SymbolFile/DWARF/HashedNameToDIE.cpp b/lldb/source/Plugins/SymbolFile/DWARF/HashedNameToDIE.cpp --- a/lldb/source/Plugins/SymbolFile/DWARF/HashedNameToDIE.cpp +++ b/lldb/source/Plugins/SymbolFile/DWARF/HashedNameToDIE.cpp @@ -9,20 +9,21 @@ #include "HashedNameToDIE.h" #include "llvm/ADT/StringRef.h" -void DWARFMappedHash::ExtractDIEArray(const DIEInfoArray &die_info_array, - DIEArray &die_offsets) { +bool DWARFMappedHash::ExtractDIEArray( + const DIEInfoArray &die_info_array, + llvm::function_ref callback) { const size_t count = die_info_array.size(); for (size_t i = 0; i < count; ++i) - die_offsets.emplace_back(die_info_array[i]); + if (callback(DIERef(die_info_array[i]))) + return true; + return false; } -void DWARFMappedHash::ExtractDIEArray(const DIEInfoArray &die_info_array, - const dw_tag_t tag, - DIEArray &die_offsets) { - if (tag == 0) { - ExtractDIEArray(die_info_array, die_offsets); - return; - } +bool DWARFMappedHash::ExtractDIEArray( + const DIEInfoArray &die_info_array, const dw_tag_t tag, + llvm::function_ref callback) { + if (tag == 0) + return ExtractDIEArray(die_info_array, callback); const size_t count = die_info_array.size(); for (size_t i = 0; i < count; ++i) { @@ -32,19 +33,21 @@ if (die_tag == DW_TAG_class_type || die_tag == DW_TAG_structure_type) tag_matches = tag == DW_TAG_structure_type || tag == DW_TAG_class_type; } - if (tag_matches) - die_offsets.emplace_back(die_info_array[i]); + if (tag_matches) { + if (callback(DIERef(die_info_array[i]))) + return false; + } } + + return false; } -void DWARFMappedHash::ExtractDIEArray(const DIEInfoArray &die_info_array, - const dw_tag_t tag, - const uint32_t qualified_name_hash, - DIEArray &die_offsets) { - if (tag == 0) { - ExtractDIEArray(die_info_array, die_offsets); - return; - } +bool DWARFMappedHash::ExtractDIEArray( + const DIEInfoArray &die_info_array, const dw_tag_t tag, + const uint32_t qualified_name_hash, + llvm::function_ref callback) { + if (tag == 0) + return ExtractDIEArray(die_info_array, callback); const size_t count = die_info_array.size(); for (size_t i = 0; i < count; ++i) { @@ -56,45 +59,51 @@ if (die_tag == DW_TAG_class_type || die_tag == DW_TAG_structure_type) tag_matches = tag == DW_TAG_structure_type || tag == DW_TAG_class_type; } - if (tag_matches) - die_offsets.emplace_back(die_info_array[i]); + if (tag_matches) { + if (callback(DIERef(die_info_array[i]))) + return true; + } } + + return false; } -void DWARFMappedHash::ExtractClassOrStructDIEArray( +bool DWARFMappedHash::ExtractClassOrStructDIEArray( const DIEInfoArray &die_info_array, - bool return_implementation_only_if_available, DIEArray &die_offsets) { + bool return_implementation_only_if_available, + llvm::function_ref callback) { const size_t count = die_info_array.size(); for (size_t i = 0; i < count; ++i) { const dw_tag_t die_tag = die_info_array[i].tag; if (!(die_tag == 0 || die_tag == DW_TAG_class_type || die_tag == DW_TAG_structure_type)) continue; - if (die_info_array[i].type_flags & eTypeFlagClassIsImplementation) { - if (return_implementation_only_if_available) { - // We found the one true definition for this class, so only return - // that - die_offsets.clear(); - die_offsets.emplace_back(die_info_array[i]); - return; - } else { - // Put the one true definition as the first entry so it matches first - die_offsets.emplace(die_offsets.begin(), die_info_array[i]); - } - } else { - die_offsets.emplace_back(die_info_array[i]); + bool is_implementation = + (die_info_array[i].type_flags & eTypeFlagClassIsImplementation) != 0; + if (is_implementation != return_implementation_only_if_available) + continue; + if (return_implementation_only_if_available) { + // We found the one true definition for this class, so only return + // that + return callback(DIERef(die_info_array[i])); } + if (callback(DIERef(die_info_array[i]))) + return true; } + return false; } -void DWARFMappedHash::ExtractTypesFromDIEArray( +bool DWARFMappedHash::ExtractTypesFromDIEArray( const DIEInfoArray &die_info_array, uint32_t type_flag_mask, - uint32_t type_flag_value, DIEArray &die_offsets) { + uint32_t type_flag_value, llvm::function_ref callback) { const size_t count = die_info_array.size(); for (size_t i = 0; i < count; ++i) { - if ((die_info_array[i].type_flags & type_flag_mask) == type_flag_value) - die_offsets.emplace_back(die_info_array[i]); + if ((die_info_array[i].type_flags & type_flag_mask) == type_flag_value) { + if (callback(DIERef(die_info_array[i]))) + return true; + } } + return false; } const char *DWARFMappedHash::GetAtomTypeName(uint16_t atom) { @@ -453,7 +462,7 @@ } } -size_t DWARFMappedHash::MemoryTable::AppendAllDIEsThatMatchingRegex( +void DWARFMappedHash::MemoryTable::AppendAllDIEsThatMatchingRegex( const lldb_private::RegularExpression ®ex, DIEInfoArray &die_info_array) const { const uint32_t hash_count = m_header.hashes_count; @@ -482,10 +491,9 @@ } } die_info_array.swap(pair.value); - return die_info_array.size(); } -size_t DWARFMappedHash::MemoryTable::AppendAllDIEsInRange( +void DWARFMappedHash::MemoryTable::AppendAllDIEsInRange( const uint32_t die_offset_start, const uint32_t die_offset_end, DIEInfoArray &die_info_array) const { const uint32_t hash_count = m_header.hashes_count; @@ -512,73 +520,73 @@ } } } - return die_info_array.size(); } -size_t DWARFMappedHash::MemoryTable::FindByName(llvm::StringRef name, - DIEArray &die_offsets) { +bool DWARFMappedHash::MemoryTable::FindByName( + llvm::StringRef name, llvm::function_ref callback) { if (name.empty()) - return 0; + return false; DIEInfoArray die_info_array; - if (FindByName(name, die_info_array)) - DWARFMappedHash::ExtractDIEArray(die_info_array, die_offsets); - return die_info_array.size(); + FindByName(name, die_info_array); + return DWARFMappedHash::ExtractDIEArray(die_info_array, callback); } -size_t DWARFMappedHash::MemoryTable::FindByNameAndTag(llvm::StringRef name, - const dw_tag_t tag, - DIEArray &die_offsets) { +bool DWARFMappedHash::MemoryTable::FindByNameAndTag( + llvm::StringRef name, const dw_tag_t tag, + llvm::function_ref callback) { DIEInfoArray die_info_array; - if (FindByName(name, die_info_array)) - DWARFMappedHash::ExtractDIEArray(die_info_array, tag, die_offsets); - return die_info_array.size(); + FindByName(name, die_info_array); + return DWARFMappedHash::ExtractDIEArray(die_info_array, tag, callback); } -size_t DWARFMappedHash::MemoryTable::FindByNameAndTagAndQualifiedNameHash( +bool DWARFMappedHash::MemoryTable::FindByNameAndTagAndQualifiedNameHash( llvm::StringRef name, const dw_tag_t tag, - const uint32_t qualified_name_hash, DIEArray &die_offsets) { + const uint32_t qualified_name_hash, + llvm::function_ref callback) { DIEInfoArray die_info_array; - if (FindByName(name, die_info_array)) - DWARFMappedHash::ExtractDIEArray(die_info_array, tag, qualified_name_hash, - die_offsets); - return die_info_array.size(); + FindByName(name, die_info_array); + return DWARFMappedHash::ExtractDIEArray(die_info_array, tag, + qualified_name_hash, callback); } -size_t DWARFMappedHash::MemoryTable::FindCompleteObjCClassByName( - llvm::StringRef name, DIEArray &die_offsets, bool must_be_implementation) { +bool DWARFMappedHash::MemoryTable::FindCompleteObjCClassByName( + llvm::StringRef name, llvm::function_ref callback, + bool must_be_implementation) { DIEInfoArray die_info_array; - if (!FindByName(name, die_info_array)) - return 0; + FindByName(name, die_info_array); if (must_be_implementation && GetHeader().header_data.ContainsAtom(eAtomTypeTypeFlags)) { // If we have two atoms, then we have the DIE offset and the type flags // so we can find the objective C class efficiently. - DWARFMappedHash::ExtractTypesFromDIEArray(die_info_array, UINT32_MAX, - eTypeFlagClassIsImplementation, - die_offsets); - return die_offsets.size(); + return DWARFMappedHash::ExtractTypesFromDIEArray( + die_info_array, UINT32_MAX, eTypeFlagClassIsImplementation, callback); } // We don't only want the one true definition, so try and see what we can // find, and only return class or struct DIEs. If we do have the full // implementation, then return it alone, else return all possible // matches. - const bool return_implementation_only_if_available = true; - DWARFMappedHash::ExtractClassOrStructDIEArray( - die_info_array, return_implementation_only_if_available, die_offsets); - return die_offsets.size(); + bool found_implementation = false; + if (DWARFMappedHash::ExtractClassOrStructDIEArray( + die_info_array, true /*return_implementation_only_if_available*/, + [&](DIERef ref) { + found_implementation = true; + return callback(ref); + })) + return true; + if (found_implementation) + return false; + return DWARFMappedHash::ExtractClassOrStructDIEArray( + die_info_array, false /*return_implementation_only_if_available*/, + callback); } -size_t DWARFMappedHash::MemoryTable::FindByName(llvm::StringRef name, - DIEInfoArray &die_info_array) { +void DWARFMappedHash::MemoryTable::FindByName(llvm::StringRef name, + DIEInfoArray &die_info_array) { if (name.empty()) - return 0; + return; Pair kv_pair; - size_t old_size = die_info_array.size(); - if (Find(name, kv_pair)) { + if (Find(name, kv_pair)) die_info_array.swap(kv_pair.value); - return die_info_array.size() - old_size; - } - return 0; } diff --git a/lldb/source/Plugins/SymbolFile/DWARF/ManualDWARFIndex.h b/lldb/source/Plugins/SymbolFile/DWARF/ManualDWARFIndex.h --- a/lldb/source/Plugins/SymbolFile/DWARF/ManualDWARFIndex.h +++ b/lldb/source/Plugins/SymbolFile/DWARF/ManualDWARFIndex.h @@ -26,21 +26,32 @@ void Preload() override { Index(); } - void GetGlobalVariables(ConstString basename, DIEArray &offsets) override; - void GetGlobalVariables(const RegularExpression ®ex, - DIEArray &offsets) override; - void GetGlobalVariables(const DWARFUnit &unit, DIEArray &offsets) override; - void GetObjCMethods(ConstString class_name, DIEArray &offsets) override; - void GetCompleteObjCClass(ConstString class_name, bool must_be_implementation, - DIEArray &offsets) override; - void GetTypes(ConstString name, DIEArray &offsets) override; - void GetTypes(const DWARFDeclContext &context, DIEArray &offsets) override; - void GetNamespaces(ConstString name, DIEArray &offsets) override; - void GetFunctions(ConstString name, SymbolFileDWARF &dwarf, + bool + GetGlobalVariables(ConstString basename, + llvm::function_ref callback) override; + bool + GetGlobalVariables(const RegularExpression ®ex, + llvm::function_ref callback) override; + bool + GetGlobalVariables(const DWARFUnit &unit, + llvm::function_ref callback) override; + bool GetObjCMethods(ConstString class_name, + llvm::function_ref callback) override; + bool + GetCompleteObjCClass(ConstString class_name, bool must_be_implementation, + llvm::function_ref callback) override; + bool GetTypes(ConstString name, + llvm::function_ref callback) override; + bool GetTypes(const DWARFDeclContext &context, + llvm::function_ref callback) override; + bool GetNamespaces(ConstString name, + llvm::function_ref callback) override; + bool GetFunctions(ConstString name, SymbolFileDWARF &dwarf, const CompilerDeclContext &parent_decl_ctx, uint32_t name_type_mask, - std::vector &dies) override; - void GetFunctions(const RegularExpression ®ex, DIEArray &offsets) override; + llvm::function_ref callback) override; + bool GetFunctions(const RegularExpression ®ex, + llvm::function_ref callback) override; void ReportInvalidDIERef(const DIERef &ref, llvm::StringRef name) override {} void Dump(Stream &s) override; diff --git a/lldb/source/Plugins/SymbolFile/DWARF/ManualDWARFIndex.cpp b/lldb/source/Plugins/SymbolFile/DWARF/ManualDWARFIndex.cpp --- a/lldb/source/Plugins/SymbolFile/DWARF/ManualDWARFIndex.cpp +++ b/lldb/source/Plugins/SymbolFile/DWARF/ManualDWARFIndex.cpp @@ -367,113 +367,118 @@ } } -void ManualDWARFIndex::GetGlobalVariables(ConstString basename, DIEArray &offsets) { +bool ManualDWARFIndex::GetGlobalVariables( + ConstString basename, llvm::function_ref callback) { Index(); - m_set.globals.Find(basename, offsets); + return m_set.globals.Find(basename, callback); } -void ManualDWARFIndex::GetGlobalVariables(const RegularExpression ®ex, - DIEArray &offsets) { +bool ManualDWARFIndex::GetGlobalVariables( + const RegularExpression ®ex, + llvm::function_ref callback) { Index(); - m_set.globals.Find(regex, offsets); + return m_set.globals.Find(regex, callback); } -void ManualDWARFIndex::GetGlobalVariables(const DWARFUnit &unit, - DIEArray &offsets) { +bool ManualDWARFIndex::GetGlobalVariables( + const DWARFUnit &unit, llvm::function_ref callback) { Index(); - m_set.globals.FindAllEntriesForUnit(unit, offsets); + return m_set.globals.FindAllEntriesForUnit(unit, callback); } -void ManualDWARFIndex::GetObjCMethods(ConstString class_name, - DIEArray &offsets) { +bool ManualDWARFIndex::GetObjCMethods( + ConstString class_name, llvm::function_ref callback) { Index(); - m_set.objc_class_selectors.Find(class_name, offsets); + return m_set.objc_class_selectors.Find(class_name, callback); } -void ManualDWARFIndex::GetCompleteObjCClass(ConstString class_name, - bool must_be_implementation, - DIEArray &offsets) { +bool ManualDWARFIndex::GetCompleteObjCClass( + ConstString class_name, bool must_be_implementation, + llvm::function_ref callback) { Index(); - m_set.types.Find(class_name, offsets); + return m_set.types.Find(class_name, callback); } -void ManualDWARFIndex::GetTypes(ConstString name, DIEArray &offsets) { +bool ManualDWARFIndex::GetTypes(ConstString name, + llvm::function_ref callback) { Index(); - m_set.types.Find(name, offsets); + return m_set.types.Find(name, callback); } -void ManualDWARFIndex::GetTypes(const DWARFDeclContext &context, - DIEArray &offsets) { +bool ManualDWARFIndex::GetTypes(const DWARFDeclContext &context, + llvm::function_ref callback) { Index(); - m_set.types.Find(ConstString(context[0].name), offsets); + return m_set.types.Find(ConstString(context[0].name), callback); } -void ManualDWARFIndex::GetNamespaces(ConstString name, DIEArray &offsets) { +bool ManualDWARFIndex::GetNamespaces( + ConstString name, llvm::function_ref callback) { Index(); - m_set.namespaces.Find(name, offsets); + return m_set.namespaces.Find(name, callback); } -void ManualDWARFIndex::GetFunctions(ConstString name, SymbolFileDWARF &dwarf, - const CompilerDeclContext &parent_decl_ctx, - uint32_t name_type_mask, - std::vector &dies) { +bool ManualDWARFIndex::GetFunctions( + ConstString name, SymbolFileDWARF &dwarf, + const CompilerDeclContext &parent_decl_ctx, uint32_t name_type_mask, + llvm::function_ref callback) { Index(); if (name_type_mask & eFunctionNameTypeFull) { - DIEArray offsets; - m_set.function_fullnames.Find(name, offsets); - for (const DIERef &die_ref: offsets) { - DWARFDIE die = dwarf.GetDIE(die_ref); - if (!die) - continue; - if (!SymbolFileDWARF::DIEInDeclContext(parent_decl_ctx, die)) - continue; - dies.push_back(die); - } + if (m_set.function_fullnames.Find(name, [&](DIERef die_ref) { + DWARFDIE die = dwarf.GetDIE(die_ref); + if (!die) + return false; + if (!SymbolFileDWARF::DIEInDeclContext(parent_decl_ctx, die)) + return false; + return callback(die); + })) + return true; } if (name_type_mask & eFunctionNameTypeBase) { - DIEArray offsets; - m_set.function_basenames.Find(name, offsets); - for (const DIERef &die_ref: offsets) { - DWARFDIE die = dwarf.GetDIE(die_ref); - if (!die) - continue; - if (!SymbolFileDWARF::DIEInDeclContext(parent_decl_ctx, die)) - continue; - dies.push_back(die); - } + if (m_set.function_basenames.Find(name, [&](DIERef die_ref) { + DWARFDIE die = dwarf.GetDIE(die_ref); + if (!die) + return false; + if (!SymbolFileDWARF::DIEInDeclContext(parent_decl_ctx, die)) + return false; + return callback(die); + })) + return true; } if (name_type_mask & eFunctionNameTypeMethod && !parent_decl_ctx.IsValid()) { - DIEArray offsets; - m_set.function_methods.Find(name, offsets); - for (const DIERef &die_ref: offsets) { - DWARFDIE die = dwarf.GetDIE(die_ref); - if (!die) - continue; - dies.push_back(die); - } + if (m_set.function_methods.Find(name, [&](DIERef die_ref) { + DWARFDIE die = dwarf.GetDIE(die_ref); + if (!die) + return false; + return callback(die); + })) + return true; } if (name_type_mask & eFunctionNameTypeSelector && !parent_decl_ctx.IsValid()) { - DIEArray offsets; - m_set.function_selectors.Find(name, offsets); - for (const DIERef &die_ref: offsets) { - DWARFDIE die = dwarf.GetDIE(die_ref); - if (!die) - continue; - dies.push_back(die); - } + if (m_set.function_selectors.Find(name, [&](DIERef die_ref) { + DWARFDIE die = dwarf.GetDIE(die_ref); + if (!die) + return false; + return callback(die); + })) + return true; } + return false; } -void ManualDWARFIndex::GetFunctions(const RegularExpression ®ex, - DIEArray &offsets) { +bool ManualDWARFIndex::GetFunctions( + const RegularExpression ®ex, + llvm::function_ref callback) { Index(); - m_set.function_basenames.Find(regex, offsets); - m_set.function_fullnames.Find(regex, offsets); + if (m_set.function_basenames.Find(regex, callback)) + return true; + if (m_set.function_fullnames.Find(regex, callback)) + return true; + return false; } void ManualDWARFIndex::Dump(Stream &s) { diff --git a/lldb/source/Plugins/SymbolFile/DWARF/NameToDIE.h b/lldb/source/Plugins/SymbolFile/DWARF/NameToDIE.h --- a/lldb/source/Plugins/SymbolFile/DWARF/NameToDIE.h +++ b/lldb/source/Plugins/SymbolFile/DWARF/NameToDIE.h @@ -32,14 +32,15 @@ void Finalize(); - size_t Find(lldb_private::ConstString name, - DIEArray &info_array) const; + bool Find(lldb_private::ConstString name, + llvm::function_ref callback) const; - size_t Find(const lldb_private::RegularExpression ®ex, - DIEArray &info_array) const; + bool Find(const lldb_private::RegularExpression ®ex, + llvm::function_ref callback) const; - size_t FindAllEntriesForUnit(const DWARFUnit &unit, - DIEArray &info_array) const; + bool + FindAllEntriesForUnit(const DWARFUnit &unit, + llvm::function_ref callback) const; void ForEach(std::function callback) const { + for (const auto &entry : m_map.equal_range(name)) + if (callback(entry.value)) + return true; + return false; } -size_t NameToDIE::Find(const RegularExpression ®ex, - DIEArray &info_array) const { - return m_map.GetValues(regex, info_array); +bool NameToDIE::Find(const RegularExpression ®ex, + llvm::function_ref callback) const { + for (const auto &entry : m_map) + if (regex.Execute(entry.cstring.GetCString())) { + if (callback(entry.value)) + return true; + } + return false; } -size_t NameToDIE::FindAllEntriesForUnit(const DWARFUnit &unit, - DIEArray &info_array) const { - const size_t initial_size = info_array.size(); +bool NameToDIE::FindAllEntriesForUnit( + const DWARFUnit &unit, + llvm::function_ref callback) const { const uint32_t size = m_map.GetSize(); for (uint32_t i = 0; i < size; ++i) { const DIERef &die_ref = m_map.GetValueAtIndexUnchecked(i); if (unit.GetSymbolFileDWARF().GetDwoNum() == die_ref.dwo_num() && unit.GetDebugSection() == die_ref.section() && unit.GetOffset() <= die_ref.die_offset() && - die_ref.die_offset() < unit.GetNextUnitOffset()) - info_array.push_back(die_ref); + die_ref.die_offset() < unit.GetNextUnitOffset()) { + if (callback(die_ref)) + return true; + } } - return info_array.size() - initial_size; + return false; } void NameToDIE::Dump(Stream *s) { diff --git a/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.h b/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.h --- a/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.h +++ b/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.h @@ -237,8 +237,8 @@ lldb_private::CompileUnit * GetCompUnitForDWARFCompUnit(DWARFCompileUnit &dwarf_cu); - virtual size_t GetObjCMethodDIEOffsets(lldb_private::ConstString class_name, - DIEArray &method_die_offsets); + virtual bool GetObjCMethods(lldb_private::ConstString class_name, + llvm::function_ref callback); bool Supports_DW_AT_APPLE_objc_complete_type(DWARFUnit *cu); diff --git a/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp b/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp --- a/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp +++ b/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp @@ -1457,11 +1457,9 @@ return static_cast(non_dwo_cu->GetUserData()); } -size_t SymbolFileDWARF::GetObjCMethodDIEOffsets(ConstString class_name, - DIEArray &method_die_offsets) { - method_die_offsets.clear(); - m_index->GetObjCMethods(class_name, method_die_offsets); - return method_die_offsets.size(); +bool SymbolFileDWARF::GetObjCMethods( + ConstString class_name, llvm::function_ref callback) { + return m_index->GetObjCMethods(class_name, callback); } bool SymbolFileDWARF::GetFunction(const DWARFDIE &die, SymbolContext &sc) { @@ -2042,24 +2040,20 @@ context, basename)) basename = name.GetStringRef(); - DIEArray die_offsets; - m_index->GetGlobalVariables(ConstString(basename), die_offsets); - const size_t num_die_matches = die_offsets.size(); - - SymbolContext sc; - sc.module_sp = m_objfile_sp->GetModule(); - assert(sc.module_sp); - // Loop invariant: Variables up to this index have been checked for context // matches. uint32_t pruned_idx = original_size; - for (size_t i = 0; i < num_die_matches; ++i) { - const DIERef &die_ref = die_offsets[i]; + SymbolContext sc; + m_index->GetGlobalVariables(ConstString(basename), [&](DIERef die_ref) { + if (!sc.module_sp) + sc.module_sp = m_objfile_sp->GetModule(); + assert(sc.module_sp); + DWARFDIE die = GetDIE(die_ref); if (!die) { m_index->ReportInvalidDIERef(die_ref, name.GetStringRef()); - continue; + return false; } switch (die.Tag()) { @@ -2068,14 +2062,14 @@ case DW_TAG_inlined_subroutine: case DW_TAG_try_block: case DW_TAG_catch_block: - continue; + return false; case DW_TAG_variable: break; } auto *dwarf_cu = llvm::dyn_cast(die.GetCU()); if (!dwarf_cu) - continue; + return false; sc.comp_unit = GetCompUnitForDWARFCompUnit(*dwarf_cu); if (parent_decl_ctx) { @@ -2084,7 +2078,7 @@ dwarf_ast->GetDeclContextContainingUIDFromDWARF(die); if (!actual_parent_decl_ctx || actual_parent_decl_ctx != parent_decl_ctx) - continue; + return false; } } @@ -2098,9 +2092,8 @@ variables.RemoveVariableAtIndex(pruned_idx); } - if (variables.GetSize() - original_size >= max_matches) - break; - } + return variables.GetSize() - original_size >= max_matches; + }); // Return the number of variable that were appended to the list const uint32_t num_matches = variables.GetSize() - original_size; @@ -2131,32 +2124,27 @@ // Remember how many variables are in the list before we search. const uint32_t original_size = variables.GetSize(); - DIEArray die_offsets; - m_index->GetGlobalVariables(regex, die_offsets); - SymbolContext sc; - sc.module_sp = m_objfile_sp->GetModule(); - assert(sc.module_sp); + m_index->GetGlobalVariables(regex, [&](DIERef die_ref) { + if (!sc.module_sp) + sc.module_sp = m_objfile_sp->GetModule(); + assert(sc.module_sp); - const size_t num_matches = die_offsets.size(); - for (size_t i = 0; i < num_matches; ++i) { - const DIERef &die_ref = die_offsets[i]; DWARFDIE die = GetDIE(die_ref); if (!die) { m_index->ReportInvalidDIERef(die_ref, regex.GetText()); - continue; + return false; } DWARFCompileUnit *dwarf_cu = llvm::dyn_cast(die.GetCU()); if (!dwarf_cu) - continue; + return false; sc.comp_unit = GetCompUnitForDWARFCompUnit(*dwarf_cu); ParseVariables(sc, die, LLDB_INVALID_ADDRESS, false, false, &variables); - if (variables.GetSize() - original_size >= max_matches) - break; - } + return variables.GetSize() - original_size >= max_matches; + }); } bool SymbolFileDWARF::ResolveFunction(const DWARFDIE &orig_die, @@ -2270,12 +2258,12 @@ llvm::DenseSet resolved_dies; - std::vector dies; - m_index->GetFunctions(name, *this, parent_decl_ctx, name_type_mask, dies); - for (const DWARFDIE &die : dies) { - if (resolved_dies.insert(die.GetDIE()).second) - ResolveFunction(die, include_inlines, sc_list); - } + m_index->GetFunctions(name, *this, parent_decl_ctx, name_type_mask, + [&](DWARFDIE die) { + if (resolved_dies.insert(die.GetDIE()).second) + ResolveFunction(die, include_inlines, sc_list); + return false; + }); // Return the number of variable that were appended to the list const uint32_t num_matches = sc_list.GetSize() - original_size; @@ -2307,19 +2295,17 @@ } DWARFDebugInfo &info = DebugInfo(); - DIEArray offsets; - m_index->GetFunctions(regex, offsets); - llvm::DenseSet resolved_dies; - for (DIERef ref : offsets) { + m_index->GetFunctions(regex, [&](DIERef ref) { DWARFDIE die = info.GetDIE(ref); if (!die) { m_index->ReportInvalidDIERef(ref, regex.GetText()); - continue; + return false; } if (resolved_dies.insert(die.GetDIE()).second) ResolveFunction(die, include_inlines, sc_list); - } + return false; + }); } void SymbolFileDWARF::GetMangledNamesForFunction( @@ -2375,31 +2361,25 @@ if (!DeclContextMatchesThisSymbolFile(parent_decl_ctx)) return; - DIEArray die_offsets; - m_index->GetTypes(name, die_offsets); - const size_t num_die_matches = die_offsets.size(); - - for (size_t i = 0; i < num_die_matches; ++i) { - const DIERef &die_ref = die_offsets[i]; + m_index->GetTypes(name, [&](DIERef die_ref) { DWARFDIE die = GetDIE(die_ref); if (!die) { m_index->ReportInvalidDIERef(die_ref, name.GetStringRef()); - continue; + return false; } if (!DIEInDeclContext(parent_decl_ctx, die)) - continue; // The containing decl contexts don't match + return false; // The containing decl contexts don't match Type *matching_type = ResolveType(die, true, true); if (!matching_type) - continue; + return false; // We found a type pointer, now find the shared pointer form our type // list types.InsertUnique(matching_type->shared_from_this()); - if (types.GetSize() >= max_matches) - break; - } + return types.GetSize() >= max_matches; + }); // Next search through the reachable Clang modules. This only applies for // DWARF objects compiled with -gmodules that haven't been processed by @@ -2449,32 +2429,28 @@ if (!name) return; - DIEArray die_offsets; - m_index->GetTypes(name, die_offsets); - const size_t num_die_matches = die_offsets.size(); - - for (size_t i = 0; i < num_die_matches; ++i) { - const DIERef &die_ref = die_offsets[i]; + m_index->GetTypes(name, [&](DIERef die_ref) { DWARFDIE die = GetDIE(die_ref); if (!die) { m_index->ReportInvalidDIERef(die_ref, name.GetStringRef()); - continue; + return false; } if (!languages[GetLanguage(*die.GetCU())]) - continue; + return false; llvm::SmallVector die_context; die.GetDeclContext(die_context); if (!contextMatches(die_context, pattern)) - continue; + return false; if (Type *matching_type = ResolveType(die, true, true)) { // We found a type pointer, now find the shared pointer form our type // list. types.InsertUnique(matching_type->shared_from_this()); } - } + return false; + }); // Next search through the reachable Clang modules. This only applies for // DWARF objects compiled with -gmodules that haven't been processed by @@ -2504,28 +2480,24 @@ if (!DeclContextMatchesThisSymbolFile(parent_decl_ctx)) return namespace_decl_ctx; - DIEArray die_offsets; - m_index->GetNamespaces(name, die_offsets); - const size_t num_matches = die_offsets.size(); - for (size_t i = 0; i < num_matches; ++i) { - const DIERef &die_ref = die_offsets[i]; + m_index->GetNamespaces(name, [&](DIERef die_ref) { DWARFDIE die = GetDIE(die_ref); if (!die) { m_index->ReportInvalidDIERef(die_ref, name.GetStringRef()); - continue; + return false; } if (!DIEInDeclContext(parent_decl_ctx, die)) - continue; // The containing decl contexts don't match + return false; // The containing decl contexts don't match DWARFASTParser *dwarf_ast = GetDWARFParser(*die.GetCU()); if (!dwarf_ast) - continue; + return false; namespace_decl_ctx = dwarf_ast->GetDeclContextForUIDFromDWARF(die); - if (namespace_decl_ctx) - break; - } + return namespace_decl_ctx.IsValid(); + }); + if (log && namespace_decl_ctx) { GetObjectFile()->GetModule()->LogMessage( log, @@ -2679,59 +2651,54 @@ if (!type_name || (must_be_implementation && !GetObjCClassSymbol(type_name))) return type_sp; - DIEArray die_offsets; - m_index->GetCompleteObjCClass(type_name, must_be_implementation, die_offsets); - - const size_t num_matches = die_offsets.size(); - - for (size_t i = 0; i < num_matches; ++i) { - const DIERef &die_ref = die_offsets[i]; - DWARFDIE type_die = GetDIE(die_ref); - if (!type_die) { - m_index->ReportInvalidDIERef(die_ref, type_name.GetStringRef()); - continue; - } + m_index->GetCompleteObjCClass( + type_name, must_be_implementation, [&](DIERef die_ref) { + DWARFDIE type_die = GetDIE(die_ref); + if (!type_die) { + m_index->ReportInvalidDIERef(die_ref, type_name.GetStringRef()); + return false; + } - bool try_resolving_type = false; + bool try_resolving_type = false; - // Don't try and resolve the DIE we are looking for with the DIE - // itself! - if (type_die != die) { - switch (type_die.Tag()) { - case DW_TAG_class_type: - case DW_TAG_structure_type: - try_resolving_type = true; - break; - default: - break; - } - } - if (!try_resolving_type) - continue; + // Don't try and resolve the DIE we are looking for with the DIE + // itself! + if (type_die != die) { + switch (type_die.Tag()) { + case DW_TAG_class_type: + case DW_TAG_structure_type: + try_resolving_type = true; + break; + default: + break; + } + } + if (!try_resolving_type) + return false; - if (must_be_implementation && - type_die.Supports_DW_AT_APPLE_objc_complete_type()) - try_resolving_type = type_die.GetAttributeValueAsUnsigned( - DW_AT_APPLE_objc_complete_type, 0); - if (!try_resolving_type) - continue; + if (must_be_implementation && + type_die.Supports_DW_AT_APPLE_objc_complete_type()) + try_resolving_type = type_die.GetAttributeValueAsUnsigned( + DW_AT_APPLE_objc_complete_type, 0); + if (!try_resolving_type) + return false; - Type *resolved_type = ResolveType(type_die, false, true); - if (!resolved_type || resolved_type == DIE_IS_BEING_PARSED) - continue; + Type *resolved_type = ResolveType(type_die, false, true); + if (!resolved_type || resolved_type == DIE_IS_BEING_PARSED) + return false; - DEBUG_PRINTF( - "resolved 0x%8.8" PRIx64 " from %s to 0x%8.8" PRIx64 - " (cu 0x%8.8" PRIx64 ")\n", - die.GetID(), - m_objfile_sp->GetFileSpec().GetFilename().AsCString(""), - type_die.GetID(), type_cu->GetID()); + DEBUG_PRINTF( + "resolved 0x%8.8" PRIx64 " from %s to 0x%8.8" PRIx64 + " (cu 0x%8.8" PRIx64 ")\n", + die.GetID(), + m_objfile_sp->GetFileSpec().GetFilename().AsCString(""), + type_die.GetID(), type_cu->GetID()); - if (die) - GetDIEToType()[die.GetDIE()] = resolved_type; - type_sp = resolved_type->shared_from_this(); - break; - } + if (die) + GetDIEToType()[die.GetDIE()] = resolved_type; + type_sp = resolved_type->shared_from_this(); + return true; + }); return type_sp; } @@ -2845,10 +2812,6 @@ dwarf_decl_ctx.GetQualifiedName()); } - DIEArray die_offsets; - m_index->GetTypes(dwarf_decl_ctx, die_offsets); - const size_t num_matches = die_offsets.size(); - // Get the type system that we are looking to find a type for. We will // use this to ensure any matches we find are in a language that this // type system supports @@ -2865,12 +2828,12 @@ type_system = &type_system_or_err.get(); } } - for (size_t i = 0; i < num_matches; ++i) { - const DIERef &die_ref = die_offsets[i]; + + m_index->GetTypes(dwarf_decl_ctx, [&](DIERef die_ref) { DWARFDIE type_die = GetDIE(die_ref); if (!type_die) { m_index->ReportInvalidDIERef(die_ref, type_name.GetStringRef()); - continue; + return false; } // Make sure type_die's langauge matches the type system we are @@ -2878,7 +2841,7 @@ // are looking for a "Foo" type for C, C++, ObjC, or ObjC++. if (type_system && !type_system->SupportsLanguage(GetLanguage(*type_die.GetCU()))) - continue; + return false; bool try_resolving_type = false; // Don't try and resolve the DIE we are looking for with the DIE @@ -2912,7 +2875,7 @@ if (!try_resolving_type) { if (!log) - continue; + return false; std::string qualified_name; type_die.GetQualifiedName(qualified_name); GetObjectFile()->GetModule()->LogMessage( @@ -2923,7 +2886,7 @@ DW_TAG_value_to_name(dwarf_decl_ctx[0].tag), dwarf_decl_ctx.GetQualifiedName(), type_die.GetOffset(), qualified_name.c_str()); - continue; + return false; } DWARFDeclContext type_dwarf_decl_ctx = GetDWARFDeclContext(type_die); @@ -2941,15 +2904,15 @@ // Make sure the decl contexts match all the way up if (dwarf_decl_ctx != type_dwarf_decl_ctx) - continue; + return false; Type *resolved_type = ResolveType(type_die, false); if (!resolved_type || resolved_type == DIE_IS_BEING_PARSED) - continue; + return false; type_sp = resolved_type->shared_from_this(); - break; - } + return true; + }); } } return type_sp; @@ -3093,24 +3056,21 @@ variables = std::make_shared(); sc.comp_unit->SetVariableList(variables); - DIEArray die_offsets; - m_index->GetGlobalVariables(dwarf_cu->GetNonSkeletonUnit(), - die_offsets); - const size_t num_matches = die_offsets.size(); - for (size_t i = 0; i < num_matches; ++i) { - const DIERef &die_ref = die_offsets[i]; - DWARFDIE die = GetDIE(die_ref); - if (!die) { - m_index->ReportInvalidDIERef(die_ref, ""); - continue; - } - - VariableSP var_sp(ParseVariableDIE(sc, die, LLDB_INVALID_ADDRESS)); - if (var_sp) { - variables->AddVariableIfUnique(var_sp); - ++vars_added; - } - } + m_index->GetGlobalVariables( + dwarf_cu->GetNonSkeletonUnit(), [&](DIERef die_ref) { + DWARFDIE die = GetDIE(die_ref); + if (!die) { + m_index->ReportInvalidDIERef(die_ref, ""); + return false; + } + VariableSP var_sp( + ParseVariableDIE(sc, die, LLDB_INVALID_ADDRESS)); + if (var_sp) { + variables->AddVariableIfUnique(var_sp); + ++vars_added; + } + return false; + }); } return vars_added; } diff --git a/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDwo.h b/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDwo.h --- a/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDwo.h +++ b/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDwo.h @@ -31,8 +31,8 @@ DWARFCompileUnit *GetDWOCompileUnitForHash(uint64_t hash); - size_t GetObjCMethodDIEOffsets(lldb_private::ConstString class_name, - DIEArray &method_die_offsets) override; + bool GetObjCMethods(lldb_private::ConstString class_name, + llvm::function_ref callback) override; llvm::Expected GetTypeSystemForLanguage(lldb::LanguageType language) override; diff --git a/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDwo.cpp b/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDwo.cpp --- a/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDwo.cpp +++ b/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDwo.cpp @@ -95,10 +95,10 @@ return GetBaseSymbolFile().GetForwardDeclClangTypeToDie(); } -size_t SymbolFileDWARFDwo::GetObjCMethodDIEOffsets( - lldb_private::ConstString class_name, DIEArray &method_die_offsets) { - return GetBaseSymbolFile().GetObjCMethodDIEOffsets(class_name, - method_die_offsets); +bool SymbolFileDWARFDwo::GetObjCMethods( + lldb_private::ConstString class_name, + llvm::function_ref callback) { + return GetBaseSymbolFile().GetObjCMethods(class_name, callback); } UniqueDWARFASTTypeMap &SymbolFileDWARFDwo::GetUniqueDWARFASTTypeMap() {