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 @@ -32,6 +32,10 @@ T value; }; + typedef std::vector collection; + typedef typename collection::iterator iterator; + typedef typename collection::const_iterator const_iterator; + // Call this function multiple times to add a bunch of entries to this map, // then later call UniqueCStringMap::Sort() before doing any searches by // name. @@ -175,6 +179,18 @@ } } + 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(); } + + // 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( + std::equal_range(m_map.begin(), m_map.end(), unique_cstr, Compare())); + }; + protected: struct Compare { bool operator()(const Entry &lhs, const Entry &rhs) { @@ -196,9 +212,6 @@ return uintptr_t(lhs.GetCString()) < uintptr_t(rhs.GetCString()); } }; - typedef std::vector collection; - typedef typename collection::iterator iterator; - typedef typename collection::const_iterator const_iterator; collection m_map; }; 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 + GetGlobalVariables(ConstString basename, + llvm::function_ref callback) override; + void + GetGlobalVariables(const RegularExpression ®ex, + llvm::function_ref callback) override; + void + GetGlobalVariables(const DWARFUnit &cu, + llvm::function_ref callback) override; + void GetObjCMethods(ConstString class_name, + llvm::function_ref callback) override; + void + GetCompleteObjCClass(ConstString class_name, bool must_be_implementation, + llvm::function_ref callback) override; + void GetTypes(ConstString name, + llvm::function_ref callback) override; + void GetTypes(const DWARFDeclContext &context, + llvm::function_ref callback) override; + void GetNamespaces(ConstString name, + llvm::function_ref callback) override; void 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; + void 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,57 +52,60 @@ return nullptr; } -void AppleDWARFIndex::GetGlobalVariables(ConstString basename, DIEArray &offsets) { +void AppleDWARFIndex::GetGlobalVariables( + ConstString basename, llvm::function_ref callback) { if (!m_apple_names_up) return; - m_apple_names_up->FindByName(basename.GetStringRef(), offsets); + m_apple_names_up->FindByName(basename.GetStringRef(), callback); } -void AppleDWARFIndex::GetGlobalVariables(const RegularExpression ®ex, - DIEArray &offsets) { +void AppleDWARFIndex::GetGlobalVariables( + const RegularExpression ®ex, + llvm::function_ref callback) { if (!m_apple_names_up) return; 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); + DWARFMappedHash::ExtractDIEArray(hash_data, callback); } -void AppleDWARFIndex::GetGlobalVariables(const DWARFUnit &cu, - DIEArray &offsets) { +void AppleDWARFIndex::GetGlobalVariables( + const DWARFUnit &cu, llvm::function_ref callback) { if (!m_apple_names_up) return; 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); + DWARFMappedHash::ExtractDIEArray(hash_data, callback); } -void AppleDWARFIndex::GetObjCMethods(ConstString class_name, - DIEArray &offsets) { +void AppleDWARFIndex::GetObjCMethods( + ConstString class_name, llvm::function_ref callback) { if (!m_apple_objc_up) return; - m_apple_objc_up->FindByName(class_name.GetStringRef(), offsets); + m_apple_objc_up->FindByName(class_name.GetStringRef(), callback); } -void AppleDWARFIndex::GetCompleteObjCClass(ConstString class_name, - bool must_be_implementation, - DIEArray &offsets) { +void 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); + class_name.GetStringRef(), callback, must_be_implementation); } -void AppleDWARFIndex::GetTypes(ConstString name, DIEArray &offsets) { +void AppleDWARFIndex::GetTypes(ConstString name, + llvm::function_ref callback) { if (!m_apple_types_up) return; - m_apple_types_up->FindByName(name.GetStringRef(), offsets); + m_apple_types_up->FindByName(name.GetStringRef(), callback); } void AppleDWARFIndex::GetTypes(const DWARFDeclContext &context, - DIEArray &offsets) { + llvm::function_ref callback) { if (!m_apple_types_up) return; @@ -122,7 +125,7 @@ if (log) m_module.LogMessage(log, "FindByNameAndTagAndQualifiedNameHash()"); m_apple_types_up->FindByNameAndTagAndQualifiedNameHash( - type_name.GetStringRef(), tag, qualified_name_hash, offsets); + type_name.GetStringRef(), tag, qualified_name_hash, callback); return; } @@ -136,47 +139,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()) + if (m_apple_types_up->FindByName(context[1].name, + [&](DIERef ref) { return false; })) return; } if (log) m_module.LogMessage(log, "FindByNameAndTag()"); - m_apple_types_up->FindByNameAndTag(type_name.GetStringRef(), tag, offsets); + m_apple_types_up->FindByNameAndTag(type_name.GetStringRef(), tag, callback); return; } - m_apple_types_up->FindByName(type_name.GetStringRef(), offsets); + m_apple_types_up->FindByName(type_name.GetStringRef(), callback); } -void AppleDWARFIndex::GetNamespaces(ConstString name, DIEArray &offsets) { +void AppleDWARFIndex::GetNamespaces( + ConstString name, llvm::function_ref callback) { if (!m_apple_namespaces_up) return; - m_apple_namespaces_up->FindByName(name.GetStringRef(), offsets); + 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); - } +void AppleDWARFIndex::GetFunctions( + ConstString name, SymbolFileDWARF &dwarf, + const CompilerDeclContext &parent_decl_ctx, uint32_t name_type_mask, + llvm::function_ref callback) { + 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) { +void AppleDWARFIndex::GetFunctions( + const RegularExpression ®ex, + llvm::function_ref callback) { if (!m_apple_names_up) return; 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); + 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 @@ -2013,18 +2013,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 true; + }); 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 void + 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 + GetGlobalVariables(const RegularExpression ®ex, + llvm::function_ref callback) = 0; + virtual void + GetGlobalVariables(const DWARFUnit &cu, + llvm::function_ref callback) = 0; + virtual void + GetObjCMethods(ConstString class_name, + llvm::function_ref callback) = 0; + virtual void + GetCompleteObjCClass(ConstString class_name, bool must_be_implementation, + llvm::function_ref callback) = 0; + virtual void GetTypes(ConstString name, + llvm::function_ref callback) = 0; + virtual void GetTypes(const DWARFDeclContext &context, + llvm::function_ref callback) = 0; + virtual void GetNamespaces(ConstString name, + llvm::function_ref callback) = 0; + virtual void + GetFunctions(ConstString name, SymbolFileDWARF &dwarf, + const CompilerDeclContext &parent_decl_ctx, + uint32_t name_type_mask, + llvm::function_ref callback) = 0; virtual void GetFunctions(const RegularExpression ®ex, - DIEArray &offsets) = 0; + 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 true; } // 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 true; // 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 true; // 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 true; } 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,32 @@ 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 + GetGlobalVariables(ConstString basename, + llvm::function_ref callback) override; + void + GetGlobalVariables(const RegularExpression ®ex, + llvm::function_ref callback) override; + void + GetGlobalVariables(const DWARFUnit &cu, + llvm::function_ref callback) override; + void GetObjCMethods(ConstString class_name, + llvm::function_ref callback) override {} + void + GetCompleteObjCClass(ConstString class_name, bool must_be_implementation, + llvm::function_ref callback) override; + void GetTypes(ConstString name, + llvm::function_ref callback) override; + void GetTypes(const DWARFDeclContext &context, + llvm::function_ref callback) override; + void GetNamespaces(ConstString name, + llvm::function_ref callback) override; void GetFunctions(ConstString name, SymbolFileDWARF &dwarf, const CompilerDeclContext &parent_decl_ctx, uint32_t name_type_mask, - std::vector &dies) override; + llvm::function_ref callback) override; void GetFunctions(const RegularExpression ®ex, - DIEArray &offsets) override; + llvm::function_ref callback) override; void ReportInvalidDIERef(const DIERef &ref, llvm::StringRef name) override {} void Dump(Stream &s) override; @@ -68,7 +78,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 true; } void DebugNamesDWARFIndex::MaybeLogLookupError(llvm::Error error, @@ -74,23 +76,23 @@ ni.getUnitOffset(), name); } -void DebugNamesDWARFIndex::GetGlobalVariables(ConstString basename, - DIEArray &offsets) { - m_fallback.GetGlobalVariables(basename, offsets); - +void DebugNamesDWARFIndex::GetGlobalVariables( + ConstString basename, llvm::function_ref 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)) + 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 callback) { for (const DebugNames::NameIndex &ni: *m_debug_names_up) { for (DebugNames::NameTableEntry nte: ni) { if (!regex.Execute(nte.getString())) @@ -102,17 +104,18 @@ if (entry_or->tag() != DW_TAG_variable) continue; - Append(*entry_or, offsets); + if (!ProcessEntry(*entry_or, callback)) + 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 callback) { uint64_t cu_offset = cu.GetOffset(); for (const DebugNames::NameIndex &ni: *m_debug_names_up) { for (DebugNames::NameTableEntry nte: ni) { @@ -124,18 +127,19 @@ if (entry_or->getCUOffset() != cu_offset) continue; - Append(*entry_or, offsets); + if (!ProcessEntry(*entry_or, callback)) + 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 callback) { // Keep a list of incomplete types as fallback for when we don't find the // complete type. DIEArray incomplete_types; @@ -163,76 +167,89 @@ if (die.GetAttributeValueAsUnsigned(DW_AT_APPLE_objc_complete_type, 0)) { // If we find the complete version we're done. - offsets.push_back(*ref); + callback(*ref); return; } incomplete_types.push_back(*ref); } - offsets.insert(offsets.end(), incomplete_types.begin(), - incomplete_types.end()); -} + for (DIERef ref : incomplete_types) + if (!callback(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 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)) + return; + } } -} -void DebugNamesDWARFIndex::GetTypes(const DWARFDeclContext &context, - DIEArray &offsets) { - m_fallback.GetTypes(context, offsets); + m_fallback.GetTypes(name, callback); +} +void DebugNamesDWARFIndex::GetTypes( + const DWARFDeclContext &context, + llvm::function_ref callback) { 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; + } } -} -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 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)) + 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 &dies) { - - std::vector v; - m_fallback.GetFunctions(name, dwarf, parent_decl_ctx, name_type_mask, v); + llvm::function_ref callback) { + 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 true; + return callback(die); + })) + return; + } } - std::set 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 callback) { for (const DebugNames::NameIndex &ni: *m_debug_names_up) { for (DebugNames::NameTableEntry nte: ni) { if (!regex.Execute(nte.getString())) @@ -245,11 +262,14 @@ if (tag != DW_TAG_subprogram && tag != DW_TAG_inlined_subroutine) continue; - Append(*entry_or, offsets); + if (!ProcessEntry(*entry_or, callback)) + return; } MaybeLogLookupError(entry_or.takeError(), ni, nte.getString()); } } + + m_fallback.GetFunctions(regex, callback); } 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); + void FindByNameAndTag(llvm::StringRef name, const dw_tag_t tag, + llvm::function_ref callback); - size_t FindByNameAndTagAndQualifiedNameHash( + void 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); + void + 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); + const dw_tag_t tag, + llvm::function_ref callback); static void 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 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 void + 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,18 +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 false; + return true; } -void DWARFMappedHash::ExtractDIEArray(const DIEInfoArray &die_info_array, - const dw_tag_t tag, - DIEArray &die_offsets) { +void DWARFMappedHash::ExtractDIEArray( + const DIEInfoArray &die_info_array, const dw_tag_t tag, + llvm::function_ref callback) { if (tag == 0) { - ExtractDIEArray(die_info_array, die_offsets); + ExtractDIEArray(die_info_array, callback); return; } @@ -32,17 +35,19 @@ 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; + } } } -void DWARFMappedHash::ExtractDIEArray(const DIEInfoArray &die_info_array, - const dw_tag_t tag, - const uint32_t qualified_name_hash, - DIEArray &die_offsets) { +void 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) { - ExtractDIEArray(die_info_array, die_offsets); + ExtractDIEArray(die_info_array, callback); return; } @@ -56,44 +61,47 @@ 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; + } } } void 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 + callback(DIERef(die_info_array[i])); + return; } + if (!callback(DIERef(die_info_array[i]))) + return; } } void 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; + } } } @@ -453,7 +461,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 +490,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 +519,74 @@ } } } - 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 true; 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) { +void 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); + DWARFMappedHash::ExtractDIEArray(die_info_array, tag, callback); } -size_t DWARFMappedHash::MemoryTable::FindByNameAndTagAndQualifiedNameHash( +void 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); + 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) { +void 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(); + DWARFMappedHash::ExtractTypesFromDIEArray( + die_info_array, UINT32_MAX, eTypeFlagClassIsImplementation, callback); + return; } // 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; + bool found_implementation = false; DWARFMappedHash::ExtractClassOrStructDIEArray( - die_info_array, return_implementation_only_if_available, die_offsets); - return die_offsets.size(); + die_info_array, true /*return_implementation_only_if_available*/, + [&](DIERef ref) { + found_implementation = true; + // Here the return value does not matter as we are called at most once. + return callback(ref); + }); + if (found_implementation) + 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 + GetGlobalVariables(ConstString basename, + llvm::function_ref callback) override; + void + GetGlobalVariables(const RegularExpression ®ex, + llvm::function_ref callback) override; + void + GetGlobalVariables(const DWARFUnit &unit, + llvm::function_ref callback) override; + void GetObjCMethods(ConstString class_name, + llvm::function_ref callback) override; + void + GetCompleteObjCClass(ConstString class_name, bool must_be_implementation, + llvm::function_ref callback) override; + void GetTypes(ConstString name, + llvm::function_ref callback) override; + void GetTypes(const DWARFDeclContext &context, + llvm::function_ref callback) override; + void GetNamespaces(ConstString name, + llvm::function_ref callback) override; void 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; + void 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 @@ -320,113 +320,116 @@ } } -void ManualDWARFIndex::GetGlobalVariables(ConstString basename, DIEArray &offsets) { +void ManualDWARFIndex::GetGlobalVariables( + ConstString basename, llvm::function_ref callback) { Index(); - m_set.globals.Find(basename, offsets); + m_set.globals.Find(basename, callback); } -void ManualDWARFIndex::GetGlobalVariables(const RegularExpression ®ex, - DIEArray &offsets) { +void ManualDWARFIndex::GetGlobalVariables( + const RegularExpression ®ex, + llvm::function_ref callback) { Index(); - m_set.globals.Find(regex, offsets); + m_set.globals.Find(regex, callback); } -void ManualDWARFIndex::GetGlobalVariables(const DWARFUnit &unit, - DIEArray &offsets) { +void ManualDWARFIndex::GetGlobalVariables( + const DWARFUnit &unit, llvm::function_ref callback) { Index(); - m_set.globals.FindAllEntriesForUnit(unit, offsets); + m_set.globals.FindAllEntriesForUnit(unit, callback); } -void ManualDWARFIndex::GetObjCMethods(ConstString class_name, - DIEArray &offsets) { +void ManualDWARFIndex::GetObjCMethods( + ConstString class_name, llvm::function_ref callback) { Index(); - m_set.objc_class_selectors.Find(class_name, offsets); + m_set.objc_class_selectors.Find(class_name, callback); } -void ManualDWARFIndex::GetCompleteObjCClass(ConstString class_name, - bool must_be_implementation, - DIEArray &offsets) { +void ManualDWARFIndex::GetCompleteObjCClass( + ConstString class_name, bool must_be_implementation, + llvm::function_ref callback) { Index(); - m_set.types.Find(class_name, offsets); + m_set.types.Find(class_name, callback); } -void ManualDWARFIndex::GetTypes(ConstString name, DIEArray &offsets) { +void ManualDWARFIndex::GetTypes(ConstString name, + llvm::function_ref callback) { Index(); - m_set.types.Find(name, offsets); + m_set.types.Find(name, callback); } void ManualDWARFIndex::GetTypes(const DWARFDeclContext &context, - DIEArray &offsets) { + llvm::function_ref callback) { Index(); - m_set.types.Find(ConstString(context[0].name), offsets); + m_set.types.Find(ConstString(context[0].name), callback); } -void ManualDWARFIndex::GetNamespaces(ConstString name, DIEArray &offsets) { +void ManualDWARFIndex::GetNamespaces( + ConstString name, llvm::function_ref callback) { Index(); - m_set.namespaces.Find(name, offsets); + 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) { +void 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 true; + if (!SymbolFileDWARF::DIEInDeclContext(parent_decl_ctx, die)) + return true; + return callback(die); + })) + return; } 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 true; + if (!SymbolFileDWARF::DIEInDeclContext(parent_decl_ctx, die)) + return true; + return callback(die); + })) + return; } 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 true; + return callback(die); + })) + return; } 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 true; + return callback(die); + })) + return; } } -void ManualDWARFIndex::GetFunctions(const RegularExpression ®ex, - DIEArray &offsets) { +void 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; + if (!m_set.function_fullnames.Find(regex, callback)) + return; } 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; + void + 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 false; + return true; } -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 false; + } + return true; } -size_t NameToDIE::FindAllEntriesForUnit(const DWARFUnit &unit, - DIEArray &info_array) const { - const size_t initial_size = info_array.size(); +void 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; + } } - return info_array.size() - initial_size; } 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 void 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 @@ -1463,11 +1463,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(); +void SymbolFileDWARF::GetObjCMethods( + ConstString class_name, llvm::function_ref callback) { + m_index->GetObjCMethods(class_name, callback); } bool SymbolFileDWARF::GetFunction(const DWARFDIE &die, SymbolContext &sc) { @@ -2048,32 +2046,28 @@ 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 true; } if (die.Tag() != DW_TAG_variable) - continue; + return true; auto *dwarf_cu = llvm::dyn_cast(die.GetCU()); if (!dwarf_cu) - continue; + return true; sc.comp_unit = GetCompUnitForDWARFCompUnit(*dwarf_cu); if (parent_decl_ctx) { @@ -2082,7 +2076,7 @@ dwarf_ast->GetDeclContextContainingUIDFromDWARF(die); if (!actual_parent_decl_ctx || actual_parent_decl_ctx != parent_decl_ctx) - continue; + return true; } } @@ -2096,9 +2090,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; @@ -2129,32 +2122,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 true; } DWARFCompileUnit *dwarf_cu = llvm::dyn_cast(die.GetCU()); if (!dwarf_cu) - continue; + return true; 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, @@ -2268,12 +2256,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 true; + }); // Return the number of variable that were appended to the list const uint32_t num_matches = sc_list.GetSize() - original_size; @@ -2305,19 +2293,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 true; } if (resolved_dies.insert(die.GetDIE()).second) ResolveFunction(die, include_inlines, sc_list); - } + return true; + }); } void SymbolFileDWARF::GetMangledNamesForFunction( @@ -2373,31 +2359,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 true; } if (!DIEInDeclContext(parent_decl_ctx, die)) - continue; // The containing decl contexts don't match + return true; // The containing decl contexts don't match Type *matching_type = ResolveType(die, true, true); if (!matching_type) - continue; + return true; // 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 @@ -2447,32 +2427,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 true; } if (!languages[GetLanguage(*die.GetCU())]) - continue; + return true; llvm::SmallVector die_context; die.GetDeclContext(die_context); if (!contextMatches(die_context, pattern)) - continue; + return true; 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 true; + }); // Next search through the reachable Clang modules. This only applies for // DWARF objects compiled with -gmodules that haven't been processed by @@ -2502,28 +2478,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 true; } if (!DIEInDeclContext(parent_decl_ctx, die)) - continue; // The containing decl contexts don't match + return true; // The containing decl contexts don't match DWARFASTParser *dwarf_ast = GetDWARFParser(*die.GetCU()); if (!dwarf_ast) - continue; + return true; 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, @@ -2677,59 +2649,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 true; + } - 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 true; - 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 true; - 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 true; - 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 false; + }); return type_sp; } @@ -2843,10 +2810,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 @@ -2863,12 +2826,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 true; } // Make sure type_die's langauge matches the type system we are @@ -2876,7 +2839,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 true; bool try_resolving_type = false; // Don't try and resolve the DIE we are looking for with the DIE @@ -2921,7 +2884,7 @@ dwarf_decl_ctx.GetQualifiedName(), type_die.GetOffset(), qualified_name.c_str()); } - continue; + return true; } DWARFDeclContext type_dwarf_decl_ctx = GetDWARFDeclContext(type_die); @@ -2939,15 +2902,15 @@ // Make sure the decl contexts match all the way up if (dwarf_decl_ctx != type_dwarf_decl_ctx) - continue; + return true; Type *resolved_type = ResolveType(type_die, false); if (!resolved_type || resolved_type == DIE_IS_BEING_PARSED) - continue; + return true; type_sp = resolved_type->shared_from_this(); - break; - } + return false; + }); } } return type_sp; @@ -3091,24 +3054,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 true; + } + VariableSP var_sp( + ParseVariableDIE(sc, die, LLDB_INVALID_ADDRESS)); + if (var_sp) { + variables->AddVariableIfUnique(var_sp); + ++vars_added; + } + return true; + }); } 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; + void 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); +void SymbolFileDWARFDwo::GetObjCMethods( + lldb_private::ConstString class_name, + llvm::function_ref callback) { + GetBaseSymbolFile().GetObjCMethods(class_name, callback); } UniqueDWARFASTTypeMap &SymbolFileDWARFDwo::GetUniqueDWARFASTTypeMap() {