[llvm] r270485 - Modify emitTypeInformation to use MemoryTypeTableBuilder, take 2

Reid Kleckner via llvm-commits llvm-commits at lists.llvm.org
Mon May 23 13:23:46 PDT 2016


Author: rnk
Date: Mon May 23 15:23:46 2016
New Revision: 270485

URL: http://llvm.org/viewvc/llvm-project?rev=270485&view=rev
Log:
Modify emitTypeInformation to use MemoryTypeTableBuilder, take 2

This effectively revers commit r270389 and re-lands r270106, but it's
almost a rewrite.

The behavior change in r270106 was that we could no longer assume that
each LF_FUNC_ID record got its own type index. This patch adds a map
from DINode* to TypeIndex, so we can stop making that assumption.

This change also emits padding bytes between type records similar to the
way MSVC does. The size of the type record includes the padding bytes.

Added:
    llvm/trunk/test/DebugInfo/COFF/inlining-padding.ll
    llvm/trunk/test/DebugInfo/COFF/inlining-same-name.ll
Modified:
    llvm/trunk/include/llvm/DebugInfo/CodeView/MemoryTypeTableBuilder.h
    llvm/trunk/lib/CodeGen/AsmPrinter/CodeViewDebug.cpp
    llvm/trunk/lib/CodeGen/AsmPrinter/CodeViewDebug.h

Modified: llvm/trunk/include/llvm/DebugInfo/CodeView/MemoryTypeTableBuilder.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/DebugInfo/CodeView/MemoryTypeTableBuilder.h?rev=270485&r1=270484&r2=270485&view=diff
==============================================================================
--- llvm/trunk/include/llvm/DebugInfo/CodeView/MemoryTypeTableBuilder.h (original)
+++ llvm/trunk/include/llvm/DebugInfo/CodeView/MemoryTypeTableBuilder.h Mon May 23 15:23:46 2016
@@ -46,6 +46,8 @@ private:
 public:
   MemoryTypeTableBuilder() {}
 
+  bool empty() const { return Records.empty(); }
+
   template <typename TFunc> void ForEachRecord(TFunc Func) {
     uint32_t Index = TypeIndex::FirstNonSimpleIndex;
 

Modified: llvm/trunk/lib/CodeGen/AsmPrinter/CodeViewDebug.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/AsmPrinter/CodeViewDebug.cpp?rev=270485&r1=270484&r2=270485&view=diff
==============================================================================
--- llvm/trunk/lib/CodeGen/AsmPrinter/CodeViewDebug.cpp (original)
+++ llvm/trunk/lib/CodeGen/AsmPrinter/CodeViewDebug.cpp Mon May 23 15:23:46 2016
@@ -113,14 +113,34 @@ CodeViewDebug::getInlineSite(const DILoc
   if (SiteInsertion.second) {
     Site->SiteFuncId = NextFuncId++;
     Site->Inlinee = Inlinee;
-    auto InlineeInsertion =
-        SubprogramIndices.insert({Inlinee, InlinedSubprograms.size()});
-    if (InlineeInsertion.second)
-      InlinedSubprograms.push_back(Inlinee);
+    InlinedSubprograms.insert(Inlinee);
+    recordFuncIdForSubprogram(Inlinee);
   }
   return *Site;
 }
 
+TypeIndex CodeViewDebug::getGenericFunctionTypeIndex() {
+  if (VoidFnTyIdx.getIndex() != 0)
+    return VoidFnTyIdx;
+
+  ArrayRef<TypeIndex> NoArgs;
+  ArgListRecord ArgListRec(TypeRecordKind::ArgList, NoArgs);
+  TypeIndex ArgListIndex = TypeTable.writeArgList(ArgListRec);
+
+  ProcedureRecord Procedure(TypeIndex::Void(), CallingConvention::NearC,
+                            FunctionOptions::None, 0, ArgListIndex);
+  VoidFnTyIdx = TypeTable.writeProcedure(Procedure);
+  return VoidFnTyIdx;
+}
+
+void CodeViewDebug::recordFuncIdForSubprogram(const DISubprogram *SP) {
+  TypeIndex ParentScope = TypeIndex(0);
+  StringRef DisplayName = SP->getDisplayName();
+  FuncIdRecord FuncId(ParentScope, getGenericFunctionTypeIndex(), DisplayName);
+  TypeIndex TI = TypeTable.writeFuncId(FuncId);
+  TypeIndices[SP] = TI;
+}
+
 void CodeViewDebug::recordLocalVariable(LocalVariable &&Var,
                                         const DILocation *InlinedAt) {
   if (InlinedAt) {
@@ -244,72 +264,38 @@ static void emitNullTerminatedSymbolName
 }
 
 void CodeViewDebug::emitTypeInformation() {
-  // Do nothing if we have no debug info or no inlined subprograms.  The types
-  // we currently emit exist only to support inlined call site info.
+  // Do nothing if we have no debug info or if no non-trivial types were emitted
+  // to TypeTable during codegen.
   NamedMDNode *CU_Nodes =
       MMI->getModule()->getNamedMetadata("llvm.dbg.cu");
   if (!CU_Nodes)
     return;
-  if (InlinedSubprograms.empty())
+  if (TypeTable.empty())
     return;
 
   // Start the .debug$T section with 0x4.
   OS.SwitchSection(Asm->getObjFileLowering().getCOFFDebugTypesSection());
   OS.AddComment("Debug section magic");
+  OS.EmitValueToAlignment(4);
   OS.EmitIntValue(COFF::DEBUG_SECTION_MAGIC, 4);
 
-  // This type info currently only holds function ids for use with inline call
-  // frame info. All functions are assigned a simple 'void ()' type. Emit that
-  // type here.
-  unsigned ArgListIndex = getNextTypeIndex();
-  OS.AddComment("Type record length");
-  OS.EmitIntValue(ArgListRecord::getLayoutSize(), 2);
-  OS.AddComment("Leaf type: LF_ARGLIST");
-  OS.EmitIntValue(LF_ARGLIST, 2);
-  OS.AddComment("Number of arguments");
-  OS.EmitIntValue(0, 4);
-
-  unsigned VoidFnTyIdx = getNextTypeIndex();
-  OS.AddComment("Type record length");
-  OS.EmitIntValue(ProcedureRecord::getLayoutSize(), 2);
-  OS.AddComment("Leaf type: LF_PROCEDURE");
-  OS.EmitIntValue(LF_PROCEDURE, 2);
-  OS.AddComment("Return type index");
-  OS.EmitIntValue(TypeIndex::Void().getIndex(), 4);
-  OS.AddComment("Calling convention");
-  OS.EmitIntValue(char(CallingConvention::NearC), 1);
-  OS.AddComment("Function options");
-  OS.EmitIntValue(char(FunctionOptions::None), 1);
-  OS.AddComment("# of parameters");
-  OS.EmitIntValue(0, 2);
-  OS.AddComment("Argument list type index");
-  OS.EmitIntValue(ArgListIndex, 4);
-
-  // Emit LF_FUNC_ID records for all inlined subprograms to the type stream.
-  // Allocate one type index for each func id.
-  unsigned NextIdx = getNextTypeIndex(InlinedSubprograms.size());
-  (void)NextIdx;
-  assert(NextIdx == FuncIdTypeIndexStart && "func id type indices broken");
-  for (auto *SP : InlinedSubprograms) {
-    StringRef DisplayName = SP->getDisplayName();
-    OS.AddComment("Type record length");
-    MCSymbol *FuncBegin = MMI->getContext().createTempSymbol(),
-             *FuncEnd = MMI->getContext().createTempSymbol();
-    OS.emitAbsoluteSymbolDiff(FuncEnd, FuncBegin, 2);
-    OS.EmitLabel(FuncBegin);
-    OS.AddComment("Leaf type: LF_FUNC_ID");
-    OS.EmitIntValue(LF_FUNC_ID, 2);
-
-    OS.AddComment("Scope type index");
-    OS.EmitIntValue(0, 4);
-    OS.AddComment("Function type");
-    OS.EmitIntValue(VoidFnTyIdx, 4);
-    {
-      OS.AddComment("Function name");
-      emitNullTerminatedSymbolName(OS, DisplayName);
-    }
-    OS.EmitLabel(FuncEnd);
-  }
+  TypeTable.ForEachRecord(
+      [&](TypeIndex Index, const MemoryTypeTableBuilder::Record *R) {
+        // Each record should be 4 byte aligned. We achieve that by emitting
+        // LF_PAD padding bytes. The on-disk record size includes the padding
+        // bytes so that consumers don't have to skip past them.
+        uint64_t RecordSize = R->size() + 2;
+        uint64_t AlignedSize = alignTo(RecordSize, 4);
+        uint64_t AlignedRecordSize = AlignedSize - 2;
+        assert(AlignedRecordSize < (1 << 16) && "type record size overflow");
+        OS.AddComment("Type record length");
+        OS.EmitIntValue(AlignedRecordSize, 2);
+        OS.AddComment("Type record data");
+        OS.EmitBytes(StringRef(R->data(), R->size()));
+        // Pad the record with LF_PAD bytes.
+        for (unsigned I = AlignedSize - RecordSize; I > 0; --I)
+          OS.EmitIntValue(LF_PAD0 + I, 1);
+      });
 }
 
 void CodeViewDebug::emitInlineeFuncIdsAndLines() {
@@ -330,8 +316,10 @@ void CodeViewDebug::emitInlineeFuncIdsAn
   OS.AddComment("Inlinee lines signature");
   OS.EmitIntValue(unsigned(InlineeLinesSignature::Normal), 4);
 
-  unsigned InlineeIndex = FuncIdTypeIndexStart;
   for (const DISubprogram *SP : InlinedSubprograms) {
+    assert(TypeIndices.count(SP));
+    TypeIndex InlineeIdx = TypeIndices[SP];
+
     OS.AddBlankLine();
     unsigned FileId = maybeRecordFile(SP->getFile());
     OS.AddComment("Inlined function " + SP->getDisplayName() + " starts at " +
@@ -341,14 +329,11 @@ void CodeViewDebug::emitInlineeFuncIdsAn
     // 1.
     unsigned FileOffset = (FileId - 1) * 8;
     OS.AddComment("Type index of inlined function");
-    OS.EmitIntValue(InlineeIndex, 4);
+    OS.EmitIntValue(InlineeIdx.getIndex(), 4);
     OS.AddComment("Offset into filechecksum table");
     OS.EmitIntValue(FileOffset, 4);
     OS.AddComment("Starting line number");
     OS.EmitIntValue(SP->getLine(), 4);
-
-    // The next inlined subprogram has the next function id.
-    InlineeIndex++;
   }
 
   OS.EmitLabel(InlineEnd);
@@ -371,8 +356,8 @@ void CodeViewDebug::emitInlinedCallSite(
   MCSymbol *InlineBegin = MMI->getContext().createTempSymbol(),
            *InlineEnd = MMI->getContext().createTempSymbol();
 
-  assert(SubprogramIndices.count(Site.Inlinee));
-  unsigned InlineeIdx = FuncIdTypeIndexStart + SubprogramIndices[Site.Inlinee];
+  assert(TypeIndices.count(Site.Inlinee));
+  TypeIndex InlineeIdx = TypeIndices[Site.Inlinee];
 
   // SymbolRecord
   OS.AddComment("Record length");
@@ -386,7 +371,7 @@ void CodeViewDebug::emitInlinedCallSite(
   OS.AddComment("PtrEnd");
   OS.EmitIntValue(0, 4);
   OS.AddComment("Inlinee type index");
-  OS.EmitIntValue(InlineeIdx, 4);
+  OS.EmitIntValue(InlineeIdx.getIndex(), 4);
 
   unsigned FileId = maybeRecordFile(Site.Inlinee->getFile());
   unsigned StartLineNum = Site.Inlinee->getLine();

Modified: llvm/trunk/lib/CodeGen/AsmPrinter/CodeViewDebug.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/AsmPrinter/CodeViewDebug.h?rev=270485&r1=270484&r2=270485&view=diff
==============================================================================
--- llvm/trunk/lib/CodeGen/AsmPrinter/CodeViewDebug.h (original)
+++ llvm/trunk/lib/CodeGen/AsmPrinter/CodeViewDebug.h Mon May 23 15:23:46 2016
@@ -20,6 +20,7 @@
 #include "llvm/CodeGen/AsmPrinter.h"
 #include "llvm/CodeGen/MachineFunction.h"
 #include "llvm/CodeGen/MachineModuleInfo.h"
+#include "llvm/DebugInfo/CodeView/MemoryTypeTableBuilder.h"
 #include "llvm/DebugInfo/CodeView/TypeIndex.h"
 #include "llvm/IR/DebugInfo.h"
 #include "llvm/IR/DebugLoc.h"
@@ -34,6 +35,7 @@ class LexicalScope;
 /// \brief Collects and handles line tables information in a CodeView format.
 class LLVM_LIBRARY_VISIBILITY CodeViewDebug : public DebugHandlerBase {
   MCStreamer &OS;
+  codeview::MemoryTypeTableBuilder TypeTable;
 
   /// Represents the most general definition range.
   struct LocalVarDefRange {
@@ -103,20 +105,16 @@ class LLVM_LIBRARY_VISIBILITY CodeViewDe
   /// to be confused with type indices for LF_FUNC_ID records.
   unsigned NextFuncId = 0;
 
-  /// The next available type index.
-  unsigned NextTypeIndex = llvm::codeview::TypeIndex::FirstNonSimpleIndex;
+  codeview::TypeIndex VoidFnTyIdx;
 
-  /// Get the next type index and reserve it. Can be used to reserve more than
-  /// one type index.
-  unsigned getNextTypeIndex(unsigned NumRecords = 1) {
-    unsigned Result = NextTypeIndex;
-    NextTypeIndex += NumRecords;
-    return Result;
-  }
+  /// Get a type index for a generic void function type.
+  codeview::TypeIndex getGenericFunctionTypeIndex();
 
   InlineSite &getInlineSite(const DILocation *InlinedAt,
                             const DISubprogram *Inlinee);
 
+  void recordFuncIdForSubprogram(const DISubprogram *SP);
+
   static void collectInlineSiteChildren(SmallVectorImpl<unsigned> &Children,
                                         const FunctionInfo &FI,
                                         const InlineSite &Site);
@@ -128,18 +126,12 @@ class LLVM_LIBRARY_VISIBILITY CodeViewDe
   /// Map from DIFile to .cv_file id.
   DenseMap<const DIFile *, unsigned> FileIdMap;
 
-  /// Map from subprogram to index in InlinedSubprograms.
-  DenseMap<const DISubprogram *, size_t> SubprogramIndices;
-
   /// All inlined subprograms in the order they should be emitted.
-  SmallVector<const DISubprogram *, 4> InlinedSubprograms;
+  SmallSetVector<const DISubprogram *, 4> InlinedSubprograms;
 
-  /// The first type index that refers to an LF_FUNC_ID record. We have one
-  /// record per inlined subprogram.
-  /// FIXME: Keep in sync with emitTypeInformation until we buffer type records
-  /// on the side as we go. Once we buffer type records, we can allocate type
-  /// indices on demand without interleaving our assembly output.
-  unsigned FuncIdTypeIndexStart = NextTypeIndex + 2;
+  /// Map from DI metadata nodes to CodeView type indices. Primarily indexed by
+  /// DIType* and DISubprogram*.
+  DenseMap<const DINode *, codeview::TypeIndex> TypeIndices;
 
   typedef std::map<const DIFile *, std::string> FileToFilepathMapTy;
   FileToFilepathMapTy FileToFilepathMap;

Added: llvm/trunk/test/DebugInfo/COFF/inlining-padding.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/DebugInfo/COFF/inlining-padding.ll?rev=270485&view=auto
==============================================================================
--- llvm/trunk/test/DebugInfo/COFF/inlining-padding.ll (added)
+++ llvm/trunk/test/DebugInfo/COFF/inlining-padding.ll Mon May 23 15:23:46 2016
@@ -0,0 +1,101 @@
+; RUN: llc < %s -filetype=obj -o - | llvm-readobj -codeview -codeview-subsection-bytes | FileCheck %s
+
+; Check how we pad out the LF_FUNC_ID records. The 00F3F2F1 bytes in LeafData are
+; what's interesting here.
+
+; CHECK:  FuncId (0x1002) {
+; CHECK:    TypeLeafKind: LF_FUNC_ID (0x1601)
+; CHECK:    Name: a
+; CHECK:    LeafData (
+; CHECK:      0000: {{.*}} 6100F2F1           |........a...|
+; CHECK:    )
+; CHECK:  }
+; CHECK:  FuncId (0x1003) {
+; CHECK:    TypeLeafKind: LF_FUNC_ID (0x1601)
+; CHECK:    Name: ab
+; CHECK:    LeafData (
+; CHECK:      0000: {{.*}} 616200F1           |........ab..|
+; CHECK:    )
+; CHECK:  }
+; CHECK:  FuncId (0x1004) {
+; CHECK:    TypeLeafKind: LF_FUNC_ID (0x1601)
+; CHECK:    Name: abc
+; CHECK:    LeafData (
+; CHECK:      0000: {{.*}} 61626300           |........abc.|
+; CHECK:    )
+; CHECK:  }
+; CHECK:  FuncId (0x1005) {
+; CHECK:    TypeLeafKind: LF_FUNC_ID (0x1601)
+; CHECK:    Name: abcd
+; CHECK:    LeafData (
+; CHECK:      0000: {{.*}} 61626364 00F3F2F1  |........abcd....|
+; CHECK:    )
+; CHECK:  }
+
+; C++ source used to generate the IR:
+;
+; extern volatile int x;
+; static void a() { x++; }
+; static void ab() { x++; }
+; static void abc() { x++; }
+; static void abcd() { x++; }
+; int main() {
+;   a();
+;   ab();
+;   abc();
+;   abcd();
+; }
+
+; ModuleID = 't.cpp'
+source_filename = "t.cpp"
+target datalayout = "e-m:w-i64:64-f80:128-n8:16:32:64-S128"
+target triple = "x86_64-pc-windows-msvc"
+
+ at x = external global i32, align 4
+
+; Function Attrs: norecurse nounwind
+define i32 @main() #0 !dbg !6 {
+entry:
+  store volatile i32 0, i32* @x, align 4, !dbg !11, !tbaa !16
+  store volatile i32 0, i32* @x, align 4, !dbg !20, !tbaa !16
+  store volatile i32 0, i32* @x, align 4, !dbg !23, !tbaa !16
+  store volatile i32 0, i32* @x, align 4, !dbg !26, !tbaa !16
+  ret i32 0, !dbg !29
+}
+
+attributes #0 = { norecurse nounwind "disable-tail-calls"="false" "less-precise-fpmad"="false" "no-frame-pointer-elim"="false" "no-infs-fp-math"="false" "no-jump-tables"="false" "no-nans-fp-math"="false" "stack-protector-buffer-size"="8" "target-features"="+mmx,+sse,+sse2,+x87" "unsafe-fp-math"="false" "use-soft-float"="false" }
+
+!llvm.dbg.cu = !{!0}
+!llvm.module.flags = !{!3, !4}
+!llvm.ident = !{!5}
+
+!0 = distinct !DICompileUnit(language: DW_LANG_C99, file: !1, producer: "clang version 3.9.0 (trunk 270461) (llvm/trunk 270469)", isOptimized: true, runtimeVersion: 0, emissionKind: FullDebug, enums: !2)
+!1 = !DIFile(filename: "<stdin>", directory: "D:\5Csrc\5Cllvm\5Cbuild")
+!2 = !{}
+!3 = !{i32 2, !"CodeView", i32 1}
+!4 = !{i32 2, !"Debug Info Version", i32 3}
+!5 = !{!"clang version 3.9.0 (trunk 270461) (llvm/trunk 270469)"}
+!6 = distinct !DISubprogram(name: "main", scope: !7, file: !7, line: 6, type: !8, isLocal: false, isDefinition: true, scopeLine: 6, isOptimized: true, unit: !0, variables: !2)
+!7 = !DIFile(filename: "t.cpp", directory: "D:\5Csrc\5Cllvm\5Cbuild")
+!8 = !DISubroutineType(types: !9)
+!9 = !{!10}
+!10 = !DIBasicType(name: "int", size: 32, align: 32, encoding: DW_ATE_signed)
+!11 = !DILocation(line: 2, scope: !12, inlinedAt: !15)
+!12 = distinct !DISubprogram(name: "a", scope: !7, file: !7, line: 2, type: !13, isLocal: true, isDefinition: true, scopeLine: 2, isOptimized: true, unit: !0, variables: !2)
+!13 = !DISubroutineType(types: !14)
+!14 = !{null}
+!15 = distinct !DILocation(line: 7, scope: !6)
+!16 = !{!17, !17, i64 0}
+!17 = !{!"int", !18, i64 0}
+!18 = !{!"omnipotent char", !19, i64 0}
+!19 = !{!"Simple C/C++ TBAA"}
+!20 = !DILocation(line: 3, scope: !21, inlinedAt: !22)
+!21 = distinct !DISubprogram(name: "ab", scope: !7, file: !7, line: 3, type: !13, isLocal: true, isDefinition: true, scopeLine: 3, isOptimized: true, unit: !0, variables: !2)
+!22 = distinct !DILocation(line: 8, scope: !6)
+!23 = !DILocation(line: 4, scope: !24, inlinedAt: !25)
+!24 = distinct !DISubprogram(name: "abc", scope: !7, file: !7, line: 4, type: !13, isLocal: true, isDefinition: true, scopeLine: 4, isOptimized: true, unit: !0, variables: !2)
+!25 = distinct !DILocation(line: 9, scope: !6)
+!26 = !DILocation(line: 5, scope: !27, inlinedAt: !28)
+!27 = distinct !DISubprogram(name: "abcd", scope: !7, file: !7, line: 5, type: !13, isLocal: true, isDefinition: true, scopeLine: 5, isOptimized: true, unit: !0, variables: !2)
+!28 = distinct !DILocation(line: 10, scope: !6)
+!29 = !DILocation(line: 11, scope: !6)

Added: llvm/trunk/test/DebugInfo/COFF/inlining-same-name.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/DebugInfo/COFF/inlining-same-name.ll?rev=270485&view=auto
==============================================================================
--- llvm/trunk/test/DebugInfo/COFF/inlining-same-name.ll (added)
+++ llvm/trunk/test/DebugInfo/COFF/inlining-same-name.ll Mon May 23 15:23:46 2016
@@ -0,0 +1,57 @@
+; RUN: llc -mtriple=x86_64-windows-msvc < %s -filetype=obj -o - | llvm-readobj - -codeview | FileCheck %s
+
+; We should only get one func id record, and both inlinees should point to it,
+; even though there are two DISubprograms.
+
+; CHECK:  FuncId (0x1002) {
+; CHECK-NEXT:    TypeLeafKind: LF_FUNC_ID (0x1601)
+; CHECK-NEXT:    ParentScope: 0x0
+; CHECK-NEXT:    FunctionType: void () (0x1001)
+; CHECK-NEXT:    Name: same_name
+; CHECK-NEXT:  }
+; CHECK-NOT:    Name: same_name
+
+; CHECK: CodeViewDebugInfo [
+; CHECK:   Section: .debug$S
+; CHECK:   Subsection [
+; CHECK:     ProcStart {
+; CHECK:       DisplayName: main
+; CHECK:     }
+; CHECK:     InlineSite {
+; CHECK:       Inlinee: same_name (0x1002)
+; CHECK:     }
+; CHECK:     InlineSiteEnd {
+; CHECK:     }
+; CHECK:     InlineSite {
+; CHECK:       Inlinee: same_name (0x1002)
+; CHECK:     }
+; CHECK:     InlineSiteEnd {
+; CHECK:     }
+; CHECK:     ProcEnd
+; CHECK:   ]
+
+target datalayout = "e-m:w-i64:64-f80:128-n8:16:32:64-S128"
+target triple = "x86_64-pc-windows-msvc"
+
+define void @main(i32* %i.i) {
+  store volatile i32 3, i32* %i.i, !dbg !6
+  store volatile i32 3, i32* %i.i, !dbg !19
+  ret void
+}
+
+!llvm.module.flags = !{!0, !1, !2}
+!llvm.dbg.cu = !{!4}
+
+!0 = !{i32 2, !"CodeView", i32 1}
+!1 = !{i32 2, !"Debug Info Version", i32 3}
+!2 = !{i32 6, !"Linker Options", !{}}
+!4 = distinct !DICompileUnit(language: DW_LANG_D, file: !5, producer: "LDC (http://wiki.dlang.org/LDC)", isOptimized: false, runtimeVersion: 1, emissionKind: FullDebug)
+!5 = !DIFile(filename: "opover2.d", directory: "C:\5CLDC\5Cninja-ldc\5C..\5Cldc\5Ctests\5Cd2\5Cdmd-testsuite\5Crunnable")
+!6 = !DILocation(line: 302, column: 9, scope: !7, inlinedAt: !15)
+!7 = distinct !DISubprogram(name: "same_name", linkageName: "same_name", scope: null, file: !5, line: 302, type: !8, isLocal: false, isDefinition: true, scopeLine: 302, flags: DIFlagPrototyped, isOptimized: false, unit: !4, variables: !{})
+!8 = !DISubroutineType(types: !{})
+!15 = distinct !DILocation(line: 333, column: 5, scope: !16)
+!16 = distinct !DISubprogram(name: "main", linkageName: "main", scope: null, file: !5, line: 328, type: !8, isLocal: false, isDefinition: true, scopeLine: 328, flags: DIFlagPrototyped, isOptimized: false, unit: !4, variables: !{})
+!19 = !DILocation(line: 308, column: 9, scope: !20, inlinedAt: !25)
+!20 = distinct !DISubprogram(name: "same_name", linkageName: "same_name",  scope: null, file: !5, line: 308, type: !8, isLocal: false, isDefinition: true, scopeLine: 308, flags: DIFlagPrototyped, isOptimized: false, unit: !4, variables: !{})
+!25 = distinct !DILocation(line: 334, column: 5, scope: !16)




More information about the llvm-commits mailing list