Index: lldb/trunk/source/Plugins/SymbolFile/DWARF/AppleDWARFIndex.h =================================================================== --- lldb/trunk/source/Plugins/SymbolFile/DWARF/AppleDWARFIndex.h +++ lldb/trunk/source/Plugins/SymbolFile/DWARF/AppleDWARFIndex.h @@ -43,15 +43,10 @@ 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, DWARFDebugInfo &info, - llvm::function_ref - resolve_function, - llvm::function_ref - get_decl_context_containing_uid, - const CompilerDeclContext *parent_decl_ctx, uint32_t name_type_mask, - bool include_inlines, SymbolContextList &sc_list) override; + void GetFunctions(ConstString name, DWARFDebugInfo &info, + const CompilerDeclContext &parent_decl_ctx, + uint32_t name_type_mask, + std::vector &dies) override; void GetFunctions( const RegularExpression ®ex, DWARFDebugInfo &info, llvm::function_ref - resolve_function, - llvm::function_ref - get_decl_context_containing_uid, - const CompilerDeclContext *parent_decl_ctx, uint32_t name_type_mask, - bool include_inlines, SymbolContextList &sc_list) { - if (!m_apple_names_up) - return; - - std::set resolved_dies; - DIEArray offsets; - - uint32_t num_matches = 0; - +void AppleDWARFIndex::GetFunctions(ConstString name, DWARFDebugInfo &info, + const CompilerDeclContext &parent_decl_ctx, + uint32_t name_type_mask, + std::vector &dies) { if (name_type_mask & eFunctionNameTypeFull) { // If they asked for the full name, match what they typed. At some // point we may want to canonicalize this (strip double spaces, etc. // For now, we just add all the dies that we find by exact match. - num_matches = m_apple_names_up->FindByName(name.GetStringRef(), offsets); - for (uint32_t i = 0; i < num_matches; i++) { - const DIERef &die_ref = offsets[i]; + DIEArray offsets; + m_apple_names_up->FindByName(name.GetStringRef(), offsets); + for (const DIERef &die_ref: offsets) { DWARFDIE die = info.GetDIE(die_ref); - if (die) { - if (!SymbolFileDWARF::DIEInDeclContext(parent_decl_ctx, die)) - continue; // The containing decl contexts don't match - - if (resolved_dies.find(die.GetDIE()) == resolved_dies.end()) { - if (resolve_function(die, include_inlines, sc_list)) - resolved_dies.insert(die.GetDIE()); - } - } else + if (!die) { ReportInvalidDIEOffset(die_ref.die_offset, name.GetStringRef()); + continue; + } + if (SymbolFileDWARF::DIEInDeclContext(&parent_decl_ctx, die)) + dies.push_back(die); } } + if (name_type_mask & eFunctionNameTypeSelector && + !parent_decl_ctx.IsValid()) { + DIEArray offsets; + m_apple_names_up->FindByName(name.GetStringRef(), offsets); - if (name_type_mask & eFunctionNameTypeSelector) { - if (parent_decl_ctx && parent_decl_ctx->IsValid()) - return; // no selectors in namespaces - - num_matches = m_apple_names_up->FindByName(name.GetStringRef(), offsets); // Now make sure these are actually ObjC methods. In this case we can // simply look up the name, and if it is an ObjC method name, we're // good. - - for (uint32_t i = 0; i < num_matches; i++) { - const DIERef &die_ref = offsets[i]; + for (const DIERef &die_ref: offsets) { DWARFDIE die = info.GetDIE(die_ref); - if (die) { - const char *die_name = die.GetName(); - if (ObjCLanguage::IsPossibleObjCMethodName(die_name)) { - if (resolved_dies.find(die.GetDIE()) == resolved_dies.end()) { - if (resolve_function(die, include_inlines, sc_list)) - resolved_dies.insert(die.GetDIE()); - } - } - } else + if (!die) { ReportInvalidDIEOffset(die_ref.die_offset, name.GetStringRef()); + continue; + } + const char *die_name = die.GetName(); + if (ObjCLanguage::IsPossibleObjCMethodName(die_name)) + dies.push_back(die); } - offsets.clear(); } - - if (((name_type_mask & eFunctionNameTypeMethod) && !parent_decl_ctx) || + if (((name_type_mask & eFunctionNameTypeMethod) && + !parent_decl_ctx.IsValid()) || name_type_mask & eFunctionNameTypeBase) { // The apple_names table stores just the "base name" of C++ methods in // the table. So we have to extract the base name, look that up, and // if there is any other information in the name we were passed in we // have to post-filter based on that. - // FIXME: Arrange the logic above so that we don't calculate the base - // name twice: - num_matches = m_apple_names_up->FindByName(name.GetStringRef(), offsets); + DIEArray offsets; + m_apple_names_up->FindByName(name.GetStringRef(), offsets); - for (uint32_t i = 0; i < num_matches; i++) { - const DIERef &die_ref = offsets[i]; + for (const DIERef &die_ref: offsets) { DWARFDIE die = info.GetDIE(die_ref); - if (die) { - if (!SymbolFileDWARF::DIEInDeclContext(parent_decl_ctx, die)) - continue; // The containing decl contexts don't match - - if (!KeepFunctionDIE(die, name_type_mask)) - continue; - - if (resolved_dies.find(die.GetDIE()) != resolved_dies.end()) - continue; - - // If we get to here, the die is good, and we should add it: - if (resolve_function(die, include_inlines, sc_list)) - resolved_dies.insert(die.GetDIE()); - } else + if (!die) { ReportInvalidDIEOffset(die_ref.die_offset, name.GetStringRef()); + continue; + } + if (SymbolFileDWARF::DIEInDeclContext(&parent_decl_ctx, die) && + KeepFunctionDIE(die, name_type_mask)) + dies.push_back(die); } - offsets.clear(); } } Index: lldb/trunk/source/Plugins/SymbolFile/DWARF/DWARFIndex.h =================================================================== --- lldb/trunk/source/Plugins/SymbolFile/DWARF/DWARFIndex.h +++ lldb/trunk/source/Plugins/SymbolFile/DWARF/DWARFIndex.h @@ -36,15 +36,10 @@ 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, DWARFDebugInfo &info, - llvm::function_ref - resolve_function, - llvm::function_ref - get_decl_context_containing_uid, - const CompilerDeclContext *parent_decl_ctx, uint32_t name_type_mask, - bool include_inlines, SymbolContextList &sc_list) = 0; + virtual void GetFunctions(ConstString name, DWARFDebugInfo &info, + const CompilerDeclContext &parent_decl_ctx, + uint32_t name_type_mask, + std::vector &dies); virtual void GetFunctions( const RegularExpression ®ex, DWARFDebugInfo &info, llvm::function_ref - resolve_function, - llvm::function_ref - get_decl_context_containing_uid, - const CompilerDeclContext *parent_decl_ctx, uint32_t name_type_mask, - bool include_inlines, SymbolContextList &sc_list) override; + void GetFunctions(ConstString name, DWARFDebugInfo &info, + const CompilerDeclContext &parent_decl_ctx, + uint32_t name_type_mask, + std::vector &dies) override; void GetFunctions( const RegularExpression ®ex, DWARFDebugInfo &info, llvm::function_ref - resolve_function, - llvm::function_ref - get_decl_context_containing_uid, - const CompilerDeclContext *parent_decl_ctx, uint32_t name_type_mask, - bool include_inlines, SymbolContextList &sc_list) { - +void ManualDWARFIndex::GetFunctions(ConstString name, DWARFDebugInfo &info, + const CompilerDeclContext &parent_decl_ctx, + uint32_t name_type_mask, + std::vector &dies) { Index(); - std::set resolved_dies; - DIEArray offsets; if (name_type_mask & eFunctionNameTypeFull) { - uint32_t num_matches = m_set.function_basenames.Find(name, offsets); - num_matches += m_set.function_methods.Find(name, offsets); - num_matches += m_set.function_fullnames.Find(name, offsets); - for (uint32_t i = 0; i < num_matches; i++) { - const DIERef &die_ref = offsets[i]; + DIEArray offsets; + m_set.function_basenames.Find(name, offsets); + m_set.function_methods.Find(name, offsets); + m_set.function_fullnames.Find(name, offsets); + for (const DIERef &die_ref: offsets) { DWARFDIE die = info.GetDIE(die_ref); - if (die) { - if (!SymbolFileDWARF::DIEInDeclContext(parent_decl_ctx, die)) - continue; // The containing decl contexts don't match - - if (resolved_dies.find(die.GetDIE()) == resolved_dies.end()) { - if (resolve_function(die, include_inlines, sc_list)) - resolved_dies.insert(die.GetDIE()); - } - } + if (!die) + continue; + if (SymbolFileDWARF::DIEInDeclContext(&parent_decl_ctx, die)) + dies.push_back(die); } - offsets.clear(); } if (name_type_mask & eFunctionNameTypeBase) { - uint32_t num_base = m_set.function_basenames.Find(name, offsets); - for (uint32_t i = 0; i < num_base; i++) { - DWARFDIE die = info.GetDIE(offsets[i]); - if (die) { - if (!SymbolFileDWARF::DIEInDeclContext(parent_decl_ctx, die)) - continue; // The containing decl contexts don't match - - // If we get to here, the die is good, and we should add it: - if (resolved_dies.find(die.GetDIE()) == resolved_dies.end()) { - if (resolve_function(die, include_inlines, sc_list)) - resolved_dies.insert(die.GetDIE()); - } - } + DIEArray offsets; + m_set.function_basenames.Find(name, offsets); + for (const DIERef &die_ref: offsets) { + DWARFDIE die = info.GetDIE(die_ref); + if (!die) + continue; + if (SymbolFileDWARF::DIEInDeclContext(&parent_decl_ctx, die)) + dies.push_back(die); } offsets.clear(); } - if (name_type_mask & eFunctionNameTypeMethod) { - if (parent_decl_ctx && parent_decl_ctx->IsValid()) - return; // no methods in namespaces - - uint32_t num_base = m_set.function_methods.Find(name, offsets); - { - for (uint32_t i = 0; i < num_base; i++) { - DWARFDIE die = info.GetDIE(offsets[i]); - if (die) { - // If we get to here, the die is good, and we should add it: - if (resolved_dies.find(die.GetDIE()) == resolved_dies.end()) { - if (resolve_function(die, include_inlines, sc_list)) - resolved_dies.insert(die.GetDIE()); - } - } - } + if (name_type_mask & eFunctionNameTypeMethod && !parent_decl_ctx.IsValid()) { + DIEArray offsets; + m_set.function_methods.Find(name, offsets); + for (const DIERef &die_ref: offsets) { + if (DWARFDIE die = info.GetDIE(die_ref)) + dies.push_back(die); } - offsets.clear(); } - if ((name_type_mask & eFunctionNameTypeSelector) && - (!parent_decl_ctx || !parent_decl_ctx->IsValid())) { - uint32_t num_selectors = m_set.function_selectors.Find(name, offsets); - for (uint32_t i = 0; i < num_selectors; i++) { - DWARFDIE die = info.GetDIE(offsets[i]); - if (die) { - // If we get to here, the die is good, and we should add it: - if (resolved_dies.find(die.GetDIE()) == resolved_dies.end()) { - if (resolve_function(die, include_inlines, sc_list)) - resolved_dies.insert(die.GetDIE()); - } - } + if (name_type_mask & eFunctionNameTypeSelector && + !parent_decl_ctx.IsValid()) { + DIEArray offsets; + m_set.function_selectors.Find(name, offsets); + for (const DIERef &die_ref: offsets) { + if (DWARFDIE die = info.GetDIE(die_ref)) + dies.push_back(die); } } } Index: lldb/trunk/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp =================================================================== --- lldb/trunk/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp +++ lldb/trunk/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp @@ -2223,16 +2223,18 @@ if (info == NULL) return 0; - m_index->GetFunctions(name, *info, - [this](const DWARFDIE &die, bool include_inlines, - lldb_private::SymbolContextList &sc_list) { - return ResolveFunction(die, include_inlines, sc_list); - }, - [this](lldb::user_id_t type_uid) { - return GetDeclContextContainingUID(type_uid); - }, - parent_decl_ctx, name_type_mask, include_inlines, - sc_list); + llvm::DenseSet resolved_dies; + DIEArray offsets; + CompilerDeclContext empty_decl_ctx; + if (!parent_decl_ctx) + parent_decl_ctx = &empty_decl_ctx; + + std::vector dies; + m_index->GetFunctions(name, *info, *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); + } // Return the number of variable that were appended to the list const uint32_t num_matches = sc_list.GetSize() - original_size;