[llvm] [llvm/DWARF] Recursively resolve DW_AT_signature references (PR #97423)

via llvm-commits llvm-commits at lists.llvm.org
Tue Jul 2 07:30:33 PDT 2024


llvmbot wrote:


<!--LLVM PR SUMMARY COMMENT-->

@llvm/pr-subscribers-debuginfo

Author: Pavel Labath (labath)

<details>
<summary>Changes</summary>

findRecursively follows DW_AT_specification and DW_AT_abstract_origin references, but not DW_AT_signature. As far as I can tell, there is no fundamental difference between these attributes that would make this behavior desirable, and this just seems like a consequence of the fact that this attribute is newer. This patch aims to change that.

The motivation is some code in lldb, which assumes that it can construct a qualified name of a type by just walking the parent chain and looking at the name attribute. This works for "regular" debug info, even when some of the DIEs are just forward declarations, but it breaks in the presence of type units, because of the need to explicitly resolve the signature reference.

While LLDB does not use the llvm's DWARFDie class (yet?), this seems like a very important change in the overall API, and any divergence here would complicate eventual reunification, which is why I am making the change in the llvm API first. However, putting lldb aside, I think this change is beneficial in llvm on its own, as it allows us to remove the explicit DW_AT_signature resolution in the DWARFTypePrinter.

---
Full diff: https://github.com/llvm/llvm-project/pull/97423.diff


3 Files Affected:

- (modified) llvm/include/llvm/DebugInfo/DWARF/DWARFDie.h (-2) 
- (modified) llvm/lib/DebugInfo/DWARF/DWARFDie.cpp (+15-28) 
- (modified) llvm/lib/DebugInfo/DWARF/DWARFTypePrinter.cpp (+25-27) 


``````````diff
diff --git a/llvm/include/llvm/DebugInfo/DWARF/DWARFDie.h b/llvm/include/llvm/DebugInfo/DWARF/DWARFDie.h
index 421b84d644db6..497d3bee048ab 100644
--- a/llvm/include/llvm/DebugInfo/DWARF/DWARFDie.h
+++ b/llvm/include/llvm/DebugInfo/DWARF/DWARFDie.h
@@ -181,8 +181,6 @@ class DWARFDie {
   DWARFDie getAttributeValueAsReferencedDie(dwarf::Attribute Attr) const;
   DWARFDie getAttributeValueAsReferencedDie(const DWARFFormValue &V) const;
 
-  DWARFDie resolveTypeUnitReference() const;
-
   /// Extract the range base attribute from this DIE as absolute section offset.
   ///
   /// This is a utility function that checks for either the DW_AT_rnglists_base
diff --git a/llvm/lib/DebugInfo/DWARF/DWARFDie.cpp b/llvm/lib/DebugInfo/DWARF/DWARFDie.cpp
index 410842a80b015..2cc5b416fe1a2 100644
--- a/llvm/lib/DebugInfo/DWARF/DWARFDie.cpp
+++ b/llvm/lib/DebugInfo/DWARF/DWARFDie.cpp
@@ -103,10 +103,6 @@ static void dumpLocationExpr(raw_ostream &OS, const DWARFFormValue &FormValue,
       .print(OS, DumpOpts, U);
 }
 
-static DWARFDie resolveReferencedType(DWARFDie D, DWARFFormValue F) {
-  return D.getAttributeValueAsReferencedDie(F).resolveTypeUnitReference();
-}
-
 static void dumpAttribute(raw_ostream &OS, const DWARFDie &Die,
                           const DWARFAttribute &AttrValue, unsigned Indent,
                           DIDumpOptions DumpOpts) {
@@ -198,8 +194,8 @@ static void dumpAttribute(raw_ostream &OS, const DWARFDie &Die,
                 DINameKind::LinkageName))
       OS << Space << "\"" << Name << '\"';
   } else if (Attr == DW_AT_type || Attr == DW_AT_containing_type) {
-    DWARFDie D = resolveReferencedType(Die, FormValue);
-    if (D && !D.isNULL()) {
+    if (DWARFDie D = Die.getAttributeValueAsReferencedDie(FormValue);
+        D && !D.isNULL()) {
       OS << Space << "\"";
       dumpTypeQualifiedName(D, OS);
       OS << '"';
@@ -291,13 +287,12 @@ DWARFDie::findRecursively(ArrayRef<dwarf::Attribute> Attrs) const {
     if (auto Value = Die.find(Attrs))
       return Value;
 
-    if (auto D = Die.getAttributeValueAsReferencedDie(DW_AT_abstract_origin))
-      if (Seen.insert(D).second)
-        Worklist.push_back(D);
-
-    if (auto D = Die.getAttributeValueAsReferencedDie(DW_AT_specification))
-      if (Seen.insert(D).second)
-        Worklist.push_back(D);
+    for (dwarf::Attribute Attr :
+         {DW_AT_abstract_origin, DW_AT_specification, DW_AT_signature}) {
+      if (auto D = Die.getAttributeValueAsReferencedDie(Attr))
+        if (Seen.insert(D).second)
+          Worklist.push_back(D);
+    }
   }
 
   return std::nullopt;
@@ -312,27 +307,19 @@ DWARFDie::getAttributeValueAsReferencedDie(dwarf::Attribute Attr) const {
 
 DWARFDie
 DWARFDie::getAttributeValueAsReferencedDie(const DWARFFormValue &V) const {
-  DWARFDie Result;
   if (auto SpecRef = V.getAsRelativeReference()) {
     if (SpecRef->Unit)
-      Result = SpecRef->Unit->getDIEForOffset(SpecRef->Unit->getOffset() +
-                                              SpecRef->Offset);
-    else if (auto SpecUnit =
-                 U->getUnitVector().getUnitForOffset(SpecRef->Offset))
-      Result = SpecUnit->getDIEForOffset(SpecRef->Offset);
-  }
-  return Result;
-}
-
-DWARFDie DWARFDie::resolveTypeUnitReference() const {
-  if (auto Attr = find(DW_AT_signature)) {
-    if (std::optional<uint64_t> Sig = Attr->getAsReferenceUVal()) {
+      return SpecRef->Unit->getDIEForOffset(SpecRef->Unit->getOffset() +
+                                            SpecRef->Offset);
+    if (V.getForm() == dwarf::DW_FORM_ref_sig8) {
       if (DWARFTypeUnit *TU = U->getContext().getTypeUnitForHash(
-              U->getVersion(), *Sig, U->isDWOUnit()))
+              U->getVersion(), SpecRef->Offset, U->isDWOUnit()))
         return TU->getDIEForOffset(TU->getTypeOffset() + TU->getOffset());
     }
+    if (auto *SpecUnit = U->getUnitVector().getUnitForOffset(SpecRef->Offset))
+      return SpecUnit->getDIEForOffset(SpecRef->Offset);
   }
-  return *this;
+  return {};
 }
 
 std::optional<uint64_t> DWARFDie::getRangesBaseAttribute() const {
diff --git a/llvm/lib/DebugInfo/DWARF/DWARFTypePrinter.cpp b/llvm/lib/DebugInfo/DWARF/DWARFTypePrinter.cpp
index a26431e8313f6..fc1aae77a9293 100644
--- a/llvm/lib/DebugInfo/DWARF/DWARFTypePrinter.cpp
+++ b/llvm/lib/DebugInfo/DWARF/DWARFTypePrinter.cpp
@@ -62,17 +62,10 @@ void DWARFTypePrinter::appendArrayType(const DWARFDie &D) {
   EndedWithTemplate = false;
 }
 
-static DWARFDie resolveReferencedType(DWARFDie D,
-                                      dwarf::Attribute Attr = DW_AT_type) {
-  return D.getAttributeValueAsReferencedDie(Attr).resolveTypeUnitReference();
-}
-static DWARFDie resolveReferencedType(DWARFDie D, DWARFFormValue F) {
-  return D.getAttributeValueAsReferencedDie(F).resolveTypeUnitReference();
-}
 DWARFDie DWARFTypePrinter::skipQualifiers(DWARFDie D) {
   while (D && (D.getTag() == DW_TAG_const_type ||
                D.getTag() == DW_TAG_volatile_type))
-    D = resolveReferencedType(D);
+    D = D.getAttributeValueAsReferencedDie(DW_AT_type);
   return D;
 }
 
@@ -103,7 +96,9 @@ DWARFTypePrinter::appendUnqualifiedNameBefore(DWARFDie D,
     return DWARFDie();
   }
   DWARFDie InnerDIE;
-  auto Inner = [&] { return InnerDIE = resolveReferencedType(D); };
+  auto Inner = [&] {
+    return InnerDIE = D.getAttributeValueAsReferencedDie(DW_AT_type);
+  };
   const dwarf::Tag T = D.getTag();
   switch (T) {
   case DW_TAG_pointer_type: {
@@ -134,7 +129,8 @@ DWARFTypePrinter::appendUnqualifiedNameBefore(DWARFDie D,
       OS << '(';
     else if (Word)
       OS << ' ';
-    if (DWARFDie Cont = resolveReferencedType(D, DW_AT_containing_type)) {
+    if (DWARFDie Cont =
+            D.getAttributeValueAsReferencedDie(DW_AT_containing_type)) {
       appendQualifiedName(Cont);
       EndedWithTemplate = false;
       OS << "::";
@@ -173,7 +169,8 @@ DWARFTypePrinter::appendUnqualifiedNameBefore(DWARFDie D,
   case DW_TAG_base_type:
   */
   default: {
-    const char *NamePtr = dwarf::toString(D.find(DW_AT_name), nullptr);
+    const char *NamePtr =
+        dwarf::toString(D.findRecursively(DW_AT_name), nullptr);
     if (!NamePtr) {
       appendTypeTagName(D.getTag());
       return DWARFDie();
@@ -235,9 +232,9 @@ void DWARFTypePrinter::appendUnqualifiedNameAfter(
   case DW_TAG_pointer_type: {
     if (needsParens(Inner))
       OS << ')';
-    appendUnqualifiedNameAfter(Inner, resolveReferencedType(Inner),
-                               /*SkipFirstParamIfArtificial=*/D.getTag() ==
-                                   DW_TAG_ptr_to_member_type);
+    appendUnqualifiedNameAfter(
+        Inner, Inner.getAttributeValueAsReferencedDie(DW_AT_type),
+        /*SkipFirstParamIfArtificial=*/D.getTag() == DW_TAG_ptr_to_member_type);
     break;
   }
   case DW_TAG_LLVM_ptrauth_type: {
@@ -341,7 +338,7 @@ bool DWARFTypePrinter::appendTemplateParameters(DWARFDie D,
       appendTemplateParameters(C, FirstParameter);
     }
     if (C.getTag() == dwarf::DW_TAG_template_value_parameter) {
-      DWARFDie T = resolveReferencedType(C);
+      DWARFDie T = C.getAttributeValueAsReferencedDie(DW_AT_type);
       Sep();
       if (T.getTag() == DW_TAG_enumeration_type) {
         OS << '(';
@@ -461,7 +458,7 @@ bool DWARFTypePrinter::appendTemplateParameters(DWARFDie D,
       continue;
     auto TypeAttr = C.find(DW_AT_type);
     Sep();
-    appendQualifiedName(TypeAttr ? resolveReferencedType(C, *TypeAttr)
+    appendQualifiedName(TypeAttr ? C.getAttributeValueAsReferencedDie(*TypeAttr)
                                  : DWARFDie());
   }
   if (IsTemplate && *FirstParameter && FirstParameter == &FirstParameterValue) {
@@ -473,15 +470,15 @@ bool DWARFTypePrinter::appendTemplateParameters(DWARFDie D,
 void DWARFTypePrinter::decomposeConstVolatile(DWARFDie &N, DWARFDie &T,
                                               DWARFDie &C, DWARFDie &V) {
   (N.getTag() == DW_TAG_const_type ? C : V) = N;
-  T = resolveReferencedType(N);
+  T = N.getAttributeValueAsReferencedDie(DW_AT_type);
   if (T) {
     auto Tag = T.getTag();
     if (Tag == DW_TAG_const_type) {
       C = T;
-      T = resolveReferencedType(T);
+      T = T.getAttributeValueAsReferencedDie(DW_AT_type);
     } else if (Tag == DW_TAG_volatile_type) {
       V = T;
-      T = resolveReferencedType(T);
+      T = T.getAttributeValueAsReferencedDie(DW_AT_type);
     }
   }
 }
@@ -491,10 +488,11 @@ void DWARFTypePrinter::appendConstVolatileQualifierAfter(DWARFDie N) {
   DWARFDie T;
   decomposeConstVolatile(N, T, C, V);
   if (T && T.getTag() == DW_TAG_subroutine_type)
-    appendSubroutineNameAfter(T, resolveReferencedType(T), false, C.isValid(),
-                              V.isValid());
+    appendSubroutineNameAfter(T, T.getAttributeValueAsReferencedDie(DW_AT_type),
+                              false, C.isValid(), V.isValid());
   else
-    appendUnqualifiedNameAfter(T, resolveReferencedType(T));
+    appendUnqualifiedNameAfter(T,
+                               T.getAttributeValueAsReferencedDie(DW_AT_type));
 }
 void DWARFTypePrinter::appendConstVolatileQualifierBefore(DWARFDie N) {
   DWARFDie C;
@@ -504,7 +502,7 @@ void DWARFTypePrinter::appendConstVolatileQualifierBefore(DWARFDie N) {
   bool Subroutine = T && T.getTag() == DW_TAG_subroutine_type;
   DWARFDie A = T;
   while (A && A.getTag() == DW_TAG_array_type)
-    A = resolveReferencedType(A);
+    A = A.getAttributeValueAsReferencedDie(DW_AT_type);
   bool Leading =
       (!A || (A.getTag() != DW_TAG_pointer_type &&
               A.getTag() != llvm::dwarf::DW_TAG_ptr_to_member_type)) &&
@@ -546,7 +544,7 @@ void DWARFTypePrinter::appendSubroutineNameAfter(
     if (P.getTag() != DW_TAG_formal_parameter &&
         P.getTag() != DW_TAG_unspecified_parameters)
       return;
-    DWARFDie T = resolveReferencedType(P);
+    DWARFDie T = P.getAttributeValueAsReferencedDie(DW_AT_type);
     if (SkipFirstParamIfArtificial && RealFirst && P.find(DW_AT_artificial)) {
       FirstParamIfArtificial = T;
       RealFirst = false;
@@ -567,7 +565,7 @@ void DWARFTypePrinter::appendSubroutineNameAfter(
     if (DWARFDie P = FirstParamIfArtificial) {
       if (P.getTag() == DW_TAG_pointer_type) {
         auto CVStep = [&](DWARFDie CV) {
-          if (DWARFDie U = resolveReferencedType(CV)) {
+          if (DWARFDie U = CV.getAttributeValueAsReferencedDie(DW_AT_type)) {
             Const |= U.getTag() == DW_TAG_const_type;
             Volatile |= U.getTag() == DW_TAG_volatile_type;
             return U;
@@ -653,7 +651,8 @@ void DWARFTypePrinter::appendSubroutineNameAfter(
   if (D.find(DW_AT_rvalue_reference))
     OS << " &&";
 
-  appendUnqualifiedNameAfter(Inner, resolveReferencedType(Inner));
+  appendUnqualifiedNameAfter(
+      Inner, Inner.getAttributeValueAsReferencedDie(DW_AT_type));
 }
 void DWARFTypePrinter::appendScopes(DWARFDie D) {
   if (D.getTag() == DW_TAG_compile_unit)
@@ -666,7 +665,6 @@ void DWARFTypePrinter::appendScopes(DWARFDie D) {
     return;
   if (D.getTag() == DW_TAG_lexical_block)
     return;
-  D = D.resolveTypeUnitReference();
   if (DWARFDie P = D.getParent())
     appendScopes(P);
   appendUnqualifiedName(D);

``````````

</details>


https://github.com/llvm/llvm-project/pull/97423


More information about the llvm-commits mailing list