diff --git a/llvm/include/llvm/DebugInfo/DWARF/DWARFAcceleratorTable.h b/llvm/include/llvm/DebugInfo/DWARF/DWARFAcceleratorTable.h index b89536bc0c723..44a19c7b13f9a 100644 --- a/llvm/include/llvm/DebugInfo/DWARF/DWARFAcceleratorTable.h +++ b/llvm/include/llvm/DebugInfo/DWARF/DWARFAcceleratorTable.h @@ -460,6 +460,16 @@ class DWARFDebugNames : public DWARFAcceleratorTable { /// Returns the Offset of the DIE within the containing CU or TU. std::optional getDIEUnitOffset() const; + /// Returns true if this Entry has information about its parent DIE (i.e. if + /// it has an IDX_parent attribute) + bool hasParentInformation() const; + + /// Returns the Entry corresponding to the parent of the DIE represented by + /// `this` Entry. If the parent is not in the table, nullopt is returned. + /// Precondition: hasParentInformation() == true. + /// An error is returned for ill-formed tables. + Expected> getParentDIEEntry() const; + /// Return the Abbreviation that can be used to interpret the raw values of /// this Accelerator Entry. const Abbrev &getAbbrev() const { return *Abbr; } @@ -469,6 +479,7 @@ class DWARFDebugNames : public DWARFAcceleratorTable { std::optional lookup(dwarf::Index Index) const; void dump(ScopedPrinter &W) const; + void dumpParentIdx(ScopedPrinter &W, const DWARFFormValue &FormValue) const; friend class NameIndex; friend class ValueIterator; @@ -609,6 +620,13 @@ class DWARFDebugNames : public DWARFAcceleratorTable { Expected getEntry(uint64_t *Offset) const; + /// Returns the Entry at the relative `Offset` from the start of the Entry + /// pool. + Expected getEntryAtRelativeOffset(uint64_t Offset) const { + auto OffsetFromSection = Offset + this->EntriesBase; + return getEntry(&OffsetFromSection); + } + /// Look up all entries in this Name Index matching \c Key. iterator_range equal_range(StringRef Key) const; diff --git a/llvm/lib/DebugInfo/DWARF/DWARFAcceleratorTable.cpp b/llvm/lib/DebugInfo/DWARF/DWARFAcceleratorTable.cpp index 0f9c8ef485d45..03ad5d133cadd 100644 --- a/llvm/lib/DebugInfo/DWARF/DWARFAcceleratorTable.cpp +++ b/llvm/lib/DebugInfo/DWARF/DWARFAcceleratorTable.cpp @@ -611,6 +611,10 @@ DWARFDebugNames::Entry::lookup(dwarf::Index Index) const { return std::nullopt; } +bool DWARFDebugNames::Entry::hasParentInformation() const { + return lookup(dwarf::DW_IDX_parent).has_value(); +} + std::optional DWARFDebugNames::Entry::getDIEUnitOffset() const { if (std::optional Off = lookup(dwarf::DW_IDX_die_offset)) return Off->getAsReferenceUVal(); @@ -650,13 +654,48 @@ std::optional DWARFDebugNames::Entry::getLocalTUIndex() const { return std::nullopt; } +Expected> +DWARFDebugNames::Entry::getParentDIEEntry() const { + // The offset of the accelerator table entry for the parent. + std::optional ParentEntryOff = lookup(dwarf::DW_IDX_parent); + assert(ParentEntryOff.has_value() && "hasParentInformation() must be called"); + + if (ParentEntryOff->getForm() == dwarf::Form::DW_FORM_flag_present) + return std::nullopt; + return NameIdx->getEntryAtRelativeOffset(ParentEntryOff->getRawUValue()); +} + +void DWARFDebugNames::Entry::dumpParentIdx( + ScopedPrinter &W, const DWARFFormValue &FormValue) const { + Expected> ParentEntry = getParentDIEEntry(); + if (!ParentEntry) { + W.getOStream() << ""; + consumeError(ParentEntry.takeError()); + return; + } + + if (!ParentEntry->has_value()) { + W.getOStream() << ""; + return; + } + + auto AbsoluteOffset = NameIdx->EntriesBase + FormValue.getRawUValue(); + W.getOStream() << "Entry @ 0x" + Twine::utohexstr(AbsoluteOffset); +} + void DWARFDebugNames::Entry::dump(ScopedPrinter &W) const { W.startLine() << formatv("Abbrev: {0:x}\n", Abbr->Code); W.startLine() << formatv("Tag: {0}\n", Abbr->Tag); assert(Abbr->Attributes.size() == Values.size()); for (auto Tuple : zip_first(Abbr->Attributes, Values)) { - W.startLine() << formatv("{0}: ", std::get<0>(Tuple).Index); - std::get<1>(Tuple).dump(W.getOStream()); + auto Index = std::get<0>(Tuple).Index; + W.startLine() << formatv("{0}: ", Index); + + auto FormValue = std::get<1>(Tuple); + if (Index == dwarf::Index::DW_IDX_parent) + dumpParentIdx(W, FormValue); + else + FormValue.dump(W.getOStream()); W.getOStream() << '\n'; } } diff --git a/llvm/test/CodeGen/X86/dwarf-headers.o b/llvm/test/CodeGen/X86/dwarf-headers.o new file mode 100644 index 0000000000000..e69de29bb2d1d diff --git a/llvm/test/DebugInfo/Generic/debug-names-one-cu.ll b/llvm/test/DebugInfo/Generic/debug-names-one-cu.ll index 92212a24bd153..46b753e9e2def 100644 --- a/llvm/test/DebugInfo/Generic/debug-names-one-cu.ll +++ b/llvm/test/DebugInfo/Generic/debug-names-one-cu.ll @@ -35,7 +35,7 @@ ; CHECK-NEXT: Abbrev: [[ABBREV]] ; CHECK-NEXT: Tag: DW_TAG_variable ; CHECK-NEXT: DW_IDX_die_offset: 0x{{[0-9a-f]*}} -; CHECK-NEXT: DW_IDX_parent: true +; CHECK-NEXT: DW_IDX_parent: ; CHECK-NEXT: } ; CHECK: String: 0x{{[0-9a-f]*}} "foobar" @@ -43,7 +43,7 @@ ; CHECK-NEXT: Abbrev: [[ABBREV]] ; CHECK-NEXT: Tag: DW_TAG_variable ; CHECK-NEXT: DW_IDX_die_offset: 0x{{[0-9a-f]*}} -; CHECK-NEXT: DW_IDX_parent: true +; CHECK-NEXT: DW_IDX_parent: ; CHECK-NEXT: } ; VERIFY: No errors. diff --git a/llvm/test/DebugInfo/X86/debug-names-dwarf64.ll b/llvm/test/DebugInfo/X86/debug-names-dwarf64.ll index a6855d77a34ac..c15e2ad1d56b0 100644 --- a/llvm/test/DebugInfo/X86/debug-names-dwarf64.ll +++ b/llvm/test/DebugInfo/X86/debug-names-dwarf64.ll @@ -59,7 +59,7 @@ ; CHECK-NEXT: Abbrev: [[ABBREV]] ; CHECK-NEXT: Tag: DW_TAG_base_type ; CHECK-NEXT: DW_IDX_die_offset: [[TYPEDIE]] -; CHECK-NEXT: DW_IDX_parent: true +; CHECK-NEXT: DW_IDX_parent: ; CHECK-NEXT: } ; CHECK-NEXT: } ; CHECK-NEXT: ] @@ -71,17 +71,17 @@ ; CHECK-NEXT: Abbrev: [[ABBREV1]] ; CHECK-NEXT: Tag: DW_TAG_variable ; CHECK-NEXT: DW_IDX_die_offset: [[VARDIE]] -; CHECK-NEXT: DW_IDX_parent: true +; CHECK-NEXT: DW_IDX_parent: ; CHECK-NEXT: } ; CHECK-NEXT: } ; CHECK-NEXT: Name 3 { ; CHECK-NEXT: Hash: 0x7C96FE71 ; CHECK-NEXT: String: {{.+}} "func" -; CHECK-NEXT: Entry @ {{.+}} { +; CHECK-NEXT: Entry @ [[FUNC_ENTRY:0x.+]] { ; CHECK-NEXT: Abbrev: [[ABBREV_SP]] ; CHECK-NEXT: Tag: DW_TAG_subprogram ; CHECK-NEXT: DW_IDX_die_offset: [[SPDIE]] -; CHECK-NEXT: DW_IDX_parent: true +; CHECK-NEXT: DW_IDX_parent: ; CHECK-NEXT: } ; CHECK-NEXT: } ; CHECK-NEXT: ] @@ -96,7 +96,7 @@ ; CHECK-NEXT: Abbrev: [[ABBREV_LABEL]] ; CHECK-NEXT: Tag: DW_TAG_label ; CHECK-NEXT: DW_IDX_die_offset: [[LABELDIE]] -; CHECK-NEXT: DW_IDX_parent: 0x{{.*}} +; CHECK-NEXT: DW_IDX_parent: Entry @ [[FUNC_ENTRY]] ; CHECK-NEXT: } ; CHECK-NEXT: } ; CHECK-NEXT: ] diff --git a/llvm/test/DebugInfo/X86/debug-names-parents-same-offset.ll b/llvm/test/DebugInfo/X86/debug-names-parents-same-offset.ll index 9170cfc8508fa..95d85ab0ffe0f 100644 --- a/llvm/test/DebugInfo/X86/debug-names-parents-same-offset.ll +++ b/llvm/test/DebugInfo/X86/debug-names-parents-same-offset.ll @@ -21,16 +21,30 @@ ; CHECK-NEXT: Abbrev: [[ABBREV:0x.*]] ; CHECK-NEXT: Tag: DW_TAG_structure_type ; CHECK-NEXT: DW_IDX_type_unit: 0x01 -; CHECK-NEXT: DW_IDX_die_offset: [[DieOffset:0x.*]] -; CHECK-NEXT: DW_IDX_parent: [[Parent1:0x.*]] +; CHECK-NEXT: DW_IDX_die_offset: [[DieOffsetStruct:0x.*]] +; CHECK-NEXT: DW_IDX_parent: Entry @ [[Parent2:0x.*]] +; CHECK: String: {{.*}} "MyNamespace" +; CHECK-NEXT: Entry @ [[Parent1:0x.*]] { +; CHECK-NEXT: Abbrev: {{.*}} +; CHECK-NEXT: Tag: DW_TAG_namespace +; CHECK-NEXT: DW_IDX_type_unit: 0x00 +; CHECK-NEXT: DW_IDX_die_offset: [[DieOffsetNamespace:0x.*]] +; CHECK-NEXT: DW_IDX_parent: +; CHECK-NEXT: } +; CHECK-NEXT: Entry @ [[Parent2]] { +; CHECK-NEXT: Abbrev: {{.*}} +; CHECK-NEXT: Tag: DW_TAG_namespace +; CHECK-NEXT: DW_IDX_type_unit: 0x01 +; CHECK-NEXT: DW_IDX_die_offset: [[DieOffsetNamespace:0x.*]] +; CHECK-NEXT: DW_IDX_parent: +; CHECK-NEXT: } ; CHECK: String: {{.*}} "MyStruct1" ; CHECK-NEXT: Entry @ {{.*}} { ; CHECK-NEXT: Abbrev: [[ABBREV]] ; CHECK-NEXT: Tag: DW_TAG_structure_type ; CHECK-NEXT: DW_IDX_type_unit: 0x00 -; CHECK-NEXT: DW_IDX_die_offset: [[DieOffset:0x.*]] -; CHECK-NOT: DW_IDX_parent: [[Parent1]] -; CHECK-NEXT: DW_IDX_parent: 0x{{.*}} +; CHECK-NEXT: DW_IDX_die_offset: [[DieOffsetStruct:0x.*]] +; CHECK-NEXT: DW_IDX_parent: Entry @ [[Parent1]] %"struct.MyNamespace::MyStruct1" = type { i8 } diff --git a/llvm/test/DebugInfo/X86/debug-names-types.ll b/llvm/test/DebugInfo/X86/debug-names-types.ll index c44e82578f14a..f41bb5524b9c3 100644 --- a/llvm/test/DebugInfo/X86/debug-names-types.ll +++ b/llvm/test/DebugInfo/X86/debug-names-types.ll @@ -73,7 +73,7 @@ ; CHECK-NEXT: Abbrev: [[ABBREV]] ; CHECK-NEXT: Tag: DW_TAG_base_type ; CHECK-NEXT: DW_IDX_die_offset: 0x0000003e -; CHECK-NEXT: DW_IDX_parent: true +; CHECK-NEXT: DW_IDX_parent: ; CHECK-NEXT: } ; CHECK-NEXT: } ; CHECK-NEXT: ] @@ -86,13 +86,13 @@ ; CHECK-NEXT: Tag: DW_TAG_structure_type ; CHECK-NEXT: DW_IDX_type_unit: 0x00 ; CHECK-NEXT: DW_IDX_die_offset: 0x00000023 -; CHECK-NEXT: DW_IDX_parent: true +; CHECK-NEXT: DW_IDX_parent: ; CHECK-NEXT: } ; CHECK-NEXT: Entry @ {{.+}} { ; CHECK-NEXT: Abbrev: [[ABBREV1]] ; CHECK-NEXT: Tag: DW_TAG_structure_type ; CHECK-NEXT: DW_IDX_die_offset: 0x00000042 -; CHECK-NEXT: DW_IDX_parent: true +; CHECK-NEXT: DW_IDX_parent: ; CHECK-NEXT: } ; CHECK-NEXT: } ; CHECK-NEXT: ] @@ -104,7 +104,7 @@ ; CHECK-NEXT: Abbrev: [[ABBREV2]] ; CHECK-NEXT: Tag: DW_TAG_subprogram ; CHECK-NEXT: DW_IDX_die_offset: 0x00000023 -; CHECK-NEXT: DW_IDX_parent: true +; CHECK-NEXT: DW_IDX_parent: ; CHECK-NEXT: } ; CHECK-NEXT: } ; CHECK-NEXT: ] @@ -117,7 +117,7 @@ ; CHECK-NEXT: Tag: DW_TAG_base_type ; CHECK-NEXT: DW_IDX_type_unit: 0x00 ; CHECK-NEXT: DW_IDX_die_offset: 0x00000038 -; CHECK-NEXT: DW_IDX_parent: true +; CHECK-NEXT: DW_IDX_parent: ; CHECK-NEXT: } ; CHECK-NEXT: } ; CHECK-NEXT: ] @@ -176,7 +176,7 @@ ; CHECK-SPLIT-NEXT: Abbrev: [[ABBREV2]] ; CHECK-SPLIT-NEXT: Tag: DW_TAG_base_type ; CHECK-SPLIT-NEXT: DW_IDX_die_offset: 0x00000035 -; CHECK-SPLIT-NEXT: DW_IDX_parent: true +; CHECK-SPLIT-NEXT: DW_IDX_parent: ; CHECK-SPLIT-NEXT: } ; CHECK-SPLIT-NEXT: } ; CHECK-SPLIT-NEXT: ] @@ -189,13 +189,13 @@ ; CHECK-SPLIT-NEXT: Tag: DW_TAG_structure_type ; CHECK-SPLIT-NEXT: DW_IDX_type_unit: 0x00 ; CHECK-SPLIT-NEXT: DW_IDX_die_offset: 0x00000021 -; CHECK-SPLIT-NEXT: DW_IDX_parent: true +; CHECK-SPLIT-NEXT: DW_IDX_parent: ; CHECK-SPLIT-NEXT: } ; CHECK-SPLIT-NEXT: Entry @ {{.*}} { ; CHECK-SPLIT-NEXT: Abbrev: [[ABBREV]] ; CHECK-SPLIT-NEXT: Tag: DW_TAG_structure_type ; CHECK-SPLIT-NEXT: DW_IDX_die_offset: 0x00000039 -; CHECK-SPLIT-NEXT: DW_IDX_parent: true +; CHECK-SPLIT-NEXT: DW_IDX_parent: ; CHECK-SPLIT-NEXT: } ; CHECK-SPLIT-NEXT: } ; CHECK-SPLIT-NEXT: ] @@ -207,7 +207,7 @@ ; CHECK-SPLIT-NEXT: Abbrev: [[ABBREV3]] ; CHECK-SPLIT-NEXT: Tag: DW_TAG_subprogram ; CHECK-SPLIT-NEXT: DW_IDX_die_offset: 0x0000001a -; CHECK-SPLIT-NEXT: DW_IDX_parent: true +; CHECK-SPLIT-NEXT: DW_IDX_parent: ; CHECK-SPLIT-NEXT: } ; CHECK-SPLIT-NEXT: } ; CHECK-SPLIT-NEXT: ] @@ -220,7 +220,7 @@ ; CHECK-SPLIT-NEXT: Tag: DW_TAG_base_type ; CHECK-SPLIT-NEXT: DW_IDX_type_unit: 0x00 ; CHECK-SPLIT-NEXT: DW_IDX_die_offset: 0x00000036 -; CHECK-SPLIT-NEXT: DW_IDX_parent: true +; CHECK-SPLIT-NEXT: DW_IDX_parent: ; CHECK-SPLIT-NEXT: } ; CHECK-SPLIT-NEXT: } ; CHECK-SPLIT-NEXT: ] diff --git a/llvm/test/tools/dsymutil/ARM/accel-imported-declarations.test b/llvm/test/tools/dsymutil/ARM/accel-imported-declarations.test index a8bf191e036f7..8afbe34dcdbfb 100644 --- a/llvm/test/tools/dsymutil/ARM/accel-imported-declarations.test +++ b/llvm/test/tools/dsymutil/ARM/accel-imported-declarations.test @@ -23,13 +23,13 @@ DWARF-NEXT: Entry {{.*}} { DWARF-NEXT: Abbrev: {{.*}} DWARF-NEXT: Tag: DW_TAG_namespace DWARF: DW_IDX_die_offset: [[NAMESPACE]] -DWARF-NEXT: DW_IDX_parent: 0x{{.*}} +DWARF-NEXT: DW_IDX_parent: Entry @ 0x{{.*}} DWARF-NEXT: } DWARF-NEXT: Entry {{.*}} { DWARF-NEXT: Abbrev: {{.*}} DWARF: Tag: DW_TAG_imported_declaration DWARF: DW_IDX_die_offset: 0x0000005c -DWARF-NEXT: DW_IDX_parent: 0x{{.*}} +DWARF-NEXT: DW_IDX_parent: Entry @ 0x{{.*}} DWARF-NEXT: } DWARF-NEXT: }