Skip to content

Commit 30c7cef

Browse files
committed
[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.
1 parent 8a25bb9 commit 30c7cef

File tree

3 files changed

+40
-57
lines changed

3 files changed

+40
-57
lines changed

llvm/include/llvm/DebugInfo/DWARF/DWARFDie.h

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -181,8 +181,6 @@ class DWARFDie {
181181
DWARFDie getAttributeValueAsReferencedDie(dwarf::Attribute Attr) const;
182182
DWARFDie getAttributeValueAsReferencedDie(const DWARFFormValue &V) const;
183183

184-
DWARFDie resolveTypeUnitReference() const;
185-
186184
/// Extract the range base attribute from this DIE as absolute section offset.
187185
///
188186
/// This is a utility function that checks for either the DW_AT_rnglists_base

llvm/lib/DebugInfo/DWARF/DWARFDie.cpp

Lines changed: 15 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -103,10 +103,6 @@ static void dumpLocationExpr(raw_ostream &OS, const DWARFFormValue &FormValue,
103103
.print(OS, DumpOpts, U);
104104
}
105105

106-
static DWARFDie resolveReferencedType(DWARFDie D, DWARFFormValue F) {
107-
return D.getAttributeValueAsReferencedDie(F).resolveTypeUnitReference();
108-
}
109-
110106
static void dumpAttribute(raw_ostream &OS, const DWARFDie &Die,
111107
const DWARFAttribute &AttrValue, unsigned Indent,
112108
DIDumpOptions DumpOpts) {
@@ -198,8 +194,8 @@ static void dumpAttribute(raw_ostream &OS, const DWARFDie &Die,
198194
DINameKind::LinkageName))
199195
OS << Space << "\"" << Name << '\"';
200196
} else if (Attr == DW_AT_type || Attr == DW_AT_containing_type) {
201-
DWARFDie D = resolveReferencedType(Die, FormValue);
202-
if (D && !D.isNULL()) {
197+
if (DWARFDie D = Die.getAttributeValueAsReferencedDie(FormValue);
198+
D && !D.isNULL()) {
203199
OS << Space << "\"";
204200
dumpTypeQualifiedName(D, OS);
205201
OS << '"';
@@ -291,13 +287,12 @@ DWARFDie::findRecursively(ArrayRef<dwarf::Attribute> Attrs) const {
291287
if (auto Value = Die.find(Attrs))
292288
return Value;
293289

294-
if (auto D = Die.getAttributeValueAsReferencedDie(DW_AT_abstract_origin))
295-
if (Seen.insert(D).second)
296-
Worklist.push_back(D);
297-
298-
if (auto D = Die.getAttributeValueAsReferencedDie(DW_AT_specification))
299-
if (Seen.insert(D).second)
300-
Worklist.push_back(D);
290+
for (dwarf::Attribute Attr :
291+
{DW_AT_abstract_origin, DW_AT_specification, DW_AT_signature}) {
292+
if (auto D = Die.getAttributeValueAsReferencedDie(Attr))
293+
if (Seen.insert(D).second)
294+
Worklist.push_back(D);
295+
}
301296
}
302297

303298
return std::nullopt;
@@ -312,27 +307,19 @@ DWARFDie::getAttributeValueAsReferencedDie(dwarf::Attribute Attr) const {
312307

313308
DWARFDie
314309
DWARFDie::getAttributeValueAsReferencedDie(const DWARFFormValue &V) const {
315-
DWARFDie Result;
316310
if (auto SpecRef = V.getAsRelativeReference()) {
317311
if (SpecRef->Unit)
318-
Result = SpecRef->Unit->getDIEForOffset(SpecRef->Unit->getOffset() +
319-
SpecRef->Offset);
320-
else if (auto SpecUnit =
321-
U->getUnitVector().getUnitForOffset(SpecRef->Offset))
322-
Result = SpecUnit->getDIEForOffset(SpecRef->Offset);
323-
}
324-
return Result;
325-
}
326-
327-
DWARFDie DWARFDie::resolveTypeUnitReference() const {
328-
if (auto Attr = find(DW_AT_signature)) {
329-
if (std::optional<uint64_t> Sig = Attr->getAsReferenceUVal()) {
312+
return SpecRef->Unit->getDIEForOffset(SpecRef->Unit->getOffset() +
313+
SpecRef->Offset);
314+
if (V.getForm() == dwarf::DW_FORM_ref_sig8) {
330315
if (DWARFTypeUnit *TU = U->getContext().getTypeUnitForHash(
331-
U->getVersion(), *Sig, U->isDWOUnit()))
316+
U->getVersion(), SpecRef->Offset, U->isDWOUnit()))
332317
return TU->getDIEForOffset(TU->getTypeOffset() + TU->getOffset());
333318
}
319+
if (auto *SpecUnit = U->getUnitVector().getUnitForOffset(SpecRef->Offset))
320+
return SpecUnit->getDIEForOffset(SpecRef->Offset);
334321
}
335-
return *this;
322+
return {};
336323
}
337324

338325
std::optional<uint64_t> DWARFDie::getRangesBaseAttribute() const {

llvm/lib/DebugInfo/DWARF/DWARFTypePrinter.cpp

Lines changed: 25 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -62,17 +62,10 @@ void DWARFTypePrinter::appendArrayType(const DWARFDie &D) {
6262
EndedWithTemplate = false;
6363
}
6464

65-
static DWARFDie resolveReferencedType(DWARFDie D,
66-
dwarf::Attribute Attr = DW_AT_type) {
67-
return D.getAttributeValueAsReferencedDie(Attr).resolveTypeUnitReference();
68-
}
69-
static DWARFDie resolveReferencedType(DWARFDie D, DWARFFormValue F) {
70-
return D.getAttributeValueAsReferencedDie(F).resolveTypeUnitReference();
71-
}
7265
DWARFDie DWARFTypePrinter::skipQualifiers(DWARFDie D) {
7366
while (D && (D.getTag() == DW_TAG_const_type ||
7467
D.getTag() == DW_TAG_volatile_type))
75-
D = resolveReferencedType(D);
68+
D = D.getAttributeValueAsReferencedDie(DW_AT_type);
7669
return D;
7770
}
7871

@@ -103,7 +96,9 @@ DWARFTypePrinter::appendUnqualifiedNameBefore(DWARFDie D,
10396
return DWARFDie();
10497
}
10598
DWARFDie InnerDIE;
106-
auto Inner = [&] { return InnerDIE = resolveReferencedType(D); };
99+
auto Inner = [&] {
100+
return InnerDIE = D.getAttributeValueAsReferencedDie(DW_AT_type);
101+
};
107102
const dwarf::Tag T = D.getTag();
108103
switch (T) {
109104
case DW_TAG_pointer_type: {
@@ -134,7 +129,8 @@ DWARFTypePrinter::appendUnqualifiedNameBefore(DWARFDie D,
134129
OS << '(';
135130
else if (Word)
136131
OS << ' ';
137-
if (DWARFDie Cont = resolveReferencedType(D, DW_AT_containing_type)) {
132+
if (DWARFDie Cont =
133+
D.getAttributeValueAsReferencedDie(DW_AT_containing_type)) {
138134
appendQualifiedName(Cont);
139135
EndedWithTemplate = false;
140136
OS << "::";
@@ -173,7 +169,8 @@ DWARFTypePrinter::appendUnqualifiedNameBefore(DWARFDie D,
173169
case DW_TAG_base_type:
174170
*/
175171
default: {
176-
const char *NamePtr = dwarf::toString(D.find(DW_AT_name), nullptr);
172+
const char *NamePtr =
173+
dwarf::toString(D.findRecursively(DW_AT_name), nullptr);
177174
if (!NamePtr) {
178175
appendTypeTagName(D.getTag());
179176
return DWARFDie();
@@ -235,9 +232,9 @@ void DWARFTypePrinter::appendUnqualifiedNameAfter(
235232
case DW_TAG_pointer_type: {
236233
if (needsParens(Inner))
237234
OS << ')';
238-
appendUnqualifiedNameAfter(Inner, resolveReferencedType(Inner),
239-
/*SkipFirstParamIfArtificial=*/D.getTag() ==
240-
DW_TAG_ptr_to_member_type);
235+
appendUnqualifiedNameAfter(
236+
Inner, Inner.getAttributeValueAsReferencedDie(DW_AT_type),
237+
/*SkipFirstParamIfArtificial=*/D.getTag() == DW_TAG_ptr_to_member_type);
241238
break;
242239
}
243240
case DW_TAG_LLVM_ptrauth_type: {
@@ -341,7 +338,7 @@ bool DWARFTypePrinter::appendTemplateParameters(DWARFDie D,
341338
appendTemplateParameters(C, FirstParameter);
342339
}
343340
if (C.getTag() == dwarf::DW_TAG_template_value_parameter) {
344-
DWARFDie T = resolveReferencedType(C);
341+
DWARFDie T = C.getAttributeValueAsReferencedDie(DW_AT_type);
345342
Sep();
346343
if (T.getTag() == DW_TAG_enumeration_type) {
347344
OS << '(';
@@ -461,7 +458,7 @@ bool DWARFTypePrinter::appendTemplateParameters(DWARFDie D,
461458
continue;
462459
auto TypeAttr = C.find(DW_AT_type);
463460
Sep();
464-
appendQualifiedName(TypeAttr ? resolveReferencedType(C, *TypeAttr)
461+
appendQualifiedName(TypeAttr ? C.getAttributeValueAsReferencedDie(*TypeAttr)
465462
: DWARFDie());
466463
}
467464
if (IsTemplate && *FirstParameter && FirstParameter == &FirstParameterValue) {
@@ -473,15 +470,15 @@ bool DWARFTypePrinter::appendTemplateParameters(DWARFDie D,
473470
void DWARFTypePrinter::decomposeConstVolatile(DWARFDie &N, DWARFDie &T,
474471
DWARFDie &C, DWARFDie &V) {
475472
(N.getTag() == DW_TAG_const_type ? C : V) = N;
476-
T = resolveReferencedType(N);
473+
T = N.getAttributeValueAsReferencedDie(DW_AT_type);
477474
if (T) {
478475
auto Tag = T.getTag();
479476
if (Tag == DW_TAG_const_type) {
480477
C = T;
481-
T = resolveReferencedType(T);
478+
T = T.getAttributeValueAsReferencedDie(DW_AT_type);
482479
} else if (Tag == DW_TAG_volatile_type) {
483480
V = T;
484-
T = resolveReferencedType(T);
481+
T = T.getAttributeValueAsReferencedDie(DW_AT_type);
485482
}
486483
}
487484
}
@@ -491,10 +488,11 @@ void DWARFTypePrinter::appendConstVolatileQualifierAfter(DWARFDie N) {
491488
DWARFDie T;
492489
decomposeConstVolatile(N, T, C, V);
493490
if (T && T.getTag() == DW_TAG_subroutine_type)
494-
appendSubroutineNameAfter(T, resolveReferencedType(T), false, C.isValid(),
495-
V.isValid());
491+
appendSubroutineNameAfter(T, T.getAttributeValueAsReferencedDie(DW_AT_type),
492+
false, C.isValid(), V.isValid());
496493
else
497-
appendUnqualifiedNameAfter(T, resolveReferencedType(T));
494+
appendUnqualifiedNameAfter(T,
495+
T.getAttributeValueAsReferencedDie(DW_AT_type));
498496
}
499497
void DWARFTypePrinter::appendConstVolatileQualifierBefore(DWARFDie N) {
500498
DWARFDie C;
@@ -504,7 +502,7 @@ void DWARFTypePrinter::appendConstVolatileQualifierBefore(DWARFDie N) {
504502
bool Subroutine = T && T.getTag() == DW_TAG_subroutine_type;
505503
DWARFDie A = T;
506504
while (A && A.getTag() == DW_TAG_array_type)
507-
A = resolveReferencedType(A);
505+
A = A.getAttributeValueAsReferencedDie(DW_AT_type);
508506
bool Leading =
509507
(!A || (A.getTag() != DW_TAG_pointer_type &&
510508
A.getTag() != llvm::dwarf::DW_TAG_ptr_to_member_type)) &&
@@ -546,7 +544,7 @@ void DWARFTypePrinter::appendSubroutineNameAfter(
546544
if (P.getTag() != DW_TAG_formal_parameter &&
547545
P.getTag() != DW_TAG_unspecified_parameters)
548546
return;
549-
DWARFDie T = resolveReferencedType(P);
547+
DWARFDie T = P.getAttributeValueAsReferencedDie(DW_AT_type);
550548
if (SkipFirstParamIfArtificial && RealFirst && P.find(DW_AT_artificial)) {
551549
FirstParamIfArtificial = T;
552550
RealFirst = false;
@@ -567,7 +565,7 @@ void DWARFTypePrinter::appendSubroutineNameAfter(
567565
if (DWARFDie P = FirstParamIfArtificial) {
568566
if (P.getTag() == DW_TAG_pointer_type) {
569567
auto CVStep = [&](DWARFDie CV) {
570-
if (DWARFDie U = resolveReferencedType(CV)) {
568+
if (DWARFDie U = CV.getAttributeValueAsReferencedDie(DW_AT_type)) {
571569
Const |= U.getTag() == DW_TAG_const_type;
572570
Volatile |= U.getTag() == DW_TAG_volatile_type;
573571
return U;
@@ -653,7 +651,8 @@ void DWARFTypePrinter::appendSubroutineNameAfter(
653651
if (D.find(DW_AT_rvalue_reference))
654652
OS << " &&";
655653

656-
appendUnqualifiedNameAfter(Inner, resolveReferencedType(Inner));
654+
appendUnqualifiedNameAfter(
655+
Inner, Inner.getAttributeValueAsReferencedDie(DW_AT_type));
657656
}
658657
void DWARFTypePrinter::appendScopes(DWARFDie D) {
659658
if (D.getTag() == DW_TAG_compile_unit)
@@ -666,7 +665,6 @@ void DWARFTypePrinter::appendScopes(DWARFDie D) {
666665
return;
667666
if (D.getTag() == DW_TAG_lexical_block)
668667
return;
669-
D = D.resolveTypeUnitReference();
670668
if (DWARFDie P = D.getParent())
671669
appendScopes(P);
672670
appendUnqualifiedName(D);

0 commit comments

Comments
 (0)