[llvm] [llvm/DWARF] Recursively resolve DW_AT_signature references (PR #97423)
Pavel Labath via llvm-commits
llvm-commits at lists.llvm.org
Tue Jul 2 07:29:59 PDT 2024
https://github.com/labath created https://github.com/llvm/llvm-project/pull/97423
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.
>From 30c7cef157e9b52f8024d4b802aafa298964a3e9 Mon Sep 17 00:00:00 2001
From: Pavel Labath <pavel at labath.sk>
Date: Tue, 2 Jul 2024 14:10:35 +0000
Subject: [PATCH] [llvm/DWARF] Recursively resolve DW_AT_signature references
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 divergance here
would complicate eventual reunification, which is why I am making the
change in the llvm API first. Nonetheless, I think this change is
beneficial in llvm as well, as it allows us to remove the explicit
DW_AT_signature resolution in the DWARFTypePrinter.
---
llvm/include/llvm/DebugInfo/DWARF/DWARFDie.h | 2 -
llvm/lib/DebugInfo/DWARF/DWARFDie.cpp | 43 ++++++---------
llvm/lib/DebugInfo/DWARF/DWARFTypePrinter.cpp | 52 +++++++++----------
3 files changed, 40 insertions(+), 57 deletions(-)
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);
More information about the llvm-commits
mailing list