[Lldb-commits] [lldb] [lldb] Move DWARFDeclContext functions from DWARFDebugInfoEntry to DW… (PR #95227)

Pavel Labath via lldb-commits lldb-commits at lists.llvm.org
Wed Jun 12 04:56:41 PDT 2024


https://github.com/labath created https://github.com/llvm/llvm-project/pull/95227

…ARFDIE

This puts them closer to the other two functions doing something very similar. I've tried to stick to the original logic of the functions as much as possible, though I did apply some easy simplifications.

The changes in DWARFDeclContext.h are there to make the unit tests produce more useful error messages.

>From 7a79c68fa118f9795fc72d77dfb494b549e83af0 Mon Sep 17 00:00:00 2001
From: Pavel Labath <pavel at labath.sk>
Date: Wed, 12 Jun 2024 09:18:35 +0200
Subject: [PATCH] [lldb] Move DWARFDeclContext functions from
 DWARFDebugInfoEntry to DWARFDIE

This puts them closer to the other two functions doing something very
similar. I've tried to stick to the original logic of the functions as
much as possible, though I did apply some easy simplifications.

The changes in DWARFDeclContext.h are there to make the unit tests
produce more useful error messages.
---
 .../SymbolFile/DWARF/DWARFASTParserClang.cpp  |  2 +-
 .../Plugins/SymbolFile/DWARF/DWARFDIE.cpp     | 60 ++++++++++++++-
 .../Plugins/SymbolFile/DWARF/DWARFDIE.h       |  2 +
 .../SymbolFile/DWARF/DWARFDebugInfoEntry.cpp  | 73 -------------------
 .../SymbolFile/DWARF/DWARFDebugInfoEntry.h    |  9 ---
 .../SymbolFile/DWARF/DWARFDeclContext.cpp     | 18 ++---
 .../SymbolFile/DWARF/DWARFDeclContext.h       | 15 ++++
 .../Plugins/SymbolFile/DWARF/DWARFIndex.cpp   |  3 +-
 .../SymbolFile/DWARF/SymbolFileDWARF.cpp      | 17 ++---
 .../SymbolFile/DWARF/SymbolFileDWARF.h        |  2 -
 .../SymbolFile/DWARF/DWARFDIETest.cpp         |  5 ++
 11 files changed, 93 insertions(+), 113 deletions(-)

diff --git a/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp b/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp
index b5d8cf8b2d480..02c91ddc57f83 100644
--- a/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp
+++ b/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp
@@ -2461,7 +2461,7 @@ DWARFASTParserClang::ConstructDemangledNameFromDWARF(const DWARFDIE &die) {
   std::vector<clang::ParmVarDecl *> param_decls;
   StreamString sstr;
 
-  DWARFDeclContext decl_ctx = SymbolFileDWARF::GetDWARFDeclContext(die);
+  DWARFDeclContext decl_ctx = die.GetDWARFDeclContext();
   sstr << decl_ctx.GetQualifiedName();
 
   clang::DeclContext *containing_decl_ctx =
diff --git a/lldb/source/Plugins/SymbolFile/DWARF/DWARFDIE.cpp b/lldb/source/Plugins/SymbolFile/DWARF/DWARFDIE.cpp
index 992d814793f9d..ada3da85112fe 100644
--- a/lldb/source/Plugins/SymbolFile/DWARF/DWARFDIE.cpp
+++ b/lldb/source/Plugins/SymbolFile/DWARF/DWARFDIE.cpp
@@ -505,12 +505,64 @@ std::vector<CompilerContext> DWARFDIE::GetTypeLookupContext() const {
   return context;
 }
 
+static DWARFDeclContext GetDWARFDeclContextImpl(DWARFDIE die) {
+  DWARFDeclContext dwarf_decl_ctx;
+  while (die) {
+    const dw_tag_t tag = die.Tag();
+    if (tag == DW_TAG_compile_unit || tag == DW_TAG_partial_unit)
+      break;
+    dwarf_decl_ctx.AppendDeclContext(tag, die.GetName());
+    DWARFDIE parent_decl_ctx_die = die.GetParentDeclContextDIE();
+    if (parent_decl_ctx_die == die)
+      break;
+    die = parent_decl_ctx_die;
+  }
+  return dwarf_decl_ctx;
+}
+
+DWARFDeclContext DWARFDIE::GetDWARFDeclContext() const {
+  return GetDWARFDeclContextImpl(*this);
+}
+
+static DWARFDIE GetParentDeclContextDIEImpl(DWARFDIE die) {
+  DWARFDIE orig_die = die;
+  while (die) {
+    // If this is the original DIE that we are searching for a declaration for,
+    // then don't look in the cache as we don't want our own decl context to be
+    // our decl context...
+    if (die != orig_die) {
+      switch (die.Tag()) {
+      case DW_TAG_compile_unit:
+      case DW_TAG_partial_unit:
+      case DW_TAG_namespace:
+      case DW_TAG_structure_type:
+      case DW_TAG_union_type:
+      case DW_TAG_class_type:
+        return die;
+
+      default:
+        break;
+      }
+    }
+
+    if (DWARFDIE spec_die = die.GetReferencedDIE(DW_AT_specification)) {
+      if (DWARFDIE decl_ctx_die = spec_die.GetParentDeclContextDIE())
+        return decl_ctx_die;
+    }
+
+    if (DWARFDIE abs_die = die.GetReferencedDIE(DW_AT_abstract_origin)) {
+      if (DWARFDIE decl_ctx_die = abs_die.GetParentDeclContextDIE())
+        return decl_ctx_die;
+    }
+
+    die = die.GetParent();
+  }
+  return DWARFDIE();
+}
+
 DWARFDIE
 DWARFDIE::GetParentDeclContextDIE() const {
-  if (IsValid())
-    return m_die->GetParentDeclContextDIE(m_cu);
-  else
-    return DWARFDIE();
+  return GetParentDeclContextDIEImpl(*this);
 }
 
 bool DWARFDIE::IsStructUnionOrClass() const {
diff --git a/lldb/source/Plugins/SymbolFile/DWARF/DWARFDIE.h b/lldb/source/Plugins/SymbolFile/DWARF/DWARFDIE.h
index c74a82061fccf..e1318953a384c 100644
--- a/lldb/source/Plugins/SymbolFile/DWARF/DWARFDIE.h
+++ b/lldb/source/Plugins/SymbolFile/DWARF/DWARFDIE.h
@@ -86,6 +86,8 @@ class DWARFDIE : public DWARFBaseDIE {
   /// using a full or partial CompilerContext array.
   std::vector<CompilerContext> GetTypeLookupContext() const;
 
+  DWARFDeclContext GetDWARFDeclContext() const;
+
   // Getting attribute values from the DIE.
   //
   // GetAttributeValueAsXXX() functions should only be used if you are
diff --git a/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugInfoEntry.cpp b/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugInfoEntry.cpp
index 688a287a06500..e2660735ea7de 100644
--- a/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugInfoEntry.cpp
+++ b/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugInfoEntry.cpp
@@ -610,79 +610,6 @@ void DWARFDebugInfoEntry::BuildFunctionAddressRangeTable(
   }
 }
 
-DWARFDeclContext
-DWARFDebugInfoEntry::GetDWARFDeclContextStatic(const DWARFDebugInfoEntry *die,
-                                               DWARFUnit *cu) {
-  DWARFDeclContext dwarf_decl_ctx;
-  for (;;) {
-    const dw_tag_t tag = die->Tag();
-    if (tag == DW_TAG_compile_unit || tag == DW_TAG_partial_unit)
-      return dwarf_decl_ctx;
-    dwarf_decl_ctx.AppendDeclContext(tag, die->GetName(cu));
-    DWARFDIE parent_decl_ctx_die = die->GetParentDeclContextDIE(cu);
-    if (!parent_decl_ctx_die || parent_decl_ctx_die.GetDIE() == die)
-      return dwarf_decl_ctx;
-    if (parent_decl_ctx_die.Tag() == DW_TAG_compile_unit ||
-        parent_decl_ctx_die.Tag() == DW_TAG_partial_unit)
-      return dwarf_decl_ctx;
-    die = parent_decl_ctx_die.GetDIE();
-    cu = parent_decl_ctx_die.GetCU();
-  }
-}
-
-DWARFDeclContext DWARFDebugInfoEntry::GetDWARFDeclContext(DWARFUnit *cu) const {
-  return GetDWARFDeclContextStatic(this, cu);
-}
-
-DWARFDIE
-DWARFDebugInfoEntry::GetParentDeclContextDIE(DWARFUnit *cu) const {
-  DWARFAttributes attributes = GetAttributes(cu, Recurse::yes);
-  return GetParentDeclContextDIE(cu, attributes);
-}
-
-DWARFDIE
-DWARFDebugInfoEntry::GetParentDeclContextDIE(
-    DWARFUnit *cu, const DWARFAttributes &attributes) const {
-  DWARFDIE die(cu, const_cast<DWARFDebugInfoEntry *>(this));
-
-  while (die) {
-    // If this is the original DIE that we are searching for a declaration for,
-    // then don't look in the cache as we don't want our own decl context to be
-    // our decl context...
-    if (die.GetDIE() != this) {
-      switch (die.Tag()) {
-      case DW_TAG_compile_unit:
-      case DW_TAG_partial_unit:
-      case DW_TAG_namespace:
-      case DW_TAG_structure_type:
-      case DW_TAG_union_type:
-      case DW_TAG_class_type:
-        return die;
-
-      default:
-        break;
-      }
-    }
-
-    DWARFDIE spec_die = attributes.FormValueAsReference(DW_AT_specification);
-    if (spec_die) {
-      DWARFDIE decl_ctx_die = spec_die.GetParentDeclContextDIE();
-      if (decl_ctx_die)
-        return decl_ctx_die;
-    }
-
-    DWARFDIE abs_die = attributes.FormValueAsReference(DW_AT_abstract_origin);
-    if (abs_die) {
-      DWARFDIE decl_ctx_die = abs_die.GetParentDeclContextDIE();
-      if (decl_ctx_die)
-        return decl_ctx_die;
-    }
-
-    die = die.GetParent();
-  }
-  return DWARFDIE();
-}
-
 lldb::offset_t DWARFDebugInfoEntry::GetFirstAttributeOffset() const {
   return GetOffset() + llvm::getULEB128Size(m_abbr_idx);
 }
diff --git a/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugInfoEntry.h b/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugInfoEntry.h
index 6773b00e82069..3816c6500717a 100644
--- a/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugInfoEntry.h
+++ b/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugInfoEntry.h
@@ -157,12 +157,6 @@ class DWARFDebugInfoEntry {
     return HasChildren() ? this + 1 : nullptr;
   }
 
-  DWARFDeclContext GetDWARFDeclContext(DWARFUnit *cu) const;
-
-  DWARFDIE GetParentDeclContextDIE(DWARFUnit *cu) const;
-  DWARFDIE GetParentDeclContextDIE(DWARFUnit *cu,
-                                   const DWARFAttributes &attributes) const;
-
   void SetSiblingIndex(uint32_t idx) { m_sibling_idx = idx; }
   void SetParentIndex(uint32_t idx) { m_parent_idx = idx; }
 
@@ -172,9 +166,6 @@ class DWARFDebugInfoEntry {
   bool IsGlobalOrStaticScopeVariable() const;
 
 protected:
-  static DWARFDeclContext
-  GetDWARFDeclContextStatic(const DWARFDebugInfoEntry *die, DWARFUnit *cu);
-
   // Up to 2TB offset within the .debug_info/.debug_types
   dw_offset_t m_offset : DW_DIE_OFFSET_MAX_BITSIZE;
   // How many to subtract from "this" to get the parent. If zero this die has no
diff --git a/lldb/source/Plugins/SymbolFile/DWARF/DWARFDeclContext.cpp b/lldb/source/Plugins/SymbolFile/DWARF/DWARFDeclContext.cpp
index 44421c0eda3ee..f759cb8fae611 100644
--- a/lldb/source/Plugins/SymbolFile/DWARF/DWARFDeclContext.cpp
+++ b/lldb/source/Plugins/SymbolFile/DWARF/DWARFDeclContext.cpp
@@ -12,18 +12,16 @@
 using namespace lldb_private::dwarf;
 using namespace lldb_private::plugin::dwarf;
 
-/// Returns the name of `entry` if it has one, or the appropriate "anonymous
-/// {namespace, class, struct, union}".
-static const char *GetName(DWARFDeclContext::Entry entry) {
-  if (entry.name != nullptr)
-    return entry.name;
-  if (entry.tag == DW_TAG_namespace)
+const char *DWARFDeclContext::Entry::GetName() const {
+  if (name != nullptr)
+    return name;
+  if (tag == DW_TAG_namespace)
     return "(anonymous namespace)";
-  if (entry.tag == DW_TAG_class_type)
+  if (tag == DW_TAG_class_type)
     return "(anonymous class)";
-  if (entry.tag == DW_TAG_structure_type)
+  if (tag == DW_TAG_structure_type)
     return "(anonymous struct)";
-  if (entry.tag == DW_TAG_union_type)
+  if (tag == DW_TAG_union_type)
     return "(anonymous union)";
   return "(anonymous)";
 }
@@ -46,7 +44,7 @@ const char *DWARFDeclContext::GetQualifiedName() const {
         llvm::raw_string_ostream string_stream(m_qualified_name);
         llvm::interleave(
             llvm::reverse(m_entries), string_stream,
-            [&](auto entry) { string_stream << GetName(entry); }, "::");
+            [&](auto entry) { string_stream << entry.GetName(); }, "::");
       }
     }
   }
diff --git a/lldb/source/Plugins/SymbolFile/DWARF/DWARFDeclContext.h b/lldb/source/Plugins/SymbolFile/DWARF/DWARFDeclContext.h
index 7e6c5f51f4beb..e3085b80d639c 100644
--- a/lldb/source/Plugins/SymbolFile/DWARF/DWARFDeclContext.h
+++ b/lldb/source/Plugins/SymbolFile/DWARF/DWARFDeclContext.h
@@ -11,6 +11,7 @@
 
 #include "lldb/Utility/ConstString.h"
 #include "DWARFDefines.h"
+#include "llvm/ADT/StringExtras.h"
 
 #include <cassert>
 #include <string>
@@ -38,6 +39,10 @@ class DWARFDeclContext {
       return false;
     }
 
+    /// Returns the name of this entry if it has one, or the appropriate
+    /// "anonymous {namespace, class, struct, union}".
+    const char *GetName() const;
+
     // Test operator
     explicit operator bool() const { return tag != 0; }
 
@@ -83,6 +88,16 @@ class DWARFDeclContext {
     m_qualified_name.clear();
   }
 
+  friend llvm::raw_ostream &operator<<(llvm::raw_ostream &OS, const DWARFDeclContext &ctx) {
+    OS << "DWARFDeclContext{";
+    llvm::ListSeparator LS;
+    for (const Entry &e : ctx.m_entries) {
+      OS << LS << "{" << DW_TAG_value_to_name(e.tag) << ", " << e.GetName()
+         << "}";
+    }
+    return OS << "}";
+  }
+
 protected:
   typedef std::vector<Entry> collection;
   collection m_entries;
diff --git a/lldb/source/Plugins/SymbolFile/DWARF/DWARFIndex.cpp b/lldb/source/Plugins/SymbolFile/DWARF/DWARFIndex.cpp
index 30fb5d5ebdb0d..eafddbad03f57 100644
--- a/lldb/source/Plugins/SymbolFile/DWARF/DWARFIndex.cpp
+++ b/lldb/source/Plugins/SymbolFile/DWARF/DWARFIndex.cpp
@@ -121,8 +121,7 @@ void DWARFIndex::GetFullyQualifiedType(
 bool DWARFIndex::GetFullyQualifiedTypeImpl(
     const DWARFDeclContext &context, DWARFDIE die,
     llvm::function_ref<bool(DWARFDIE die)> callback) {
-  DWARFDeclContext dwarf_decl_ctx =
-      die.GetDIE()->GetDWARFDeclContext(die.GetCU());
+  DWARFDeclContext dwarf_decl_ctx = die.GetDWARFDeclContext();
   if (dwarf_decl_ctx == context)
     return callback(die);
   return true;
diff --git a/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp b/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp
index d9e81f9c105b2..369c742a5ee02 100644
--- a/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp
+++ b/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp
@@ -3080,7 +3080,7 @@ SymbolFileDWARF::FindDefinitionTypeForDWARFDeclContext(const DWARFDIE &die) {
         template_params = dwarf_ast->GetDIEClassTemplateParams(die);
     }
 
-    const DWARFDeclContext die_dwarf_decl_ctx = GetDWARFDeclContext(die);
+    const DWARFDeclContext die_dwarf_decl_ctx = die.GetDWARFDeclContext();
     m_index->GetFullyQualifiedType(die_dwarf_decl_ctx, [&](DWARFDIE type_die) {
       // Make sure type_die's language matches the type system we are
       // looking for. We don't want to find a "Foo" type from Java if we
@@ -3109,7 +3109,7 @@ SymbolFileDWARF::FindDefinitionTypeForDWARFDeclContext(const DWARFDIE &die) {
       }
 
       if (log) {
-        DWARFDeclContext type_dwarf_decl_ctx = GetDWARFDeclContext(type_die);
+        DWARFDeclContext type_dwarf_decl_ctx = type_die.GetDWARFDeclContext();
         GetObjectFile()->GetModule()->LogMessage(
             log,
             "SymbolFileDWARF::"
@@ -3535,8 +3535,9 @@ VariableSP SymbolFileDWARF::ParseVariableDIE(const SymbolContext &sc,
     if ((parent_tag == DW_TAG_compile_unit ||
          parent_tag == DW_TAG_partial_unit) &&
         Language::LanguageIsCPlusPlus(GetLanguage(*die.GetCU())))
-      mangled =
-          GetDWARFDeclContext(die).GetQualifiedNameAsConstString().GetCString();
+      mangled = die.GetDWARFDeclContext()
+                    .GetQualifiedNameAsConstString()
+                    .GetCString();
   }
 
   if (tag == DW_TAG_formal_parameter)
@@ -4361,14 +4362,6 @@ SymbolFileDWARF::GetContainingDeclContext(const DWARFDIE &die) {
   return CompilerDeclContext();
 }
 
-DWARFDeclContext SymbolFileDWARF::GetDWARFDeclContext(const DWARFDIE &die) {
-  if (!die.IsValid())
-    return {};
-  DWARFDeclContext dwarf_decl_ctx =
-      die.GetDIE()->GetDWARFDeclContext(die.GetCU());
-  return dwarf_decl_ctx;
-}
-
 LanguageType SymbolFileDWARF::LanguageTypeFromDWARF(uint64_t val) {
   // Note: user languages between lo_user and hi_user must be handled
   // explicitly here.
diff --git a/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.h b/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.h
index 5d3654efcce54..bb2d949677d98 100644
--- a/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.h
+++ b/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.h
@@ -296,8 +296,6 @@ class SymbolFileDWARF : public SymbolFileCommon {
 
   static CompilerDeclContext GetContainingDeclContext(const DWARFDIE &die);
 
-  static DWARFDeclContext GetDWARFDeclContext(const DWARFDIE &die);
-
   static lldb::LanguageType LanguageTypeFromDWARF(uint64_t val);
 
   static lldb::LanguageType GetLanguage(DWARFUnit &unit);
diff --git a/lldb/unittests/SymbolFile/DWARF/DWARFDIETest.cpp b/lldb/unittests/SymbolFile/DWARF/DWARFDIETest.cpp
index 65da7de1ba2d8..2a7d38f18fc77 100644
--- a/lldb/unittests/SymbolFile/DWARF/DWARFDIETest.cpp
+++ b/lldb/unittests/SymbolFile/DWARF/DWARFDIETest.cpp
@@ -8,6 +8,7 @@
 
 #include "Plugins/SymbolFile/DWARF/DWARFDIE.h"
 #include "Plugins/SymbolFile/DWARF/DWARFDebugInfo.h"
+#include "Plugins/SymbolFile/DWARF/DWARFDeclContext.h"
 #include "TestingSupport/Symbol/YAMLModuleTester.h"
 #include "lldb/Core/dwarf.h"
 #include "lldb/Symbol/Type.h"
@@ -19,6 +20,7 @@
 using namespace lldb;
 using namespace lldb_private;
 using namespace lldb_private::plugin::dwarf;
+using namespace lldb_private::dwarf;
 
 TEST(DWARFDIETest, ChildIteration) {
   // Tests DWARFDIE::child_iterator.
@@ -257,6 +259,9 @@ TEST(DWARFDIETest, GetContext) {
   EXPECT_THAT(
       struct_die.GetTypeLookupContext(),
       testing::ElementsAre(make_namespace("NAMESPACE"), make_struct("STRUCT")));
+  EXPECT_THAT(struct_die.GetDWARFDeclContext(),
+              DWARFDeclContext({{DW_TAG_structure_type, "STRUCT"},
+                                {DW_TAG_namespace, "NAMESPACE"}}));
 }
 
 TEST(DWARFDIETest, GetContextInFunction) {



More information about the lldb-commits mailing list