]> Gitweb @ Texas Instruments - Open Source Git Repositories - git.TI.com/gitweb - opencl/llvm.git/commitdiff
Provide gmlt-like inline scope information in the skeleton CU to facilitate symbolica...
authorDavid Blaikie <dblaikie@gmail.com>
Tue, 4 Nov 2014 22:12:25 +0000 (22:12 +0000)
committerDavid Blaikie <dblaikie@gmail.com>
Tue, 4 Nov 2014 22:12:25 +0000 (22:12 +0000)
Clang -gsplit-dwarf self-host -O0, binary increases by 0.0005%, -O2,
binary increases by 25%.

A large binary inside Google, split-dwarf, -O0, and other internal flags
(GDB index, etc) increases by 1.8%, optimized build is 35%.

The size impact may be somewhat greater in .o files (I haven't measured
that much - since the linked executable -O0 numbers seemed low enough)
due to relocations. These relocations could be removed if we taught the
llvm-symbolizer to handle indexed addressing in the .o file (GDB can't
cope with this just yet, but GDB won't be reading this info anyway).
Also debug_ranges could be shared between .o and .dwo, though ideally
debug_ranges would get a schema that could used index(+offset)
addressing, and move to the .dwo file, then we'd be back to sharing
addresses in the address pool again.

But for now, these sizes seem small enough to go ahead with this.

Verified that no other DW_TAGs are produced into the .o file other than
subprograms and inlined_subroutines.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@221306 91177308-0d34-0410-b5e6-96231b3b80d8

lib/CodeGen/AsmPrinter/DwarfCompileUnit.cpp
lib/CodeGen/AsmPrinter/DwarfCompileUnit.h
lib/CodeGen/AsmPrinter/DwarfDebug.cpp
lib/CodeGen/AsmPrinter/DwarfUnit.cpp
lib/CodeGen/AsmPrinter/DwarfUnit.h
test/DebugInfo/X86/fission-inline.ll [new file with mode: 0644]
test/DebugInfo/X86/generate-odr-hash.ll

index 580785588a7e4777f6de3a6af083637a9cb0947e..a8f867a16c880f25e116225b8abccff4d91f42c9 100644 (file)
@@ -283,7 +283,7 @@ void DwarfCompileUnit::attachLowHighPC(DIE &D, const MCSymbol *Begin,
 // and DW_AT_high_pc attributes. If there are global variables in this
 // scope then create and insert DIEs for these variables.
 DIE &DwarfCompileUnit::updateSubprogramScopeDIE(DISubprogram SP) {
-  DIE *SPDie = getOrCreateSubprogramDIE(SP);
+  DIE *SPDie = getOrCreateSubprogramDIE(SP, includeMinimalInlineScopes());
 
   attachLowHighPC(*SPDie, DD->getFunctionBeginSym(), DD->getFunctionEndSym());
   if (!DD->getCurrentFunction()->getTarget().Options.DisableFramePointerElim(
@@ -291,7 +291,7 @@ DIE &DwarfCompileUnit::updateSubprogramScopeDIE(DISubprogram SP) {
     addFlag(*SPDie, dwarf::DW_AT_APPLE_omit_frame_ptr);
 
   // Only include DW_AT_frame_base in full debug info
-  if (getCUNode().getEmissionKind() != DIBuilder::LineTablesOnly) {
+  if (!includeMinimalInlineScopes()) {
     const TargetRegisterInfo *RI =
         Asm->TM.getSubtargetImpl()->getRegisterInfo();
     MachineLocation Location(RI->getFrameRegister(*Asm->MF));
@@ -341,10 +341,14 @@ void DwarfCompileUnit::constructScopeDIE(
     // null and the children will be added to the scope DIE.
     createScopeChildrenDIE(Scope, Children, &ChildScopeCount);
 
-    // There is no need to emit empty lexical block DIE.
-    for (const auto &E : DD->findImportedEntitiesForScope(DS))
-      Children.push_back(
-          constructImportedEntityDIE(DIImportedEntity(E.second)));
+    // Skip imported directives in gmlt-like data.
+    if (!includeMinimalInlineScopes()) {
+      // There is no need to emit empty lexical block DIE.
+      for (const auto &E : DD->findImportedEntitiesForScope(DS))
+        Children.push_back(
+            constructImportedEntityDIE(DIImportedEntity(E.second)));
+    }
+
     // If there are only other scopes as children, put them directly in the
     // parent instead, as this scope would serve no purpose.
     if (Children.size() == ChildScopeCount) {
@@ -576,7 +580,8 @@ void DwarfCompileUnit::constructSubprogramScopeDIE(LexicalScope *Scope) {
   // If we have more than one elements and the last one is null, it is a
   // variadic function.
   if (FnArgs.getNumElements() > 1 &&
-      !FnArgs.getElement(FnArgs.getNumElements() - 1))
+      !FnArgs.getElement(FnArgs.getNumElements() - 1) &&
+      !includeMinimalInlineScopes())
     ScopeDIE.addChild(make_unique<DIE>(dwarf::DW_TAG_unspecified_parameters));
 }
 
@@ -603,11 +608,13 @@ DwarfCompileUnit::constructAbstractSubprogramScopeDIE(LexicalScope *Scope) {
 
   DIE *ContextDIE;
 
+  if (includeMinimalInlineScopes())
+    ContextDIE = &getUnitDie();
   // Some of this is duplicated from DwarfUnit::getOrCreateSubprogramDIE, with
   // the important distinction that the DIDescriptor is not associated with the
   // DIE (since the DIDescriptor will be associated with the concrete DIE, if
   // any). It could be refactored to some common utility function.
-  if (DISubprogram SPDecl = SP.getFunctionDeclaration()) {
+  else if (DISubprogram SPDecl = SP.getFunctionDeclaration()) {
     ContextDIE = &getUnitDie();
     getOrCreateSubprogramDIE(SPDecl);
   } else
@@ -619,7 +626,7 @@ DwarfCompileUnit::constructAbstractSubprogramScopeDIE(LexicalScope *Scope) {
       &createAndAddDIE(dwarf::DW_TAG_subprogram, *ContextDIE, DIDescriptor());
   applySubprogramAttributesToDefinition(SP, *AbsDef);
 
-  if (getCUNode().getEmissionKind() != DIBuilder::LineTablesOnly)
+  if (!includeMinimalInlineScopes())
     addUInt(*AbsDef, dwarf::DW_AT_inline, None, dwarf::DW_INL_inlined);
   if (DIE *ObjectPointer = createAndAddScopeChildren(Scope, *AbsDef))
     addDIEEntry(*AbsDef, dwarf::DW_AT_object_pointer, *ObjectPointer);
@@ -660,7 +667,7 @@ void DwarfCompileUnit::finishSubprogramDefinition(DISubprogram SP) {
       // If this subprogram has an abstract definition, reference that
       addDIEEntry(*D, dwarf::DW_AT_abstract_origin, *AbsSPDIE);
   } else {
-    if (!D && getCUNode().getEmissionKind() != DIBuilder::LineTablesOnly)
+    if (!D && !includeMinimalInlineScopes())
       // Lazily construct the subprogram if we didn't see either concrete or
       // inlined versions during codegen. (except in -gmlt ^ where we want
       // to omit these entirely)
@@ -703,7 +710,7 @@ void DwarfCompileUnit::emitHeader(const MCSymbol *ASectionSym) const {
 /// addGlobalName - Add a new global name to the compile unit.
 void DwarfCompileUnit::addGlobalName(StringRef Name, DIE &Die,
                                      DIScope Context) {
-  if (getCUNode().getEmissionKind() == DIBuilder::LineTablesOnly)
+  if (includeMinimalInlineScopes())
     return;
   std::string FullName = getParentContextString(Context) + Name.str();
   GlobalNames[FullName] = &Die;
@@ -712,7 +719,7 @@ void DwarfCompileUnit::addGlobalName(StringRef Name, DIE &Die,
 /// Add a new global type to the unit.
 void DwarfCompileUnit::addGlobalType(DIType Ty, const DIE &Die,
                                      DIScope Context) {
-  if (getCUNode().getEmissionKind() == DIBuilder::LineTablesOnly)
+  if (includeMinimalInlineScopes())
     return;
   std::string FullName = getParentContextString(Context) + Ty.getName().str();
   GlobalTypes[FullName] = &Die;
@@ -838,12 +845,16 @@ void DwarfCompileUnit::applySubprogramAttributesToDefinition(DISubprogram SP,
                                                              DIE &SPDie) {
   DISubprogram SPDecl = SP.getFunctionDeclaration();
   DIScope Context = resolve(SPDecl ? SPDecl.getContext() : SP.getContext());
-  applySubprogramAttributes(SP, SPDie, getCUNode().getEmissionKind() ==
-                                           DIBuilder::LineTablesOnly);
+  applySubprogramAttributes(SP, SPDie, includeMinimalInlineScopes());
   addGlobalName(SP.getName(), SPDie, Context);
 }
 
 bool DwarfCompileUnit::isDwoUnit() const {
   return DD->useSplitDwarf() && Skeleton;
 }
+
+bool DwarfCompileUnit::includeMinimalInlineScopes() const {
+  return getCUNode().getEmissionKind() == DIBuilder::LineTablesOnly ||
+         (DD->useSplitDwarf() && !Skeleton);
+}
 } // end llvm namespace
index 1f50dbce886f3415241d01ab99c6ed9f4cb0e2d3..e521f39fa88217df478c7837a98bc63e12f5c55c 100644 (file)
@@ -66,6 +66,8 @@ class DwarfCompileUnit : public DwarfUnit {
 
   bool isDwoUnit() const override;
 
+  bool includeMinimalInlineScopes() const;
+
 public:
   DwarfCompileUnit(unsigned UID, DICompileUnit Node, AsmPrinter *A,
                    DwarfDebug *DW, DwarfFile *DWU);
index 9109a3bb8c7bdfb662cf1ad3cdbf2f8ed064c32a..4acd7271be9aff13f1fcb8ec6818e51365f581f1 100644 (file)
@@ -330,6 +330,12 @@ bool DwarfDebug::isLexicalScopeDIENull(LexicalScope *Scope) {
   return !getLabelAfterInsn(Ranges.front().second);
 }
 
+template <typename Func> void forBothCUs(DwarfCompileUnit &CU, Func F) {
+  F(CU);
+  if (auto *SkelCU = CU.getSkeleton())
+    F(*SkelCU);
+}
+
 void DwarfDebug::constructAbstractSubprogramScopeDIE(LexicalScope *Scope) {
   assert(Scope && Scope->getScopeNode());
   assert(Scope->isAbstractScope());
@@ -341,7 +347,10 @@ void DwarfDebug::constructAbstractSubprogramScopeDIE(LexicalScope *Scope) {
 
   // Find the subprogram's DwarfCompileUnit in the SPMap in case the subprogram
   // was inlined from another compile unit.
-  SPMap[SP]->constructAbstractSubprogramScopeDIE(Scope);
+  auto &CU = SPMap[SP];
+  forBothCUs(*CU, [&](DwarfCompileUnit &CU) {
+    CU.constructAbstractSubprogramScopeDIE(Scope);
+  });
 }
 
 void DwarfDebug::addGnuPubAttributes(DwarfUnit &U, DIE &D) const {
@@ -506,7 +515,9 @@ void DwarfDebug::finishVariableDefinitions() {
 
 void DwarfDebug::finishSubprogramDefinitions() {
   for (const auto &P : SPMap)
-    P.second->finishSubprogramDefinition(DISubprogram(P.first));
+    forBothCUs(*P.second, [&](DwarfCompileUnit &CU) {
+      CU.finishSubprogramDefinition(DISubprogram(P.first));
+    });
 }
 
 
@@ -1286,6 +1297,9 @@ void DwarfDebug::endFunction(const MachineFunction *MF) {
   }
 
   TheCU.constructSubprogramScopeDIE(FnScope);
+  if (auto *SkelCU = TheCU.getSkeleton())
+    if (!LScopes.getAbstractScopesList().empty())
+      SkelCU->constructSubprogramScopeDIE(FnScope);
 
   // Clear debug info
   // Ownership of DbgVariables is a bit subtle - ScopeVariables owns all the
@@ -1984,6 +1998,9 @@ void DwarfDebug::emitDebugRanges() {
   for (const auto &I : CUMap) {
     DwarfCompileUnit *TheCU = I.second;
 
+    if (auto *Skel = TheCU->getSkeleton())
+      TheCU = Skel;
+
     // Iterate over the misc ranges for the compile units in the module.
     for (const RangeSpanList &List : TheCU->getRangeLists()) {
       // Emit our symbol so we can find the beginning of the range.
index 1793757afcfdfa5bfcc11ce3a4cc1e409fb0c50c..919d9d27480b316a10e513313488ca392a39f4d7 100644 (file)
@@ -1233,20 +1233,23 @@ DIE *DwarfUnit::getOrCreateNameSpace(DINameSpace NS) {
 }
 
 /// getOrCreateSubprogramDIE - Create new DIE using SP.
-DIE *DwarfUnit::getOrCreateSubprogramDIE(DISubprogram SP) {
+DIE *DwarfUnit::getOrCreateSubprogramDIE(DISubprogram SP, bool Minimal) {
   // Construct the context before querying for the existence of the DIE in case
   // such construction creates the DIE (as is the case for member function
   // declarations).
-  DIE *ContextDIE = getOrCreateContextDIE(resolve(SP.getContext()));
+  DIE *ContextDIE =
+      Minimal ? &getUnitDie() : getOrCreateContextDIE(resolve(SP.getContext()));
 
   if (DIE *SPDie = getDIE(SP))
     return SPDie;
 
   if (DISubprogram SPDecl = SP.getFunctionDeclaration()) {
-    // Add subprogram definitions to the CU die directly.
-    ContextDIE = &getUnitDie();
-    // Build the decl now to ensure it precedes the definition.
-    getOrCreateSubprogramDIE(SPDecl);
+    if (!Minimal) {
+      // Add subprogram definitions to the CU die directly.
+      ContextDIE = &getUnitDie();
+      // Build the decl now to ensure it precedes the definition.
+      getOrCreateSubprogramDIE(SPDecl);
+    }
   }
 
   // DW_TAG_inlined_subroutine may refer to this DIE.
@@ -1261,8 +1264,8 @@ DIE *DwarfUnit::getOrCreateSubprogramDIE(DISubprogram SP) {
   return &SPDie;
 }
 
-void DwarfUnit::applySubprogramAttributes(DISubprogram SP, DIE &SPDie,
-                                          bool Minimal) {
+bool DwarfUnit::applySubprogramDefinitionAttributes(DISubprogram SP,
+                                                    DIE &SPDie) {
   DIE *DeclDie = nullptr;
   StringRef DeclLinkageName;
   if (DISubprogram SPDecl = SP.getFunctionDeclaration()) {
@@ -1285,12 +1288,20 @@ void DwarfUnit::applySubprogramAttributes(DISubprogram SP, DIE &SPDie,
     addString(SPDie, dwarf::DW_AT_MIPS_linkage_name,
               GlobalValue::getRealLinkageName(LinkageName));
 
-  if (DeclDie) {
-    // Refer to the function declaration where all the other attributes will be
-    // found.
-    addDIEEntry(SPDie, dwarf::DW_AT_specification, *DeclDie);
-    return;
-  }
+  if (!DeclDie)
+    return false;
+
+  // Refer to the function declaration where all the other attributes will be
+  // found.
+  addDIEEntry(SPDie, dwarf::DW_AT_specification, *DeclDie);
+  return true;
+}
+
+void DwarfUnit::applySubprogramAttributes(DISubprogram SP, DIE &SPDie,
+                                          bool Minimal) {
+  if (!Minimal)
+    if (applySubprogramDefinitionAttributes(SP, SPDie))
+      return;
 
   // Constructors and operators for anonymous aggregates do not have names.
   if (!SP.getName().empty())
index bd31ea4a32da56d1fdd7ea30e53725248e3acda0..f40c937a632f9bb987bb2e30e7732b6506d1f4f9 100644 (file)
@@ -127,6 +127,8 @@ protected:
 
   void addIndexedString(DIE &Die, dwarf::Attribute Attribute, StringRef Str);
 
+  bool applySubprogramDefinitionAttributes(DISubprogram SP, DIE &SPDie);
+
 public:
   virtual ~DwarfUnit();
 
@@ -278,7 +280,7 @@ public:
   DIE *getOrCreateNameSpace(DINameSpace NS);
 
   /// getOrCreateSubprogramDIE - Create new DIE using SP.
-  DIE *getOrCreateSubprogramDIE(DISubprogram SP);
+  DIE *getOrCreateSubprogramDIE(DISubprogram SP, bool Minimal = false);
 
   void applySubprogramAttributes(DISubprogram SP, DIE &SPDie,
                                  bool Minimal = false);
diff --git a/test/DebugInfo/X86/fission-inline.ll b/test/DebugInfo/X86/fission-inline.ll
new file mode 100644 (file)
index 0000000..29c770d
--- /dev/null
@@ -0,0 +1,119 @@
+; RUN: llc -split-dwarf=Enable -O0 < %s -mtriple=x86_64-unknown-linux-gnu -filetype=obj | llvm-dwarfdump -debug-dump=info - | FileCheck %s
+
+; Test the emission of gmlt-like inlining information into the skeleton unit.
+; This allows inline-aware symbolication/backtracing given only the linked
+; executable, without needing access to the .dwos.
+
+; A simple example of inlining generated with clang -gsplit-dwarf
+
+; A member function is used to force emission of the declaration of the
+; function into the .dwo file, which may be shared with other CUs in the dwo ;
+; under fission, but should not be shared with the skeleton's CU. This also
+; tests the general case of context emission, which is suppressed in gmlt-like
+; data.
+
+; Include a template just to test template parameters are not emitted in
+; gmlt-like data.
+
+; And some varargs to make sure DW_TAG_unspecified_parameters is not emitted.
+
+; And a using declaration in a nested lexical_block... because that shouldn't
+; be emitted either.
+
+; Minor complication: after generating the LLVM IR, it was manually edited so
+; that the 'f1()' call from f3 was reordered to appear between the two inlined
+; f1 calls from f2. This causes f2's inlined_subroutine to use DW_AT_ranges,
+; thus exercising range list generation/referencing which was buggy.
+
+; struct foo {
+;   template<typename T>
+;   static void f2();
+;   static void f3(...);
+; };
+;
+; void f1();
+;
+; template<typename T>
+; inline __attribute__((always_inline)) void foo::f2() {
+;   f1();
+;   f1();
+; }
+;
+; void foo::f3(...) {
+;   if (true) {
+;     f1();
+;     f2<int>();
+;     using ::foo;
+;   }
+; }
+
+; Check that we emit the usual gmlt-like data for this file, including brief
+; descriptions of subprograms with inlined scopes.
+
+; FIXME: Once tools support indexed addresses in the skeleton CU, we should use
+; those (DW_FORM_addr would become DW_FORM_GNU_addr_index below) since those
+; addresses will already be in the address pool anyway.
+
+; CHECK:      DW_TAG_subprogram
+; CHECK-NEXT:   DW_AT_name {{.*}} "f2<int>"
+; CHECK-NOT: DW_
+; CHECK:      DW_TAG_subprogram
+; CHECK-NEXT:   DW_AT_low_pc [DW_FORM_addr]
+; CHECK-NEXT:   DW_AT_high_pc
+; CHECK-NEXT:   DW_AT_name {{.*}} "f3"
+; CHECK-NOT: {{DW_|NULL}}
+; CHECK:        DW_TAG_inlined_subroutine
+; CHECK-NEXT:     DW_AT_abstract_origin {{.*}} "f2<int>"
+; CHECK-NEXT:     DW_AT_ranges
+; CHECK-NEXT:     DW_AT_call_file
+; CHECK-NEXT:     DW_AT_call_line {{.*}} (18)
+; CHECK-NOT: DW_
+
+; Function Attrs: uwtable
+define void @_ZN3foo2f3Ez(...) #0 align 2 {
+entry:
+  call void @_Z2f1v(), !dbg !26
+  call void @_Z2f1v(), !dbg !25
+  call void @_Z2f1v(), !dbg !28
+  ret void, !dbg !29
+}
+
+declare void @_Z2f1v() #1
+
+attributes #0 = { uwtable "less-precise-fpmad"="false" "no-frame-pointer-elim"="true" "no-frame-pointer-elim-non-leaf" "no-infs-fp-math"="false" "no-nans-fp-math"="false" "stack-protector-buffer-size"="8" "unsafe-fp-math"="false" "use-soft-float"="false" }
+attributes #1 = { "less-precise-fpmad"="false" "no-frame-pointer-elim"="true" "no-frame-pointer-elim-non-leaf" "no-infs-fp-math"="false" "no-nans-fp-math"="false" "stack-protector-buffer-size"="8" "unsafe-fp-math"="false" "use-soft-float"="false" }
+
+!llvm.dbg.cu = !{!0}
+!llvm.module.flags = !{!22, !23}
+!llvm.ident = !{!24}
+
+!0 = metadata !{metadata !"0x11\004\00clang version 3.6.0 \000\00\000\00fission-inline.dwo\001", metadata !1, metadata !2, metadata !3, metadata !9, metadata !2, metadata !18} ; [ DW_TAG_compile_unit ] [/tmp/dbginfo/fission-inline.cpp] [DW_LANG_C_plus_plus]
+!1 = metadata !{metadata !"fission-inline.cpp", metadata !"/tmp/dbginfo"}
+!2 = metadata !{}
+!3 = metadata !{metadata !4}
+!4 = metadata !{metadata !"0x13\00foo\001\008\008\000\000\000", metadata !1, null, null, metadata !5, null, null, metadata !"_ZTS3foo"} ; [ DW_TAG_structure_type ] [foo] [line 1, size 8, align 8, offset 0] [def] [from ]
+!5 = metadata !{metadata !6}
+!6 = metadata !{metadata !"0x2e\00f3\00f3\00_ZN3foo2f3Ez\004\000\000\000\000\00256\000\004", metadata !1, metadata !"_ZTS3foo", metadata !7, null, null, null, null, null} ; [ DW_TAG_subprogram ] [line 4] [f3]
+!7 = metadata !{metadata !"0x15\00\000\000\000\000\000\000", null, null, null, metadata !8, null, null, null} ; [ DW_TAG_subroutine_type ] [line 0, size 0, align 0, offset 0] [from ]
+!8 = metadata !{null, null}
+!9 = metadata !{metadata !10, metadata !11}
+!10 = metadata !{metadata !"0x2e\00f3\00f3\00_ZN3foo2f3Ez\0015\000\001\000\000\00256\000\0015", metadata !1, metadata !"_ZTS3foo", metadata !7, null, void (...)* @_ZN3foo2f3Ez, null, metadata !6, metadata !2} ; [ DW_TAG_subprogram ] [line 15] [def] [f3]
+!11 = metadata !{metadata !"0x2e\00f2<int>\00f2<int>\00_ZN3foo2f2IiEEvv\0010\000\001\000\000\00256\000\0010", metadata !1, metadata !"_ZTS3foo", metadata !12, null, null, metadata !14, metadata !17, metadata !2} ; [ DW_TAG_subprogram ] [line 10] [def] [f2<int>]
+!12 = metadata !{metadata !"0x15\00\000\000\000\000\000\000", null, null, null, metadata !13, null, null, null} ; [ DW_TAG_subroutine_type ] [line 0, size 0, align 0, offset 0] [from ]
+!13 = metadata !{null}
+!14 = metadata !{metadata !15}
+!15 = metadata !{metadata !"0x2f\00T\000\000", null, metadata !16, null} ; [ DW_TAG_template_type_parameter ]
+!16 = metadata !{metadata !"0x24\00int\000\0032\0032\000\000\005", null, null} ; [ DW_TAG_base_type ] [int] [line 0, size 32, align 32, offset 0, enc DW_ATE_signed]
+!17 = metadata !{metadata !"0x2e\00f2<int>\00f2<int>\00_ZN3foo2f2IiEEvv\0010\000\000\000\000\00256\000\0010", metadata !1, metadata !"_ZTS3foo", metadata !12, null, null, metadata !14, null, null} ; [ DW_TAG_subprogram ] [line 10] [f2<int>]
+!18 = metadata !{metadata !19}
+!19 = metadata !{metadata !"0x8\0019\00", metadata !20, metadata !"_ZTS3foo"} ; [ DW_TAG_imported_declaration ]
+!20 = metadata !{metadata !"0xb\0016\0013\001", metadata !1, metadata !21} ; [ DW_TAG_lexical_block ] [/tmp/dbginfo/fission-inline.cpp]
+!21 = metadata !{metadata !"0xb\0016\007\000", metadata !1, metadata !10} ; [ DW_TAG_lexical_block ] [/tmp/dbginfo/fission-inline.cpp]
+!22 = metadata !{i32 2, metadata !"Dwarf Version", i32 4}
+!23 = metadata !{i32 2, metadata !"Debug Info Version", i32 2}
+!24 = metadata !{metadata !"clang version 3.6.0 "}
+!25 = metadata !{i32 17, i32 5, metadata !20, null}
+!26 = metadata !{i32 11, i32 3, metadata !11, metadata !27}
+!27 = metadata !{i32 18, i32 5, metadata !20, null}
+!28 = metadata !{i32 12, i32 3, metadata !11, metadata !27}
+!29 = metadata !{i32 21, i32 1, metadata !10, null}
index 87914864bd856e5de0dd5d0d8a1ab6c06c2d0f47..e7a37ea8727a30fa8a7a10f5b0835f08e88b71eb 100644 (file)
@@ -82,7 +82,8 @@
 ; CHECK-NOT: type_signature
 ; CHECK-LABEL: type_signature = 0x1d02f3be30cc5688
 ; CHECK: DW_TAG_structure_type
-; CHECK-NEXT: DW_AT_name{{.*}}"bar"
+; FISSION-NEXT: DW_AT_name {{.*}} ( indexed {{.*}} "bar"
+; SINGLE-NEXT: DW_AT_name {{.*}} "bar"
 
 
 ; Check that we generate a hash for fluffy and the value.