[Lldb-commits] [lldb] Improve namespace lookup using .debug_names parent chain (PR #110062)

via lldb-commits lldb-commits at lists.llvm.org
Sun Oct 13 19:25:50 PDT 2024


https://github.com/jeffreytan81 updated https://github.com/llvm/llvm-project/pull/110062

>From c5bbc5f17dd5039fb9d5a01ade2397afd5d4c967 Mon Sep 17 00:00:00 2001
From: jeffreytan81 <jeffreytan at fb.com>
Date: Tue, 24 Sep 2024 14:43:44 -0700
Subject: [PATCH 1/2] Improve namespace lookup

---
 .../Plugins/SymbolFile/DWARF/DWARFIndex.cpp   | 16 +++++++
 .../Plugins/SymbolFile/DWARF/DWARFIndex.h     | 11 +++++
 .../SymbolFile/DWARF/DebugNamesDWARFIndex.cpp | 42 +++++++++++++++++++
 .../SymbolFile/DWARF/DebugNamesDWARFIndex.h   |  4 +-
 .../SymbolFile/DWARF/SymbolFileDWARF.cpp      |  2 +-
 5 files changed, 73 insertions(+), 2 deletions(-)

diff --git a/lldb/source/Plugins/SymbolFile/DWARF/DWARFIndex.cpp b/lldb/source/Plugins/SymbolFile/DWARF/DWARFIndex.cpp
index dee90804c52584..c18edd10b96819 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<bool(DWARFDIE die)> 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<bool(DWARFDIE die)> 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 fea3a4fd697389..ac1f75e91c2195 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<bool(DWARFDIE die)> 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<bool(DWARFDIE die)> 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<bool(DWARFDIE die)> callback);
+  bool ProcessNamespaceDieMatchParents(
+      const CompilerDeclContext &parent_decl_ctx, DWARFDIE die,
+      llvm::function_ref<bool(DWARFDIE die)> 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 c809e5ff7f8535..aeeb6b91c80fa3 100644
--- a/lldb/source/Plugins/SymbolFile/DWARF/DebugNamesDWARFIndex.cpp
+++ b/lldb/source/Plugins/SymbolFile/DWARF/DebugNamesDWARFIndex.cpp
@@ -565,6 +565,48 @@ void DebugNamesDWARFIndex::GetTypesWithQuery(
   m_fallback.GetTypesWithQuery(query, callback);
 }
 
+void DebugNamesDWARFIndex::GetNamespacesWithParents(
+    ConstString name, const CompilerDeclContext &parent_decl_ctx,
+    llvm::function_ref<bool(DWARFDIE die)> callback) {
+  std::vector<lldb_private::CompilerContext> parent_contexts =
+      parent_decl_ctx.GetCompilerContext();
+  if (parent_contexts.empty())
+    return GetNamespaces(name, callback);
+
+  llvm::SmallVector<CompilerContext> 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<llvm::SmallVector<Entry, 4>> 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) &&
+          !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);
+          }))
+        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 074f68a8c55963..ab6cde12623f6a 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<bool(DWARFDIE die)> callback) override;
-
+  void GetNamespacesWithParents(
+      ConstString name, const CompilerDeclContext &parent_decl_ctx,
+      llvm::function_ref<bool(DWARFDIE die)> 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 9287d4baf19e9c..0ffbb9d315317a 100644
--- a/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp
+++ b/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp
@@ -2899,7 +2899,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
 

>From 3d83ffaf5099d6b82a32f2c738905201c05f11ec Mon Sep 17 00:00:00 2001
From: jeffreytan81 <jeffreytan at fb.com>
Date: Sun, 13 Oct 2024 19:25:34 -0700
Subject: [PATCH 2/2] Address review feedback

---
 .../SymbolFile/DWARF/DebugNamesDWARFIndex.cpp | 44 ++++++++++---------
 1 file changed, 23 insertions(+), 21 deletions(-)

diff --git a/lldb/source/Plugins/SymbolFile/DWARF/DebugNamesDWARFIndex.cpp b/lldb/source/Plugins/SymbolFile/DWARF/DebugNamesDWARFIndex.cpp
index aeeb6b91c80fa3..6f2cb455ec00e1 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,13 +555,15 @@ 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);
 }
@@ -570,9 +573,6 @@ void DebugNamesDWARFIndex::GetNamespacesWithParents(
     llvm::function_ref<bool(DWARFDIE die)> callback) {
   std::vector<lldb_private::CompilerContext> parent_contexts =
       parent_decl_ctx.GetCompilerContext();
-  if (parent_contexts.empty())
-    return GetNamespaces(name, callback);
-
   llvm::SmallVector<CompilerContext> parent_named_contexts;
   std::copy_if(parent_contexts.rbegin(), parent_contexts.rend(),
                std::back_inserter(parent_named_contexts),
@@ -594,14 +594,16 @@ void DebugNamesDWARFIndex::GetNamespacesWithParents(
         continue;
       }
 
-      if (WithinParentChain(parent_named_contexts, *parent_chain) &&
-          !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);
-          }))
-        return;
+      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);



More information about the lldb-commits mailing list