diff --git a/lldb/source/Plugins/SymbolFile/DWARF/DWARFIndex.cpp b/lldb/source/Plugins/SymbolFile/DWARF/DWARFIndex.cpp index dee90804c5258..c18edd10b9681 100644 --- a/lldb/source/Plugins/SymbolFile/DWARF/DWARFIndex.cpp +++ b/lldb/source/Plugins/SymbolFile/DWARF/DWARFIndex.cpp @@ -151,3 +151,19 @@ bool DWARFIndex::ProcessTypeDIEMatchQuery( return true; return callback(die); } + +void DWARFIndex::GetNamespacesWithParents( + ConstString name, const CompilerDeclContext &parent_decl_ctx, + llvm::function_ref callback) { + GetNamespaces(name, [&](DWARFDIE die) { + return ProcessNamespaceDieMatchParents(parent_decl_ctx, die, callback); + }); +} + +bool DWARFIndex::ProcessNamespaceDieMatchParents( + const CompilerDeclContext &parent_decl_ctx, DWARFDIE die, + llvm::function_ref callback) { + if (!SymbolFileDWARF::DIEInDeclContext(parent_decl_ctx, die)) + return true; + return callback(die); +} diff --git a/lldb/source/Plugins/SymbolFile/DWARF/DWARFIndex.h b/lldb/source/Plugins/SymbolFile/DWARF/DWARFIndex.h index fea3a4fd69738..ac1f75e91c219 100644 --- a/lldb/source/Plugins/SymbolFile/DWARF/DWARFIndex.h +++ b/lldb/source/Plugins/SymbolFile/DWARF/DWARFIndex.h @@ -71,6 +71,14 @@ class DWARFIndex { virtual void GetTypesWithQuery(TypeQuery &query, llvm::function_ref callback); + /// Get namespace DIEs whose base name match \param name with \param + /// parent_decl_ctx in its decl parent chain. A base implementation + /// is provided. Specializations should override this if they are able to + /// provide a faster implementation. + virtual void + GetNamespacesWithParents(ConstString name, + const CompilerDeclContext &parent_decl_ctx, + llvm::function_ref callback); virtual void GetFunctions(const Module::LookupInfo &lookup_info, SymbolFileDWARF &dwarf, const CompilerDeclContext &parent_decl_ctx, @@ -127,6 +135,9 @@ class DWARFIndex { bool ProcessTypeDIEMatchQuery(TypeQuery &query, DWARFDIE die, llvm::function_ref callback); + bool ProcessNamespaceDieMatchParents( + const CompilerDeclContext &parent_decl_ctx, DWARFDIE die, + llvm::function_ref callback); }; } // namespace dwarf } // namespace lldb_private::plugin diff --git a/lldb/source/Plugins/SymbolFile/DWARF/DebugNamesDWARFIndex.cpp b/lldb/source/Plugins/SymbolFile/DWARF/DebugNamesDWARFIndex.cpp index c809e5ff7f853..6f2cb455ec00e 100644 --- a/lldb/source/Plugins/SymbolFile/DWARF/DebugNamesDWARFIndex.cpp +++ b/lldb/source/Plugins/SymbolFile/DWARF/DebugNamesDWARFIndex.cpp @@ -368,9 +368,10 @@ void DebugNamesDWARFIndex::GetFullyQualifiedType( continue; } - if (SameParentChain(parent_names, *parent_chain) && - !ProcessEntry(entry, callback)) - return; + if (SameParentChain(parent_names, *parent_chain)) { + if (!ProcessEntry(entry, callback)) + return; + } } m_fallback.GetFullyQualifiedType(context, callback); } @@ -554,17 +555,60 @@ void DebugNamesDWARFIndex::GetTypesWithQuery( continue; } - if (WithinParentChain(parent_contexts, *parent_chain) && - !ProcessEntry(entry, [&](DWARFDIE die) { - // After .debug_names filtering still sending to base class for - // further filtering before calling the callback. - return ProcessTypeDIEMatchQuery(query, die, callback); - })) - return; + if (WithinParentChain(parent_contexts, *parent_chain)) { + if (!ProcessEntry(entry, [&](DWARFDIE die) { + // After .debug_names filtering still sending to base class for + // further filtering before calling the callback. + return ProcessTypeDIEMatchQuery(query, die, callback); + })) + // If the callback returns false, we're done. + return; + } } m_fallback.GetTypesWithQuery(query, callback); } +void DebugNamesDWARFIndex::GetNamespacesWithParents( + ConstString name, const CompilerDeclContext &parent_decl_ctx, + llvm::function_ref callback) { + std::vector parent_contexts = + parent_decl_ctx.GetCompilerContext(); + llvm::SmallVector parent_named_contexts; + std::copy_if(parent_contexts.rbegin(), parent_contexts.rend(), + std::back_inserter(parent_named_contexts), + [](const CompilerContext &ctx) { return !ctx.name.IsEmpty(); }); + for (const DebugNames::Entry &entry : + m_debug_names_up->equal_range(name.GetStringRef())) { + lldb_private::dwarf::Tag entry_tag = entry.tag(); + if (entry_tag == DW_TAG_namespace || + entry_tag == DW_TAG_imported_declaration) { + std::optional> parent_chain = + getParentChain(entry); + if (!parent_chain) { + // Fallback: use the base class implementation. + if (!ProcessEntry(entry, [&](DWARFDIE die) { + return ProcessNamespaceDieMatchParents(parent_decl_ctx, die, + callback); + })) + return; + continue; + } + + if (WithinParentChain(parent_named_contexts, *parent_chain)) { + if (!ProcessEntry(entry, [&](DWARFDIE die) { + // After .debug_names filtering still sending to base class for + // further filtering before calling the callback. + return ProcessNamespaceDieMatchParents(parent_decl_ctx, die, + callback); + })) + // If the callback returns false, we're done. + return; + } + } + } + m_fallback.GetNamespacesWithParents(name, parent_decl_ctx, callback); +} + void DebugNamesDWARFIndex::GetFunctions( const Module::LookupInfo &lookup_info, SymbolFileDWARF &dwarf, const CompilerDeclContext &parent_decl_ctx, diff --git a/lldb/source/Plugins/SymbolFile/DWARF/DebugNamesDWARFIndex.h b/lldb/source/Plugins/SymbolFile/DWARF/DebugNamesDWARFIndex.h index 074f68a8c5596..ab6cde12623f6 100644 --- a/lldb/source/Plugins/SymbolFile/DWARF/DebugNamesDWARFIndex.h +++ b/lldb/source/Plugins/SymbolFile/DWARF/DebugNamesDWARFIndex.h @@ -55,7 +55,9 @@ class DebugNamesDWARFIndex : public DWARFIndex { void GetTypesWithQuery(TypeQuery &query, llvm::function_ref callback) override; - + void GetNamespacesWithParents( + ConstString name, const CompilerDeclContext &parent_decl_ctx, + llvm::function_ref callback) override; void GetFunctions(const Module::LookupInfo &lookup_info, SymbolFileDWARF &dwarf, const CompilerDeclContext &parent_decl_ctx, diff --git a/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp b/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp index e5b8eee8d08c2..f23f8cc3d781d 100644 --- a/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp +++ b/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp @@ -2900,7 +2900,7 @@ SymbolFileDWARF::FindNamespace(ConstString name, if (!DeclContextMatchesThisSymbolFile(parent_decl_ctx)) return namespace_decl_ctx; - m_index->GetNamespaces(name, [&](DWARFDIE die) { + m_index->GetNamespacesWithParents(name, parent_decl_ctx, [&](DWARFDIE die) { if (!DIEInDeclContext(parent_decl_ctx, die, only_root_namespaces)) return true; // The containing decl contexts don't match