diff --git a/llvm/include/llvm/CodeGen/AccelTable.h b/llvm/include/llvm/CodeGen/AccelTable.h index 6eb09f32f9f95..9098a1a821bf4 100644 --- a/llvm/include/llvm/CodeGen/AccelTable.h +++ b/llvm/include/llvm/CodeGen/AccelTable.h @@ -305,9 +305,9 @@ class DWARF5AccelTable : public AccelTable { TUVectorTy TUSymbolsOrHashes; public: - struct UnitIndexAndEncoding { + struct UnitIndex { unsigned Index; - DWARF5AccelTableData::AttributeEncoding Encoding; + bool IsType; }; /// Returns type units that were constructed. const TUVectorTy &getTypeUnitsSymbols() { return TUSymbolsOrHashes; } @@ -366,7 +366,7 @@ void emitDWARF5AccelTable(AsmPrinter *Asm, DWARF5AccelTable &Contents, void emitDWARF5AccelTable( AsmPrinter *Asm, DWARF5AccelTable &Contents, ArrayRef> CUs, - llvm::function_ref( + llvm::function_ref( const DWARF5AccelTableData &)> getIndexForEntry); diff --git a/llvm/lib/CodeGen/AsmPrinter/AccelTable.cpp b/llvm/lib/CodeGen/AsmPrinter/AccelTable.cpp index 30ea7eef3a12b..0fbebc207a630 100644 --- a/llvm/lib/CodeGen/AsmPrinter/AccelTable.cpp +++ b/llvm/lib/CodeGen/AsmPrinter/AccelTable.cpp @@ -179,14 +179,124 @@ class AppleAccelTableWriter : public AccelTableWriter { #endif }; +/// Helper enum to encode whether something is a Type or Compile unit (or none) +/// with the minimal number of bits. +enum class TypeOrCompileUnit : uint8_t { Compile = 0, Type = 1, None = 2 }; + +/// Helper enum to encode DW_FORM_data{1,2,4,8} with the minimal number of +/// bits. +enum class FormDataLength : uint8_t { + Data1 = 0, + Data2 = 1, + Data4 = 2, + Data8 = 3 +}; + +/// Maps `Index` into the smallest DW_FORM_data{1,2,4,8} that can represent it, +/// and returns the corresponding `FormDataLength`. +static FormDataLength getFormForIndex(uint32_t Index) { + dwarf::Form Form = DIEInteger::BestForm(false /*IsSigned*/, Index); + switch (Form) { + case dwarf::Form::DW_FORM_data1: + return FormDataLength::Data1; + case dwarf::Form::DW_FORM_data2: + return FormDataLength::Data2; + case dwarf::Form::DW_FORM_data4: + return FormDataLength::Data4; + case dwarf::Form::DW_FORM_data8: + return FormDataLength::Data8; + default: + llvm_unreachable("invalid getFormForIndex"); + } +} + +/// Maps a `FormDataLength` back to the corresponding DW_FORM_data{1,2,4,8} +static dwarf::Form toDwarfDataForm(FormDataLength DataLength) { + switch (DataLength) { + case FormDataLength::Data1: + return dwarf::Form::DW_FORM_data1; + case FormDataLength::Data2: + return dwarf::Form::DW_FORM_data2; + case FormDataLength::Data4: + return dwarf::Form::DW_FORM_data4; + case FormDataLength::Data8: + return dwarf::Form::DW_FORM_data8; + } + llvm_unreachable("invalid toDwarfDataForm"); +} + +/// Converts `UnitType` and `UnitForm` into an `AttributeEncoding` and push it +/// into `Ans`, if UnitType != None. +void pushTypeOrCompileUnitEncondings( + SmallVectorImpl &Vec, + TypeOrCompileUnit UnitType, FormDataLength UnitForm) { + switch (UnitType) { + case TypeOrCompileUnit::Compile: + Vec.push_back({dwarf::DW_IDX_compile_unit, toDwarfDataForm(UnitForm)}); + break; + case TypeOrCompileUnit::Type: + Vec.push_back({dwarf::DW_IDX_type_unit, toDwarfDataForm((UnitForm))}); + break; + case TypeOrCompileUnit::None: + break; + } + return; +} + +/// Represent the contents of an Abbreviation Entry for a DWARF5AccelTable, so +/// that a set of such entries may be created. +/// All Abbreviations have some common content: +/// 1. IDX_die_offset, with form ref4. +/// 2. IDX_{type, compile}_unit with a form DW_FORM_data{1,2,4,8}. +/// This class doesn't encode such common elements; instead, it only encodes +/// contents that may change from one abbreviation to another, as those define +/// the uniqueness of each abbreviation. +/// Common elements still show up in accessor methods (e.g. `getAttrEncodings`). +struct AbbreviationContents { + uint16_t Tag : 16; + TypeOrCompileUnit UnitType : 2; + FormDataLength UnitForm : 2; + + AbbreviationContents(uint16_t Tag, TypeOrCompileUnit UnitType, + uint32_t UnitIndex) + : Tag(Tag), UnitType(UnitType), UnitForm(getFormForIndex(UnitIndex)) {} + AbbreviationContents(uint16_t Tag) + : Tag(Tag), UnitType(TypeOrCompileUnit::None), + UnitForm(getFormForIndex(0)) {} + + uint32_t getUniqueCode() const { + uint32_t Bitfield = static_cast(UnitType); + Bitfield |= static_cast(UnitForm) << 2; + Bitfield |= static_cast(Tag) << 4; + return Bitfield; + } + + SmallVector + getAttrEncodings() const { + SmallVector Ans; + pushTypeOrCompileUnitEncondings(Ans, UnitType, UnitForm); + Ans.push_back({dwarf::DW_IDX_die_offset, dwarf::DW_FORM_ref4}); + return Ans; + } +}; + +struct AbbreviationContentsInfo { + static AbbreviationContents getEmptyKey() { return AbbreviationContents(0); }; + static AbbreviationContents getTombstoneKey() { + return AbbreviationContents(~0); + }; + static uint32_t getHashValue(AbbreviationContents Contents) { + return Contents.getUniqueCode(); + } + static bool isEqual(AbbreviationContents LHS, AbbreviationContents RHS) { + return LHS.Tag == RHS.Tag && LHS.UnitType == RHS.UnitType; + } +}; + /// Class responsible for emitting a DWARF v5 Accelerator Table. The only /// public function is emit(), which performs the actual emission. /// -/// The class is templated in its data type. This allows us to emit both dyamic -/// and static data entries. A callback abstract the logic to provide a CU -/// index for a given entry, which is different per data type, but identical -/// for every entry in the same table. -template +/// A callback abstracts the logic to provide a CU index for a given entry. class Dwarf5AccelTableWriter : public AccelTableWriter { struct Header { uint16_t Version = 5; @@ -211,12 +321,11 @@ class Dwarf5AccelTableWriter : public AccelTableWriter { }; Header Header; - DenseMap> - Abbreviations; + DenseSet Abbreviations; ArrayRef> CompUnits; ArrayRef> TypeUnits; - llvm::function_ref( - const DataT &)> + llvm::function_ref( + const DWARF5AccelTableData &)> getIndexForEntry; MCSymbol *ContributionEnd = nullptr; MCSymbol *AbbrevStart = Asm->createTempSymbol("names_abbrev_start"); @@ -232,7 +341,7 @@ class Dwarf5AccelTableWriter : public AccelTableWriter { void emitBuckets() const; void emitStringOffsets() const; void emitAbbrevs() const; - void emitEntry(const DataT &Entry) const; + void emitEntry(const DWARF5AccelTableData &Entry) const; void emitData() const; public: @@ -240,8 +349,8 @@ class Dwarf5AccelTableWriter : public AccelTableWriter { AsmPrinter *Asm, const AccelTableBase &Contents, ArrayRef> CompUnits, ArrayRef> TypeUnits, - llvm::function_ref< - std::optional(const DataT &)> + llvm::function_ref( + const DWARF5AccelTableData &)> getIndexForEntry, bool IsSplitDwarf); @@ -370,8 +479,7 @@ DWARF5AccelTableData::DWARF5AccelTableData(const DIE &Die, const bool IsTU) : OffsetVal(&Die), DieTag(Die.getTag()), UnitID(UnitID), IsTU(IsTU) {} -template -void Dwarf5AccelTableWriter::Header::emit(Dwarf5AccelTableWriter &Ctx) { +void Dwarf5AccelTableWriter::Header::emit(Dwarf5AccelTableWriter &Ctx) { assert(CompUnitCount > 0 && "Index must have at least one CU."); AsmPrinter *Asm = Ctx.Asm; @@ -400,46 +508,33 @@ void Dwarf5AccelTableWriter::Header::emit(Dwarf5AccelTableWriter &Ctx) { Asm->OutStreamer->emitBytes({AugmentationString, AugmentationStringSize}); } -static uint32_t constexpr LowerBitSize = dwarf::DW_IDX_type_hash; -static uint32_t getTagFromAbbreviationTag(const uint32_t AbbrvTag) { - return AbbrvTag >> LowerBitSize; +static AbbreviationContents constructAbbreviationContents( + const unsigned Tag, + const std::optional &EntryRet) { + if (!EntryRet) + return AbbreviationContents(Tag); + return AbbreviationContents(Tag, + EntryRet->IsType ? TypeOrCompileUnit::Type + : TypeOrCompileUnit::Compile, + EntryRet->Index); } -/// Constructs a unique AbbrevTag that captures what a DIE accesses. -/// Using this tag we can emit a unique abbreviation for each DIE. -static uint32_t constructAbbreviationTag( - const unsigned Tag, - const std::optional &EntryRet) { - uint32_t AbbrvTag = 0; - if (EntryRet) - AbbrvTag |= 1 << EntryRet->Encoding.Index; - AbbrvTag |= 1 << dwarf::DW_IDX_die_offset; - AbbrvTag |= Tag << LowerBitSize; - return AbbrvTag; -} -template -void Dwarf5AccelTableWriter::populateAbbrevsMap() { +void Dwarf5AccelTableWriter::populateAbbrevsMap() { for (auto &Bucket : Contents.getBuckets()) { for (auto *Hash : Bucket) { for (auto *Value : Hash->Values) { - std::optional EntryRet = - getIndexForEntry(*static_cast(Value)); - unsigned Tag = static_cast(Value)->getDieTag(); - uint32_t AbbrvTag = constructAbbreviationTag(Tag, EntryRet); - if (Abbreviations.count(AbbrvTag) == 0) { - SmallVector UA; - if (EntryRet) - UA.push_back(EntryRet->Encoding); - UA.push_back({dwarf::DW_IDX_die_offset, dwarf::DW_FORM_ref4}); - Abbreviations.try_emplace(AbbrvTag, UA); - } + std::optional EntryRet = + getIndexForEntry(*static_cast(Value)); + unsigned Tag = + static_cast(Value)->getDieTag(); + auto AbbrevContents = constructAbbreviationContents(Tag, EntryRet); + Abbreviations.insert(AbbrevContents); } } } } -template -void Dwarf5AccelTableWriter::emitCUList() const { +void Dwarf5AccelTableWriter::emitCUList() const { for (const auto &CU : enumerate(CompUnits)) { Asm->OutStreamer->AddComment("Compilation unit " + Twine(CU.index())); if (std::holds_alternative(CU.value())) @@ -449,8 +544,7 @@ void Dwarf5AccelTableWriter::emitCUList() const { } } -template -void Dwarf5AccelTableWriter::emitTUList() const { +void Dwarf5AccelTableWriter::emitTUList() const { for (const auto &TU : enumerate(TypeUnits)) { Asm->OutStreamer->AddComment("Type unit " + Twine(TU.index())); if (std::holds_alternative(TU.value())) @@ -462,8 +556,7 @@ void Dwarf5AccelTableWriter::emitTUList() const { } } -template -void Dwarf5AccelTableWriter::emitBuckets() const { +void Dwarf5AccelTableWriter::emitBuckets() const { uint32_t Index = 1; for (const auto &Bucket : enumerate(Contents.getBuckets())) { Asm->OutStreamer->AddComment("Bucket " + Twine(Bucket.index())); @@ -472,8 +565,7 @@ void Dwarf5AccelTableWriter::emitBuckets() const { } } -template -void Dwarf5AccelTableWriter::emitStringOffsets() const { +void Dwarf5AccelTableWriter::emitStringOffsets() const { for (const auto &Bucket : enumerate(Contents.getBuckets())) { for (auto *Hash : Bucket.value()) { DwarfStringPoolEntryRef String = Hash->Name; @@ -484,17 +576,15 @@ void Dwarf5AccelTableWriter::emitStringOffsets() const { } } -template -void Dwarf5AccelTableWriter::emitAbbrevs() const { +void Dwarf5AccelTableWriter::emitAbbrevs() const { Asm->OutStreamer->emitLabel(AbbrevStart); for (const auto &Abbrev : Abbreviations) { Asm->OutStreamer->AddComment("Abbrev code"); - uint32_t Tag = getTagFromAbbreviationTag(Abbrev.first); - assert(Tag != 0); - Asm->emitULEB128(Abbrev.first); - Asm->OutStreamer->AddComment(dwarf::TagString(Tag)); - Asm->emitULEB128(Tag); - for (const auto &AttrEnc : Abbrev.second) { + assert(Abbrev.Tag != 0); + Asm->emitULEB128(Abbrev.getUniqueCode()); + Asm->OutStreamer->AddComment(dwarf::TagString(Abbrev.Tag)); + Asm->emitULEB128(Abbrev.Tag); + for (const auto &AttrEnc : Abbrev.getAttrEncodings()) { Asm->emitULEB128(AttrEnc.Index, dwarf::IndexString(AttrEnc.Index).data()); Asm->emitULEB128(AttrEnc.Form, dwarf::FormEncodingString(AttrEnc.Form).data()); @@ -506,19 +596,16 @@ void Dwarf5AccelTableWriter::emitAbbrevs() const { Asm->OutStreamer->emitLabel(AbbrevEnd); } -template -void Dwarf5AccelTableWriter::emitEntry(const DataT &Entry) const { - std::optional EntryRet = - getIndexForEntry(Entry); - uint32_t AbbrvTag = constructAbbreviationTag(Entry.getDieTag(), EntryRet); - auto AbbrevIt = Abbreviations.find(AbbrvTag); - assert(AbbrevIt != Abbreviations.end() && +void Dwarf5AccelTableWriter::emitEntry( + const DWARF5AccelTableData &Entry) const { + std::optional EntryRet = getIndexForEntry(Entry); + auto AbbrevContents = + constructAbbreviationContents(Entry.getDieTag(), EntryRet); + assert(Abbreviations.contains(AbbrevContents) && "Why wasn't this abbrev generated?"); - assert(getTagFromAbbreviationTag(AbbrevIt->first) == Entry.getDieTag() && - "Invalid Tag"); - Asm->emitULEB128(AbbrevIt->first, "Abbreviation code"); + Asm->emitULEB128(AbbrevContents.getUniqueCode(), "Abbreviation code"); - for (const auto &AttrEnc : AbbrevIt->second) { + for (const auto &AttrEnc : AbbrevContents.getAttrEncodings()) { Asm->OutStreamer->AddComment(dwarf::IndexString(AttrEnc.Index)); switch (AttrEnc.Index) { case dwarf::DW_IDX_compile_unit: @@ -537,27 +624,26 @@ void Dwarf5AccelTableWriter::emitEntry(const DataT &Entry) const { } } -template void Dwarf5AccelTableWriter::emitData() const { +void Dwarf5AccelTableWriter::emitData() const { Asm->OutStreamer->emitLabel(EntryPool); for (auto &Bucket : Contents.getBuckets()) { for (auto *Hash : Bucket) { // Remember to emit the label for our offset. Asm->OutStreamer->emitLabel(Hash->Sym); for (const auto *Value : Hash->Values) - emitEntry(*static_cast(Value)); + emitEntry(*static_cast(Value)); Asm->OutStreamer->AddComment("End of list: " + Hash->Name.getString()); Asm->emitInt8(0); } } } -template -Dwarf5AccelTableWriter::Dwarf5AccelTableWriter( +Dwarf5AccelTableWriter::Dwarf5AccelTableWriter( AsmPrinter *Asm, const AccelTableBase &Contents, ArrayRef> CompUnits, ArrayRef> TypeUnits, - llvm::function_ref< - std::optional(const DataT &)> + llvm::function_ref( + const DWARF5AccelTableData &)> getIndexForEntry, bool IsSplitDwarf) : AccelTableWriter(Asm, Contents, false), @@ -570,7 +656,7 @@ Dwarf5AccelTableWriter::Dwarf5AccelTableWriter( populateAbbrevsMap(); } -template void Dwarf5AccelTableWriter::emit() { +void Dwarf5AccelTableWriter::emit() { Header.emit(*this); emitCUList(); emitTUList(); @@ -631,20 +717,14 @@ void llvm::emitDWARF5AccelTable( Asm->getObjFileLowering().getDwarfDebugNamesSection()); Contents.finalize(Asm, "names"); - dwarf::Form CUIndexForm = - DIEInteger::BestForm(/*IsSigned*/ false, CompUnits.size() - 1); - dwarf::Form TUIndexForm = - DIEInteger::BestForm(/*IsSigned*/ false, TypeUnits.size() - 1); - Dwarf5AccelTableWriter( + Dwarf5AccelTableWriter( Asm, Contents, CompUnits, TypeUnits, [&](const DWARF5AccelTableData &Entry) - -> std::optional { + -> std::optional { if (Entry.isTU()) - return {{TUIndex[Entry.getUnitID()], - {dwarf::DW_IDX_type_unit, TUIndexForm}}}; + return {{TUIndex[Entry.getUnitID()], true /*IsType*/}}; if (CUIndex.size() > 1) - return {{CUIndex[Entry.getUnitID()], - {dwarf::DW_IDX_compile_unit, CUIndexForm}}}; + return {{CUIndex[Entry.getUnitID()], false /*IsType*/}}; return std::nullopt; }, DD.useSplitDwarf()) @@ -662,13 +742,12 @@ void DWARF5AccelTable::addTypeUnitSignature(DwarfTypeUnit &U) { void llvm::emitDWARF5AccelTable( AsmPrinter *Asm, DWARF5AccelTable &Contents, ArrayRef> CUs, - llvm::function_ref( + llvm::function_ref( const DWARF5AccelTableData &)> getIndexForEntry) { std::vector> TypeUnits; Contents.finalize(Asm, "names"); - Dwarf5AccelTableWriter(Asm, Contents, CUs, TypeUnits, - getIndexForEntry, false) + Dwarf5AccelTableWriter(Asm, Contents, CUs, TypeUnits, getIndexForEntry, false) .emit(); } diff --git a/llvm/lib/DWARFLinker/DWARFStreamer.cpp b/llvm/lib/DWARFLinker/DWARFStreamer.cpp index cd649c328ed93..80a215bb216cd 100644 --- a/llvm/lib/DWARFLinker/DWARFStreamer.cpp +++ b/llvm/lib/DWARFLinker/DWARFStreamer.cpp @@ -306,18 +306,15 @@ void DwarfStreamer::emitDebugNames(DWARF5AccelTable &Table) { } Asm->OutStreamer->switchSection(MOFI->getDwarfDebugNamesSection()); - dwarf::Form Form = DIEInteger::BestForm(/*IsSigned*/ false, - (uint64_t)UniqueIdToCuMap.size() - 1); /// llvm-dwarfutil doesn't support type units + .debug_names right now. // FIXME: add support for type units + .debug_names. For now the behavior is // unsuported. emitDWARF5AccelTable( Asm.get(), Table, CompUnits, [&](const DWARF5AccelTableData &Entry) - -> std::optional { + -> std::optional { if (UniqueIdToCuMap.size() > 1) - return {{UniqueIdToCuMap[Entry.getUnitID()], - {dwarf::DW_IDX_compile_unit, Form}}}; + return {{UniqueIdToCuMap[Entry.getUnitID()], false /*IsType*/}}; return std::nullopt; }); } diff --git a/llvm/lib/DWARFLinkerParallel/DWARFEmitterImpl.cpp b/llvm/lib/DWARFLinkerParallel/DWARFEmitterImpl.cpp index 355cfae3a6462..7ae7a5db3a9dd 100644 --- a/llvm/lib/DWARFLinkerParallel/DWARFEmitterImpl.cpp +++ b/llvm/lib/DWARFLinkerParallel/DWARFEmitterImpl.cpp @@ -230,17 +230,14 @@ void DwarfEmitterImpl::emitDebugNames(DWARF5AccelTable &Table, return; Asm->OutStreamer->switchSection(MOFI->getDwarfDebugNamesSection()); - dwarf::Form Form = - DIEInteger::BestForm(/*IsSigned*/ false, (uint64_t)CUidToIdx.size() - 1); // FIXME: add support for type units + .debug_names. For now the behavior is // unsuported. emitDWARF5AccelTable( Asm.get(), Table, CUOffsets, [&](const DWARF5AccelTableData &Entry) - -> std::optional { + -> std::optional { if (CUidToIdx.size() > 1) - return {{CUidToIdx[Entry.getUnitID()], - {dwarf::DW_IDX_compile_unit, Form}}}; + return {{CUidToIdx[Entry.getUnitID()], false /*IsType*/}}; return std::nullopt; }); } diff --git a/llvm/test/DebugInfo/Generic/debug-names-many-cu.ll b/llvm/test/DebugInfo/Generic/debug-names-many-cu.ll index 698d0cba67a67..8b6fd734efc62 100644 --- a/llvm/test/DebugInfo/Generic/debug-names-many-cu.ll +++ b/llvm/test/DebugInfo/Generic/debug-names-many-cu.ll @@ -14,21 +14,26 @@ ; ... ; CHECK: CU[256]: 0x{{[0-9a-f]*}} -; CHECK: Abbreviation [[ABBREV:0x[0-9a-f]*]] +; CHECK: Abbreviation [[ABBREV_1BYTE:0x[0-9a-f]*]] +; CHECK-NEXT: Tag: DW_TAG_variable +; CHECK-NEXT: DW_IDX_compile_unit: DW_FORM_data1 +; CHECK-NEXT: DW_IDX_die_offset: DW_FORM_ref4 + +; CHECK: Abbreviation [[ABBREV_2BYTES:0x[0-9a-f]*]] ; CHECK-NEXT: Tag: DW_TAG_variable ; CHECK-NEXT: DW_IDX_compile_unit: DW_FORM_data2 ; CHECK-NEXT: DW_IDX_die_offset: DW_FORM_ref4 ; CHECK: String: 0x{{[0-9a-f]*}} "foobar1" ; CHECK-NEXT: Entry -; CHECK-NEXT: Abbrev: [[ABBREV]] +; CHECK-NEXT: Abbrev: [[ABBREV_1BYTE]] ; CHECK-NEXT: Tag: DW_TAG_variable -; CHECK-NEXT: DW_IDX_compile_unit: 0x0000 +; CHECK-NEXT: DW_IDX_compile_unit: 0x00 ; CHECK-NEXT: DW_IDX_die_offset: 0x{{[0-9a-f]*}} ; CHECK: String: 0x{{[0-9a-f]*}} "foobar257" ; CHECK-NEXT: Entry -; CHECK-NEXT: Abbrev: [[ABBREV]] +; CHECK-NEXT: Abbrev: [[ABBREV_2BYTES]] ; CHECK-NEXT: Tag: DW_TAG_variable ; CHECK-NEXT: DW_IDX_compile_unit: 0x0100 ; CHECK-NEXT: DW_IDX_die_offset: 0x{{[0-9a-f]*}} diff --git a/llvm/test/DebugInfo/X86/debug-names-types.ll b/llvm/test/DebugInfo/X86/debug-names-types.ll index 501b7efd88eb9..c0e5fb2a7c023 100644 --- a/llvm/test/DebugInfo/X86/debug-names-types.ll +++ b/llvm/test/DebugInfo/X86/debug-names-types.ll @@ -37,8 +37,8 @@ ; CHECK-NEXT: LocalTU[0]: 0x00000000 ; CHECK-NEXT: ] ; CHECK: Abbreviations [ -; CHECK-NEXT: Abbreviation [[ABBREV1:0x[0-9a-f]*]] { -; CHECK-NEXT: Tag: DW_TAG_structure_type +; CHECK-NEXT: Abbreviation [[ABBREV:0x[0-9a-f]*]] { +; CHECK-NEXT: Tag: DW_TAG_base_type ; CHECK-NEXT: DW_IDX_die_offset: DW_FORM_ref4 ; CHECK-NEXT: } ; CHECK-NEXT: Abbreviation [[ABBREV3:0x[0-9a-f]*]] { @@ -46,17 +46,17 @@ ; CHECK-NEXT: DW_IDX_type_unit: DW_FORM_data1 ; CHECK-NEXT: DW_IDX_die_offset: DW_FORM_ref4 ; CHECK-NEXT: } -; CHECK-NEXT: Abbreviation [[ABBREV:0x[0-9a-f]*]] { +; CHECK-NEXT: Abbreviation [[ABBREV4:0x[0-9a-f]*]] { ; CHECK-NEXT: Tag: DW_TAG_base_type +; CHECK-NEXT: DW_IDX_type_unit: DW_FORM_data1 ; CHECK-NEXT: DW_IDX_die_offset: DW_FORM_ref4 ; CHECK-NEXT: } ; CHECK-NEXT: Abbreviation [[ABBREV2:0x[0-9a-f]*]] { ; CHECK-NEXT: Tag: DW_TAG_subprogram ; CHECK-NEXT: DW_IDX_die_offset: DW_FORM_ref4 ; CHECK-NEXT: } -; CHECK-NEXT: Abbreviation [[ABBREV4:0x[0-9a-f]*]] { -; CHECK-NEXT: Tag: DW_TAG_base_type -; CHECK-NEXT: DW_IDX_type_unit: DW_FORM_data1 +; CHECK-NEXT: Abbreviation [[ABBREV1:0x[0-9a-f]*]] { +; CHECK-NEXT: Tag: DW_TAG_structure_type ; CHECK-NEXT: DW_IDX_die_offset: DW_FORM_ref4 ; CHECK-NEXT: } ; CHECK-NEXT: ] @@ -130,8 +130,8 @@ ; CHECK-SPLIT-NEXT: ForeignTU[0]: 0x675d23e4f33235f2 ; CHECK-SPLIT-NEXT: ] ; CHECK-SPLIT-NEXT: Abbreviations [ -; CHECK-SPLIT-NEXT: Abbreviation [[ABBREV:0x[0-9a-f]*]] { -; CHECK-SPLIT-NEXT: Tag: DW_TAG_structure_type +; CHECK-SPLIT-NEXT: Abbreviation [[ABBREV2:0x[0-9a-f]*]] { +; CHECK-SPLIT-NEXT: Tag: DW_TAG_base_type ; CHECK-SPLIT-NEXT: DW_IDX_die_offset: DW_FORM_ref4 ; CHECK-SPLIT-NEXT: } ; CHECK-SPLIT-NEXT: Abbreviation [[ABBREV1:0x[0-9a-f]*]] { @@ -139,17 +139,17 @@ ; CHECK-SPLIT-NEXT: DW_IDX_type_unit: DW_FORM_data1 ; CHECK-SPLIT-NEXT: DW_IDX_die_offset: DW_FORM_ref4 ; CHECK-SPLIT-NEXT: } -; CHECK-SPLIT-NEXT: Abbreviation [[ABBREV2:0x[0-9a-f]*]] { +; CHECK-SPLIT-NEXT: Abbreviation [[ABBREV4:0x[0-9a-f]*]] { ; CHECK-SPLIT-NEXT: Tag: DW_TAG_base_type +; CHECK-SPLIT-NEXT: DW_IDX_type_unit: DW_FORM_data1 ; CHECK-SPLIT-NEXT: DW_IDX_die_offset: DW_FORM_ref4 ; CHECK-SPLIT-NEXT: } ; CHECK-SPLIT-NEXT: Abbreviation [[ABBREV3:0x[0-9a-f]*]] { ; CHECK-SPLIT-NEXT: Tag: DW_TAG_subprogram ; CHECK-SPLIT-NEXT: DW_IDX_die_offset: DW_FORM_ref4 ; CHECK-SPLIT-NEXT: } -; CHECK-SPLIT-NEXT: Abbreviation [[ABBREV4:0x[0-9a-f]*]] { -; CHECK-SPLIT-NEXT: Tag: DW_TAG_base_type -; CHECK-SPLIT-NEXT: DW_IDX_type_unit: DW_FORM_data1 +; CHECK-SPLIT-NEXT: Abbreviation [[ABBREV:0x[0-9a-f]*]] { +; CHECK-SPLIT-NEXT: Tag: DW_TAG_structure_type ; CHECK-SPLIT-NEXT: DW_IDX_die_offset: DW_FORM_ref4 ; CHECK-SPLIT-NEXT: } ; CHECK-SPLIT-NEXT: ]