Index: lib/CodeGen/AsmPrinter/DIE.cpp =================================================================== --- lib/CodeGen/AsmPrinter/DIE.cpp +++ lib/CodeGen/AsmPrinter/DIE.cpp @@ -410,6 +410,7 @@ case dwarf::DW_FORM_GNU_str_index: case dwarf::DW_FORM_GNU_addr_index: case dwarf::DW_FORM_ref_udata: + case dwarf::DW_FORM_strx: case dwarf::DW_FORM_udata: Asm->EmitULEB128(Integer); return; @@ -469,6 +470,7 @@ case dwarf::DW_FORM_GNU_str_index: case dwarf::DW_FORM_GNU_addr_index: case dwarf::DW_FORM_ref_udata: + case dwarf::DW_FORM_strx: case dwarf::DW_FORM_udata: return getULEB128Size(Integer); case dwarf::DW_FORM_sdata: @@ -564,44 +566,47 @@ /// EmitValue - Emit string value. /// void DIEString::EmitValue(const AsmPrinter *AP, dwarf::Form Form) const { - assert( - (Form == dwarf::DW_FORM_strp || Form == dwarf::DW_FORM_GNU_str_index) && - "Expected valid string form"); - // Index of string in symbol table. - if (Form == dwarf::DW_FORM_GNU_str_index) { + switch (Form) { + case dwarf::DW_FORM_GNU_str_index: + case dwarf::DW_FORM_strx: + case dwarf::DW_FORM_strx1: + case dwarf::DW_FORM_strx2: + case dwarf::DW_FORM_strx3: + case dwarf::DW_FORM_strx4: DIEInteger(S.getIndex()).EmitValue(AP, Form); return; - } - - // Relocatable symbol. - assert(Form == dwarf::DW_FORM_strp); - if (AP->MAI->doesDwarfUseRelocationsAcrossSections()) { - DIELabel(S.getSymbol()).EmitValue(AP, Form); + case dwarf::DW_FORM_strp: + if (AP->MAI->doesDwarfUseRelocationsAcrossSections()) + DIELabel(S.getSymbol()).EmitValue(AP, Form); + else + DIEInteger(S.getOffset()).EmitValue(AP, Form); return; + default: + llvm_unreachable("Expected valid string form"); } - - // Offset into symbol table. - DIEInteger(S.getOffset()).EmitValue(AP, Form); } /// SizeOf - Determine size of delta value in bytes. /// unsigned DIEString::SizeOf(const AsmPrinter *AP, dwarf::Form Form) const { - assert( - (Form == dwarf::DW_FORM_strp || Form == dwarf::DW_FORM_GNU_str_index) && - "Expected valid string form"); - // Index of string in symbol table. - if (Form == dwarf::DW_FORM_GNU_str_index) + switch (Form) { + case dwarf::DW_FORM_GNU_str_index: + case dwarf::DW_FORM_strx: + case dwarf::DW_FORM_strx1: + case dwarf::DW_FORM_strx2: + case dwarf::DW_FORM_strx3: + case dwarf::DW_FORM_strx4: return DIEInteger(S.getIndex()).SizeOf(AP, Form); - - // Relocatable symbol. - if (AP->MAI->doesDwarfUseRelocationsAcrossSections()) - return DIELabel(S.getSymbol()).SizeOf(AP, Form); - - // Offset into symbol table. - return DIEInteger(S.getOffset()).SizeOf(AP, Form); + case dwarf::DW_FORM_strp: + if (AP->MAI->doesDwarfUseRelocationsAcrossSections()) + return DIELabel(S.getSymbol()).SizeOf(AP, Form); + return DIEInteger(S.getOffset()).SizeOf(AP, Form); + default: + llvm_unreachable("Expected valid string form"); + return 0; + } } LLVM_DUMP_METHOD Index: lib/CodeGen/AsmPrinter/DwarfDebug.h =================================================================== --- lib/CodeGen/AsmPrinter/DwarfDebug.h +++ lib/CodeGen/AsmPrinter/DwarfDebug.h @@ -261,6 +261,9 @@ bool HasAppleExtensionAttributes; bool HasSplitDwarf; + /// Whether to use the DWARF v5 string offsets table. + bool UseSegmentedStringOffsetsTable; + /// Separated Dwarf Variables /// In general these will all be for bits that are left in the /// original object file, rather than things that are meant @@ -324,6 +327,10 @@ /// Emit the abbreviation section. void emitAbbreviations(); + /// Emit the string offsets table header. The table entries are emitted by + /// emitDebugStr(). + void emitStringOffsetsTableHeader(); + /// Emit a specified accelerator table. void emitAccel(DwarfAccelTable &Accel, MCSection *Section, StringRef TableName); @@ -388,6 +395,10 @@ /// Emit the debug line dwo section. void emitDebugLineDWO(); + /// Emit the dwo stringoffsets table header. The table entries are emitted + /// by emitDebugStrDWO(). + void emitStringOffsetsTableHeaderDWO(); + /// Emit the debug str dwo section. void emitDebugStrDWO(); @@ -492,6 +503,16 @@ /// split dwarf proposal support. bool useSplitDwarf() const { return HasSplitDwarf; } + /// Returns whether to generate a string offsets table with (possibly shared) + /// contributions from each CU and type unit. This implies the use of + /// DW_FORM_strx* indirect references with DWARF v5 and beyond. Note that + /// DW_FORM_GNU_str_index is also an indirect reference, but it is used with + /// a pre-DWARF v5 implementation of split DWARF sections, which uses a + /// monolithic string offsets table. + bool useSegmentedStringOffsetsTable() const { + return UseSegmentedStringOffsetsTable; + } + bool shareAcrossDWOCUs() const; /// Returns the Dwarf Version. Index: lib/CodeGen/AsmPrinter/DwarfDebug.cpp =================================================================== --- lib/CodeGen/AsmPrinter/DwarfDebug.cpp +++ lib/CodeGen/AsmPrinter/DwarfDebug.cpp @@ -321,6 +321,12 @@ // GDB does not fully support the DWARF 4 representation for bitfields. UseDWARF2Bitfields = (DwarfVersion < 4) || tuneForGDB(); + // The DWARF v5 string offsets table has - possibly shared - contributions + // from each compile and type unit each preceded by a header. The string + // offsets table used by the pre-DWARF v5 split-DWARF implementation uses + // a monolithic string offsets table without any header. + UseSegmentedStringOffsetsTable = DwarfVersion >= 5; + Asm->OutStreamer->getContext().setDwarfVersion(DwarfVersion); } @@ -486,6 +492,10 @@ DIUnit->getSourceLanguage()); NewCU.addString(Die, dwarf::DW_AT_name, FN); + // Add DW_str_offsets_base to the unit DIE, except for split units. + if (useSegmentedStringOffsetsTable() && !useSplitDwarf()) + NewCU.addStringOffsetsStart(); + if (!useSplitDwarf()) { NewCU.initStmtList(); @@ -590,6 +600,17 @@ GVMap[GVE->getVariable()].push_back({&Global, GVE->getExpression()}); } + // Create the symbol that designates the start of the unit's contribution + // to the string offsets table. In a split DWARF scenario, only the skeleton + // unit has the DW_AT_str_offsets_base attribute (and hence needs the symbol). + if (useSegmentedStringOffsetsTable()) { + InfoHolder.setStringOffsetsStartSym( + Asm->createTempSymbol("str_offsets_base")); + if (useSplitDwarf()) + SkeletonHolder.setStringOffsetsStartSym( + Asm->createTempSymbol("str_offsets_base")); + } + for (DICompileUnit *CUNode : M->debug_compile_units()) { // FIXME: Move local imported entities into a list attached to the // subprogram, then this search won't be needed and a @@ -1399,6 +1420,12 @@ Holder.emitAbbrevs(Asm->getObjFileLowering().getDwarfAbbrevSection()); } +void DwarfDebug::emitStringOffsetsTableHeader() { + DwarfFile &Holder = useSplitDwarf() ? SkeletonHolder : InfoHolder; + Holder.emitStringOffsetsTableHeader( + Asm->getObjFileLowering().getDwarfStrOffSection()); +} + void DwarfDebug::emitAccel(DwarfAccelTable &Accel, MCSection *Section, StringRef TableName) { Accel.FinalizeTable(Asm, TableName); @@ -1573,8 +1600,14 @@ /// Emit null-terminated strings into a debug str section. void DwarfDebug::emitDebugStr() { + MCSection *StringOffsetsSection = nullptr; + if (useSegmentedStringOffsetsTable()) { + emitStringOffsetsTableHeader(); + StringOffsetsSection = Asm->getObjFileLowering().getDwarfStrOffSection(); + } DwarfFile &Holder = useSplitDwarf() ? SkeletonHolder : InfoHolder; - Holder.emitStrings(Asm->getObjFileLowering().getDwarfStrSection()); + Holder.emitStrings(Asm->getObjFileLowering().getDwarfStrSection(), + StringOffsetsSection, /* UseRelativeOffsets = */ true); } void DwarfDebug::emitDebugLocEntry(ByteStreamer &Streamer, @@ -2024,6 +2057,9 @@ NewCU.initStmtList(); + if (useSegmentedStringOffsetsTable()) + NewCU.addStringOffsetsStart(); + initSkeletonUnit(CU, NewCU.getUnitDie(), std::move(OwnedUnit)); return NewCU; @@ -2051,14 +2087,22 @@ SplitTypeUnitFileTable.Emit(*Asm->OutStreamer, MCDwarfLineTableParams()); } +void DwarfDebug::emitStringOffsetsTableHeaderDWO() { + assert(useSplitDwarf() && "No split dwarf?"); + InfoHolder.emitStringOffsetsTableHeader( + Asm->getObjFileLowering().getDwarfStrOffDWOSection()); +} + // Emit the .debug_str.dwo section for separated dwarf. This contains the // string section and is identical in format to traditional .debug_str // sections. void DwarfDebug::emitDebugStrDWO() { + if (useSegmentedStringOffsetsTable()) + emitStringOffsetsTableHeaderDWO(); assert(useSplitDwarf() && "No split dwarf?"); MCSection *OffSec = Asm->getObjFileLowering().getDwarfStrOffDWOSection(); InfoHolder.emitStrings(Asm->getObjFileLowering().getDwarfStrDWOSection(), - OffSec); + OffSec, /* UseRelativeOffsets = */ false); } MCDwarfDwoLineTable *DwarfDebug::getDwoLineTable(const DwarfCompileUnit &CU) { @@ -2118,6 +2162,11 @@ NewTU.setSection(Asm->getObjFileLowering().getDwarfTypesSection(Signature)); } + // Add DW_AT_str_offsets_base to the type unit DIE, but not for split type + // units. + if (useSegmentedStringOffsetsTable() && !useSplitDwarf()) + NewTU.addStringOffsetsStart(); + NewTU.setType(NewTU.createTypeDIE(CTy)); if (TopLevelType) { Index: lib/CodeGen/AsmPrinter/DwarfFile.h =================================================================== --- lib/CodeGen/AsmPrinter/DwarfFile.h +++ lib/CodeGen/AsmPrinter/DwarfFile.h @@ -43,6 +43,10 @@ DwarfStringPool StrPool; + /// DWARF v5: The symbol that designates the start of the contribution to + /// the string offsets table. The contribution is shared by all units. + MCSymbol *StringOffsetsStartSym = nullptr; + // Collection of dbg variables of a scope. DenseMap> ScopeVariables; @@ -75,6 +79,9 @@ /// \brief Add a unit to the list of CUs. void addUnit(std::unique_ptr U); + /// Emit the string table offsets header. + void emitStringOffsetsTableHeader(MCSection *Section); + /// \brief Emit all of the units to the section listed with the given /// abbreviation section. void emitUnits(bool UseOffsets); @@ -85,12 +92,20 @@ /// \brief Emit a set of abbreviations to the specific section. void emitAbbrevs(MCSection *); - /// \brief Emit all of the strings to the section given. - void emitStrings(MCSection *StrSection, MCSection *OffsetSection = nullptr); + /// Emit all of the strings to the section given. If OffsetSection is + /// non-null, emit a table of string offsets to it. If UseRelativeOffsets + /// is false, emit absolute offsets to the strings. Otherwise, emit + /// relocatable references to the strings if they are supported by the target. + void emitStrings(MCSection *StrSection, MCSection *OffsetSection = nullptr, + bool UseRelativeOffsets = false); /// \brief Returns the string pool. DwarfStringPool &getStringPool() { return StrPool; } + MCSymbol *getStringOffsetsStartSym() const { return StringOffsetsStartSym; } + + void setStringOffsetsStartSym(MCSymbol *Sym) { StringOffsetsStartSym = Sym; } + /// \returns false if the variable was merged with a previous one. bool addScopeVariable(LexicalScope *LS, DbgVariable *Var); Index: lib/CodeGen/AsmPrinter/DwarfFile.cpp =================================================================== --- lib/CodeGen/AsmPrinter/DwarfFile.cpp +++ lib/CodeGen/AsmPrinter/DwarfFile.cpp @@ -28,6 +28,23 @@ CUs.push_back(std::move(U)); } +void DwarfFile::emitStringOffsetsTableHeader(MCSection *Section) { + Asm->OutStreamer->SwitchSection(Section); + unsigned EntrySize = 4; + // FIXME: DWARF64 + // We are emitting the header for a contribution to the string offsets + // table. The header consists of an entry with the contribution's + // size (not including the size of the header), the DWARF version and + // 2 bytes of padding. + Asm->EmitInt32(StrPool.size() * EntrySize); + Asm->EmitInt16(Asm->getDwarfVersion()); + Asm->EmitInt16(0); + // Define the symbol that marks the start of the contribution. It is + // referenced by most unit headers via DW_AT_str_offsets_base. + // Split compile units and split type units do not use the attribute. + Asm->OutStreamer->EmitLabel(StringOffsetsStartSym); +} + // Emit the various dwarf units to the unit section USection with // the abbreviations going into ASection. void DwarfFile::emitUnits(bool UseOffsets) { @@ -77,8 +94,9 @@ void DwarfFile::emitAbbrevs(MCSection *Section) { Abbrevs.Emit(Asm, Section); } // Emit strings into a string section. -void DwarfFile::emitStrings(MCSection *StrSection, MCSection *OffsetSection) { - StrPool.emit(*Asm, StrSection, OffsetSection); +void DwarfFile::emitStrings(MCSection *StrSection, MCSection *OffsetSection, + bool UseRelativeOffsets) { + StrPool.emit(*Asm, StrSection, OffsetSection, UseRelativeOffsets); } bool DwarfFile::addScopeVariable(LexicalScope *LS, DbgVariable *Var) { Index: lib/CodeGen/AsmPrinter/DwarfStringPool.h =================================================================== --- lib/CodeGen/AsmPrinter/DwarfStringPool.h +++ lib/CodeGen/AsmPrinter/DwarfStringPool.h @@ -37,10 +37,13 @@ DwarfStringPool(BumpPtrAllocator &A, AsmPrinter &Asm, StringRef Prefix); void emit(AsmPrinter &Asm, MCSection *StrSection, - MCSection *OffsetSection = nullptr); + MCSection *OffsetSection = nullptr, + bool UseRelativeOffsets = false); bool empty() const { return Pool.empty(); } + unsigned size() const { return Pool.size(); } + /// Get a reference to an entry in the string pool. EntryRef getEntry(AsmPrinter &Asm, StringRef Str); }; Index: lib/CodeGen/AsmPrinter/DwarfStringPool.cpp =================================================================== --- lib/CodeGen/AsmPrinter/DwarfStringPool.cpp +++ lib/CodeGen/AsmPrinter/DwarfStringPool.cpp @@ -40,7 +40,7 @@ } void DwarfStringPool::emit(AsmPrinter &Asm, MCSection *StrSection, - MCSection *OffsetSection) { + MCSection *OffsetSection, bool UseRelativeOffsets) { if (Pool.empty()) return; @@ -74,6 +74,9 @@ Asm.OutStreamer->SwitchSection(OffsetSection); unsigned size = 4; // FIXME: DWARF64 is 8. for (const auto &Entry : Entries) - Asm.OutStreamer->EmitIntValue(Entry->getValue().Offset, size); + if (UseRelativeOffsets) + Asm.emitDwarfStringOffset(Entry->getValue()); + else + Asm.OutStreamer->EmitIntValue(Entry->getValue().Offset, size); } } Index: lib/CodeGen/AsmPrinter/DwarfUnit.h =================================================================== --- lib/CodeGen/AsmPrinter/DwarfUnit.h +++ lib/CodeGen/AsmPrinter/DwarfUnit.h @@ -273,6 +273,10 @@ /// call insertDIE if MD is not null. DIE &createAndAddDIE(unsigned Tag, DIE &Parent, const DINode *N = nullptr); + bool useSegmentedStringOffsetsTable() const { + return DD->useSegmentedStringOffsetsTable(); + } + /// Compute the size of a header for this unit, not including the initial /// length field. virtual unsigned getHeaderSize() const { @@ -286,6 +290,9 @@ /// Emit the header for this unit, not including the initial length field. virtual void emitHeader(bool UseOffsets) = 0; + /// Add the DW_AT_str_offsets_base attribute to the unit DIE. + void addStringOffsetsStart(); + virtual DwarfCompileUnit &getCU() = 0; void constructTypeDIE(DIE &Buffer, const DICompositeType *CTy); Index: lib/CodeGen/AsmPrinter/DwarfUnit.cpp =================================================================== --- lib/CodeGen/AsmPrinter/DwarfUnit.cpp +++ lib/CodeGen/AsmPrinter/DwarfUnit.cpp @@ -241,9 +241,22 @@ void DwarfUnit::addString(DIE &Die, dwarf::Attribute Attribute, StringRef String) { - Die.addValue(DIEValueAllocator, Attribute, - isDwoUnit() ? dwarf::DW_FORM_GNU_str_index : dwarf::DW_FORM_strp, - DIEString(DU->getStringPool().getEntry(*Asm, String))); + auto StringPoolEntry = DU->getStringPool().getEntry(*Asm, String); + dwarf::Form IxForm = + isDwoUnit() ? dwarf::DW_FORM_GNU_str_index : dwarf::DW_FORM_strp; + // For DWARF v5 and beyond, use the smallest strx? form possible. + if (useSegmentedStringOffsetsTable()) { + IxForm = dwarf::DW_FORM_strx4; + unsigned Index = StringPoolEntry.getIndex(); + if ((Index & 0xff) == Index) + IxForm = dwarf::DW_FORM_strx1; + else if ((Index & 0xffff) == Index) + IxForm = dwarf::DW_FORM_strx2; + else if ((Index & 0xffffff) == Index) + IxForm = dwarf::DW_FORM_strx3; + } + Die.addValue(DIEValueAllocator, Attribute, IxForm, + DIEString(StringPoolEntry)); } DIEValueList::value_iterator DwarfUnit::addLabel(DIEValueList &Die, @@ -1652,3 +1665,10 @@ return nullptr; return getSection()->getBeginSymbol(); } + +void DwarfUnit::addStringOffsetsStart() { + const TargetLoweringObjectFile &TLOF = Asm->getObjFileLowering(); + addSectionLabel(getUnitDie(), dwarf::DW_AT_str_offsets_base, + DU->getStringOffsetsStartSym(), + TLOF.getDwarfStrOffSection()->getBeginSymbol()); +} Index: test/DebugInfo/Generic/string-offsets-form.ll =================================================================== --- test/DebugInfo/Generic/string-offsets-form.ll +++ test/DebugInfo/Generic/string-offsets-form.ll @@ -0,0 +1,432 @@ +; RUN: %llc_dwarf -filetype=obj < %s | llvm-dwarfdump -all -show-form -v - \ +; RUN: | FileCheck %s +; +; Generated from the following source with clang -S -emit-llvm -gdwarf-5. +; The IR has been manually stripped to its essentials by removing almost all +; %struct.SXXX = type { %struct.SYYY } constructs. +; +; struct S0 { int i;}; +; struct S1 { S0 s0; }; +; struct S2 { S1 s1; }; +; ... +; struct S125 { S124 s124; }; +; S125 s125; +; +; This test verifies that we generate DW_FORM_strx2 for indexed strings properly. +; +; Check that we have an abbreviation for the DW_TAG_structure_type DIE and that it +; uses DW_FORM_strx2. +; +; CHECK: .debug_abbrev contents: +; CHECK-NOT: contents: +; CHECK: DW_TAG_structure_type +; CHECK-NOT: DW_TAG +; CHECK: DW_AT_name DW_FORM_strx2 + +; Check that the first usage of DW_FORM_strx2 is with index 256. +; +; CHECK: .debug_info contents: +; CHECK-NOT: DW_FORM_strx2 +; CHECK: DW_AT_name [DW_FORM_strx2] ( indexed (00000100) string = + +; ModuleID = 'types.cpp' +source_filename = "types.cpp" + +%struct.S125 = type { %struct.S0 } +%struct.S0 = type { i32 } + +@s125 = global %struct.S125 zeroinitializer, align 4, !dbg !0 + +!llvm.dbg.cu = !{!2} +!llvm.module.flags = !{!385, !386, !387} +!llvm.ident = !{!388} + +!0 = !DIGlobalVariableExpression(var: !1, expr: !DIExpression()) +!1 = distinct !DIGlobalVariable(name: "s125", scope: !2, file: !3, line: 127, type: !6, isLocal: false, isDefinition: true) +!2 = distinct !DICompileUnit(language: DW_LANG_C_plus_plus, file: !3, producer: "clang version 7.0.0 (trunk 322295)", isOptimized: false, runtimeVersion: 0, emissionKind: FullDebug, enums: !4, globals: !5) +!3 = !DIFile(filename: "types.cpp", directory: "/home/test/DWARF") +!4 = !{} +!5 = !{!0} +!6 = distinct !DICompositeType(tag: DW_TAG_structure_type, name: "S125", file: !3, line: 126, size: 32, flags: DIFlagTypePassByValue, elements: !7, identifier: "_ZTS4S125") +!7 = !{!8} +!8 = !DIDerivedType(tag: DW_TAG_member, name: "s124", scope: !6, file: !3, line: 126, baseType: !9, size: 32) +!9 = distinct !DICompositeType(tag: DW_TAG_structure_type, name: "S124", file: !3, line: 125, size: 32, flags: DIFlagTypePassByValue, elements: !10, identifier: "_ZTS4S124") +!10 = !{!11} +!11 = !DIDerivedType(tag: DW_TAG_member, name: "s123", scope: !9, file: !3, line: 125, baseType: !12, size: 32) +!12 = distinct !DICompositeType(tag: DW_TAG_structure_type, name: "S123", file: !3, line: 124, size: 32, flags: DIFlagTypePassByValue, elements: !13, identifier: "_ZTS4S123") +!13 = !{!14} +!14 = !DIDerivedType(tag: DW_TAG_member, name: "s122", scope: !12, file: !3, line: 124, baseType: !15, size: 32) +!15 = distinct !DICompositeType(tag: DW_TAG_structure_type, name: "S122", file: !3, line: 123, size: 32, flags: DIFlagTypePassByValue, elements: !16, identifier: "_ZTS4S122") +!16 = !{!17} +!17 = !DIDerivedType(tag: DW_TAG_member, name: "s121", scope: !15, file: !3, line: 123, baseType: !18, size: 32) +!18 = distinct !DICompositeType(tag: DW_TAG_structure_type, name: "S121", file: !3, line: 122, size: 32, flags: DIFlagTypePassByValue, elements: !19, identifier: "_ZTS4S121") +!19 = !{!20} +!20 = !DIDerivedType(tag: DW_TAG_member, name: "s120", scope: !18, file: !3, line: 122, baseType: !21, size: 32) +!21 = distinct !DICompositeType(tag: DW_TAG_structure_type, name: "S120", file: !3, line: 121, size: 32, flags: DIFlagTypePassByValue, elements: !22, identifier: "_ZTS4S120") +!22 = !{!23} +!23 = !DIDerivedType(tag: DW_TAG_member, name: "s119", scope: !21, file: !3, line: 121, baseType: !24, size: 32) +!24 = distinct !DICompositeType(tag: DW_TAG_structure_type, name: "S119", file: !3, line: 120, size: 32, flags: DIFlagTypePassByValue, elements: !25, identifier: "_ZTS4S119") +!25 = !{!26} +!26 = !DIDerivedType(tag: DW_TAG_member, name: "s118", scope: !24, file: !3, line: 120, baseType: !27, size: 32) +!27 = distinct !DICompositeType(tag: DW_TAG_structure_type, name: "S118", file: !3, line: 119, size: 32, flags: DIFlagTypePassByValue, elements: !28, identifier: "_ZTS4S118") +!28 = !{!29} +!29 = !DIDerivedType(tag: DW_TAG_member, name: "s117", scope: !27, file: !3, line: 119, baseType: !30, size: 32) +!30 = distinct !DICompositeType(tag: DW_TAG_structure_type, name: "S117", file: !3, line: 118, size: 32, flags: DIFlagTypePassByValue, elements: !31, identifier: "_ZTS4S117") +!31 = !{!32} +!32 = !DIDerivedType(tag: DW_TAG_member, name: "s116", scope: !30, file: !3, line: 118, baseType: !33, size: 32) +!33 = distinct !DICompositeType(tag: DW_TAG_structure_type, name: "S116", file: !3, line: 117, size: 32, flags: DIFlagTypePassByValue, elements: !34, identifier: "_ZTS4S116") +!34 = !{!35} +!35 = !DIDerivedType(tag: DW_TAG_member, name: "s115", scope: !33, file: !3, line: 117, baseType: !36, size: 32) +!36 = distinct !DICompositeType(tag: DW_TAG_structure_type, name: "S115", file: !3, line: 116, size: 32, flags: DIFlagTypePassByValue, elements: !37, identifier: "_ZTS4S115") +!37 = !{!38} +!38 = !DIDerivedType(tag: DW_TAG_member, name: "s114", scope: !36, file: !3, line: 116, baseType: !39, size: 32) +!39 = distinct !DICompositeType(tag: DW_TAG_structure_type, name: "S114", file: !3, line: 115, size: 32, flags: DIFlagTypePassByValue, elements: !40, identifier: "_ZTS4S114") +!40 = !{!41} +!41 = !DIDerivedType(tag: DW_TAG_member, name: "s113", scope: !39, file: !3, line: 115, baseType: !42, size: 32) +!42 = distinct !DICompositeType(tag: DW_TAG_structure_type, name: "S113", file: !3, line: 114, size: 32, flags: DIFlagTypePassByValue, elements: !43, identifier: "_ZTS4S113") +!43 = !{!44} +!44 = !DIDerivedType(tag: DW_TAG_member, name: "s112", scope: !42, file: !3, line: 114, baseType: !45, size: 32) +!45 = distinct !DICompositeType(tag: DW_TAG_structure_type, name: "S112", file: !3, line: 113, size: 32, flags: DIFlagTypePassByValue, elements: !46, identifier: "_ZTS4S112") +!46 = !{!47} +!47 = !DIDerivedType(tag: DW_TAG_member, name: "s111", scope: !45, file: !3, line: 113, baseType: !48, size: 32) +!48 = distinct !DICompositeType(tag: DW_TAG_structure_type, name: "S111", file: !3, line: 112, size: 32, flags: DIFlagTypePassByValue, elements: !49, identifier: "_ZTS4S111") +!49 = !{!50} +!50 = !DIDerivedType(tag: DW_TAG_member, name: "s110", scope: !48, file: !3, line: 112, baseType: !51, size: 32) +!51 = distinct !DICompositeType(tag: DW_TAG_structure_type, name: "S110", file: !3, line: 111, size: 32, flags: DIFlagTypePassByValue, elements: !52, identifier: "_ZTS4S110") +!52 = !{!53} +!53 = !DIDerivedType(tag: DW_TAG_member, name: "s109", scope: !51, file: !3, line: 111, baseType: !54, size: 32) +!54 = distinct !DICompositeType(tag: DW_TAG_structure_type, name: "S109", file: !3, line: 110, size: 32, flags: DIFlagTypePassByValue, elements: !55, identifier: "_ZTS4S109") +!55 = !{!56} +!56 = !DIDerivedType(tag: DW_TAG_member, name: "s108", scope: !54, file: !3, line: 110, baseType: !57, size: 32) +!57 = distinct !DICompositeType(tag: DW_TAG_structure_type, name: "S108", file: !3, line: 109, size: 32, flags: DIFlagTypePassByValue, elements: !58, identifier: "_ZTS4S108") +!58 = !{!59} +!59 = !DIDerivedType(tag: DW_TAG_member, name: "s107", scope: !57, file: !3, line: 109, baseType: !60, size: 32) +!60 = distinct !DICompositeType(tag: DW_TAG_structure_type, name: "S107", file: !3, line: 108, size: 32, flags: DIFlagTypePassByValue, elements: !61, identifier: "_ZTS4S107") +!61 = !{!62} +!62 = !DIDerivedType(tag: DW_TAG_member, name: "s106", scope: !60, file: !3, line: 108, baseType: !63, size: 32) +!63 = distinct !DICompositeType(tag: DW_TAG_structure_type, name: "S106", file: !3, line: 107, size: 32, flags: DIFlagTypePassByValue, elements: !64, identifier: "_ZTS4S106") +!64 = !{!65} +!65 = !DIDerivedType(tag: DW_TAG_member, name: "s105", scope: !63, file: !3, line: 107, baseType: !66, size: 32) +!66 = distinct !DICompositeType(tag: DW_TAG_structure_type, name: "S105", file: !3, line: 106, size: 32, flags: DIFlagTypePassByValue, elements: !67, identifier: "_ZTS4S105") +!67 = !{!68} +!68 = !DIDerivedType(tag: DW_TAG_member, name: "s104", scope: !66, file: !3, line: 106, baseType: !69, size: 32) +!69 = distinct !DICompositeType(tag: DW_TAG_structure_type, name: "S104", file: !3, line: 105, size: 32, flags: DIFlagTypePassByValue, elements: !70, identifier: "_ZTS4S104") +!70 = !{!71} +!71 = !DIDerivedType(tag: DW_TAG_member, name: "s103", scope: !69, file: !3, line: 105, baseType: !72, size: 32) +!72 = distinct !DICompositeType(tag: DW_TAG_structure_type, name: "S103", file: !3, line: 104, size: 32, flags: DIFlagTypePassByValue, elements: !73, identifier: "_ZTS4S103") +!73 = !{!74} +!74 = !DIDerivedType(tag: DW_TAG_member, name: "s102", scope: !72, file: !3, line: 104, baseType: !75, size: 32) +!75 = distinct !DICompositeType(tag: DW_TAG_structure_type, name: "S102", file: !3, line: 103, size: 32, flags: DIFlagTypePassByValue, elements: !76, identifier: "_ZTS4S102") +!76 = !{!77} +!77 = !DIDerivedType(tag: DW_TAG_member, name: "s101", scope: !75, file: !3, line: 103, baseType: !78, size: 32) +!78 = distinct !DICompositeType(tag: DW_TAG_structure_type, name: "S101", file: !3, line: 102, size: 32, flags: DIFlagTypePassByValue, elements: !79, identifier: "_ZTS4S101") +!79 = !{!80} +!80 = !DIDerivedType(tag: DW_TAG_member, name: "s100", scope: !78, file: !3, line: 102, baseType: !81, size: 32) +!81 = distinct !DICompositeType(tag: DW_TAG_structure_type, name: "S100", file: !3, line: 101, size: 32, flags: DIFlagTypePassByValue, elements: !82, identifier: "_ZTS4S100") +!82 = !{!83} +!83 = !DIDerivedType(tag: DW_TAG_member, name: "s99", scope: !81, file: !3, line: 101, baseType: !84, size: 32) +!84 = distinct !DICompositeType(tag: DW_TAG_structure_type, name: "S99", file: !3, line: 100, size: 32, flags: DIFlagTypePassByValue, elements: !85, identifier: "_ZTS3S99") +!85 = !{!86} +!86 = !DIDerivedType(tag: DW_TAG_member, name: "s98", scope: !84, file: !3, line: 100, baseType: !87, size: 32) +!87 = distinct !DICompositeType(tag: DW_TAG_structure_type, name: "S98", file: !3, line: 99, size: 32, flags: DIFlagTypePassByValue, elements: !88, identifier: "_ZTS3S98") +!88 = !{!89} +!89 = !DIDerivedType(tag: DW_TAG_member, name: "s97", scope: !87, file: !3, line: 99, baseType: !90, size: 32) +!90 = distinct !DICompositeType(tag: DW_TAG_structure_type, name: "S97", file: !3, line: 98, size: 32, flags: DIFlagTypePassByValue, elements: !91, identifier: "_ZTS3S97") +!91 = !{!92} +!92 = !DIDerivedType(tag: DW_TAG_member, name: "s96", scope: !90, file: !3, line: 98, baseType: !93, size: 32) +!93 = distinct !DICompositeType(tag: DW_TAG_structure_type, name: "S96", file: !3, line: 97, size: 32, flags: DIFlagTypePassByValue, elements: !94, identifier: "_ZTS3S96") +!94 = !{!95} +!95 = !DIDerivedType(tag: DW_TAG_member, name: "s95", scope: !93, file: !3, line: 97, baseType: !96, size: 32) +!96 = distinct !DICompositeType(tag: DW_TAG_structure_type, name: "S95", file: !3, line: 96, size: 32, flags: DIFlagTypePassByValue, elements: !97, identifier: "_ZTS3S95") +!97 = !{!98} +!98 = !DIDerivedType(tag: DW_TAG_member, name: "s94", scope: !96, file: !3, line: 96, baseType: !99, size: 32) +!99 = distinct !DICompositeType(tag: DW_TAG_structure_type, name: "S94", file: !3, line: 95, size: 32, flags: DIFlagTypePassByValue, elements: !100, identifier: "_ZTS3S94") +!100 = !{!101} +!101 = !DIDerivedType(tag: DW_TAG_member, name: "s93", scope: !99, file: !3, line: 95, baseType: !102, size: 32) +!102 = distinct !DICompositeType(tag: DW_TAG_structure_type, name: "S93", file: !3, line: 94, size: 32, flags: DIFlagTypePassByValue, elements: !103, identifier: "_ZTS3S93") +!103 = !{!104} +!104 = !DIDerivedType(tag: DW_TAG_member, name: "s92", scope: !102, file: !3, line: 94, baseType: !105, size: 32) +!105 = distinct !DICompositeType(tag: DW_TAG_structure_type, name: "S92", file: !3, line: 93, size: 32, flags: DIFlagTypePassByValue, elements: !106, identifier: "_ZTS3S92") +!106 = !{!107} +!107 = !DIDerivedType(tag: DW_TAG_member, name: "s91", scope: !105, file: !3, line: 93, baseType: !108, size: 32) +!108 = distinct !DICompositeType(tag: DW_TAG_structure_type, name: "S91", file: !3, line: 92, size: 32, flags: DIFlagTypePassByValue, elements: !109, identifier: "_ZTS3S91") +!109 = !{!110} +!110 = !DIDerivedType(tag: DW_TAG_member, name: "s90", scope: !108, file: !3, line: 92, baseType: !111, size: 32) +!111 = distinct !DICompositeType(tag: DW_TAG_structure_type, name: "S90", file: !3, line: 91, size: 32, flags: DIFlagTypePassByValue, elements: !112, identifier: "_ZTS3S90") +!112 = !{!113} +!113 = !DIDerivedType(tag: DW_TAG_member, name: "s89", scope: !111, file: !3, line: 91, baseType: !114, size: 32) +!114 = distinct !DICompositeType(tag: DW_TAG_structure_type, name: "S89", file: !3, line: 90, size: 32, flags: DIFlagTypePassByValue, elements: !115, identifier: "_ZTS3S89") +!115 = !{!116} +!116 = !DIDerivedType(tag: DW_TAG_member, name: "s88", scope: !114, file: !3, line: 90, baseType: !117, size: 32) +!117 = distinct !DICompositeType(tag: DW_TAG_structure_type, name: "S88", file: !3, line: 89, size: 32, flags: DIFlagTypePassByValue, elements: !118, identifier: "_ZTS3S88") +!118 = !{!119} +!119 = !DIDerivedType(tag: DW_TAG_member, name: "s87", scope: !117, file: !3, line: 89, baseType: !120, size: 32) +!120 = distinct !DICompositeType(tag: DW_TAG_structure_type, name: "S87", file: !3, line: 88, size: 32, flags: DIFlagTypePassByValue, elements: !121, identifier: "_ZTS3S87") +!121 = !{!122} +!122 = !DIDerivedType(tag: DW_TAG_member, name: "s86", scope: !120, file: !3, line: 88, baseType: !123, size: 32) +!123 = distinct !DICompositeType(tag: DW_TAG_structure_type, name: "S86", file: !3, line: 87, size: 32, flags: DIFlagTypePassByValue, elements: !124, identifier: "_ZTS3S86") +!124 = !{!125} +!125 = !DIDerivedType(tag: DW_TAG_member, name: "s85", scope: !123, file: !3, line: 87, baseType: !126, size: 32) +!126 = distinct !DICompositeType(tag: DW_TAG_structure_type, name: "S85", file: !3, line: 86, size: 32, flags: DIFlagTypePassByValue, elements: !127, identifier: "_ZTS3S85") +!127 = !{!128} +!128 = !DIDerivedType(tag: DW_TAG_member, name: "s84", scope: !126, file: !3, line: 86, baseType: !129, size: 32) +!129 = distinct !DICompositeType(tag: DW_TAG_structure_type, name: "S84", file: !3, line: 85, size: 32, flags: DIFlagTypePassByValue, elements: !130, identifier: "_ZTS3S84") +!130 = !{!131} +!131 = !DIDerivedType(tag: DW_TAG_member, name: "s83", scope: !129, file: !3, line: 85, baseType: !132, size: 32) +!132 = distinct !DICompositeType(tag: DW_TAG_structure_type, name: "S83", file: !3, line: 84, size: 32, flags: DIFlagTypePassByValue, elements: !133, identifier: "_ZTS3S83") +!133 = !{!134} +!134 = !DIDerivedType(tag: DW_TAG_member, name: "s82", scope: !132, file: !3, line: 84, baseType: !135, size: 32) +!135 = distinct !DICompositeType(tag: DW_TAG_structure_type, name: "S82", file: !3, line: 83, size: 32, flags: DIFlagTypePassByValue, elements: !136, identifier: "_ZTS3S82") +!136 = !{!137} +!137 = !DIDerivedType(tag: DW_TAG_member, name: "s81", scope: !135, file: !3, line: 83, baseType: !138, size: 32) +!138 = distinct !DICompositeType(tag: DW_TAG_structure_type, name: "S81", file: !3, line: 82, size: 32, flags: DIFlagTypePassByValue, elements: !139, identifier: "_ZTS3S81") +!139 = !{!140} +!140 = !DIDerivedType(tag: DW_TAG_member, name: "s80", scope: !138, file: !3, line: 82, baseType: !141, size: 32) +!141 = distinct !DICompositeType(tag: DW_TAG_structure_type, name: "S80", file: !3, line: 81, size: 32, flags: DIFlagTypePassByValue, elements: !142, identifier: "_ZTS3S80") +!142 = !{!143} +!143 = !DIDerivedType(tag: DW_TAG_member, name: "s79", scope: !141, file: !3, line: 81, baseType: !144, size: 32) +!144 = distinct !DICompositeType(tag: DW_TAG_structure_type, name: "S79", file: !3, line: 80, size: 32, flags: DIFlagTypePassByValue, elements: !145, identifier: "_ZTS3S79") +!145 = !{!146} +!146 = !DIDerivedType(tag: DW_TAG_member, name: "s78", scope: !144, file: !3, line: 80, baseType: !147, size: 32) +!147 = distinct !DICompositeType(tag: DW_TAG_structure_type, name: "S78", file: !3, line: 79, size: 32, flags: DIFlagTypePassByValue, elements: !148, identifier: "_ZTS3S78") +!148 = !{!149} +!149 = !DIDerivedType(tag: DW_TAG_member, name: "s77", scope: !147, file: !3, line: 79, baseType: !150, size: 32) +!150 = distinct !DICompositeType(tag: DW_TAG_structure_type, name: "S77", file: !3, line: 78, size: 32, flags: DIFlagTypePassByValue, elements: !151, identifier: "_ZTS3S77") +!151 = !{!152} +!152 = !DIDerivedType(tag: DW_TAG_member, name: "s76", scope: !150, file: !3, line: 78, baseType: !153, size: 32) +!153 = distinct !DICompositeType(tag: DW_TAG_structure_type, name: "S76", file: !3, line: 77, size: 32, flags: DIFlagTypePassByValue, elements: !154, identifier: "_ZTS3S76") +!154 = !{!155} +!155 = !DIDerivedType(tag: DW_TAG_member, name: "s75", scope: !153, file: !3, line: 77, baseType: !156, size: 32) +!156 = distinct !DICompositeType(tag: DW_TAG_structure_type, name: "S75", file: !3, line: 76, size: 32, flags: DIFlagTypePassByValue, elements: !157, identifier: "_ZTS3S75") +!157 = !{!158} +!158 = !DIDerivedType(tag: DW_TAG_member, name: "s74", scope: !156, file: !3, line: 76, baseType: !159, size: 32) +!159 = distinct !DICompositeType(tag: DW_TAG_structure_type, name: "S74", file: !3, line: 75, size: 32, flags: DIFlagTypePassByValue, elements: !160, identifier: "_ZTS3S74") +!160 = !{!161} +!161 = !DIDerivedType(tag: DW_TAG_member, name: "s73", scope: !159, file: !3, line: 75, baseType: !162, size: 32) +!162 = distinct !DICompositeType(tag: DW_TAG_structure_type, name: "S73", file: !3, line: 74, size: 32, flags: DIFlagTypePassByValue, elements: !163, identifier: "_ZTS3S73") +!163 = !{!164} +!164 = !DIDerivedType(tag: DW_TAG_member, name: "s72", scope: !162, file: !3, line: 74, baseType: !165, size: 32) +!165 = distinct !DICompositeType(tag: DW_TAG_structure_type, name: "S72", file: !3, line: 73, size: 32, flags: DIFlagTypePassByValue, elements: !166, identifier: "_ZTS3S72") +!166 = !{!167} +!167 = !DIDerivedType(tag: DW_TAG_member, name: "s71", scope: !165, file: !3, line: 73, baseType: !168, size: 32) +!168 = distinct !DICompositeType(tag: DW_TAG_structure_type, name: "S71", file: !3, line: 72, size: 32, flags: DIFlagTypePassByValue, elements: !169, identifier: "_ZTS3S71") +!169 = !{!170} +!170 = !DIDerivedType(tag: DW_TAG_member, name: "s70", scope: !168, file: !3, line: 72, baseType: !171, size: 32) +!171 = distinct !DICompositeType(tag: DW_TAG_structure_type, name: "S70", file: !3, line: 71, size: 32, flags: DIFlagTypePassByValue, elements: !172, identifier: "_ZTS3S70") +!172 = !{!173} +!173 = !DIDerivedType(tag: DW_TAG_member, name: "s69", scope: !171, file: !3, line: 71, baseType: !174, size: 32) +!174 = distinct !DICompositeType(tag: DW_TAG_structure_type, name: "S69", file: !3, line: 70, size: 32, flags: DIFlagTypePassByValue, elements: !175, identifier: "_ZTS3S69") +!175 = !{!176} +!176 = !DIDerivedType(tag: DW_TAG_member, name: "s68", scope: !174, file: !3, line: 70, baseType: !177, size: 32) +!177 = distinct !DICompositeType(tag: DW_TAG_structure_type, name: "S68", file: !3, line: 69, size: 32, flags: DIFlagTypePassByValue, elements: !178, identifier: "_ZTS3S68") +!178 = !{!179} +!179 = !DIDerivedType(tag: DW_TAG_member, name: "s67", scope: !177, file: !3, line: 69, baseType: !180, size: 32) +!180 = distinct !DICompositeType(tag: DW_TAG_structure_type, name: "S67", file: !3, line: 68, size: 32, flags: DIFlagTypePassByValue, elements: !181, identifier: "_ZTS3S67") +!181 = !{!182} +!182 = !DIDerivedType(tag: DW_TAG_member, name: "s66", scope: !180, file: !3, line: 68, baseType: !183, size: 32) +!183 = distinct !DICompositeType(tag: DW_TAG_structure_type, name: "S66", file: !3, line: 67, size: 32, flags: DIFlagTypePassByValue, elements: !184, identifier: "_ZTS3S66") +!184 = !{!185} +!185 = !DIDerivedType(tag: DW_TAG_member, name: "s65", scope: !183, file: !3, line: 67, baseType: !186, size: 32) +!186 = distinct !DICompositeType(tag: DW_TAG_structure_type, name: "S65", file: !3, line: 66, size: 32, flags: DIFlagTypePassByValue, elements: !187, identifier: "_ZTS3S65") +!187 = !{!188} +!188 = !DIDerivedType(tag: DW_TAG_member, name: "s64", scope: !186, file: !3, line: 66, baseType: !189, size: 32) +!189 = distinct !DICompositeType(tag: DW_TAG_structure_type, name: "S64", file: !3, line: 65, size: 32, flags: DIFlagTypePassByValue, elements: !190, identifier: "_ZTS3S64") +!190 = !{!191} +!191 = !DIDerivedType(tag: DW_TAG_member, name: "s63", scope: !189, file: !3, line: 65, baseType: !192, size: 32) +!192 = distinct !DICompositeType(tag: DW_TAG_structure_type, name: "S63", file: !3, line: 64, size: 32, flags: DIFlagTypePassByValue, elements: !193, identifier: "_ZTS3S63") +!193 = !{!194} +!194 = !DIDerivedType(tag: DW_TAG_member, name: "s62", scope: !192, file: !3, line: 64, baseType: !195, size: 32) +!195 = distinct !DICompositeType(tag: DW_TAG_structure_type, name: "S62", file: !3, line: 63, size: 32, flags: DIFlagTypePassByValue, elements: !196, identifier: "_ZTS3S62") +!196 = !{!197} +!197 = !DIDerivedType(tag: DW_TAG_member, name: "s61", scope: !195, file: !3, line: 63, baseType: !198, size: 32) +!198 = distinct !DICompositeType(tag: DW_TAG_structure_type, name: "S61", file: !3, line: 62, size: 32, flags: DIFlagTypePassByValue, elements: !199, identifier: "_ZTS3S61") +!199 = !{!200} +!200 = !DIDerivedType(tag: DW_TAG_member, name: "s60", scope: !198, file: !3, line: 62, baseType: !201, size: 32) +!201 = distinct !DICompositeType(tag: DW_TAG_structure_type, name: "S60", file: !3, line: 61, size: 32, flags: DIFlagTypePassByValue, elements: !202, identifier: "_ZTS3S60") +!202 = !{!203} +!203 = !DIDerivedType(tag: DW_TAG_member, name: "s59", scope: !201, file: !3, line: 61, baseType: !204, size: 32) +!204 = distinct !DICompositeType(tag: DW_TAG_structure_type, name: "S59", file: !3, line: 60, size: 32, flags: DIFlagTypePassByValue, elements: !205, identifier: "_ZTS3S59") +!205 = !{!206} +!206 = !DIDerivedType(tag: DW_TAG_member, name: "s58", scope: !204, file: !3, line: 60, baseType: !207, size: 32) +!207 = distinct !DICompositeType(tag: DW_TAG_structure_type, name: "S58", file: !3, line: 59, size: 32, flags: DIFlagTypePassByValue, elements: !208, identifier: "_ZTS3S58") +!208 = !{!209} +!209 = !DIDerivedType(tag: DW_TAG_member, name: "s57", scope: !207, file: !3, line: 59, baseType: !210, size: 32) +!210 = distinct !DICompositeType(tag: DW_TAG_structure_type, name: "S57", file: !3, line: 58, size: 32, flags: DIFlagTypePassByValue, elements: !211, identifier: "_ZTS3S57") +!211 = !{!212} +!212 = !DIDerivedType(tag: DW_TAG_member, name: "s56", scope: !210, file: !3, line: 58, baseType: !213, size: 32) +!213 = distinct !DICompositeType(tag: DW_TAG_structure_type, name: "S56", file: !3, line: 57, size: 32, flags: DIFlagTypePassByValue, elements: !214, identifier: "_ZTS3S56") +!214 = !{!215} +!215 = !DIDerivedType(tag: DW_TAG_member, name: "s55", scope: !213, file: !3, line: 57, baseType: !216, size: 32) +!216 = distinct !DICompositeType(tag: DW_TAG_structure_type, name: "S55", file: !3, line: 56, size: 32, flags: DIFlagTypePassByValue, elements: !217, identifier: "_ZTS3S55") +!217 = !{!218} +!218 = !DIDerivedType(tag: DW_TAG_member, name: "s54", scope: !216, file: !3, line: 56, baseType: !219, size: 32) +!219 = distinct !DICompositeType(tag: DW_TAG_structure_type, name: "S54", file: !3, line: 55, size: 32, flags: DIFlagTypePassByValue, elements: !220, identifier: "_ZTS3S54") +!220 = !{!221} +!221 = !DIDerivedType(tag: DW_TAG_member, name: "s53", scope: !219, file: !3, line: 55, baseType: !222, size: 32) +!222 = distinct !DICompositeType(tag: DW_TAG_structure_type, name: "S53", file: !3, line: 54, size: 32, flags: DIFlagTypePassByValue, elements: !223, identifier: "_ZTS3S53") +!223 = !{!224} +!224 = !DIDerivedType(tag: DW_TAG_member, name: "s52", scope: !222, file: !3, line: 54, baseType: !225, size: 32) +!225 = distinct !DICompositeType(tag: DW_TAG_structure_type, name: "S52", file: !3, line: 53, size: 32, flags: DIFlagTypePassByValue, elements: !226, identifier: "_ZTS3S52") +!226 = !{!227} +!227 = !DIDerivedType(tag: DW_TAG_member, name: "s51", scope: !225, file: !3, line: 53, baseType: !228, size: 32) +!228 = distinct !DICompositeType(tag: DW_TAG_structure_type, name: "S51", file: !3, line: 52, size: 32, flags: DIFlagTypePassByValue, elements: !229, identifier: "_ZTS3S51") +!229 = !{!230} +!230 = !DIDerivedType(tag: DW_TAG_member, name: "s50", scope: !228, file: !3, line: 52, baseType: !231, size: 32) +!231 = distinct !DICompositeType(tag: DW_TAG_structure_type, name: "S50", file: !3, line: 51, size: 32, flags: DIFlagTypePassByValue, elements: !232, identifier: "_ZTS3S50") +!232 = !{!233} +!233 = !DIDerivedType(tag: DW_TAG_member, name: "s49", scope: !231, file: !3, line: 51, baseType: !234, size: 32) +!234 = distinct !DICompositeType(tag: DW_TAG_structure_type, name: "S49", file: !3, line: 50, size: 32, flags: DIFlagTypePassByValue, elements: !235, identifier: "_ZTS3S49") +!235 = !{!236} +!236 = !DIDerivedType(tag: DW_TAG_member, name: "s48", scope: !234, file: !3, line: 50, baseType: !237, size: 32) +!237 = distinct !DICompositeType(tag: DW_TAG_structure_type, name: "S48", file: !3, line: 49, size: 32, flags: DIFlagTypePassByValue, elements: !238, identifier: "_ZTS3S48") +!238 = !{!239} +!239 = !DIDerivedType(tag: DW_TAG_member, name: "s47", scope: !237, file: !3, line: 49, baseType: !240, size: 32) +!240 = distinct !DICompositeType(tag: DW_TAG_structure_type, name: "S47", file: !3, line: 48, size: 32, flags: DIFlagTypePassByValue, elements: !241, identifier: "_ZTS3S47") +!241 = !{!242} +!242 = !DIDerivedType(tag: DW_TAG_member, name: "s46", scope: !240, file: !3, line: 48, baseType: !243, size: 32) +!243 = distinct !DICompositeType(tag: DW_TAG_structure_type, name: "S46", file: !3, line: 47, size: 32, flags: DIFlagTypePassByValue, elements: !244, identifier: "_ZTS3S46") +!244 = !{!245} +!245 = !DIDerivedType(tag: DW_TAG_member, name: "s45", scope: !243, file: !3, line: 47, baseType: !246, size: 32) +!246 = distinct !DICompositeType(tag: DW_TAG_structure_type, name: "S45", file: !3, line: 46, size: 32, flags: DIFlagTypePassByValue, elements: !247, identifier: "_ZTS3S45") +!247 = !{!248} +!248 = !DIDerivedType(tag: DW_TAG_member, name: "s44", scope: !246, file: !3, line: 46, baseType: !249, size: 32) +!249 = distinct !DICompositeType(tag: DW_TAG_structure_type, name: "S44", file: !3, line: 45, size: 32, flags: DIFlagTypePassByValue, elements: !250, identifier: "_ZTS3S44") +!250 = !{!251} +!251 = !DIDerivedType(tag: DW_TAG_member, name: "s43", scope: !249, file: !3, line: 45, baseType: !252, size: 32) +!252 = distinct !DICompositeType(tag: DW_TAG_structure_type, name: "S43", file: !3, line: 44, size: 32, flags: DIFlagTypePassByValue, elements: !253, identifier: "_ZTS3S43") +!253 = !{!254} +!254 = !DIDerivedType(tag: DW_TAG_member, name: "s42", scope: !252, file: !3, line: 44, baseType: !255, size: 32) +!255 = distinct !DICompositeType(tag: DW_TAG_structure_type, name: "S42", file: !3, line: 43, size: 32, flags: DIFlagTypePassByValue, elements: !256, identifier: "_ZTS3S42") +!256 = !{!257} +!257 = !DIDerivedType(tag: DW_TAG_member, name: "s41", scope: !255, file: !3, line: 43, baseType: !258, size: 32) +!258 = distinct !DICompositeType(tag: DW_TAG_structure_type, name: "S41", file: !3, line: 42, size: 32, flags: DIFlagTypePassByValue, elements: !259, identifier: "_ZTS3S41") +!259 = !{!260} +!260 = !DIDerivedType(tag: DW_TAG_member, name: "s40", scope: !258, file: !3, line: 42, baseType: !261, size: 32) +!261 = distinct !DICompositeType(tag: DW_TAG_structure_type, name: "S40", file: !3, line: 41, size: 32, flags: DIFlagTypePassByValue, elements: !262, identifier: "_ZTS3S40") +!262 = !{!263} +!263 = !DIDerivedType(tag: DW_TAG_member, name: "s39", scope: !261, file: !3, line: 41, baseType: !264, size: 32) +!264 = distinct !DICompositeType(tag: DW_TAG_structure_type, name: "S39", file: !3, line: 40, size: 32, flags: DIFlagTypePassByValue, elements: !265, identifier: "_ZTS3S39") +!265 = !{!266} +!266 = !DIDerivedType(tag: DW_TAG_member, name: "s38", scope: !264, file: !3, line: 40, baseType: !267, size: 32) +!267 = distinct !DICompositeType(tag: DW_TAG_structure_type, name: "S38", file: !3, line: 39, size: 32, flags: DIFlagTypePassByValue, elements: !268, identifier: "_ZTS3S38") +!268 = !{!269} +!269 = !DIDerivedType(tag: DW_TAG_member, name: "s37", scope: !267, file: !3, line: 39, baseType: !270, size: 32) +!270 = distinct !DICompositeType(tag: DW_TAG_structure_type, name: "S37", file: !3, line: 38, size: 32, flags: DIFlagTypePassByValue, elements: !271, identifier: "_ZTS3S37") +!271 = !{!272} +!272 = !DIDerivedType(tag: DW_TAG_member, name: "s36", scope: !270, file: !3, line: 38, baseType: !273, size: 32) +!273 = distinct !DICompositeType(tag: DW_TAG_structure_type, name: "S36", file: !3, line: 37, size: 32, flags: DIFlagTypePassByValue, elements: !274, identifier: "_ZTS3S36") +!274 = !{!275} +!275 = !DIDerivedType(tag: DW_TAG_member, name: "s35", scope: !273, file: !3, line: 37, baseType: !276, size: 32) +!276 = distinct !DICompositeType(tag: DW_TAG_structure_type, name: "S35", file: !3, line: 36, size: 32, flags: DIFlagTypePassByValue, elements: !277, identifier: "_ZTS3S35") +!277 = !{!278} +!278 = !DIDerivedType(tag: DW_TAG_member, name: "s34", scope: !276, file: !3, line: 36, baseType: !279, size: 32) +!279 = distinct !DICompositeType(tag: DW_TAG_structure_type, name: "S34", file: !3, line: 35, size: 32, flags: DIFlagTypePassByValue, elements: !280, identifier: "_ZTS3S34") +!280 = !{!281} +!281 = !DIDerivedType(tag: DW_TAG_member, name: "s33", scope: !279, file: !3, line: 35, baseType: !282, size: 32) +!282 = distinct !DICompositeType(tag: DW_TAG_structure_type, name: "S33", file: !3, line: 34, size: 32, flags: DIFlagTypePassByValue, elements: !283, identifier: "_ZTS3S33") +!283 = !{!284} +!284 = !DIDerivedType(tag: DW_TAG_member, name: "s32", scope: !282, file: !3, line: 34, baseType: !285, size: 32) +!285 = distinct !DICompositeType(tag: DW_TAG_structure_type, name: "S32", file: !3, line: 33, size: 32, flags: DIFlagTypePassByValue, elements: !286, identifier: "_ZTS3S32") +!286 = !{!287} +!287 = !DIDerivedType(tag: DW_TAG_member, name: "s31", scope: !285, file: !3, line: 33, baseType: !288, size: 32) +!288 = distinct !DICompositeType(tag: DW_TAG_structure_type, name: "S31", file: !3, line: 32, size: 32, flags: DIFlagTypePassByValue, elements: !289, identifier: "_ZTS3S31") +!289 = !{!290} +!290 = !DIDerivedType(tag: DW_TAG_member, name: "s30", scope: !288, file: !3, line: 32, baseType: !291, size: 32) +!291 = distinct !DICompositeType(tag: DW_TAG_structure_type, name: "S30", file: !3, line: 31, size: 32, flags: DIFlagTypePassByValue, elements: !292, identifier: "_ZTS3S30") +!292 = !{!293} +!293 = !DIDerivedType(tag: DW_TAG_member, name: "s29", scope: !291, file: !3, line: 31, baseType: !294, size: 32) +!294 = distinct !DICompositeType(tag: DW_TAG_structure_type, name: "S29", file: !3, line: 30, size: 32, flags: DIFlagTypePassByValue, elements: !295, identifier: "_ZTS3S29") +!295 = !{!296} +!296 = !DIDerivedType(tag: DW_TAG_member, name: "s28", scope: !294, file: !3, line: 30, baseType: !297, size: 32) +!297 = distinct !DICompositeType(tag: DW_TAG_structure_type, name: "S28", file: !3, line: 29, size: 32, flags: DIFlagTypePassByValue, elements: !298, identifier: "_ZTS3S28") +!298 = !{!299} +!299 = !DIDerivedType(tag: DW_TAG_member, name: "s27", scope: !297, file: !3, line: 29, baseType: !300, size: 32) +!300 = distinct !DICompositeType(tag: DW_TAG_structure_type, name: "S27", file: !3, line: 28, size: 32, flags: DIFlagTypePassByValue, elements: !301, identifier: "_ZTS3S27") +!301 = !{!302} +!302 = !DIDerivedType(tag: DW_TAG_member, name: "s26", scope: !300, file: !3, line: 28, baseType: !303, size: 32) +!303 = distinct !DICompositeType(tag: DW_TAG_structure_type, name: "S26", file: !3, line: 27, size: 32, flags: DIFlagTypePassByValue, elements: !304, identifier: "_ZTS3S26") +!304 = !{!305} +!305 = !DIDerivedType(tag: DW_TAG_member, name: "s25", scope: !303, file: !3, line: 27, baseType: !306, size: 32) +!306 = distinct !DICompositeType(tag: DW_TAG_structure_type, name: "S25", file: !3, line: 26, size: 32, flags: DIFlagTypePassByValue, elements: !307, identifier: "_ZTS3S25") +!307 = !{!308} +!308 = !DIDerivedType(tag: DW_TAG_member, name: "s24", scope: !306, file: !3, line: 26, baseType: !309, size: 32) +!309 = distinct !DICompositeType(tag: DW_TAG_structure_type, name: "S24", file: !3, line: 25, size: 32, flags: DIFlagTypePassByValue, elements: !310, identifier: "_ZTS3S24") +!310 = !{!311} +!311 = !DIDerivedType(tag: DW_TAG_member, name: "s23", scope: !309, file: !3, line: 25, baseType: !312, size: 32) +!312 = distinct !DICompositeType(tag: DW_TAG_structure_type, name: "S23", file: !3, line: 24, size: 32, flags: DIFlagTypePassByValue, elements: !313, identifier: "_ZTS3S23") +!313 = !{!314} +!314 = !DIDerivedType(tag: DW_TAG_member, name: "s22", scope: !312, file: !3, line: 24, baseType: !315, size: 32) +!315 = distinct !DICompositeType(tag: DW_TAG_structure_type, name: "S22", file: !3, line: 23, size: 32, flags: DIFlagTypePassByValue, elements: !316, identifier: "_ZTS3S22") +!316 = !{!317} +!317 = !DIDerivedType(tag: DW_TAG_member, name: "s21", scope: !315, file: !3, line: 23, baseType: !318, size: 32) +!318 = distinct !DICompositeType(tag: DW_TAG_structure_type, name: "S21", file: !3, line: 22, size: 32, flags: DIFlagTypePassByValue, elements: !319, identifier: "_ZTS3S21") +!319 = !{!320} +!320 = !DIDerivedType(tag: DW_TAG_member, name: "s20", scope: !318, file: !3, line: 22, baseType: !321, size: 32) +!321 = distinct !DICompositeType(tag: DW_TAG_structure_type, name: "S20", file: !3, line: 21, size: 32, flags: DIFlagTypePassByValue, elements: !322, identifier: "_ZTS3S20") +!322 = !{!323} +!323 = !DIDerivedType(tag: DW_TAG_member, name: "s19", scope: !321, file: !3, line: 21, baseType: !324, size: 32) +!324 = distinct !DICompositeType(tag: DW_TAG_structure_type, name: "S19", file: !3, line: 20, size: 32, flags: DIFlagTypePassByValue, elements: !325, identifier: "_ZTS3S19") +!325 = !{!326} +!326 = !DIDerivedType(tag: DW_TAG_member, name: "s18", scope: !324, file: !3, line: 20, baseType: !327, size: 32) +!327 = distinct !DICompositeType(tag: DW_TAG_structure_type, name: "S18", file: !3, line: 19, size: 32, flags: DIFlagTypePassByValue, elements: !328, identifier: "_ZTS3S18") +!328 = !{!329} +!329 = !DIDerivedType(tag: DW_TAG_member, name: "s17", scope: !327, file: !3, line: 19, baseType: !330, size: 32) +!330 = distinct !DICompositeType(tag: DW_TAG_structure_type, name: "S17", file: !3, line: 18, size: 32, flags: DIFlagTypePassByValue, elements: !331, identifier: "_ZTS3S17") +!331 = !{!332} +!332 = !DIDerivedType(tag: DW_TAG_member, name: "s16", scope: !330, file: !3, line: 18, baseType: !333, size: 32) +!333 = distinct !DICompositeType(tag: DW_TAG_structure_type, name: "S16", file: !3, line: 17, size: 32, flags: DIFlagTypePassByValue, elements: !334, identifier: "_ZTS3S16") +!334 = !{!335} +!335 = !DIDerivedType(tag: DW_TAG_member, name: "s15", scope: !333, file: !3, line: 17, baseType: !336, size: 32) +!336 = distinct !DICompositeType(tag: DW_TAG_structure_type, name: "S15", file: !3, line: 16, size: 32, flags: DIFlagTypePassByValue, elements: !337, identifier: "_ZTS3S15") +!337 = !{!338} +!338 = !DIDerivedType(tag: DW_TAG_member, name: "s14", scope: !336, file: !3, line: 16, baseType: !339, size: 32) +!339 = distinct !DICompositeType(tag: DW_TAG_structure_type, name: "S14", file: !3, line: 15, size: 32, flags: DIFlagTypePassByValue, elements: !340, identifier: "_ZTS3S14") +!340 = !{!341} +!341 = !DIDerivedType(tag: DW_TAG_member, name: "s13", scope: !339, file: !3, line: 15, baseType: !342, size: 32) +!342 = distinct !DICompositeType(tag: DW_TAG_structure_type, name: "S13", file: !3, line: 14, size: 32, flags: DIFlagTypePassByValue, elements: !343, identifier: "_ZTS3S13") +!343 = !{!344} +!344 = !DIDerivedType(tag: DW_TAG_member, name: "s12", scope: !342, file: !3, line: 14, baseType: !345, size: 32) +!345 = distinct !DICompositeType(tag: DW_TAG_structure_type, name: "S12", file: !3, line: 13, size: 32, flags: DIFlagTypePassByValue, elements: !346, identifier: "_ZTS3S12") +!346 = !{!347} +!347 = !DIDerivedType(tag: DW_TAG_member, name: "s11", scope: !345, file: !3, line: 13, baseType: !348, size: 32) +!348 = distinct !DICompositeType(tag: DW_TAG_structure_type, name: "S11", file: !3, line: 12, size: 32, flags: DIFlagTypePassByValue, elements: !349, identifier: "_ZTS3S11") +!349 = !{!350} +!350 = !DIDerivedType(tag: DW_TAG_member, name: "s10", scope: !348, file: !3, line: 12, baseType: !351, size: 32) +!351 = distinct !DICompositeType(tag: DW_TAG_structure_type, name: "S10", file: !3, line: 11, size: 32, flags: DIFlagTypePassByValue, elements: !352, identifier: "_ZTS3S10") +!352 = !{!353} +!353 = !DIDerivedType(tag: DW_TAG_member, name: "s9", scope: !351, file: !3, line: 11, baseType: !354, size: 32) +!354 = distinct !DICompositeType(tag: DW_TAG_structure_type, name: "S9", file: !3, line: 10, size: 32, flags: DIFlagTypePassByValue, elements: !355, identifier: "_ZTS2S9") +!355 = !{!356} +!356 = !DIDerivedType(tag: DW_TAG_member, name: "s8", scope: !354, file: !3, line: 10, baseType: !357, size: 32) +!357 = distinct !DICompositeType(tag: DW_TAG_structure_type, name: "S8", file: !3, line: 9, size: 32, flags: DIFlagTypePassByValue, elements: !358, identifier: "_ZTS2S8") +!358 = !{!359} +!359 = !DIDerivedType(tag: DW_TAG_member, name: "s7", scope: !357, file: !3, line: 9, baseType: !360, size: 32) +!360 = distinct !DICompositeType(tag: DW_TAG_structure_type, name: "S7", file: !3, line: 8, size: 32, flags: DIFlagTypePassByValue, elements: !361, identifier: "_ZTS2S7") +!361 = !{!362} +!362 = !DIDerivedType(tag: DW_TAG_member, name: "s6", scope: !360, file: !3, line: 8, baseType: !363, size: 32) +!363 = distinct !DICompositeType(tag: DW_TAG_structure_type, name: "S6", file: !3, line: 7, size: 32, flags: DIFlagTypePassByValue, elements: !364, identifier: "_ZTS2S6") +!364 = !{!365} +!365 = !DIDerivedType(tag: DW_TAG_member, name: "s5", scope: !363, file: !3, line: 7, baseType: !366, size: 32) +!366 = distinct !DICompositeType(tag: DW_TAG_structure_type, name: "S5", file: !3, line: 6, size: 32, flags: DIFlagTypePassByValue, elements: !367, identifier: "_ZTS2S5") +!367 = !{!368} +!368 = !DIDerivedType(tag: DW_TAG_member, name: "s4", scope: !366, file: !3, line: 6, baseType: !369, size: 32) +!369 = distinct !DICompositeType(tag: DW_TAG_structure_type, name: "S4", file: !3, line: 5, size: 32, flags: DIFlagTypePassByValue, elements: !370, identifier: "_ZTS2S4") +!370 = !{!371} +!371 = !DIDerivedType(tag: DW_TAG_member, name: "s3", scope: !369, file: !3, line: 5, baseType: !372, size: 32) +!372 = distinct !DICompositeType(tag: DW_TAG_structure_type, name: "S3", file: !3, line: 4, size: 32, flags: DIFlagTypePassByValue, elements: !373, identifier: "_ZTS2S3") +!373 = !{!374} +!374 = !DIDerivedType(tag: DW_TAG_member, name: "s2", scope: !372, file: !3, line: 4, baseType: !375, size: 32) +!375 = distinct !DICompositeType(tag: DW_TAG_structure_type, name: "S2", file: !3, line: 3, size: 32, flags: DIFlagTypePassByValue, elements: !376, identifier: "_ZTS2S2") +!376 = !{!377} +!377 = !DIDerivedType(tag: DW_TAG_member, name: "s1", scope: !375, file: !3, line: 3, baseType: !378, size: 32) +!378 = distinct !DICompositeType(tag: DW_TAG_structure_type, name: "S1", file: !3, line: 2, size: 32, flags: DIFlagTypePassByValue, elements: !379, identifier: "_ZTS2S1") +!379 = !{!380} +!380 = !DIDerivedType(tag: DW_TAG_member, name: "s0", scope: !378, file: !3, line: 2, baseType: !381, size: 32) +!381 = distinct !DICompositeType(tag: DW_TAG_structure_type, name: "S0", file: !3, line: 1, size: 32, flags: DIFlagTypePassByValue, elements: !382, identifier: "_ZTS2S0") +!382 = !{!383} +!383 = !DIDerivedType(tag: DW_TAG_member, name: "i", scope: !381, file: !3, line: 1, baseType: !384, size: 32) +!384 = !DIBasicType(name: "int", size: 32, encoding: DW_ATE_signed) +!385 = !{i32 2, !"Dwarf Version", i32 5} +!386 = !{i32 2, !"Debug Info Version", i32 3} +!387 = !{i32 1, !"wchar_size", i32 4} +!388 = !{!"clang version 7.0.0 (trunk 322295)"} Index: test/DebugInfo/Generic/string-offsets-multiple-cus.ll =================================================================== --- test/DebugInfo/Generic/string-offsets-multiple-cus.ll +++ test/DebugInfo/Generic/string-offsets-multiple-cus.ll @@ -0,0 +1,202 @@ +; RUN: %llc_dwarf -filetype=obj < %s | llvm-dwarfdump -v - | FileCheck --check-prefix=DEFAULT \ +; RUN: --check-prefix=BOTH %s +; RUN: %llc_dwarf -filetype=obj -generate-type-units < %s | llvm-dwarfdump -v - | \ +; RUN: FileCheck --check-prefix=TYPEUNITS --check-prefix=BOTH %s +; +; Check the correct handling of multiple compile and type units with regard to the +; string offset section. +; +; Constructed from the following sources with +; clang -gdwarf-5 -emit-llvm -S a.cpp +; clang -gdwarf-5 -emit-llvm -S b.cpp +; clang -gdwarf-5 -emit-llvm -S c.cpp +; llvm-link a.ll b.ll c.ll -o test.bc +; llvm-dis test.bc -o test.ll +; +; a.cpp: +; int aglob; +; struct A { +; int i; +; float f; +; }; +; +; void afunc(int i) +; { +; A a; +; } +; +; b.cpp: +; int bglob; +; void bfunc(int i) +; { +; } +; +; c.cpp: +; int cglob; +; void cfunc(int j) +; { +; } +; +; +; Check that all 3 compile units have the correct DW_AT_str_offsets_base attributes +; with the correct offsets. +; +; CU 1 +; BOTH: .debug_info contents: +; BOTH-NOT: .contents: +; BOTH: DW_TAG_compile_unit +; BOTH-NOT: {{DW_TAG|NULL}} +; BOTH: DW_AT_str_offsets_base [DW_FORM_sec_offset] (0x[[CU1_STROFF:[0-9a-f]+]]) +; +; CU 2 +; BOTH-NOT: contents: +; BOTH: DW_TAG_compile_unit +; BOTH-NOT: {{DW_TAG|NULL}} +; BOTH: DW_AT_str_offsets_base [DW_FORM_sec_offset] (0x[[CU1_STROFF]]) +; BOTH-NOT: NULL +; BOTH: DW_TAG_variable +; BOTH-NOT: {{DW_TAG|NULL}} +; BOTH: DW_AT_name [DW_FORM_strx1] ( indexed (00000006) string = "bglob") +; +; CU 3 +; BOTH-NOT: contents: +; BOTH: DW_TAG_compile_unit +; BOTH-NOT: {{DW_TAG|NULL}} +; BOTH: DW_AT_str_offsets_base [DW_FORM_sec_offset] (0x[[CU1_STROFF]]) +; BOTH-NOT: NULL +; BOTH: DW_TAG_variable +; BOTH-NOT: {{DW_TAG|NULL}} +; BOTH: DW_AT_name [DW_FORM_strx1] ( indexed (00000008) string = "cglob") +; +; Verify that the type unit has the proper DW_AT_str_offsets_base attribute and +; a segment in the .debug_str_offsets section. +; +; TYPEUNITS: .debug_types contents: +; TYPEUNITS-NOT: contents: +; TYPEUNITS: DW_TAG_type_unit +; TYPEUNITS-NOT: {{DW_TAG|NULL}} +; TYPEUNITS: DW_AT_str_offsets_base [DW_FORM_sec_offset] (0x[[TU_STROFF:[0-9]+]]) +; TYPEUNITS-NOT: NULL +; TYPEUNITS: DW_TAG_member +; TYPEUNITS-NOT: NULL +; TYPEUNITS: DW_TAG_member +; TYPEUNITS-NOT: {{DW_TAG|NULL}} +; TYPEUNITS: DW_AT_name [DW_FORM_strx1] ( indexed (00000011) string = "f") +; +; BOTH: .debug_str contents: +; BOTH-NOT: contents: +; BOTH: 0x[[BGLOBOFF:[0-9a-f]+]]: "bglob" +; +; Check the .debug_str_offsets section +; DEFAULT: .debug_str_offsets contents: +; DEFAULT-NEXT: 0x00000000: Contribution size = 84, Format = DWARF32, Version = 5 +; DEFAULT-NEXT: 0x[[CU1_STROFF]]: +; DEFAULT-NEXT: {{.*:}} +; DEFAULT-NEXT: {{.*:}} +; DEFAULT-NEXT: {{.*:}} +; DEFAULT-NEXT: {{.*:}} +; DEFAULT-NEXT: {{.*:}} +; The string with index 6 should be "bglob" +; DEFAULT-NEXT: {{.*:}} [[BGLOBOFF]] + +; TYPEUNITS: .debug_str_offsets contents: +; TYPEUNITS-NEXT: 0x00000000: Contribution size = 84, Format = DWARF32, Version = 5 +; TYPEUNITS-NEXT: 0x[[TU_STROFF]]: +; TYPEUNITS-NEXT: {{.*:}} +; TYPEUNITS-NEXT: {{.*:}} +; TYPEUNITS-NEXT: {{.*:}} +; TYPEUNITS-NEXT: {{.*:}} +; TYPEUNITS-NEXT: {{.*:}} +; The string with index 6 should be "bglob" +; TYPEUNITS-NEXT: {{.*:}} [[BGLOBOFF]] + +; ModuleID = 't.bc' +source_filename = "llvm-link" + +%struct.A = type { i32, float } + +@aglob = global i32 0, align 4, !dbg !0 +@bglob = global i32 0, align 4, !dbg !7 +@cglob = global i32 0, align 4, !dbg !12 + +; Function Attrs: noinline nounwind optnone uwtable +define void @_Z5afunci(i32 %i) #0 !dbg !21 { +entry: + %i.addr = alloca i32, align 4 + %a = alloca %struct.A, align 4 + store i32 %i, i32* %i.addr, align 4 + call void @llvm.dbg.declare(metadata i32* %i.addr, metadata !24, metadata !DIExpression()), !dbg !25 + call void @llvm.dbg.declare(metadata %struct.A* %a, metadata !26, metadata !DIExpression()), !dbg !32 + ret void, !dbg !33 +} + +; Function Attrs: nounwind readnone speculatable +declare void @llvm.dbg.declare(metadata, metadata, metadata) #1 + +; Function Attrs: noinline nounwind optnone uwtable +define void @_Z5bfunci(i32 %i) #0 !dbg !34 { +entry: + %i.addr = alloca i32, align 4 + store i32 %i, i32* %i.addr, align 4 + call void @llvm.dbg.declare(metadata i32* %i.addr, metadata !35, metadata !DIExpression()), !dbg !36 + ret void, !dbg !37 +} + +; Function Attrs: noinline nounwind optnone uwtable +define void @_Z5cfunci(i32 %j) #0 !dbg !38 { +entry: + %j.addr = alloca i32, align 4 + store i32 %j, i32* %j.addr, align 4 + call void @llvm.dbg.declare(metadata i32* %j.addr, metadata !39, metadata !DIExpression()), !dbg !40 + ret void, !dbg !41 +} + +attributes #0 = { noinline nounwind optnone uwtable } +attributes #1 = { nounwind readnone speculatable } + +!llvm.dbg.cu = !{!2, !9, !14} +!llvm.ident = !{!17, !17, !17} +!llvm.module.flags = !{!18, !19, !20} + +!0 = !DIGlobalVariableExpression(var: !1, expr: !DIExpression()) +!1 = distinct !DIGlobalVariable(name: "aglob", scope: !2, file: !3, line: 1, type: !6, isLocal: false, isDefinition: true) +!2 = distinct !DICompileUnit(language: DW_LANG_C_plus_plus, file: !3, producer: "clang version 6.0.0 (trunk 317598)", isOptimized: false, runtimeVersion: 0, emissionKind: FullDebug, enums: !4, globals: !5) +!3 = !DIFile(filename: "a.cpp", directory: "/home/test/DWARF") +!4 = !{} +!5 = !{!0} +!6 = !DIBasicType(name: "int", size: 32, encoding: DW_ATE_signed) +!7 = !DIGlobalVariableExpression(var: !8, expr: !DIExpression()) +!8 = distinct !DIGlobalVariable(name: "bglob", scope: !9, file: !10, line: 1, type: !6, isLocal: false, isDefinition: true) +!9 = distinct !DICompileUnit(language: DW_LANG_C_plus_plus, file: !10, producer: "clang version 6.0.0 (trunk 317598)", isOptimized: false, runtimeVersion: 0, emissionKind: FullDebug, enums: !4, globals: !11) +!10 = !DIFile(filename: "b.cpp", directory: "/home/test/DWARF") +!11 = !{!7} +!12 = !DIGlobalVariableExpression(var: !13, expr: !DIExpression()) +!13 = distinct !DIGlobalVariable(name: "cglob", scope: !14, file: !15, line: 1, type: !6, isLocal: false, isDefinition: true) +!14 = distinct !DICompileUnit(language: DW_LANG_C_plus_plus, file: !15, producer: "clang version 6.0.0 (trunk 317598)", isOptimized: false, runtimeVersion: 0, emissionKind: FullDebug, enums: !4, globals: !16) +!15 = !DIFile(filename: "c.cpp", directory: "/home/test/DWARF") +!16 = !{!12} +!17 = !{!"clang version 6.0.0 (trunk 317598)"} +!18 = !{i32 2, !"Dwarf Version", i32 5} +!19 = !{i32 2, !"Debug Info Version", i32 3} +!20 = !{i32 1, !"wchar_size", i32 4} +!21 = distinct !DISubprogram(name: "afunc", linkageName: "_Z5afunci", scope: !3, file: !3, line: 7, type: !22, isLocal: false, isDefinition: true, scopeLine: 8, flags: DIFlagPrototyped, isOptimized: false, unit: !2, variables: !4) +!22 = !DISubroutineType(types: !23) +!23 = !{null, !6} +!24 = !DILocalVariable(name: "i", arg: 1, scope: !21, file: !3, line: 7, type: !6) +!25 = !DILocation(line: 7, column: 16, scope: !21) +!26 = !DILocalVariable(name: "a", scope: !21, file: !3, line: 9, type: !27) +!27 = distinct !DICompositeType(tag: DW_TAG_structure_type, name: "A", file: !3, line: 2, size: 64, elements: !28, identifier: "_ZTS1A") +!28 = !{!29, !30} +!29 = !DIDerivedType(tag: DW_TAG_member, name: "i", scope: !27, file: !3, line: 3, baseType: !6, size: 32) +!30 = !DIDerivedType(tag: DW_TAG_member, name: "f", scope: !27, file: !3, line: 4, baseType: !31, size: 32, offset: 32) +!31 = !DIBasicType(name: "float", size: 32, encoding: DW_ATE_float) +!32 = !DILocation(line: 9, column: 5, scope: !21) +!33 = !DILocation(line: 10, column: 1, scope: !21) +!34 = distinct !DISubprogram(name: "bfunc", linkageName: "_Z5bfunci", scope: !10, file: !10, line: 3, type: !22, isLocal: false, isDefinition: true, scopeLine: 4, flags: DIFlagPrototyped, isOptimized: false, unit: !9, variables: !4) +!35 = !DILocalVariable(name: "i", arg: 1, scope: !34, file: !10, line: 3, type: !6) +!36 = !DILocation(line: 3, column: 16, scope: !34) +!37 = !DILocation(line: 5, column: 1, scope: !34) +!38 = distinct !DISubprogram(name: "cfunc", linkageName: "_Z5cfunci", scope: !15, file: !15, line: 2, type: !22, isLocal: false, isDefinition: true, scopeLine: 3, flags: DIFlagPrototyped, isOptimized: false, unit: !14, variables: !4) +!39 = !DILocalVariable(name: "j", arg: 1, scope: !38, file: !15, line: 2, type: !6) +!40 = !DILocation(line: 2, column: 16, scope: !38) +!41 = !DILocation(line: 4, column: 1, scope: !38) Index: test/DebugInfo/Generic/string-offsets-table.ll =================================================================== --- test/DebugInfo/Generic/string-offsets-table.ll +++ test/DebugInfo/Generic/string-offsets-table.ll @@ -0,0 +1,158 @@ +; RUN: %llc_dwarf -filetype=obj < %s | llvm-dwarfdump -v - | FileCheck --check-prefix=MONOLITHIC %s +; RUN: %llc_dwarf -split-dwarf-file=%t.dwo -filetype=obj < %s | llvm-dwarfdump -v - \ +; RUN: | FileCheck --check-prefix=SPLIT %s + +; Test the proper emission of the DWARF v5 string offsets table. +; We test both default (monolithic) dwarf generation and splitting into *.dwo sections. +; +; Constructed from the following source with +; clang -S -emit-llvm -gdwarf-5: +; +; int aglob; +; +; struct A { +; int i; +; float f; +; }; +; +; void afunc(int i) +; { +; A a; +; } + +; Check the DW_AT_str_offsets_base attribute in .debug_abbrev +; MONOLITHIC: .debug_abbrev contents: +; MONOLITHIC-NOT: contents: +; MONOLITHIC: DW_TAG_compile_unit +; MONOLITHIC-NOT: DW_TAG +; MONOLITHIC: DW_AT_str_offsets_base DW_FORM_sec_offset + +; Check that indexed strings come out correctly and that the DW_str_offsets_base attribute +; is there. +; MONOLITHIC: .debug_info contents: +; MONOLITHIC-NOT: contents: +; MONOLITHIC: DW_TAG_compile_unit +; MONOLITHIC-NOT: {{DW_TAG|NULL}} +; MONOLITHIC: DW_AT_producer [DW_FORM_strx1] ( indexed (00000000) string = "clang{{.*}}") +; MONOLITHIC-NOT: {{DW_TAG|NULL}} +; MONOLITHIC: DW_AT_str_offsets_base [DW_FORM_sec_offset] (0x00000008) +; MONOLITHIC-NOT: {{DW_TAG|NULL}} +; MONOLITHIC: DW_AT_comp_dir [DW_FORM_strx1] ( indexed (00000002) string = "/home/{{.*}}") +; MONOLITHIC-NOT: NULL +; MONOLITHIC: DW_TAG_subprogram +; MONOLITHIC-NOT: {{DW_TAG|NULL}} +; MONOLITHIC: DW_AT_linkage_name [DW_FORM_strx1] ( indexed (00000005) string = "_Z5afunci") + +; Extract the string offsets from the .debug_str section +; MONOLITHIC: .debug_str contents: +; MONOLITHIC-NEXT: 0x00000000: +; MONOLITHIC-NEXT: 0x[[STRING2:[0-9a-f]]] +; MONOLITHIC-NEXT: 0x[[STRING3:[0-9a-f]]] +; MONOLITHIC-NEXT: 0x[[STRING4:[0-9a-f]]] + +; Verify that the .debug_str_offsets section is there and +; that it starts with an 8-byte header, followed by offsets into the .debug_str section. +; MONOLITHIC: .debug_str_offsets contents: +; MONOLITHIC-NEXT: Contribution size = 48, Format = DWARF32, Version = 5 +; MONOLITHIC-NEXT: 0x00000008: 00000000 +; MONOLITHIC-NEXT: 0x0000000c: [[STRING2]] +; MONOLITHIC-NEXT: 0x00000010: [[STRING3]] +; MONOLITHIC-NEXT: 0x00000014: [[STRING4]] +; +; For split dwarf, verify first that the skeleton unit has the DW_AT_str_offsets_base +; attribute and that there is a .debug_str_offsets section with a proper header. +; +; SPLIT: .debug_info contents: +; SPLIT-NEXT: 0x00000000: Compile Unit:{{.*}}DW_UT_skeleton +; SPLIT-NOT: contents: +; SPLIT: DW_TAG_compile_unit +; SPLIT-NOT: {{DW_TAG|contents:}} +; SPLIT: DW_AT_str_offsets_base [DW_FORM_sec_offset] (0x00000008) +; +; Check the split CU in .debug_info.dwo for a DW_AT_str_offsets_base attribute. +; SPLIT: .debug_info.dwo contents: +; SPLIT-NEXT: 0x00000000: Compile Unit:{{.*}}DW_UT_split_compile +; SPLIT-NOT: contents: +; SPLIT: DW_TAG_compile_unit +; +; Check for a couple of indexed strings. +; SPLIT-NOT: contents: +; SPLIT: DW_TAG_variable +; SPLIT-NEXT: DW_AT_name [DW_FORM_strx1] ( indexed (00000003) string = "aglob") +; SPLIT-NOT: contents: +; SPLIT: DW_TAG_subprogram +; SPLIT-NOT: {{DW_TAG|NULL}} +; SPLIT: DW_AT_linkage_name [DW_FORM_strx1] ( indexed (00000005) string = "_Z5afunci") +; +; SPLIT: .debug_str contents: +; SPLIT-NEXT: 0x00000000: +; SPLIT-NEXT: 0x[[STRING2SPLIT:[0-9a-f]*]] +; +; SPLIT: .debug_str.dwo contents: +; SPLIT-NEXT: 0x00000000: +; SPLIT-NEXT: 0x[[STRING2DWO:[0-9a-f]*]] +; SPLIT-NEXT: 0x[[STRING3DWO:[0-9a-f]*]] +; +; Check the string_offsets sections: .debug_str_offsets and .debug_str_offsets.dwo +; SPLIT: .debug_str_offsets contents: +; SPLIT-NEXT: 0x00000000: Contribution size = 8, Format = DWARF32, Version = 5 +; SPLIT-NEXT: 0x00000008: 00000000 +; SPLIT-NEXT: 0x0000000c: [[STRING2SPLIT]] +; SPLIT: .debug_str_offsets.dwo contents: +; SPLIT-NEXT: 0x00000000: Contribution size = 48, Format = DWARF32, Version = 5 +; SPLIT-NEXT: 0x00000008: 00000000 +; SPLIT-NEXT: 0x0000000c: [[STRING2DWO]] +; SPLIT-NEXT: 0x00000010: [[STRING3DWO]] +; +; ModuleID = 'a.cpp' +source_filename = "a.cpp" + +%struct.A = type { i32, float } + +@aglob = global i32 0, align 4, !dbg !0 + +; Function Attrs: noinline nounwind uwtable +define void @_Z5afunci(i32 %i) #0 !dbg !10 { +entry: + %i.addr = alloca i32, align 4 + %a = alloca %struct.A, align 4 + store i32 %i, i32* %i.addr, align 4 + call void @llvm.dbg.declare(metadata i32* %i.addr, metadata !13, metadata !14), !dbg !15 + call void @llvm.dbg.declare(metadata %struct.A* %a, metadata !16, metadata !14), !dbg !22 + ret void, !dbg !23 +} + +; Function Attrs: nounwind readnone +declare void @llvm.dbg.declare(metadata, metadata, metadata) #1 + +attributes #0 = { noinline nounwind uwtable } +attributes #1 = { nounwind readnone } + +!llvm.dbg.cu = !{!2} +!llvm.module.flags = !{!7, !8} +!llvm.ident = !{!9} + +!0 = !DIGlobalVariableExpression(var: !1, expr: !DIExpression()) +!1 = distinct !DIGlobalVariable(name: "aglob", scope: !2, file: !3, line: 1, type: !6, isLocal: false, isDefinition: true) +!2 = distinct !DICompileUnit(language: DW_LANG_C_plus_plus, file: !3, producer: "clang version 5.0.0 (trunk 300364)", isOptimized: false, runtimeVersion: 0, emissionKind: FullDebug, enums: !4, globals: !5) +!3 = !DIFile(filename: "a.cpp", directory: "/home/test/debuginfo/DWARF5") +!4 = !{} +!5 = !{!0} +!6 = !DIBasicType(name: "int", size: 32, encoding: DW_ATE_signed) +!7 = !{i32 2, !"Dwarf Version", i32 5} +!8 = !{i32 2, !"Debug Info Version", i32 3} +!9 = !{!"clang version 5.0.0 (trunk 300364)"} +!10 = distinct !DISubprogram(name: "afunc", linkageName: "_Z5afunci", scope: !3, file: !3, line: 8, type: !11, isLocal: false, isDefinition: true, scopeLine: 9, flags: DIFlagPrototyped, isOptimized: false, unit: !2, variables: !4) +!11 = !DISubroutineType(types: !12) +!12 = !{null, !6} +!13 = !DILocalVariable(name: "i", arg: 1, scope: !10, file: !3, line: 8, type: !6) +!14 = !DIExpression() +!15 = !DILocation(line: 8, column: 16, scope: !10) +!16 = !DILocalVariable(name: "a", scope: !10, file: !3, line: 10, type: !17) +!17 = distinct !DICompositeType(tag: DW_TAG_structure_type, name: "A", file: !3, line: 3, size: 64, elements: !18, identifier: "_ZTS1A") +!18 = !{!19, !20} +!19 = !DIDerivedType(tag: DW_TAG_member, name: "i", scope: !17, file: !3, line: 4, baseType: !6, size: 32) +!20 = !DIDerivedType(tag: DW_TAG_member, name: "f", scope: !17, file: !3, line: 5, baseType: !21, size: 32, offset: 32) +!21 = !DIBasicType(name: "float", size: 32, encoding: DW_ATE_float) +!22 = !DILocation(line: 10, column: 5, scope: !10) +!23 = !DILocation(line: 11, column: 1, scope: !10)