diff options
Diffstat (limited to 'llvm/test/DebugInfo/Generic')
76 files changed, 5940 insertions, 0 deletions
diff --git a/llvm/test/DebugInfo/Generic/2009-10-16-Phi.ll b/llvm/test/DebugInfo/Generic/2009-10-16-Phi.ll new file mode 100644 index 00000000000..e14653f6fcf --- /dev/null +++ b/llvm/test/DebugInfo/Generic/2009-10-16-Phi.ll @@ -0,0 +1,13 @@ +; RUN: llvm-as %s -disable-output + +define i32 @foo() { +E: + br label %B2 +B1: + br label %B2 +B2: + %0 = phi i32 [ 0, %E ], [ 1, %B1 ], !dbg !0 + ret i32 %0 +} + +!0 = !{i32 42} diff --git a/llvm/test/DebugInfo/Generic/2009-11-03-InsertExtractValue.ll b/llvm/test/DebugInfo/Generic/2009-11-03-InsertExtractValue.ll new file mode 100644 index 00000000000..c992a43c858 --- /dev/null +++ b/llvm/test/DebugInfo/Generic/2009-11-03-InsertExtractValue.ll @@ -0,0 +1,23 @@ +; RUN: llvm-as < %s | llvm-dis | FileCheck %s + +!llvm.dbg.sp = !{!0} +!llvm.dbg.cu = !{!5} +!llvm.module.flags = !{!6} + +!0 = !DISubprogram(name: "bar", linkageName: "_ZN3foo3barEv", line: 3, isLocal: false, isDefinition: false, virtualIndex: 6, flags: DIFlagProtected | DIFlagPrototyped, isOptimized: false, scopeLine: 3, file: !4, scope: !1, type: !2) +!1 = !DIFile(filename: "/foo", directory: "bar.cpp") +!2 = !DISubroutineType(types: !3) +!3 = !{null} +!4 = !DIFile(filename: "/foo", directory: "bar.cpp") +!5 = distinct !DICompileUnit(language: DW_LANG_C99, isOptimized: true, emissionKind: 0, file: !4, enums: !{}, retainedTypes: !{}) + +define <{i32, i32}> @f1() { +; CHECK: !dbgx ![[NUMBER:[0-9]+]] + %r = insertvalue <{ i32, i32 }> zeroinitializer, i32 4, 1, !dbgx !1 +; CHECK: !dbgx ![[NUMBER]] + %e = extractvalue <{ i32, i32 }> %r, 0, !dbgx !1 + ret <{ i32, i32 }> %r +} + +; CHECK: DIFlagProtected +!6 = !{i32 1, !"Debug Info Version", i32 3} diff --git a/llvm/test/DebugInfo/Generic/2009-11-05-DeadGlobalVariable.ll b/llvm/test/DebugInfo/Generic/2009-11-05-DeadGlobalVariable.ll new file mode 100644 index 00000000000..3791005dcfe --- /dev/null +++ b/llvm/test/DebugInfo/Generic/2009-11-05-DeadGlobalVariable.ll @@ -0,0 +1,26 @@ +; RUN: llc %s -o /dev/null +; Here variable bar is optimized away. Do not trip over while trying to generate debug info. + + +define i32 @foo() nounwind uwtable readnone ssp { +entry: + ret i32 42, !dbg !15 +} + +!llvm.dbg.cu = !{!0} +!llvm.module.flags = !{!18} + +!0 = distinct !DICompileUnit(language: DW_LANG_C99, producer: "clang version 3.0 (trunk 139632)", isOptimized: true, emissionKind: 0, file: !17, enums: !1, retainedTypes: !1, subprograms: !3, globals: !12) +!1 = !{} +!3 = !{!5} +!5 = distinct !DISubprogram(name: "foo", line: 1, isLocal: false, isDefinition: true, virtualIndex: 6, isOptimized: true, file: !17, scope: !6, type: !7, function: i32 ()* @foo) +!6 = !DIFile(filename: "fb.c", directory: "/private/tmp") +!7 = !DISubroutineType(types: !8) +!8 = !{!9} +!9 = !DIBasicType(tag: DW_TAG_base_type, name: "int", size: 32, align: 32, encoding: DW_ATE_signed) +!12 = !{!14} +!14 = !DIGlobalVariable(name: "bar", line: 2, isLocal: true, isDefinition: true, scope: !5, file: !6, type: !9) +!15 = !DILocation(line: 3, column: 3, scope: !16) +!16 = distinct !DILexicalBlock(line: 1, column: 11, file: !17, scope: !5) +!17 = !DIFile(filename: "fb.c", directory: "/private/tmp") +!18 = !{i32 1, !"Debug Info Version", i32 3} diff --git a/llvm/test/DebugInfo/Generic/2009-11-06-NamelessGlobalVariable.ll b/llvm/test/DebugInfo/Generic/2009-11-06-NamelessGlobalVariable.ll new file mode 100644 index 00000000000..a871a257cc8 --- /dev/null +++ b/llvm/test/DebugInfo/Generic/2009-11-06-NamelessGlobalVariable.ll @@ -0,0 +1,14 @@ +; RUN: llc %s -o /dev/null +@0 = internal constant i32 1 + +!llvm.dbg.cu = !{!0} +!llvm.module.flags = !{!9} + +!0 = distinct !DICompileUnit(language: DW_LANG_C99, producer: "clang version 3.0 (trunk 139632)", isOptimized: true, emissionKind: 0, file: !8, enums: !2, retainedTypes: !2, subprograms: !2, globals: !3) +!2 = !{} +!3 = !{!5} +!5 = !DIGlobalVariable(name: "a", line: 2, isLocal: false, isDefinition: true, scope: null, file: !6, type: !7, variable: i32* @0) +!6 = !DIFile(filename: "g.c", directory: "/private/tmp") +!7 = !DIBasicType(tag: DW_TAG_base_type, name: "int", size: 32, align: 32, encoding: DW_ATE_signed) +!8 = !DIFile(filename: "g.c", directory: "/private/tmp") +!9 = !{i32 1, !"Debug Info Version", i32 3} diff --git a/llvm/test/DebugInfo/Generic/2009-11-10-CurrentFn.ll b/llvm/test/DebugInfo/Generic/2009-11-10-CurrentFn.ll new file mode 100644 index 00000000000..7817a73ed97 --- /dev/null +++ b/llvm/test/DebugInfo/Generic/2009-11-10-CurrentFn.ll @@ -0,0 +1,31 @@ +; RUN: llc < %s -o /dev/null + +define void @bar(i32 %i) nounwind uwtable ssp { +entry: + tail call void (...) @foo() nounwind, !dbg !14 + ret void, !dbg !16 +} + +declare void @foo(...) + +declare void @llvm.dbg.value(metadata, i64, metadata, metadata) nounwind readnone + +!llvm.dbg.cu = !{!0} +!llvm.module.flags = !{!18} + +!0 = distinct !DICompileUnit(language: DW_LANG_C99, producer: "clang version 3.0 (trunk 139632)", isOptimized: true, emissionKind: 0, file: !17, enums: !1, retainedTypes: !1, subprograms: !3, globals: !1) +!1 = !{} +!3 = !{!5} +!5 = distinct !DISubprogram(name: "bar", line: 3, isLocal: false, isDefinition: true, virtualIndex: 6, flags: DIFlagPrototyped, isOptimized: true, file: !17, scope: !6, type: !7, function: void (i32)* @bar, variables: !9) +!6 = !DIFile(filename: "cf.c", directory: "/private/tmp") +!7 = !DISubroutineType(types: !8) +!8 = !{null} +!9 = !{!11} +!11 = !DILocalVariable(name: "i", line: 3, arg: 1, scope: !5, file: !17, type: !12) +!12 = !DIBasicType(tag: DW_TAG_base_type, name: "int", size: 32, align: 32, encoding: DW_ATE_signed) +!13 = !DILocation(line: 3, column: 14, scope: !5) +!14 = !DILocation(line: 4, column: 3, scope: !15) +!15 = distinct !DILexicalBlock(line: 3, column: 17, file: !17, scope: !5) +!16 = !DILocation(line: 5, column: 1, scope: !15) +!17 = !DIFile(filename: "cf.c", directory: "/private/tmp") +!18 = !{i32 1, !"Debug Info Version", i32 3} diff --git a/llvm/test/DebugInfo/Generic/2010-01-05-DbgScope.ll b/llvm/test/DebugInfo/Generic/2010-01-05-DbgScope.ll new file mode 100644 index 00000000000..c6d7ca85847 --- /dev/null +++ b/llvm/test/DebugInfo/Generic/2010-01-05-DbgScope.ll @@ -0,0 +1,25 @@ +; RUN: llc < %s -o /dev/null +; PR 5942 +define i8* @foo() nounwind { +entry: + %0 = load i32, i32* undef, align 4, !dbg !0 ; <i32> [#uses=1] + %1 = inttoptr i32 %0 to i8*, !dbg !0 ; <i8*> [#uses=1] + ret i8* %1, !dbg !10 + +} + +!llvm.dbg.cu = !{!3} +!llvm.module.flags = !{!14} + +!0 = !DILocation(line: 571, column: 3, scope: !1) +!1 = distinct !DILexicalBlock(line: 1, column: 1, file: !11, scope: !2) +!2 = distinct !DISubprogram(name: "foo", linkageName: "foo", line: 561, isLocal: false, isDefinition: true, virtualIndex: 6, isOptimized: false, scope: !3, type: !4) +!3 = distinct !DICompileUnit(language: DW_LANG_C99, producer: "clang 1.1", isOptimized: true, emissionKind: 0, file: !11, enums: !12, retainedTypes: !12, subprograms: !13) +!4 = !DISubroutineType(types: !5) +!5 = !{!6} +!6 = !DIBasicType(tag: DW_TAG_base_type, name: "char", size: 8, align: 8, encoding: DW_ATE_signed_char) +!10 = !DILocation(line: 588, column: 1, scope: !2) +!11 = !DIFile(filename: "hashtab.c", directory: "/usr/src/gnu/usr.bin/cc/cc_tools/../../../../contrib/gcclibs/libiberty") +!12 = !{} +!13 = !{!2} +!14 = !{i32 1, !"Debug Info Version", i32 3} diff --git a/llvm/test/DebugInfo/Generic/2010-03-12-llc-crash.ll b/llvm/test/DebugInfo/Generic/2010-03-12-llc-crash.ll new file mode 100644 index 00000000000..aaa013c803f --- /dev/null +++ b/llvm/test/DebugInfo/Generic/2010-03-12-llc-crash.ll @@ -0,0 +1,22 @@ +; RUN: llc -O0 < %s -o /dev/null +; llc should not crash on this optimized out debug info. +; PR6588 +declare void @llvm.dbg.declare(metadata, metadata, metadata) nounwind readnone + +define void @foo() { +entry: + call void @llvm.dbg.declare(metadata i32* undef, metadata !0, metadata !DIExpression()), !dbg !DILocation(scope: !1) + ret void +} + +!0 = !DILocalVariable(name: "sy", line: 890, arg: 1, scope: !1, file: !2, type: !7) +!1 = distinct !DISubprogram(name: "foo", linkageName: "foo", line: 892, isLocal: false, isDefinition: true, virtualIndex: 6, isOptimized: false, file: !8, scope: !3, type: !4) +!2 = !DIFile(filename: "qpainter.h", directory: "QtGui") +!3 = distinct !DICompileUnit(language: DW_LANG_C_plus_plus, producer: "clang 1.1", isOptimized: true, emissionKind: 0, file: !9, enums: !10, retainedTypes: !10) +!4 = !DISubroutineType(types: !6) +!5 = !DIFile(filename: "splineeditor.cpp", directory: "src") +!6 = !{null} +!7 = !DIBasicType(tag: DW_TAG_base_type, name: "int", size: 32, align: 32, encoding: DW_ATE_signed) +!8 = !DIFile(filename: "qpainter.h", directory: "QtGui") +!9 = !DIFile(filename: "splineeditor.cpp", directory: "src") +!10 = !{i32 0} diff --git a/llvm/test/DebugInfo/Generic/2010-03-19-DbgDeclare.ll b/llvm/test/DebugInfo/Generic/2010-03-19-DbgDeclare.ll new file mode 100644 index 00000000000..fe7eaebc4ed --- /dev/null +++ b/llvm/test/DebugInfo/Generic/2010-03-19-DbgDeclare.ll @@ -0,0 +1,20 @@ +; RUN: opt < %s -verify -S | FileCheck %s + +; CHECK: DW_LANG_Mips_Assembler + +define void @Foo(i32 %a, i32 %b) { +entry: + call void @llvm.dbg.declare(metadata i32* null, metadata !1, metadata !DIExpression()), !dbg !DILocation(scope: !6) + ret void +} +!llvm.dbg.cu = !{!2} +!llvm.module.flags = !{!5} +!2 = distinct !DICompileUnit(language: DW_LANG_Mips_Assembler, producer: "clang version 3.3 ", isOptimized: false, emissionKind: 1, file: !4, enums: !3, retainedTypes: !3, subprograms: !3, globals: !3, imports: !3) +!3 = !{} +!0 = !DILocation(line: 662302, column: 26, scope: !1) +!1 = !DILocalVariable(name: "foo", scope: !6) +!4 = !DIFile(filename: "scratch.cpp", directory: "/usr/local/google/home/blaikie/dev/scratch") +!6 = distinct !DISubprogram() + +declare void @llvm.dbg.declare(metadata, metadata, metadata) nounwind readnone +!5 = !{i32 1, !"Debug Info Version", i32 3} diff --git a/llvm/test/DebugInfo/Generic/2010-03-24-MemberFn.ll b/llvm/test/DebugInfo/Generic/2010-03-24-MemberFn.ll new file mode 100644 index 00000000000..298c30e3de2 --- /dev/null +++ b/llvm/test/DebugInfo/Generic/2010-03-24-MemberFn.ll @@ -0,0 +1,70 @@ +; RUN: %llc_dwarf -O0 < %s | grep AT_decl_file | grep 2 +; Here _ZN1S3fooEv is defined in header file identified as AT_decl_file no. 2 in debug info. +%struct.S = type <{ i8 }> + +define i32 @_Z3barv() nounwind ssp { +entry: + %retval = alloca i32 ; <i32*> [#uses=2] + %0 = alloca i32 ; <i32*> [#uses=2] + %s1 = alloca %struct.S ; <%struct.S*> [#uses=1] + %"alloca point" = bitcast i32 0 to i32 ; <i32> [#uses=0] + call void @llvm.dbg.declare(metadata %struct.S* %s1, metadata !0, metadata !DIExpression()), !dbg !16 + %1 = call i32 @_ZN1S3fooEv(%struct.S* %s1) nounwind, !dbg !17 ; <i32> [#uses=1] + store i32 %1, i32* %0, align 4, !dbg !17 + %2 = load i32, i32* %0, align 4, !dbg !17 ; <i32> [#uses=1] + store i32 %2, i32* %retval, align 4, !dbg !17 + br label %return, !dbg !17 + +return: ; preds = %entry + %retval1 = load i32, i32* %retval, !dbg !17 ; <i32> [#uses=1] + ret i32 %retval1, !dbg !16 +} + +define linkonce_odr i32 @_ZN1S3fooEv(%struct.S* %this) nounwind ssp align 2 { +entry: + %this_addr = alloca %struct.S* ; <%struct.S**> [#uses=1] + %retval = alloca i32 ; <i32*> [#uses=1] + %"alloca point" = bitcast i32 0 to i32 ; <i32> [#uses=0] + call void @llvm.dbg.declare(metadata %struct.S** %this_addr, metadata !18, metadata !DIExpression()), !dbg !21 + store %struct.S* %this, %struct.S** %this_addr + br label %return, !dbg !21 + +return: ; preds = %entry + %retval1 = load i32, i32* %retval, !dbg !21 ; <i32> [#uses=1] + ret i32 %retval1, !dbg !22 +} + +declare void @llvm.dbg.declare(metadata, metadata, metadata) nounwind readnone + +!llvm.dbg.cu = !{!5} +!llvm.module.flags = !{!28} + +!0 = !DILocalVariable(name: "s1", line: 3, scope: !1, file: !4, type: !9) +!1 = distinct !DILexicalBlock(line: 3, column: 0, file: !25, scope: !2) +!2 = distinct !DILexicalBlock(line: 3, column: 0, file: !25, scope: !3) +!3 = distinct !DISubprogram(name: "bar", linkageName: "_Z3barv", line: 3, isLocal: false, isDefinition: true, virtualIndex: 6, isOptimized: false, scopeLine: 3, file: !25, scope: !4, type: !6, function: i32 ()* @_Z3barv) +!4 = !DIFile(filename: "one.cc", directory: "/tmp/") +!5 = distinct !DICompileUnit(language: DW_LANG_C_plus_plus, producer: "4.2.1 (Based on Apple Inc. build 5658) (LLVM build)", isOptimized: false, emissionKind: 0, file: !25, enums: !27, retainedTypes: !27, subprograms: !24, imports: null) +!6 = !DISubroutineType(types: !7) +!7 = !{!8} +!8 = !DIBasicType(tag: DW_TAG_base_type, name: "int", size: 32, align: 32, encoding: DW_ATE_signed) +!9 = !DICompositeType(tag: DW_TAG_structure_type, name: "S", line: 2, size: 8, align: 8, file: !26, scope: !4, elements: !11) +!10 = !DIFile(filename: "one.h", directory: "/tmp/") +!11 = !{!12} +!12 = distinct !DISubprogram(name: "foo", linkageName: "_ZN1S3fooEv", line: 3, isLocal: false, isDefinition: true, virtualIndex: 6, isOptimized: false, scopeLine: 3, file: !26, scope: !9, type: !13, function: i32 (%struct.S*)* @_ZN1S3fooEv) +!13 = !DISubroutineType(types: !14) +!14 = !{!8, !15} +!15 = !DIDerivedType(tag: DW_TAG_pointer_type, size: 64, align: 64, flags: DIFlagArtificial, file: !25, scope: !4, baseType: !9) +!16 = !DILocation(line: 3, scope: !1) +!17 = !DILocation(line: 3, scope: !3) +!18 = !DILocalVariable(name: "this", line: 3, arg: 1, scope: !12, file: !10, type: !19) +!19 = !DIDerivedType(tag: DW_TAG_const_type, size: 64, align: 64, flags: DIFlagArtificial, file: !25, scope: !4, baseType: !20) +!20 = !DIDerivedType(tag: DW_TAG_pointer_type, size: 64, align: 64, file: !25, scope: !4, baseType: !9) +!21 = !DILocation(line: 3, scope: !12) +!22 = !DILocation(line: 3, scope: !23) +!23 = distinct !DILexicalBlock(line: 3, column: 0, file: !26, scope: !12) +!24 = !{!3, !12} +!25 = !DIFile(filename: "one.cc", directory: "/tmp/") +!26 = !DIFile(filename: "one.h", directory: "/tmp/") +!27 = !{} +!28 = !{i32 1, !"Debug Info Version", i32 3} diff --git a/llvm/test/DebugInfo/Generic/2010-04-06-NestedFnDbgInfo.ll b/llvm/test/DebugInfo/Generic/2010-04-06-NestedFnDbgInfo.ll new file mode 100644 index 00000000000..fd9124ad00a --- /dev/null +++ b/llvm/test/DebugInfo/Generic/2010-04-06-NestedFnDbgInfo.ll @@ -0,0 +1,112 @@ +; REQUIRES: object-emission + +; RUN: %llc_dwarf -O0 -filetype=obj -o - < %s | llvm-dwarfdump -debug-dump=info - | FileCheck %s +; Radar 7833483 +; Do not emit a separate out-of-line definition DIE for the function-local 'foo' +; function (member of the function local 'A' type) +; CHECK: DW_TAG_class_type +; CHECK: DW_TAG_class_type +; CHECK-NEXT: DW_AT_name {{.*}} "A" +; Check that the subprogram inside the class definition has low_pc, only +; attached to the definition. +; CHECK: [[FOO_INL:0x........]]: DW_TAG_subprogram +; CHECK-NOT: DW_TAG +; CHECK: DW_AT_low_pc +; CHECK-NOT: DW_TAG +; CHECK: DW_AT_name {{.*}} "foo" +; And just double check that there's no out of line definition that references +; this subprogram. +; CHECK-NOT: DW_AT_specification {{.*}} {[[FOO_INL]]} + +%class.A = type { i8 } +%class.B = type { i8 } + +define i32 @main() ssp { +entry: + %retval = alloca i32, align 4 ; <i32*> [#uses=3] + %b = alloca %class.A, align 1 ; <%class.A*> [#uses=1] + store i32 0, i32* %retval + call void @llvm.dbg.declare(metadata %class.A* %b, metadata !0, metadata !DIExpression()), !dbg !14 + %call = call i32 @_ZN1B2fnEv(%class.A* %b), !dbg !15 ; <i32> [#uses=1] + store i32 %call, i32* %retval, !dbg !15 + %0 = load i32, i32* %retval, !dbg !16 ; <i32> [#uses=1] + ret i32 %0, !dbg !16 +} + +declare void @llvm.dbg.declare(metadata, metadata, metadata) nounwind readnone + +define linkonce_odr i32 @_ZN1B2fnEv(%class.A* %this) ssp align 2 { +entry: + %retval = alloca i32, align 4 ; <i32*> [#uses=2] + %this.addr = alloca %class.A*, align 8 ; <%class.A**> [#uses=2] + %a = alloca %class.A, align 1 ; <%class.A*> [#uses=1] + %i = alloca i32, align 4 ; <i32*> [#uses=2] + store %class.A* %this, %class.A** %this.addr + call void @llvm.dbg.declare(metadata %class.A** %this.addr, metadata !17, metadata !DIExpression()), !dbg !18 + %this1 = load %class.A*, %class.A** %this.addr ; <%class.A*> [#uses=0] + call void @llvm.dbg.declare(metadata %class.A* %a, metadata !19, metadata !DIExpression()), !dbg !27 + call void @llvm.dbg.declare(metadata i32* %i, metadata !28, metadata !DIExpression()), !dbg !29 + %call = call i32 @_ZZN1B2fnEvEN1A3fooEv(%class.A* %a), !dbg !30 ; <i32> [#uses=1] + store i32 %call, i32* %i, !dbg !30 + %tmp = load i32, i32* %i, !dbg !31 ; <i32> [#uses=1] + store i32 %tmp, i32* %retval, !dbg !31 + %0 = load i32, i32* %retval, !dbg !32 ; <i32> [#uses=1] + ret i32 %0, !dbg !32 +} + +define internal i32 @_ZZN1B2fnEvEN1A3fooEv(%class.A* %this) ssp align 2 { +entry: + %retval = alloca i32, align 4 ; <i32*> [#uses=2] + %this.addr = alloca %class.A*, align 8 ; <%class.A**> [#uses=2] + store %class.A* %this, %class.A** %this.addr + call void @llvm.dbg.declare(metadata %class.A** %this.addr, metadata !33, metadata !DIExpression()), !dbg !34 + %this1 = load %class.A*, %class.A** %this.addr ; <%class.A*> [#uses=0] + store i32 42, i32* %retval, !dbg !35 + %0 = load i32, i32* %retval, !dbg !35 ; <i32> [#uses=1] + ret i32 %0, !dbg !35 +} + +!llvm.dbg.cu = !{!4} +!llvm.module.flags = !{!40} +!37 = !{!2, !10, !23} + +!0 = !DILocalVariable(name: "b", line: 16, scope: !1, file: !3, type: !8) +!1 = distinct !DILexicalBlock(line: 15, column: 12, file: !38, scope: !2) +!2 = distinct !DISubprogram(name: "main", linkageName: "main", line: 15, isLocal: false, isDefinition: true, virtualIndex: 6, isOptimized: false, scopeLine: 15, file: !38, scope: !3, type: !5, function: i32 ()* @main) +!3 = !DIFile(filename: "one.cc", directory: "/tmp") +!4 = distinct !DICompileUnit(language: DW_LANG_C_plus_plus, producer: "clang 1.5", isOptimized: false, emissionKind: 0, file: !38, enums: !39, retainedTypes: !39, subprograms: !37, imports: null) +!5 = !DISubroutineType(types: !6) +!6 = !{!7} +!7 = !DIBasicType(tag: DW_TAG_base_type, name: "int", size: 32, align: 32, encoding: DW_ATE_signed) +!8 = !DICompositeType(tag: DW_TAG_class_type, name: "B", line: 2, size: 8, align: 8, file: !38, scope: !3, elements: !9) +!9 = !{!10} +!10 = distinct !DISubprogram(name: "fn", linkageName: "_ZN1B2fnEv", line: 4, isLocal: false, isDefinition: true, virtualIndex: 6, isOptimized: false, scopeLine: 4, file: !38, scope: !8, type: !11, function: i32 (%class.A*)* @_ZN1B2fnEv) +!11 = !DISubroutineType(types: !12) +!12 = !{!7, !13} +!13 = !DIDerivedType(tag: DW_TAG_pointer_type, size: 64, align: 64, flags: DIFlagArtificial, file: !38, scope: !3, baseType: !8) +!14 = !DILocation(line: 16, column: 5, scope: !1) +!15 = !DILocation(line: 17, column: 3, scope: !1) +!16 = !DILocation(line: 18, column: 1, scope: !2) +!17 = !DILocalVariable(name: "this", line: 4, arg: 1, scope: !10, file: !3, type: !13) +!18 = !DILocation(line: 4, column: 7, scope: !10) +!19 = !DILocalVariable(name: "a", line: 9, scope: !20, file: !3, type: !21) +!20 = distinct !DILexicalBlock(line: 4, column: 12, file: !38, scope: !10) +!21 = !DICompositeType(tag: DW_TAG_class_type, name: "A", line: 5, size: 8, align: 8, file: !38, scope: !10, elements: !22) +!22 = !{!23} +!23 = distinct !DISubprogram(name: "foo", linkageName: "_ZZN1B2fnEvEN1A3fooEv", line: 7, isLocal: false, isDefinition: true, virtualIndex: 6, isOptimized: false, scopeLine: 7, file: !38, scope: !21, type: !24, function: i32 (%class.A*)* @_ZZN1B2fnEvEN1A3fooEv) +!24 = !DISubroutineType(types: !25) +!25 = !{!7, !26} +!26 = !DIDerivedType(tag: DW_TAG_pointer_type, size: 64, align: 64, flags: DIFlagArtificial, file: !38, scope: !3, baseType: !21) +!27 = !DILocation(line: 9, column: 7, scope: !20) +!28 = !DILocalVariable(name: "i", line: 10, scope: !20, file: !3, type: !7) +!29 = !DILocation(line: 10, column: 9, scope: !20) +!30 = !DILocation(line: 10, column: 5, scope: !20) +!31 = !DILocation(line: 11, column: 5, scope: !20) +!32 = !DILocation(line: 12, column: 3, scope: !10) +!33 = !DILocalVariable(name: "this", line: 7, arg: 1, scope: !23, file: !3, type: !26) +!34 = !DILocation(line: 7, column: 11, scope: !23) +!35 = !DILocation(line: 7, column: 19, scope: !36) +!36 = distinct !DILexicalBlock(line: 7, column: 17, file: !38, scope: !23) +!38 = !DIFile(filename: "one.cc", directory: "/tmp") +!39 = !{} +!40 = !{i32 1, !"Debug Info Version", i32 3} diff --git a/llvm/test/DebugInfo/Generic/2010-04-19-FramePtr.ll b/llvm/test/DebugInfo/Generic/2010-04-19-FramePtr.ll new file mode 100644 index 00000000000..0b4cee03b25 --- /dev/null +++ b/llvm/test/DebugInfo/Generic/2010-04-19-FramePtr.ll @@ -0,0 +1,37 @@ +; RUN: %llc_dwarf -asm-verbose -O1 -o %t < %s +; RUN: grep DW_AT_APPLE_omit_frame_ptr %t +; RUN: %llc_dwarf -disable-fp-elim -asm-verbose -O1 -o %t < %s +; RUN: grep -v DW_AT_APPLE_omit_frame_ptr %t + + +define i32 @foo() nounwind ssp { +entry: + %retval = alloca i32 ; <i32*> [#uses=2] + %0 = alloca i32 ; <i32*> [#uses=2] + %"alloca point" = bitcast i32 0 to i32 ; <i32> [#uses=0] + store i32 42, i32* %0, align 4, !dbg !0 + %1 = load i32, i32* %0, align 4, !dbg !0 ; <i32> [#uses=1] + store i32 %1, i32* %retval, align 4, !dbg !0 + br label %return, !dbg !0 + +return: ; preds = %entry + %retval1 = load i32, i32* %retval, !dbg !0 ; <i32> [#uses=1] + ret i32 %retval1, !dbg !7 +} + +!llvm.dbg.cu = !{!3} +!llvm.module.flags = !{!12} +!9 = !{!1} + +!0 = !DILocation(line: 2, scope: !1) +!1 = distinct !DISubprogram(name: "foo", linkageName: "foo", line: 2, isLocal: false, isDefinition: true, virtualIndex: 6, isOptimized: false, scopeLine: 2, file: !10, scope: null, type: !4, function: i32 ()* @foo) +!2 = !DIFile(filename: "a.c", directory: "/tmp") +!3 = distinct !DICompileUnit(language: DW_LANG_C89, producer: "4.2.1 (Based on Apple Inc. build 5658) (LLVM build)", isOptimized: false, emissionKind: 0, file: !10, enums: !11, retainedTypes: !11, subprograms: !9, imports: null) +!4 = !DISubroutineType(types: !5) +!5 = !{!6} +!6 = !DIBasicType(tag: DW_TAG_base_type, name: "int", size: 32, align: 32, encoding: DW_ATE_signed) +!7 = !DILocation(line: 2, scope: !8) +!8 = distinct !DILexicalBlock(line: 2, column: 0, file: !10, scope: !1) +!10 = !DIFile(filename: "a.c", directory: "/tmp") +!11 = !{} +!12 = !{i32 1, !"Debug Info Version", i32 3} diff --git a/llvm/test/DebugInfo/Generic/2010-05-03-DisableFramePtr.ll b/llvm/test/DebugInfo/Generic/2010-05-03-DisableFramePtr.ll new file mode 100644 index 00000000000..c67ed73dac6 --- /dev/null +++ b/llvm/test/DebugInfo/Generic/2010-05-03-DisableFramePtr.ll @@ -0,0 +1,40 @@ +; RUN: llc -o /dev/null < %s +; Radar 7937664 +%struct.AppleEvent = type opaque + +define void @DisposeDMNotificationUPP(void (%struct.AppleEvent*)* %userUPP) "no-frame-pointer-elim-non-leaf" nounwind ssp { +entry: + %userUPP_addr = alloca void (%struct.AppleEvent*)* ; <void (%struct.AppleEvent*)**> [#uses=1] + %"alloca point" = bitcast i32 0 to i32 ; <i32> [#uses=0] + call void @llvm.dbg.declare(metadata void (%struct.AppleEvent*)** %userUPP_addr, metadata !0, metadata !DIExpression()), !dbg !13 + store void (%struct.AppleEvent*)* %userUPP, void (%struct.AppleEvent*)** %userUPP_addr + br label %return, !dbg !14 + +return: ; preds = %entry + ret void, !dbg !14 +} + +declare void @llvm.dbg.declare(metadata, metadata, metadata) nounwind readnone + +!llvm.dbg.cu = !{!3} +!llvm.module.flags = !{!19} +!0 = !DILocalVariable(name: "userUPP", line: 7, arg: 1, scope: !1, file: !2, type: !6) +!1 = distinct !DISubprogram(name: "DisposeDMNotificationUPP", linkageName: "DisposeDMNotificationUPP", line: 7, isLocal: false, isDefinition: true, virtualIndex: 6, isOptimized: false, file: !16, scope: null, type: !4) +!2 = !DIFile(filename: "t.c", directory: "/Users/echeng/LLVM/radars/r7937664/") +!3 = distinct !DICompileUnit(language: DW_LANG_C89, producer: "4.2.1 (Based on Apple Inc. build 5658) (LLVM build 9999)", isOptimized: true, emissionKind: 0, file: !16, enums: !17, retainedTypes: !17, subprograms: !18) +!4 = !DISubroutineType(types: !5) +!5 = !{null, !6} +!6 = !DIDerivedType(tag: DW_TAG_typedef, name: "DMNotificationUPP", line: 6, file: !16, scope: !2, baseType: !7) +!7 = !DIDerivedType(tag: DW_TAG_pointer_type, size: 64, align: 64, file: !16, scope: !2, baseType: !8) +!8 = !DISubroutineType(types: !9) +!9 = !{null, !10} +!10 = !DIDerivedType(tag: DW_TAG_pointer_type, size: 64, align: 64, file: !16, scope: !2, baseType: !11) +!11 = !DIDerivedType(tag: DW_TAG_typedef, name: "AppleEvent", line: 4, file: !16, scope: !2, baseType: !12) +!12 = !DICompositeType(tag: DW_TAG_structure_type, name: "AEDesc", line: 1, flags: DIFlagFwdDecl, file: !16, scope: !2) +!13 = !DILocation(line: 7, scope: !1) +!14 = !DILocation(line: 8, scope: !15) +!15 = distinct !DILexicalBlock(line: 7, column: 0, file: !16, scope: !1) +!16 = !DIFile(filename: "t.c", directory: "/Users/echeng/LLVM/radars/r7937664/") +!17 = !{} +!18 = !{!1} +!19 = !{i32 1, !"Debug Info Version", i32 3} diff --git a/llvm/test/DebugInfo/Generic/2010-05-03-OriginDIE.ll b/llvm/test/DebugInfo/Generic/2010-05-03-OriginDIE.ll new file mode 100644 index 00000000000..9ebfb06cc5e --- /dev/null +++ b/llvm/test/DebugInfo/Generic/2010-05-03-OriginDIE.ll @@ -0,0 +1,94 @@ + +;RUN: llc < %s -o /dev/null +;Radar 7937109 + +%struct.anon = type { i64, i32, i32, i32, [1 x i32] } +%struct.gpm_t = type { i32, i8*, [16 x i8], i32, i64, i64, i64, i64, i64, i64, i32, i16, i16, [8 x %struct.gpmr_t] } +%struct.gpmr_t = type { [48 x i8], [48 x i8], [16 x i8], i64, i64, i64, i64, i16 } +%struct.gpt_t = type { [8 x i8], i32, i32, i32, i32, i64, i64, i64, i64, [16 x i8], %struct.anon } + +@llvm.used = appending global [1 x i8*] [i8* bitcast (void (%struct.gpm_t*, %struct.gpt_t*)* @gpt2gpm to i8*)], section "llvm.metadata" ; <[1 x i8*]*> [#uses=0] + +define fastcc void @gpt2gpm(%struct.gpm_t* %gpm, %struct.gpt_t* %gpt) nounwind optsize ssp { +entry: + %data_addr.i18 = alloca i64, align 8 ; <i64*> [#uses=1] + %data_addr.i17 = alloca i64, align 8 ; <i64*> [#uses=2] + %data_addr.i16 = alloca i64, align 8 ; <i64*> [#uses=0] + %data_addr.i15 = alloca i32, align 4 ; <i32*> [#uses=0] + %data_addr.i = alloca i64, align 8 ; <i64*> [#uses=0] + %0 = getelementptr inbounds %struct.gpm_t, %struct.gpm_t* %gpm, i32 0, i32 2, i32 0 ; <i8*> [#uses=1] + %1 = getelementptr inbounds %struct.gpt_t, %struct.gpt_t* %gpt, i32 0, i32 9, i32 0 ; <i8*> [#uses=1] + call void @uuid_LtoB(i8* %0, i8* %1) nounwind, !dbg !0 + %a9 = load volatile i64, i64* %data_addr.i18, align 8 ; <i64> [#uses=1] + %a10 = call i64 @llvm.bswap.i64(i64 %a9) nounwind ; <i64> [#uses=1] + %a11 = getelementptr inbounds %struct.gpt_t, %struct.gpt_t* %gpt, i32 0, i32 8, !dbg !7 ; <i64*> [#uses=1] + %a12 = load i64, i64* %a11, align 4, !dbg !7 ; <i64> [#uses=1] + call void @llvm.dbg.declare(metadata i64* %data_addr.i17, metadata !8, metadata !DIExpression()) nounwind, !dbg !14 + store i64 %a12, i64* %data_addr.i17, align 8 + call void @llvm.dbg.value(metadata !6, i64 0, metadata !15, metadata !DIExpression()) nounwind, !dbg !DILocation(scope: !16) + call void @llvm.dbg.value(metadata i32 0, i64 0, metadata !19, metadata !DIExpression()) nounwind, !dbg !DILocation(scope: !16) + call void @llvm.dbg.declare(metadata !6, metadata !23, metadata !DIExpression()) nounwind, !dbg !DILocation(scope: !24) + call void @llvm.dbg.value(metadata i64* %data_addr.i17, i64 0, metadata !34, metadata !DIExpression()) nounwind, !dbg !DILocation(scope: !24) + %a13 = load volatile i64, i64* %data_addr.i17, align 8 ; <i64> [#uses=1] + %a14 = call i64 @llvm.bswap.i64(i64 %a13) nounwind ; <i64> [#uses=2] + %a15 = add i64 %a10, %a14, !dbg !7 ; <i64> [#uses=1] + %a16 = sub i64 %a15, %a14 ; <i64> [#uses=1] + %a17 = getelementptr inbounds %struct.gpm_t, %struct.gpm_t* %gpm, i32 0, i32 5, !dbg !7 ; <i64*> [#uses=1] + store i64 %a16, i64* %a17, align 4, !dbg !7 + ret void, !dbg !7 +} + +declare void @llvm.dbg.declare(metadata, metadata, metadata) nounwind readnone + +declare void @llvm.dbg.value(metadata, i64, metadata, metadata) nounwind readnone + +declare i32 @llvm.bswap.i32(i32) nounwind readnone + +declare i64 @llvm.bswap.i64(i64) nounwind readnone + +declare void @uuid_LtoB(i8*, i8*) + +!llvm.dbg.cu = !{!4} +!llvm.module.flags = !{!41} +!0 = !DILocation(line: 808, scope: !1) +!1 = distinct !DILexicalBlock(line: 807, column: 0, file: !39, scope: !2) +!2 = distinct !DISubprogram(name: "gpt2gpm", linkageName: "gpt2gpm", line: 807, isLocal: true, isDefinition: true, virtualIndex: 6, isOptimized: false, file: !39, scope: null, type: !5) +!3 = !DIFile(filename: "G.c", directory: "/tmp") +!4 = distinct !DICompileUnit(language: DW_LANG_C89, producer: "llvm-gcc", isOptimized: true, emissionKind: 0, file: !39, enums: !18, retainedTypes: !18, subprograms: !40) +!5 = !DISubroutineType(types: !6) +!6 = !{null} +!7 = !DILocation(line: 810, scope: !1) +!8 = !DILocalVariable(name: "data", line: 201, arg: 1, scope: !9, file: !10, type: !11) +!9 = distinct !DISubprogram(name: "_OSSwapInt64", linkageName: "_OSSwapInt64", line: 202, isLocal: true, isDefinition: true, virtualIndex: 6, isOptimized: false, file: !10, scope: null, type: !5) +!10 = !DIFile(filename: "OSByteOrder.h", directory: "/usr/include/libkern/ppc") +!11 = !DIDerivedType(tag: DW_TAG_typedef, name: "uint64_t", line: 59, file: !36, scope: !3, baseType: !13) +!12 = !DIFile(filename: "stdint.h", directory: "/usr/4.2.1/include") +!13 = !DIBasicType(tag: DW_TAG_base_type, name: "long long unsigned int", size: 64, align: 64, encoding: DW_ATE_unsigned) +!14 = !DILocation(line: 202, scope: !9, inlinedAt: !7) +!15 = !DILocalVariable(name: "base", line: 92, arg: 2, scope: !16, file: !10, type: !17) +!16 = distinct !DISubprogram(name: "OSReadSwapInt64", linkageName: "OSReadSwapInt64", line: 95, isLocal: true, isDefinition: true, virtualIndex: 6, isOptimized: false, file: !38, scope: null, type: !5) +!17 = !DIDerivedType(tag: DW_TAG_pointer_type, size: 32, align: 32, file: !39, scope: !3, baseType: null) +!18 = !{} +!19 = !DILocalVariable(name: "byteOffset", line: 94, arg: 3, scope: !16, file: !10, type: !20) +!20 = !DIDerivedType(tag: DW_TAG_typedef, name: "uintptr_t", line: 114, file: !37, scope: !3, baseType: !22) +!21 = !DIFile(filename: "types.h", directory: "/usr/include/ppc") +!22 = !DIBasicType(tag: DW_TAG_base_type, name: "long unsigned int", size: 32, align: 32, encoding: DW_ATE_unsigned) +!23 = !DILocalVariable(name: "u", line: 100, scope: !24, file: !10, type: !25) +!24 = distinct !DILexicalBlock(line: 95, column: 0, file: !38, scope: !16) +!25 = !DICompositeType(tag: DW_TAG_union_type, line: 97, size: 64, align: 64, file: !38, scope: !16, elements: !26) +!26 = !{!27, !28} +!27 = !DIDerivedType(tag: DW_TAG_member, name: "u64", line: 98, size: 64, align: 64, file: !38, scope: !25, baseType: !11) +!28 = !DIDerivedType(tag: DW_TAG_member, name: "u32", line: 99, size: 64, align: 32, file: !38, scope: !25, baseType: !29) +!29 = !DICompositeType(tag: DW_TAG_array_type, size: 64, align: 32, file: !39, scope: !3, baseType: !30, elements: !32) +!30 = !DIDerivedType(tag: DW_TAG_typedef, name: "uint32_t", line: 55, file: !36, scope: !3, baseType: !31) +!31 = !DIBasicType(tag: DW_TAG_base_type, name: "unsigned int", size: 32, align: 32, encoding: DW_ATE_unsigned) +!32 = !{!33} +!33 = !DISubrange(count: 2) +!34 = !DILocalVariable(name: "addr", line: 96, scope: !24, file: !10, type: !35) +!35 = !DIDerivedType(tag: DW_TAG_pointer_type, size: 32, align: 32, file: !39, scope: !3, baseType: !11) +!36 = !DIFile(filename: "stdint.h", directory: "/usr/4.2.1/include") +!37 = !DIFile(filename: "types.h", directory: "/usr/include/ppc") +!38 = !DIFile(filename: "OSByteOrder.h", directory: "/usr/include/libkern/ppc") +!39 = !DIFile(filename: "G.c", directory: "/tmp") +!40 = !{!2, !9, !16} +!41 = !{i32 1, !"Debug Info Version", i32 3} diff --git a/llvm/test/DebugInfo/Generic/2010-05-10-MultipleCU.ll b/llvm/test/DebugInfo/Generic/2010-05-10-MultipleCU.ll new file mode 100644 index 00000000000..92277a97d21 --- /dev/null +++ b/llvm/test/DebugInfo/Generic/2010-05-10-MultipleCU.ll @@ -0,0 +1,44 @@ +; REQUIRES: object-emission + +; RUN: %llc_dwarf -O0 -filetype=obj < %s | llvm-dwarfdump -debug-dump=info - | FileCheck %s + +; Check that two compile units are generated + +; CHECK: Compile Unit: +; CHECK: Compile Unit: + +define i32 @foo() nounwind readnone ssp { +return: + ret i32 42, !dbg !0 +} + +define i32 @bar() nounwind readnone ssp { +return: + ret i32 21, !dbg !8 +} + +!llvm.dbg.cu = !{!4, !12} +!llvm.module.flags = !{!21} +!16 = !{!2} +!17 = !{!10} + +!0 = !DILocation(line: 3, scope: !1) +!1 = distinct !DILexicalBlock(line: 2, column: 0, file: !18, scope: !2) +!2 = distinct !DISubprogram(name: "foo", linkageName: "foo", line: 2, isLocal: false, isDefinition: true, virtualIndex: 6, isOptimized: false, file: !18, scope: !3, type: !5, function: i32 ()* @foo) +!3 = !DIFile(filename: "a.c", directory: "/tmp/") +!4 = distinct !DICompileUnit(language: DW_LANG_C89, producer: "4.2.1 (Based on Apple Inc. build 5658) (LLVM build)", isOptimized: false, emissionKind: 0, file: !18, enums: !19, retainedTypes: !19, subprograms: !16) +!5 = !DISubroutineType(types: !6) +!6 = !{!7} +!7 = !DIBasicType(tag: DW_TAG_base_type, name: "int", size: 32, align: 32, encoding: DW_ATE_signed) +!8 = !DILocation(line: 3, scope: !9) +!9 = distinct !DILexicalBlock(line: 2, column: 0, file: !20, scope: !10) +!10 = distinct !DISubprogram(name: "bar", linkageName: "bar", line: 2, isLocal: false, isDefinition: true, virtualIndex: 6, isOptimized: false, file: !20, scope: !11, type: !13, function: i32 ()* @bar) +!11 = !DIFile(filename: "b.c", directory: "/tmp/") +!12 = distinct !DICompileUnit(language: DW_LANG_C89, producer: "4.2.1 (Based on Apple Inc. build 5658) (LLVM build)", isOptimized: false, emissionKind: 0, file: !20, enums: !19, retainedTypes: !19, subprograms: !17) +!13 = !DISubroutineType(types: !14) +!14 = !{!15} +!15 = !DIBasicType(tag: DW_TAG_base_type, name: "int", size: 32, align: 32, encoding: DW_ATE_signed) +!18 = !DIFile(filename: "a.c", directory: "/tmp/") +!19 = !{} +!20 = !DIFile(filename: "b.c", directory: "/tmp/") +!21 = !{i32 1, !"Debug Info Version", i32 3} diff --git a/llvm/test/DebugInfo/Generic/2010-06-29-InlinedFnLocalVar.ll b/llvm/test/DebugInfo/Generic/2010-06-29-InlinedFnLocalVar.ll new file mode 100644 index 00000000000..feba316213a --- /dev/null +++ b/llvm/test/DebugInfo/Generic/2010-06-29-InlinedFnLocalVar.ll @@ -0,0 +1,61 @@ +; RUN: %llc_dwarf -O2 %s -o - | FileCheck %s +; Check struct X for dead variable xyz from inlined function foo. + +; CHECK: section_info +; CHECK: DW_TAG_structure_type +; CHECK-NEXT: DW_AT_name + + +@i = common global i32 0 ; <i32*> [#uses=2] + +declare void @llvm.dbg.declare(metadata, metadata, metadata) nounwind readnone + +declare void @llvm.dbg.value(metadata, i64, metadata, metadata) nounwind readnone + +define i32 @bar() nounwind ssp { +entry: + %0 = load i32, i32* @i, align 4, !dbg !17 ; <i32> [#uses=2] + tail call void @llvm.dbg.value(metadata i32 %0, i64 0, metadata !59, metadata !DIExpression()), !dbg !19 + tail call void @llvm.dbg.declare(metadata !29, metadata !60, metadata !DIExpression()), !dbg !21 + %1 = mul nsw i32 %0, %0, !dbg !22 ; <i32> [#uses=2] + store i32 %1, i32* @i, align 4, !dbg !17 + ret i32 %1, !dbg !23 +} + +!llvm.dbg.cu = !{!2} +!llvm.module.flags = !{!28} + +!0 = distinct !DISubprogram(name: "foo", line: 9, isLocal: true, isDefinition: true, virtualIndex: 6, isOptimized: true, scopeLine: 9, file: !27, scope: !1, type: !3, variables: !24) +!1 = !DIFile(filename: "bar.c", directory: "/tmp/") +!2 = distinct !DICompileUnit(language: DW_LANG_C89, producer: "4.2.1 (Based on Apple Inc. build 5658) (LLVM build)", isOptimized: true, emissionKind: 0, file: !27, enums: !20, retainedTypes: !20, subprograms: !25, globals: !26, imports: !20) +!3 = !DISubroutineType(types: !4) +!4 = !{!5, !5} +!5 = !DIBasicType(tag: DW_TAG_base_type, name: "int", size: 32, align: 32, encoding: DW_ATE_signed) +!6 = distinct !DISubprogram(name: "bar", linkageName: "bar", line: 14, isLocal: false, isDefinition: true, virtualIndex: 6, isOptimized: true, file: !27, scope: !1, type: !7, function: i32 ()* @bar) +!7 = !DISubroutineType(types: !8) +!8 = !{!5} +!9 = !DILocalVariable(name: "j", line: 9, arg: 1, scope: !0, file: !1, type: !5) +!10 = !DILocalVariable(name: "xyz", line: 10, scope: !11, file: !1, type: !12) + +!59 = !DILocalVariable(name: "j", line: 9, arg: 1, scope: !0, file: !1, type: !5) +!60 = !DILocalVariable(name: "xyz", line: 10, scope: !11, file: !1, type: !12) + +!11 = distinct !DILexicalBlock(line: 9, column: 0, file: !1, scope: !0) +!12 = !DICompositeType(tag: DW_TAG_structure_type, name: "X", line: 10, size: 64, align: 32, file: !27, scope: !0, elements: !13) +!13 = !{!14, !15} +!14 = !DIDerivedType(tag: DW_TAG_member, name: "a", line: 10, size: 32, align: 32, file: !27, scope: !12, baseType: !5) +!15 = !DIDerivedType(tag: DW_TAG_member, name: "b", line: 10, size: 32, align: 32, offset: 32, file: !27, scope: !12, baseType: !5) +!16 = !DIGlobalVariable(name: "i", line: 5, isLocal: false, isDefinition: true, scope: !1, file: !1, type: !5, variable: i32* @i) +!17 = !DILocation(line: 15, scope: !18) +!18 = distinct !DILexicalBlock(line: 14, column: 0, file: !1, scope: !6) +!19 = !DILocation(line: 9, scope: !0, inlinedAt: !17) +!20 = !{} +!21 = !DILocation(line: 9, scope: !11, inlinedAt: !17) +!22 = !DILocation(line: 11, scope: !11, inlinedAt: !17) +!23 = !DILocation(line: 16, scope: !18) +!24 = !{!9, !10} +!25 = !{!0, !6} +!26 = !{!16} +!27 = !DIFile(filename: "bar.c", directory: "/tmp/") +!28 = !{i32 1, !"Debug Info Version", i32 3} +!29 = !{null} diff --git a/llvm/test/DebugInfo/Generic/2010-07-19-Crash.ll b/llvm/test/DebugInfo/Generic/2010-07-19-Crash.ll new file mode 100644 index 00000000000..3189f6fdb74 --- /dev/null +++ b/llvm/test/DebugInfo/Generic/2010-07-19-Crash.ll @@ -0,0 +1,30 @@ +; RUN: llc -o /dev/null < %s +; PR7662 +; Do not add variables to !11 because it is a declaration entry. + +define i32 @bar() nounwind readnone ssp { +entry: + ret i32 42, !dbg !9 +} + +!llvm.dbg.cu = !{!2} +!llvm.module.flags = !{!15} +!llvm.dbg.sp = !{!0, !6, !11} +!llvm.dbg.lv.foo = !{!7} + +!0 = distinct !DISubprogram(name: "bar", linkageName: "bar", line: 3, isLocal: false, isDefinition: true, virtualIndex: 6, isOptimized: true, file: !12, scope: !1, type: !3, function: i32 ()* @bar) +!1 = !DIFile(filename: "one.c", directory: "/private/tmp") +!2 = distinct !DICompileUnit(language: DW_LANG_C99, producer: "clang 2.8", isOptimized: true, emissionKind: 0, file: !12, enums: !14, retainedTypes: !14, subprograms: !13) +!3 = !DISubroutineType(types: !4) +!4 = !{!5} +!5 = !DIBasicType(tag: DW_TAG_base_type, name: "int", size: 32, align: 32, encoding: DW_ATE_signed) +!6 = distinct !DISubprogram(name: "foo", linkageName: "foo", line: 7, isLocal: true, isDefinition: true, virtualIndex: 6, isOptimized: true, file: !12, scope: !1, type: !3) +!7 = !DILocalVariable(name: "one", line: 8, scope: !8, file: !1, type: !5) +!8 = distinct !DILexicalBlock(line: 7, column: 18, file: !12, scope: !6) +!9 = !DILocation(line: 4, column: 3, scope: !10) +!10 = distinct !DILexicalBlock(line: 3, column: 11, file: !12, scope: !0) +!11 = !DISubprogram(name: "foo", linkageName: "foo", line: 7, isLocal: true, isDefinition: false, virtualIndex: 6, isOptimized: true, file: !12, scope: !1, type: !3) +!12 = !DIFile(filename: "one.c", directory: "/private/tmp") +!13 = !{!0} +!14 = !{} +!15 = !{i32 1, !"Debug Info Version", i32 3} diff --git a/llvm/test/DebugInfo/Generic/2010-10-01-crash.ll b/llvm/test/DebugInfo/Generic/2010-10-01-crash.ll new file mode 100644 index 00000000000..6ae48f1c408 --- /dev/null +++ b/llvm/test/DebugInfo/Generic/2010-10-01-crash.ll @@ -0,0 +1,24 @@ +; RUN: llc -O0 %s -o /dev/null + +define void @CGRectStandardize(i32* sret %agg.result, i32* byval %rect) nounwind ssp { +entry: + call void @llvm.dbg.declare(metadata i32* %rect, metadata !23, metadata !DIExpression()), !dbg !24 + ret void +} + +declare void @llvm.dbg.declare(metadata, metadata, metadata) nounwind readnone + +declare void @llvm.memcpy.p0i8.p0i8.i32(i8* nocapture, i8* nocapture, i32, i32, i1) nounwind + + +!llvm.dbg.cu = !{!2} +!llvm.module.flags = !{!27} +!0 = distinct !DISubprogram(name: "CGRectStandardize", linkageName: "CGRectStandardize", line: 54, isLocal: false, isDefinition: true, virtualIndex: 6, isOptimized: false, file: !1, scope: null, function: void (i32*, i32*)* @CGRectStandardize) +!1 = !DIFile(filename: "GSFusedSilica.m", directory: "/Volumes/Data/Users/sabre/Desktop") +!2 = distinct !DICompileUnit(language: DW_LANG_ObjC, producer: "clang version 2.9 (trunk 115292)", isOptimized: true, runtimeVersion: 1, emissionKind: 0, file: !25, enums: !26, retainedTypes: !26, subprograms: !{!0}) +!5 = !DIDerivedType(tag: DW_TAG_typedef, name: "CGRect", line: 49, file: !25, baseType: null) +!23 = !DILocalVariable(name: "rect", line: 53, arg: 2, scope: !0, file: !1, type: !5) +!24 = !DILocation(line: 53, column: 33, scope: !0) +!25 = !DIFile(filename: "GSFusedSilica.m", directory: "/Volumes/Data/Users/sabre/Desktop") +!26 = !{} +!27 = !{i32 1, !"Debug Info Version", i32 3} diff --git a/llvm/test/DebugInfo/Generic/PR20038.ll b/llvm/test/DebugInfo/Generic/PR20038.ll new file mode 100644 index 00000000000..8ad6d7834be --- /dev/null +++ b/llvm/test/DebugInfo/Generic/PR20038.ll @@ -0,0 +1,172 @@ +; REQUIRES: object-emission + +; For some reason, the output when targetting sparc is not quite as expected. +; XFAIL: sparc + +; RUN: %llc_dwarf -O0 -filetype=obj -dwarf-linkage-names=Enable < %s | llvm-dwarfdump -debug-dump=info - | FileCheck %s + +; IR generated from clang -O0 with: +; struct C { +; ~C(); +; }; +; extern bool b; +; void fun4() { b && (C(), 1); } +; __attribute__((always_inline)) C::~C() { } + +; CHECK: DW_TAG_structure_type +; CHECK-NOT: DW_TAG +; CHECK: DW_AT_name {{.*}} "C" +; CHECK-NOT: {{DW_TAG|NULL}} +; CHECK: DW_TAG_subprogram +; CHECK-NOT: DW_TAG +; CHECK: DW_AT_name {{.*}} "~C" + +; CHECK: DW_TAG_subprogram +; CHECK-NOT: DW_TAG +; CHECK: DW_AT_linkage_name {{.*}} "_ZN1CD1Ev" +; CHECK-NOT: {{DW_TAG|NULL}} +; CHECK: DW_TAG_formal_parameter +; CHECK-NOT: DW_TAG +; CHECK: DW_AT_name {{.*}} "this" + +; CHECK: DW_TAG_subprogram +; CHECK-NOT: DW_TAG +; CHECK: DW_AT_name {{.*}} "fun4" +; CHECK-NOT: {{DW_TAG|NULL}} +; CHECK: DW_TAG_inlined_subroutine +; CHECK-NOT: DW_TAG +; CHECK: DW_AT_abstract_origin {{.*}} "_ZN1CD1Ev" +; CHECK-NOT: {{DW_TAG|NULL}} +; CHECK: DW_TAG_formal_parameter +; CHECK-NOT: DW_TAG +; CHECK: DW_AT_abstract_origin {{.*}} "this" + +; FIXME: D2 is actually inlined into D1 but doesn't show up here, possibly due +; to there being no work in D2 (calling another member function from the dtor +; causes D2 to show up, calling a free function doesn't). + +; CHECK-NOT: DW_TAG +; CHECK: NULL +; CHECK-NOT: DW_TAG +; CHECK: NULL + +%struct.C = type { i8 } + +@b = external global i8 + +; Function Attrs: nounwind +define void @_Z4fun4v() #0 { +entry: + %this.addr.i.i = alloca %struct.C*, align 8, !dbg !21 + %this.addr.i = alloca %struct.C*, align 8, !dbg !22 + %agg.tmp.ensured = alloca %struct.C, align 1 + %cleanup.cond = alloca i1 + %0 = load i8, i8* @b, align 1, !dbg !24 + %tobool = trunc i8 %0 to i1, !dbg !24 + store i1 false, i1* %cleanup.cond + br i1 %tobool, label %land.rhs, label %land.end, !dbg !24 + +land.rhs: ; preds = %entry + store i1 true, i1* %cleanup.cond, !dbg !25 + br label %land.end + +land.end: ; preds = %land.rhs, %entry + %1 = phi i1 [ false, %entry ], [ true, %land.rhs ] + %cleanup.is_active = load i1, i1* %cleanup.cond, !dbg !27 + br i1 %cleanup.is_active, label %cleanup.action, label %cleanup.done, !dbg !27 + +cleanup.action: ; preds = %land.end + store %struct.C* %agg.tmp.ensured, %struct.C** %this.addr.i, align 8, !dbg !22 + call void @llvm.dbg.declare(metadata %struct.C** %this.addr.i, metadata !129, metadata !DIExpression()), !dbg !31 + %this1.i = load %struct.C*, %struct.C** %this.addr.i, !dbg !22 + store %struct.C* %this1.i, %struct.C** %this.addr.i.i, align 8, !dbg !21 + call void @llvm.dbg.declare(metadata %struct.C** %this.addr.i.i, metadata !132, metadata !DIExpression()), !dbg !33 + %this1.i.i = load %struct.C*, %struct.C** %this.addr.i.i, !dbg !21 + br label %cleanup.done, !dbg !22 + +cleanup.done: ; preds = %cleanup.action, %land.end + ret void, !dbg !34 +} + +; Function Attrs: alwaysinline nounwind +define void @_ZN1CD1Ev(%struct.C* %this) unnamed_addr #1 align 2 { +entry: + %this.addr.i = alloca %struct.C*, align 8, !dbg !37 + %this.addr = alloca %struct.C*, align 8 + store %struct.C* %this, %struct.C** %this.addr, align 8 + call void @llvm.dbg.declare(metadata %struct.C** %this.addr, metadata !29, metadata !DIExpression()), !dbg !38 + %this1 = load %struct.C*, %struct.C** %this.addr + store %struct.C* %this1, %struct.C** %this.addr.i, align 8, !dbg !37 + call void @llvm.dbg.declare(metadata %struct.C** %this.addr.i, metadata !232, metadata !DIExpression()), !dbg !39 + %this1.i = load %struct.C*, %struct.C** %this.addr.i, !dbg !37 + ret void, !dbg !37 +} + +; Function Attrs: alwaysinline nounwind +define void @_ZN1CD2Ev(%struct.C* %this) unnamed_addr #1 align 2 { +entry: + %this.addr = alloca %struct.C*, align 8 + store %struct.C* %this, %struct.C** %this.addr, align 8 + call void @llvm.dbg.declare(metadata %struct.C** %this.addr, metadata !32, metadata !DIExpression()), !dbg !40 + %this1 = load %struct.C*, %struct.C** %this.addr + ret void, !dbg !41 +} + +; Function Attrs: nounwind readnone +declare void @llvm.dbg.declare(metadata, metadata, metadata) #2 + +attributes #0 = { nounwind "less-precise-fpmad"="false" "no-frame-pointer-elim"="false" "no-infs-fp-math"="false" "no-nans-fp-math"="false" "no-realign-stack" "stack-protector-buffer-size"="8" "unsafe-fp-math"="false" "use-soft-float"="false" } +attributes #1 = { alwaysinline nounwind "less-precise-fpmad"="false" "no-frame-pointer-elim"="false" "no-infs-fp-math"="false" "no-nans-fp-math"="false" "no-realign-stack" "stack-protector-buffer-size"="8" "unsafe-fp-math"="false" "use-soft-float"="false" } +attributes #2 = { nounwind readnone } + +!llvm.dbg.cu = !{!0} +!llvm.module.flags = !{!18, !19} +!llvm.ident = !{!20} + +!0 = distinct !DICompileUnit(language: DW_LANG_C_plus_plus, producer: "clang version 3.5.0 ", isOptimized: false, emissionKind: 1, file: !1, enums: !2, retainedTypes: !3, subprograms: !11, globals: !2, imports: !2) +!1 = !DIFile(filename: "<stdin>", directory: "/tmp/dbginfo") +!2 = !{} +!3 = !{!4} +!4 = !DICompositeType(tag: DW_TAG_structure_type, name: "C", line: 1, size: 8, align: 8, file: !5, elements: !6, identifier: "_ZTS1C") +!5 = !DIFile(filename: "PR20038.cpp", directory: "/tmp/dbginfo") +!6 = !{!7} +!7 = !DISubprogram(name: "~C", line: 2, isLocal: false, isDefinition: false, virtualIndex: 6, flags: DIFlagPrototyped, isOptimized: false, scopeLine: 2, file: !5, scope: !"_ZTS1C", type: !8) +!8 = !DISubroutineType(types: !9) +!9 = !{null, !10} +!10 = !DIDerivedType(tag: DW_TAG_pointer_type, size: 64, align: 64, flags: DIFlagArtificial | DIFlagObjectPointer, baseType: !"_ZTS1C") +!11 = !{!12, !16, !17} +!12 = distinct !DISubprogram(name: "fun4", linkageName: "_Z4fun4v", line: 5, isLocal: false, isDefinition: true, virtualIndex: 6, flags: DIFlagPrototyped, isOptimized: false, scopeLine: 5, file: !5, scope: !13, type: !14, function: void ()* @_Z4fun4v, variables: !2) +!13 = !DIFile(filename: "PR20038.cpp", directory: "/tmp/dbginfo") +!14 = !DISubroutineType(types: !15) +!15 = !{null} +!16 = distinct !DISubprogram(name: "~C", linkageName: "_ZN1CD2Ev", line: 6, isLocal: false, isDefinition: true, virtualIndex: 6, flags: DIFlagPrototyped, isOptimized: false, scopeLine: 6, file: !5, scope: !"_ZTS1C", type: !8, function: void (%struct.C*)* @_ZN1CD2Ev, declaration: !7, variables: !2) +!17 = distinct !DISubprogram(name: "~C", linkageName: "_ZN1CD1Ev", line: 6, isLocal: false, isDefinition: true, virtualIndex: 6, flags: DIFlagPrototyped, isOptimized: false, scopeLine: 6, file: !5, scope: !"_ZTS1C", type: !8, function: void (%struct.C*)* @_ZN1CD1Ev, declaration: !7, variables: !2) +!18 = !{i32 2, !"Dwarf Version", i32 4} +!19 = !{i32 2, !"Debug Info Version", i32 3} +!20 = !{!"clang version 3.5.0 "} +!21 = !DILocation(line: 6, scope: !17, inlinedAt: !22) +!22 = !DILocation(line: 5, scope: !23) +!23 = distinct !DILexicalBlock(line: 5, column: 0, file: !5, scope: !12) +!24 = !DILocation(line: 5, scope: !12) +!25 = !DILocation(line: 5, scope: !26) +!26 = distinct !DILexicalBlock(line: 5, column: 0, file: !5, scope: !12) +!27 = !DILocation(line: 5, scope: !28) +!28 = distinct !DILexicalBlock(line: 5, column: 0, file: !5, scope: !12) +!29 = !DILocalVariable(name: "this", arg: 1, flags: DIFlagArtificial | DIFlagObjectPointer, scope: !17, type: !30) +!30 = !DIDerivedType(tag: DW_TAG_pointer_type, size: 64, align: 64, baseType: !"_ZTS1C") +!31 = !DILocation(line: 0, scope: !17, inlinedAt: !22) +!32 = !DILocalVariable(name: "this", arg: 1, flags: DIFlagArtificial | DIFlagObjectPointer, scope: !16, type: !30) +!33 = !DILocation(line: 0, scope: !16, inlinedAt: !21) + +!129 = !DILocalVariable(name: "this", arg: 1, flags: DIFlagArtificial | DIFlagObjectPointer, scope: !17, type: !30) +!132 = !DILocalVariable(name: "this", arg: 1, flags: DIFlagArtificial | DIFlagObjectPointer, scope: !16, type: !30) +!232 = !DILocalVariable(name: "this", arg: 1, flags: DIFlagArtificial | DIFlagObjectPointer, scope: !16, type: !30) + +!34 = !DILocation(line: 5, scope: !35) +!35 = distinct !DILexicalBlock(line: 5, column: 0, file: !5, scope: !36) +!36 = distinct !DILexicalBlock(line: 5, column: 0, file: !5, scope: !12) +!37 = !DILocation(line: 6, scope: !17) +!38 = !DILocation(line: 0, scope: !17) +!39 = !DILocation(line: 0, scope: !16, inlinedAt: !37) +!40 = !DILocation(line: 0, scope: !16) +!41 = !DILocation(line: 6, scope: !16) diff --git a/llvm/test/DebugInfo/Generic/accel-table-hash-collisions.ll b/llvm/test/DebugInfo/Generic/accel-table-hash-collisions.ll new file mode 100644 index 00000000000..ff9c7851826 --- /dev/null +++ b/llvm/test/DebugInfo/Generic/accel-table-hash-collisions.ll @@ -0,0 +1,92 @@ +; REQUIRES: object-emission +; RUN: %llc_dwarf -dwarf-accel-tables=Enable -filetype=obj -o - < %s | llvm-dwarfdump -debug-dump=apple_names - | FileCheck %s + +; Generated from the following C code using +; clang -S -emit-llvm hash-collision.c +; +; The names of the variables have been chosen so that they produce hash collisions. +; There are 12 names here that are hashed to only 6 hashes (each pair of lines +; hashes to the same value, see the CHECK lines below). +; +; int ForceTopDown; +; int _ZNSt3__116allocator_traitsINS_9allocatorINS_11__tree_nodeINS_12__value_typeIPN4llvm10BasicBlockEPNS4_10RegionNodeEEEPvEEEEE11__constructIS9_JNS_4pairIS6_S8_EEEEEvNS_17integral_constantIbLb1EEERSC_PT_DpOT0_; +; int _ZN5clang23DataRecursiveASTVisitorIN12_GLOBAL__N_124UnusedBackingIvarCheckerEE26TraverseCUDAKernelCallExprEPNS_18CUDAKernelCallExprE; +; int _ZN4llvm16DenseMapIteratorIPNS_10MDLocationENS_6detail13DenseSetEmptyENS_10MDNodeInfoIS1_EENS3_12DenseSetPairIS2_EELb0EE23AdvancePastEmptyBucketsEv; +; int _ZNK4llvm12LivePhysRegs5printERNS_11raw_ostreamE; +; int _ZN4llvm15ScalarEvolution14getSignedRangeEPKNS_4SCEVE; +; int k1; +; int is; +; int setStmt; +; int _ZN4llvm5TwineC1Ei; +; int _ZNK5clang12OverrideAttr5cloneERNS_10ASTContextE; +; int _ZN4llvm22MachineModuleInfoMachOD2Ev; + +; Check that we have the right amount of hashes. +; CHECK: Bucket count = 6 +; CHECK: Hashes count = 6 + +; Check that all the names are present in the output +; CHECK: Hash = 0x00597841 +; CHECK: Name: {{[0-9a-f]*}} "is" +; CHECK: Name: {{[0-9a-f]*}} "k1" + +; CHECK: Hash = 0xa4b42a1e +; CHECK: Name: {{[0-9a-f]*}} "_ZN5clang23DataRecursiveASTVisitorIN12_GLOBAL__N_124UnusedBackingIvarCheckerEE26TraverseCUDAKernelCallExprEPNS_18CUDAKernelCallExprE" +; CHECK: Name: {{[0-9a-f]*}} "_ZN4llvm16DenseMapIteratorIPNS_10MDLocationENS_6detail13DenseSetEmptyENS_10MDNodeInfoIS1_EENS3_12DenseSetPairIS2_EELb0EE23AdvancePastEmptyBucketsEv" + +; CHECK: Hash = 0xeee7c0b2 +; CHECK: Name: {{[0-9a-f]*}} "_ZNK4llvm12LivePhysRegs5printERNS_11raw_ostreamE" +; CHECK: Name: {{[0-9a-f]*}} "_ZN4llvm15ScalarEvolution14getSignedRangeEPKNS_4SCEVE" + +; CHECK: Hash = 0xea48ac5f +; CHECK: Name: {{[0-9a-f]*}} "ForceTopDown" +; CHECK: Name: {{[0-9a-f]*}} "_ZNSt3__116allocator_traitsINS_9allocatorINS_11__tree_nodeINS_12__value_typeIPN4llvm10BasicBlockEPNS4_10RegionNodeEEEPvEEEEE11__constructIS9_JNS_4pairIS6_S8_EEEEEvNS_17integral_constantIbLb1EEERSC_PT_DpOT0_" + +; CHECK: Hash = 0x6b22f71f +; CHECK: Name: {{[0-9a-f]*}} "_ZNK5clang12OverrideAttr5cloneERNS_10ASTContextE" +; CHECK: Name: {{[0-9a-f]*}} "_ZN4llvm22MachineModuleInfoMachOD2Ev" + +; CHECK: Hash = 0x8c248979 +; CHECK: Name: {{[0-9a-f]*}} "setStmt" +; CHECK: Name: {{[0-9a-f]*}} "_ZN4llvm5TwineC1Ei" + + + +@ForceTopDown = common global i32 0, align 4 +@_ZNSt3__116allocator_traitsINS_9allocatorINS_11__tree_nodeINS_12__value_typeIPN4llvm10BasicBlockEPNS4_10RegionNodeEEEPvEEEEE11__constructIS9_JNS_4pairIS6_S8_EEEEEvNS_17integral_constantIbLb1EEERSC_PT_DpOT0_ = common global i32 0, align 4 +@_ZN5clang23DataRecursiveASTVisitorIN12_GLOBAL__N_124UnusedBackingIvarCheckerEE26TraverseCUDAKernelCallExprEPNS_18CUDAKernelCallExprE = common global i32 0, align 4 +@_ZN4llvm16DenseMapIteratorIPNS_10MDLocationENS_6detail13DenseSetEmptyENS_10MDNodeInfoIS1_EENS3_12DenseSetPairIS2_EELb0EE23AdvancePastEmptyBucketsEv = common global i32 0, align 4 +@_ZNK4llvm12LivePhysRegs5printERNS_11raw_ostreamE = common global i32 0, align 4 +@_ZN4llvm15ScalarEvolution14getSignedRangeEPKNS_4SCEVE = common global i32 0, align 4 +@k1 = common global i32 0, align 4 +@is = common global i32 0, align 4 +@setStmt = common global i32 0, align 4 +@_ZN4llvm5TwineC1Ei = common global i32 0, align 4 +@_ZNK5clang12OverrideAttr5cloneERNS_10ASTContextE = common global i32 0, align 4 +@_ZN4llvm22MachineModuleInfoMachOD2Ev = common global i32 0, align 4 + +!llvm.dbg.cu = !{!0} +!llvm.module.flags = !{!17, !18, !19} +!llvm.ident = !{!20} + +!0 = distinct !DICompileUnit(language: DW_LANG_C99, file: !1, producer: "clang version 3.7.0 (trunk 231548) (llvm/trunk 231547)", isOptimized: false, runtimeVersion: 0, emissionKind: 1, enums: !2, retainedTypes: !2, subprograms: !2, globals: !3, imports: !2) +!1 = !DIFile(filename: "hash-collisions.c", directory: "/tmp") +!2 = !{} +!3 = !{!4, !6, !7, !8, !9, !10, !11, !12, !13, !14, !15, !16} +!4 = !DIGlobalVariable(name: "ForceTopDown", scope: !0, file: !1, line: 1, type: !5, isLocal: false, isDefinition: true, variable: i32* @ForceTopDown) +!5 = !DIBasicType(name: "int", size: 32, align: 32, encoding: DW_ATE_signed) +!6 = !DIGlobalVariable(name: "_ZNSt3__116allocator_traitsINS_9allocatorINS_11__tree_nodeINS_12__value_typeIPN4llvm10BasicBlockEPNS4_10RegionNodeEEEPvEEEEE11__constructIS9_JNS_4pairIS6_S8_EEEEEvNS_17integral_constantIbLb1EEERSC_PT_DpOT0_", scope: !0, file: !1, line: 2, type: !5, isLocal: false, isDefinition: true, variable: i32* @_ZNSt3__116allocator_traitsINS_9allocatorINS_11__tree_nodeINS_12__value_typeIPN4llvm10BasicBlockEPNS4_10RegionNodeEEEPvEEEEE11__constructIS9_JNS_4pairIS6_S8_EEEEEvNS_17integral_constantIbLb1EEERSC_PT_DpOT0_) +!7 = !DIGlobalVariable(name: "_ZN5clang23DataRecursiveASTVisitorIN12_GLOBAL__N_124UnusedBackingIvarCheckerEE26TraverseCUDAKernelCallExprEPNS_18CUDAKernelCallExprE", scope: !0, file: !1, line: 3, type: !5, isLocal: false, isDefinition: true, variable: i32* @_ZN5clang23DataRecursiveASTVisitorIN12_GLOBAL__N_124UnusedBackingIvarCheckerEE26TraverseCUDAKernelCallExprEPNS_18CUDAKernelCallExprE) +!8 = !DIGlobalVariable(name: "_ZN4llvm16DenseMapIteratorIPNS_10MDLocationENS_6detail13DenseSetEmptyENS_10MDNodeInfoIS1_EENS3_12DenseSetPairIS2_EELb0EE23AdvancePastEmptyBucketsEv", scope: !0, file: !1, line: 4, type: !5, isLocal: false, isDefinition: true, variable: i32* @_ZN4llvm16DenseMapIteratorIPNS_10MDLocationENS_6detail13DenseSetEmptyENS_10MDNodeInfoIS1_EENS3_12DenseSetPairIS2_EELb0EE23AdvancePastEmptyBucketsEv) +!9 = !DIGlobalVariable(name: "_ZNK4llvm12LivePhysRegs5printERNS_11raw_ostreamE", scope: !0, file: !1, line: 5, type: !5, isLocal: false, isDefinition: true, variable: i32* @_ZNK4llvm12LivePhysRegs5printERNS_11raw_ostreamE) +!10 = !DIGlobalVariable(name: "_ZN4llvm15ScalarEvolution14getSignedRangeEPKNS_4SCEVE", scope: !0, file: !1, line: 6, type: !5, isLocal: false, isDefinition: true, variable: i32* @_ZN4llvm15ScalarEvolution14getSignedRangeEPKNS_4SCEVE) +!11 = !DIGlobalVariable(name: "k1", scope: !0, file: !1, line: 7, type: !5, isLocal: false, isDefinition: true, variable: i32* @k1) +!12 = !DIGlobalVariable(name: "is", scope: !0, file: !1, line: 8, type: !5, isLocal: false, isDefinition: true, variable: i32* @is) +!13 = !DIGlobalVariable(name: "setStmt", scope: !0, file: !1, line: 9, type: !5, isLocal: false, isDefinition: true, variable: i32* @setStmt) +!14 = !DIGlobalVariable(name: "_ZN4llvm5TwineC1Ei", scope: !0, file: !1, line: 10, type: !5, isLocal: false, isDefinition: true, variable: i32* @_ZN4llvm5TwineC1Ei) +!15 = !DIGlobalVariable(name: "_ZNK5clang12OverrideAttr5cloneERNS_10ASTContextE", scope: !0, file: !1, line: 11, type: !5, isLocal: false, isDefinition: true, variable: i32* @_ZNK5clang12OverrideAttr5cloneERNS_10ASTContextE) +!16 = !DIGlobalVariable(name: "_ZN4llvm22MachineModuleInfoMachOD2Ev", scope: !0, file: !1, line: 12, type: !5, isLocal: false, isDefinition: true, variable: i32* @_ZN4llvm22MachineModuleInfoMachOD2Ev) +!17 = !{i32 2, !"Dwarf Version", i32 2} +!18 = !{i32 2, !"Debug Info Version", i32 3} +!19 = !{i32 1, !"PIC Level", i32 2} +!20 = !{!"clang version 3.7.0 (trunk 231548) (llvm/trunk 231547)"} diff --git a/llvm/test/DebugInfo/Generic/array.ll b/llvm/test/DebugInfo/Generic/array.ll new file mode 100644 index 00000000000..a9571db23ff --- /dev/null +++ b/llvm/test/DebugInfo/Generic/array.ll @@ -0,0 +1,40 @@ +; RUN: %llc_dwarf -O0 < %s | FileCheck %s +; Do not emit AT_upper_bound for an unbounded array. +; radar 9241695 +define i32 @main() nounwind ssp { +entry: + %retval = alloca i32, align 4 + %a = alloca [0 x i32], align 4 + store i32 0, i32* %retval + call void @llvm.dbg.declare(metadata [0 x i32]* %a, metadata !6, metadata !DIExpression()), !dbg !11 + ret i32 0, !dbg !12 +} + +declare void @llvm.dbg.declare(metadata, metadata, metadata) nounwind readnone + +!llvm.dbg.cu = !{!2} +!llvm.module.flags = !{!16} + +!0 = distinct !DISubprogram(name: "main", line: 3, isLocal: false, isDefinition: true, virtualIndex: 6, isOptimized: false, scopeLine: 3, file: !14, scope: !1, type: !3, function: i32 ()* @main) +!1 = !DIFile(filename: "array.c", directory: "/private/tmp") +!2 = distinct !DICompileUnit(language: DW_LANG_C99, producer: "clang version 3.0 (trunk 129138)", isOptimized: false, emissionKind: 0, file: !14, enums: !15, retainedTypes: !15, subprograms: !13, imports: null) +!3 = !DISubroutineType(types: !4) +!4 = !{!5} +!5 = !DIBasicType(tag: DW_TAG_base_type, name: "int", size: 32, align: 32, encoding: DW_ATE_signed) +!6 = !DILocalVariable(name: "a", line: 4, scope: !7, file: !1, type: !8) +!7 = distinct !DILexicalBlock(line: 3, column: 12, file: !14, scope: !0) +!8 = !DICompositeType(tag: DW_TAG_array_type, align: 32, file: !14, scope: !2, baseType: !5, elements: !9) +!9 = !{!10} +;CHECK: section_info: +;CHECK: DW_TAG_subrange_type +;CHECK-NEXT: DW_AT_type +;CHECK-NOT: DW_AT_lower_bound +;CHECK-NOT: DW_AT_upper_bound +;CHECK-NEXT: End Of Children Mark +!10 = !DISubrange(count: -1) +!11 = !DILocation(line: 4, column: 7, scope: !7) +!12 = !DILocation(line: 5, column: 3, scope: !7) +!13 = !{!0} +!14 = !DIFile(filename: "array.c", directory: "/private/tmp") +!15 = !{} +!16 = !{i32 1, !"Debug Info Version", i32 3} diff --git a/llvm/test/DebugInfo/Generic/block-asan.ll b/llvm/test/DebugInfo/Generic/block-asan.ll new file mode 100644 index 00000000000..ae07e7b145b --- /dev/null +++ b/llvm/test/DebugInfo/Generic/block-asan.ll @@ -0,0 +1,87 @@ +; RUN: opt -S -asan %s | FileCheck %s + +; The IR of this testcase is generated from the following C code: +; void bar (int); +; +; void foo() { +; __block int x; +; bar(x); +; } +; by compiling it with 'clang -emit-llvm -g -S' and then by manually +; adding the sanitize_address attribute to the @foo() function (so +; that ASAN accepts to instrument the function in the above opt run). + +; Check that the location of the ASAN instrumented __block variable is +; correct. +; CHECK: !DIExpression(DW_OP_deref, DW_OP_plus, 8, DW_OP_deref, DW_OP_plus, 24) + +target datalayout = "e-m:o-i64:64-f80:128-n8:16:32:64-S128" + +%struct.__block_byref_x = type { i8*, %struct.__block_byref_x*, i32, i32, i32 } + +; Function Attrs: nounwind ssp uwtable +define void @foo() #0 { +entry: + %x = alloca %struct.__block_byref_x, align 8 + call void @llvm.dbg.declare(metadata %struct.__block_byref_x* %x, metadata !12, metadata !22), !dbg !23 + %byref.isa = getelementptr inbounds %struct.__block_byref_x, %struct.__block_byref_x* %x, i32 0, i32 0, !dbg !24 + store i8* null, i8** %byref.isa, !dbg !24 + %byref.forwarding = getelementptr inbounds %struct.__block_byref_x, %struct.__block_byref_x* %x, i32 0, i32 1, !dbg !24 + store %struct.__block_byref_x* %x, %struct.__block_byref_x** %byref.forwarding, !dbg !24 + %byref.flags = getelementptr inbounds %struct.__block_byref_x, %struct.__block_byref_x* %x, i32 0, i32 2, !dbg !24 + store i32 0, i32* %byref.flags, !dbg !24 + %byref.size = getelementptr inbounds %struct.__block_byref_x, %struct.__block_byref_x* %x, i32 0, i32 3, !dbg !24 + store i32 32, i32* %byref.size, !dbg !24 + %forwarding = getelementptr inbounds %struct.__block_byref_x, %struct.__block_byref_x* %x, i32 0, i32 1, !dbg !25 + %0 = load %struct.__block_byref_x*, %struct.__block_byref_x** %forwarding, !dbg !25 + %x1 = getelementptr inbounds %struct.__block_byref_x, %struct.__block_byref_x* %0, i32 0, i32 4, !dbg !25 + %1 = load i32, i32* %x1, align 4, !dbg !25 + call void @bar(i32 %1), !dbg !25 + %2 = bitcast %struct.__block_byref_x* %x to i8*, !dbg !26 + call void @_Block_object_dispose(i8* %2, i32 8) #3, !dbg !26 + ret void, !dbg !26 +} + +; Function Attrs: nounwind readnone +declare void @llvm.dbg.declare(metadata, metadata, metadata) #1 + +declare void @bar(i32) #2 + +declare void @_Block_object_dispose(i8*, i32) + +attributes #0 = { nounwind ssp uwtable sanitize_address "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 = { nounwind readnone } +attributes #2 = { "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 #3 = { nounwind } + +!llvm.dbg.cu = !{!0} +!llvm.module.flags = !{!8, !9, !10} +!llvm.ident = !{!11} + +!0 = distinct !DICompileUnit(language: DW_LANG_C99, producer: "clang version 3.6.0 (trunk 223120) (llvm/trunk 223119)", isOptimized: false, emissionKind: 1, file: !1, enums: !2, retainedTypes: !2, subprograms: !3, globals: !2, imports: !2) +!1 = !DIFile(filename: "block.c", directory: "/tmp") +!2 = !{} +!3 = !{!4} +!4 = distinct !DISubprogram(name: "foo", line: 3, isLocal: false, isDefinition: true, isOptimized: false, scopeLine: 3, file: !1, scope: !5, type: !6, function: void ()* @foo, variables: !2) +!5 = !DIFile(filename: "block.c", directory: "/tmp") +!6 = !DISubroutineType(types: !7) +!7 = !{null} +!8 = !{i32 2, !"Dwarf Version", i32 2} +!9 = !{i32 2, !"Debug Info Version", i32 3} +!10 = !{i32 1, !"PIC Level", i32 2} +!11 = !{!"clang version 3.6.0 (trunk 223120) (llvm/trunk 223119)"} +!12 = !DILocalVariable(name: "x", line: 4, scope: !4, file: !5, type: !13) +!13 = !DICompositeType(tag: DW_TAG_structure_type, size: 224, flags: DIFlagBlockByrefStruct, file: !1, scope: !5, elements: !14) +!14 = !{!15, !17, !18, !20, !21} +!15 = !DIDerivedType(tag: DW_TAG_member, name: "__isa", size: 64, align: 64, file: !1, scope: !5, baseType: !16) +!16 = !DIDerivedType(tag: DW_TAG_pointer_type, size: 64, align: 64, baseType: null) +!17 = !DIDerivedType(tag: DW_TAG_member, name: "__forwarding", size: 64, align: 64, offset: 64, file: !1, scope: !5, baseType: !16) +!18 = !DIDerivedType(tag: DW_TAG_member, name: "__flags", size: 32, align: 32, offset: 128, file: !1, scope: !5, baseType: !19) +!19 = !DIBasicType(tag: DW_TAG_base_type, name: "int", size: 32, align: 32, encoding: DW_ATE_signed) +!20 = !DIDerivedType(tag: DW_TAG_member, name: "__size", size: 32, align: 32, offset: 160, file: !1, scope: !5, baseType: !19) +!21 = !DIDerivedType(tag: DW_TAG_member, name: "x", size: 32, align: 32, offset: 192, file: !1, scope: !5, baseType: !19) +!22 = !DIExpression(DW_OP_plus, 8, DW_OP_deref, DW_OP_plus, 24) +!23 = !DILocation(line: 4, column: 15, scope: !4) +!24 = !DILocation(line: 4, column: 3, scope: !4) +!25 = !DILocation(line: 5, column: 3, scope: !4) +!26 = !DILocation(line: 6, column: 1, scope: !4) diff --git a/llvm/test/DebugInfo/Generic/bug_null_debuginfo.ll b/llvm/test/DebugInfo/Generic/bug_null_debuginfo.ll new file mode 100644 index 00000000000..09e36db42b4 --- /dev/null +++ b/llvm/test/DebugInfo/Generic/bug_null_debuginfo.ll @@ -0,0 +1,8 @@ +; RUN: llc < %s + +!llvm.dbg.cu = !{!0} +!llvm.module.flags = !{!2} + +!0 = distinct !DICompileUnit(language: DW_LANG_C99, isOptimized: false, emissionKind: 0, file: !1, globals: null) +!1 = !DIFile(filename: "t", directory: "") +!2 = !{i32 1, !"Debug Info Version", i32 3} diff --git a/llvm/test/DebugInfo/Generic/constant-pointers.ll b/llvm/test/DebugInfo/Generic/constant-pointers.ll new file mode 100644 index 00000000000..b46ee5d98f0 --- /dev/null +++ b/llvm/test/DebugInfo/Generic/constant-pointers.ll @@ -0,0 +1,51 @@ +; REQUIRES: object-emission + +; RUN: %llc_dwarf -O0 -filetype=obj %s -o - | llvm-dwarfdump -debug-dump=info - | FileCheck %s + +; Ensure that pointer constants are emitted as unsigned data. Alternatively, +; these could be signless data (dataN). + +; Built with Clang from: +; template <void *V, void (*F)(), int i> +; void func() {} +; template void func<nullptr, nullptr, 42>(); + +; CHECK: DW_TAG_subprogram +; CHECK: DW_TAG_template_value_parameter +; CHECK: DW_AT_name {{.*}} "V" +; CHECK: DW_AT_const_value [DW_FORM_udata] (0) +; CHECK: DW_TAG_template_value_parameter +; CHECK: DW_AT_name {{.*}} "F" +; CHECK: DW_AT_const_value [DW_FORM_udata] (0) + +; Function Attrs: nounwind uwtable +define weak_odr void @_Z4funcILPv0ELPFvvE0ELi42EEvv() #0 { +entry: + ret void, !dbg !18 +} + +attributes #0 = { nounwind 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" } + +!llvm.dbg.cu = !{!0} +!llvm.module.flags = !{!15, !16} +!llvm.ident = !{!17} + +!0 = distinct !DICompileUnit(language: DW_LANG_C_plus_plus, producer: "clang version 3.5.0 ", isOptimized: false, emissionKind: 1, file: !1, enums: !2, retainedTypes: !2, subprograms: !3, globals: !2, imports: !2) +!1 = !DIFile(filename: "constant-pointers.cpp", directory: "/tmp/dbginfo") +!2 = !{} +!3 = !{!4} +!4 = distinct !DISubprogram(name: "func<nullptr, nullptr, 42>", linkageName: "_Z4funcILPv0ELPFvvE0ELi42EEvv", line: 2, isLocal: false, isDefinition: true, virtualIndex: 6, flags: DIFlagPrototyped, isOptimized: false, scopeLine: 2, file: !1, scope: !5, type: !6, function: void ()* @_Z4funcILPv0ELPFvvE0ELi42EEvv, templateParams: !8, variables: !2) +!5 = !DIFile(filename: "constant-pointers.cpp", directory: "/tmp/dbginfo") +!6 = !DISubroutineType(types: !7) +!7 = !{null} +!8 = !{!9, !11, !13} +!9 = !DITemplateValueParameter(tag: DW_TAG_template_value_parameter, name: "V", type: !10, value: i8 0) +!10 = !DIDerivedType(tag: DW_TAG_pointer_type, size: 64, align: 64, baseType: null) +!11 = !DITemplateValueParameter(tag: DW_TAG_template_value_parameter, name: "F", type: !12, value: i8 0) +!12 = !DIDerivedType(tag: DW_TAG_pointer_type, size: 64, align: 64, baseType: !6) +!13 = !DITemplateValueParameter(tag: DW_TAG_template_value_parameter, name: "i", type: !14, value: i32 42) +!14 = !DIBasicType(tag: DW_TAG_base_type, name: "int", size: 32, align: 32, encoding: DW_ATE_signed) +!15 = !{i32 2, !"Dwarf Version", i32 4} +!16 = !{i32 2, !"Debug Info Version", i32 3} +!17 = !{!"clang version 3.5.0 "} +!18 = !DILocation(line: 3, scope: !4) diff --git a/llvm/test/DebugInfo/Generic/constant-sdnodes-have-dbg-location.ll b/llvm/test/DebugInfo/Generic/constant-sdnodes-have-dbg-location.ll new file mode 100644 index 00000000000..d6b6413aa4f --- /dev/null +++ b/llvm/test/DebugInfo/Generic/constant-sdnodes-have-dbg-location.ll @@ -0,0 +1,26 @@ +; RUN: llc -debug < %s 2>&1 | FileCheck %s +; REQUIRES: asserts + +; CHECK: 0x{{[0-9,a-f]+}}: i32 = Constant<-1>test.c:4:5 + +define i32 @main() { +entry: + %retval = alloca i32, align 4 + store i32 0, i32* %retval + ret i32 -1, !dbg !10 +} + +!llvm.dbg.cu = !{!0} +!llvm.module.flags = !{!8, !9} + +!0 = distinct !DICompileUnit(language: DW_LANG_C99, file: !1, producer: "", isOptimized: false, subprograms: !3) +!1 = !DIFile(filename: "test.c", directory: "/home/user/clang-llvm/build") +!2 = !{} +!3 = !{!4} +!4 = distinct !DISubprogram(name: "main", scope: !1, file: !1, line: 2, type: !5, isLocal: false, isDefinition: true, scopeLine: 3, flags: DIFlagPrototyped, isOptimized: false, function: i32 ()* @main, variables: !2) +!5 = !DISubroutineType(types: !6) +!6 = !{!7} +!7 = !DIBasicType(name: "int", size: 32, align: 32, encoding: DW_ATE_signed) +!8 = !{i32 2, !"Dwarf Version", i32 4} +!9 = !{i32 2, !"Debug Info Version", i32 3} +!10 = !DILocation(line: 4, column: 5, scope: !4) diff --git a/llvm/test/DebugInfo/Generic/constantfp-sdnodes-have-dbg-location.ll b/llvm/test/DebugInfo/Generic/constantfp-sdnodes-have-dbg-location.ll new file mode 100644 index 00000000000..986a05d5677 --- /dev/null +++ b/llvm/test/DebugInfo/Generic/constantfp-sdnodes-have-dbg-location.ll @@ -0,0 +1,24 @@ +; RUN: llc -debug < %s 2>&1 | FileCheck %s +; REQUIRES: asserts + +; CHECK: 0x{{[0-9,a-f]+}}: f64 = ConstantFP<1.500000e+00>test.c:3:5 + +define double @f() { +entry: + ret double 1.500000e+00, !dbg !10 +} + +!llvm.dbg.cu = !{!0} +!llvm.module.flags = !{!8, !9} + +!0 = distinct !DICompileUnit(language: DW_LANG_C99, file: !1, producer: "", isOptimized: false, subprograms: !3) +!1 = !DIFile(filename: "test.c", directory: "/home/user/clang-llvm/build") +!2 = !{} +!3 = !{!4} +!4 = distinct !DISubprogram(name: "f", scope: !1, file: !1, line: 1, type: !5, isLocal: false, isDefinition: true, scopeLine: 2, flags: DIFlagPrototyped, isOptimized: false, function: double ()* @f, variables: !2) +!5 = !DISubroutineType(types: !6) +!6 = !{!7} +!7 = !DIBasicType(name: "double", size: 64, align: 64, encoding: DW_ATE_float) +!8 = !{i32 2, !"Dwarf Version", i32 4} +!9 = !{i32 2, !"Debug Info Version", i32 3} +!10 = !DILocation(line: 3, column: 5, scope: !4) diff --git a/llvm/test/DebugInfo/Generic/cross-cu-inlining.ll b/llvm/test/DebugInfo/Generic/cross-cu-inlining.ll new file mode 100644 index 00000000000..6f9436ba1cf --- /dev/null +++ b/llvm/test/DebugInfo/Generic/cross-cu-inlining.ll @@ -0,0 +1,143 @@ +; REQUIRES: object-emission + +; RUN: %llc_dwarf -O0 -filetype=obj -dwarf-linkage-names=Enable < %s | llvm-dwarfdump -debug-dump=info - | FileCheck -implicit-check-not=DW_TAG %s +; RUN: %llc_dwarf -dwarf-accel-tables=Enable -dwarf-linkage-names=Enable -O0 -filetype=obj < %s | llvm-dwarfdump - | FileCheck --check-prefix=CHECK-ACCEL --check-prefix=CHECK %s + +; Build from source: +; $ clang++ a.cpp b.cpp -g -c -emit-llvm +; $ llvm-link a.bc b.bc -o ab.bc +; $ opt -inline ab.bc -o ab-opt.bc +; $ cat a.cpp +; extern int i; +; int func(int); +; int main() { +; return func(i); +; } +; $ cat b.cpp +; int __attribute__((always_inline)) func(int x) { +; return x * 2; +; } + +; Ensure that func inlined into main is described and references the abstract +; definition in b.cpp's CU. + +; CHECK: DW_TAG_compile_unit +; CHECK: DW_AT_name {{.*}} "a.cpp" +; CHECK: DW_TAG_subprogram +; CHECK: DW_AT_type [DW_FORM_ref_addr] (0x00000000[[INT:.*]]) +; CHECK: 0x[[INLINED:[0-9a-f]*]]:{{.*}}DW_TAG_inlined_subroutine +; CHECK: DW_AT_abstract_origin {{.*}}[[ABS_FUNC:........]] "_Z4funci" +; CHECK: DW_TAG_formal_parameter +; CHECK: DW_AT_abstract_origin {{.*}}[[ABS_VAR:........]] "x" + +; Check the abstract definition is in the 'b.cpp' CU and doesn't contain any +; concrete information (address range or variable location) +; CHECK: DW_TAG_compile_unit +; CHECK: DW_AT_name {{.*}} "b.cpp" +; CHECK: 0x[[ABS_FUNC]]: DW_TAG_subprogram +; CHECK-NOT: DW_AT_low_pc +; CHECK: 0x[[ABS_VAR]]: DW_TAG_formal_parameter +; CHECK-NOT: DW_AT_location +; CHECK: DW_AT_type [DW_FORM_ref4] {{.*}} {0x[[INT]]} +; CHECK-NOT: DW_AT_location + +; CHECK: 0x[[INT]]: DW_TAG_base_type +; CHECK: DW_AT_name {{.*}} "int" + +; Check the concrete out of line definition references the abstract and +; provides the address range and variable location +; CHECK: 0x[[FUNC:[0-9a-f]*]]{{.*}}DW_TAG_subprogram +; CHECK: DW_AT_low_pc +; CHECK: DW_AT_abstract_origin {{.*}} {0x[[ABS_FUNC]]} "_Z4funci" +; CHECK: DW_TAG_formal_parameter +; CHECK: DW_AT_location +; CHECK: DW_AT_abstract_origin {{.*}} {0x[[ABS_VAR]]} "x" + +; Check that both the inline and the non out of line version of func are +; correctly referenced in the accelerator table. Before r221837, the one +; in the second compilation unit had a wrong offset +; CHECK-ACCEL: .apple_names contents: +; CHECK-ACCEL: Name{{.*}}"func" +; CHECK-ACCEL-NOT: Name +; CHECK-ACCEL: Atom[0]{{.*}}[[INLINED]] +; CHECK-ACCEL-NOT: Name +; CHECK-ACCEL: Atom[0]{{.*}}[[FUNC]] + +@i = external global i32 + +; Function Attrs: uwtable +define i32 @main() #0 { +entry: + %x.addr.i = alloca i32, align 4 + %retval = alloca i32, align 4 + store i32 0, i32* %retval + %0 = load i32, i32* @i, align 4, !dbg !19 + %1 = bitcast i32* %x.addr.i to i8* + call void @llvm.lifetime.start(i64 4, i8* %1) + store i32 %0, i32* %x.addr.i, align 4 + call void @llvm.dbg.declare(metadata i32* %x.addr.i, metadata !120, metadata !DIExpression()), !dbg !21 + %2 = load i32, i32* %x.addr.i, align 4, !dbg !22 + %mul.i = mul nsw i32 %2, 2, !dbg !22 + %3 = bitcast i32* %x.addr.i to i8*, !dbg !22 + call void @llvm.lifetime.end(i64 4, i8* %3), !dbg !22 + ret i32 %mul.i, !dbg !19 +} + +; Function Attrs: alwaysinline nounwind uwtable +define i32 @_Z4funci(i32 %x) #1 { +entry: + %x.addr = alloca i32, align 4 + store i32 %x, i32* %x.addr, align 4 + call void @llvm.dbg.declare(metadata i32* %x.addr, metadata !20, metadata !DIExpression()), !dbg !23 + %0 = load i32, i32* %x.addr, align 4, !dbg !24 + %mul = mul nsw i32 %0, 2, !dbg !24 + ret i32 %mul, !dbg !24 +} + +; Function Attrs: nounwind readnone +declare void @llvm.dbg.declare(metadata, metadata, metadata) #2 + +; Function Attrs: nounwind +declare void @llvm.lifetime.start(i64, i8* nocapture) #3 + +; Function Attrs: nounwind +declare void @llvm.lifetime.end(i64, i8* nocapture) #3 + +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 = { alwaysinline nounwind 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 #2 = { nounwind readnone } +attributes #3 = { nounwind } + +!llvm.dbg.cu = !{!0, !9} +!llvm.module.flags = !{!16, !17} +!llvm.ident = !{!18, !18} + +!0 = distinct !DICompileUnit(language: DW_LANG_C_plus_plus, producer: "clang version 3.5.0 ", isOptimized: false, emissionKind: 1, file: !1, enums: !2, retainedTypes: !2, subprograms: !3, globals: !2, imports: !2) +!1 = !DIFile(filename: "a.cpp", directory: "/tmp/dbginfo") +!2 = !{} +!3 = !{!4} +!4 = distinct !DISubprogram(name: "main", line: 3, isLocal: false, isDefinition: true, virtualIndex: 6, flags: DIFlagPrototyped, isOptimized: false, scopeLine: 3, file: !1, scope: !5, type: !6, function: i32 ()* @main, variables: !2) +!5 = !DIFile(filename: "a.cpp", directory: "/tmp/dbginfo") +!6 = !DISubroutineType(types: !7) +!7 = !{!8} +!8 = !DIBasicType(tag: DW_TAG_base_type, name: "int", size: 32, align: 32, encoding: DW_ATE_signed) +!9 = distinct !DICompileUnit(language: DW_LANG_C_plus_plus, producer: "clang version 3.5.0 ", isOptimized: false, emissionKind: 1, file: !10, enums: !2, retainedTypes: !2, subprograms: !11, globals: !2, imports: !2) +!10 = !DIFile(filename: "b.cpp", directory: "/tmp/dbginfo") +!11 = !{!12} +!12 = distinct !DISubprogram(name: "func", linkageName: "_Z4funci", line: 1, isLocal: false, isDefinition: true, virtualIndex: 6, flags: DIFlagPrototyped, isOptimized: false, scopeLine: 1, file: !10, scope: !13, type: !14, function: i32 (i32)* @_Z4funci, variables: !2) +!13 = !DIFile(filename: "b.cpp", directory: "/tmp/dbginfo") +!14 = !DISubroutineType(types: !15) +!15 = !{!8, !8} +!16 = !{i32 2, !"Dwarf Version", i32 4} +!17 = !{i32 2, !"Debug Info Version", i32 3} +!18 = !{!"clang version 3.5.0 "} +!19 = !DILocation(line: 4, scope: !4) +!20 = !DILocalVariable(name: "x", line: 1, arg: 1, scope: !12, file: !13, type: !8) + +!120 = !DILocalVariable(name: "x", line: 1, arg: 1, scope: !12, file: !13, type: !8) + +!21 = !DILocation(line: 1, scope: !12, inlinedAt: !19) +!22 = !DILocation(line: 2, scope: !12, inlinedAt: !19) +!23 = !DILocation(line: 1, scope: !12) +!24 = !DILocation(line: 2, scope: !12) + diff --git a/llvm/test/DebugInfo/Generic/cross-cu-linkonce-distinct.ll b/llvm/test/DebugInfo/Generic/cross-cu-linkonce-distinct.ll new file mode 100644 index 00000000000..25b6b971bce --- /dev/null +++ b/llvm/test/DebugInfo/Generic/cross-cu-linkonce-distinct.ll @@ -0,0 +1,95 @@ +; REQUIRES: object-emission + +; RUN: %llc_dwarf -O0 -filetype=obj < %s | llvm-dwarfdump -debug-dump=info - | FileCheck %s + +; Testing that two distinct (distinct by writing them in separate files, while +; still fulfilling C++'s ODR by having identical token sequences) functions, +; linked under LTO, get plausible debug info (and don't crash). + +; Built from source: +; $ clang++ a.cpp b.cpp -g -c -emit-llvm +; $ llvm-link a.bc b.bc -o ab.bc + +; This change is intended to tickle a case where the subprogram MDNode +; associated with the llvm::Function will differ from the subprogram +; referenced by the DbgLocs in the function. + +; $ sed -ie "s/!12, !0/!0, !12/" ab.ll +; $ cat a.cpp +; inline int func(int i) { +; return i * 2; +; } +; int (*x)(int) = &func; +; $ cat b.cpp +; inline int func(int i) { +; return i * 2; +; } +; int (*y)(int) = &func; + +; CHECK: DW_TAG_compile_unit +; CHECK: DW_TAG_subprogram +; CHECK-NOT: DW_TAG +; CHECK: DW_AT_name {{.*}} "func" +; CHECK: DW_TAG_compile_unit + +; FIXME: Maybe we should drop the subprogram here - since the function was +; emitted in one CU, due to linkonce_odr uniquing. We certainly don't emit the +; subprogram here if the source location for this definition is the same (see +; test/DebugInfo/cross-cu-linkonce.ll), though it's very easy to tickle that +; into failing even without duplicating the source as has been done in this +; case (two cpp files in different directories, including the same header that +; contains an inline function - clang will produce distinct subprogram metadata +; that won't deduplicate owing to the file location information containing the +; directory of the source file even though the file name is absolute, not +; relative) + +; CHECK: DW_TAG_subprogram + +@x = global i32 (i32)* @_Z4funci, align 8 +@y = global i32 (i32)* @_Z4funci, align 8 + +; Function Attrs: inlinehint nounwind uwtable +define linkonce_odr i32 @_Z4funci(i32 %i) #0 { + %1 = alloca i32, align 4 + store i32 %i, i32* %1, align 4 + call void @llvm.dbg.declare(metadata i32* %1, metadata !22, metadata !DIExpression()), !dbg !23 + %2 = load i32, i32* %1, align 4, !dbg !24 + %3 = mul nsw i32 %2, 2, !dbg !24 + ret i32 %3, !dbg !24 +} + +; Function Attrs: nounwind readnone +declare void @llvm.dbg.declare(metadata, metadata, metadata) #1 + +attributes #0 = { inlinehint nounwind 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 = { nounwind readnone } + +!llvm.dbg.cu = !{!12, !0} +!llvm.module.flags = !{!19, !20} +!llvm.ident = !{!21, !21} + +!0 = distinct !DICompileUnit(language: DW_LANG_C_plus_plus, producer: "clang version 3.5.0 ", isOptimized: false, emissionKind: 1, file: !1, enums: !2, retainedTypes: !2, subprograms: !3, globals: !9, imports: !2) +!1 = !DIFile(filename: "a.cpp", directory: "/tmp/dbginfo") +!2 = !{} +!3 = !{!4} +!4 = distinct !DISubprogram(name: "func", linkageName: "_Z4funci", line: 1, isLocal: false, isDefinition: true, virtualIndex: 6, flags: DIFlagPrototyped, isOptimized: false, scopeLine: 1, file: !1, scope: !5, type: !6, function: i32 (i32)* @_Z4funci, variables: !2) +!5 = !DIFile(filename: "a.cpp", directory: "/tmp/dbginfo") +!6 = !DISubroutineType(types: !7) +!7 = !{!8, !8} +!8 = !DIBasicType(tag: DW_TAG_base_type, name: "int", size: 32, align: 32, encoding: DW_ATE_signed) +!9 = !{!10} +!10 = !DIGlobalVariable(name: "x", line: 4, isLocal: false, isDefinition: true, scope: null, file: !5, type: !11, variable: i32 (i32)** @x) +!11 = !DIDerivedType(tag: DW_TAG_pointer_type, size: 64, align: 64, baseType: !6) +!12 = distinct !DICompileUnit(language: DW_LANG_C_plus_plus, producer: "clang version 3.5.0 ", isOptimized: false, emissionKind: 1, file: !13, enums: !2, retainedTypes: !2, subprograms: !14, globals: !17, imports: !2) +!13 = !DIFile(filename: "b.cpp", directory: "/tmp/dbginfo") +!14 = !{!15} +!15 = distinct !DISubprogram(name: "func", linkageName: "_Z4funci", line: 1, isLocal: false, isDefinition: true, virtualIndex: 6, flags: DIFlagPrototyped, isOptimized: false, scopeLine: 1, file: !13, scope: !16, type: !6, function: i32 (i32)* @_Z4funci, variables: !2) +!16 = !DIFile(filename: "b.cpp", directory: "/tmp/dbginfo") +!17 = !{!18} +!18 = !DIGlobalVariable(name: "y", line: 4, isLocal: false, isDefinition: true, scope: null, file: !16, type: !11, variable: i32 (i32)** @y) +!19 = !{i32 2, !"Dwarf Version", i32 4} +!20 = !{i32 1, !"Debug Info Version", i32 3} +!21 = !{!"clang version 3.5.0 "} +!22 = !DILocalVariable(name: "i", line: 1, arg: 1, scope: !4, file: !5, type: !8) +!23 = !DILocation(line: 1, scope: !4) +!24 = !DILocation(line: 2, scope: !4) diff --git a/llvm/test/DebugInfo/Generic/cross-cu-linkonce.ll b/llvm/test/DebugInfo/Generic/cross-cu-linkonce.ll new file mode 100644 index 00000000000..50708d7ebe0 --- /dev/null +++ b/llvm/test/DebugInfo/Generic/cross-cu-linkonce.ll @@ -0,0 +1,73 @@ +; REQUIRES: object-emission + +; RUN: %llc_dwarf -O0 -filetype=obj < %s | llvm-dwarfdump -debug-dump=info - | FileCheck %s + +; Built from source: +; $ clang++ a.cpp b.cpp -g -c -emit-llvm +; $ llvm-link a.bc b.bc -o ab.bc +; $ cat a.cpp +; # 1 "func.h" +; inline int func(int i) { +; return i * 2; +; } +; int (*x)(int) = &func; +; $ cat b.cpp +; # 1 "func.h" +; inline int func(int i) { +; return i * 2; +; } +; int (*y)(int) = &func; + +; CHECK: DW_TAG_compile_unit +; CHECK: DW_TAG_subprogram +; CHECK-NOT: DW_TAG +; CHECK: DW_AT_name {{.*}} "func" +; CHECK: DW_TAG_compile_unit +; CHECK-NOT: DW_TAG_subprogram + +@x = global i32 (i32)* @_Z4funci, align 8 +@y = global i32 (i32)* @_Z4funci, align 8 + +; Function Attrs: inlinehint nounwind uwtable +define linkonce_odr i32 @_Z4funci(i32 %i) #0 { + %1 = alloca i32, align 4 + store i32 %i, i32* %1, align 4 + call void @llvm.dbg.declare(metadata i32* %1, metadata !20, metadata !DIExpression()), !dbg !21 + %2 = load i32, i32* %1, align 4, !dbg !22 + %3 = mul nsw i32 %2, 2, !dbg !22 + ret i32 %3, !dbg !22 +} + +; Function Attrs: nounwind readnone +declare void @llvm.dbg.declare(metadata, metadata, metadata) #1 + +attributes #0 = { inlinehint nounwind 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 = { nounwind readnone } + +!llvm.dbg.cu = !{!0, !13} +!llvm.module.flags = !{!17, !18} +!llvm.ident = !{!19, !19} + +!0 = distinct !DICompileUnit(language: DW_LANG_C_plus_plus, producer: "clang version 3.5.0 ", isOptimized: false, emissionKind: 1, file: !1, enums: !2, retainedTypes: !2, subprograms: !3, globals: !10, imports: !2) +!1 = !DIFile(filename: "a.cpp", directory: "/tmp/dbginfo") +!2 = !{} +!3 = !{!4} +!4 = distinct !DISubprogram(name: "func", linkageName: "_Z4funci", line: 1, isLocal: false, isDefinition: true, virtualIndex: 6, flags: DIFlagPrototyped, isOptimized: false, scopeLine: 1, file: !5, scope: !6, type: !7, function: i32 (i32)* @_Z4funci, variables: !2) +!5 = !DIFile(filename: "func.h", directory: "/tmp/dbginfo") +!6 = !DIFile(filename: "func.h", directory: "/tmp/dbginfo") +!7 = !DISubroutineType(types: !8) +!8 = !{!9, !9} +!9 = !DIBasicType(tag: DW_TAG_base_type, name: "int", size: 32, align: 32, encoding: DW_ATE_signed) +!10 = !{!11} +!11 = !DIGlobalVariable(name: "x", line: 4, isLocal: false, isDefinition: true, scope: null, file: !6, type: !12, variable: i32 (i32)** @x) +!12 = !DIDerivedType(tag: DW_TAG_pointer_type, size: 64, align: 64, baseType: !7) +!13 = distinct !DICompileUnit(language: DW_LANG_C_plus_plus, producer: "clang version 3.5.0 ", isOptimized: false, emissionKind: 1, file: !14, enums: !2, retainedTypes: !2, subprograms: !3, globals: !15, imports: !2) +!14 = !DIFile(filename: "b.cpp", directory: "/tmp/dbginfo") +!15 = !{!16} +!16 = !DIGlobalVariable(name: "y", line: 4, isLocal: false, isDefinition: true, scope: null, file: !6, type: !12, variable: i32 (i32)** @y) +!17 = !{i32 2, !"Dwarf Version", i32 4} +!18 = !{i32 1, !"Debug Info Version", i32 3} +!19 = !{!"clang version 3.5.0 "} +!20 = !DILocalVariable(name: "i", line: 1, arg: 1, scope: !4, file: !6, type: !9) +!21 = !DILocation(line: 1, scope: !4) +!22 = !DILocation(line: 2, scope: !4) diff --git a/llvm/test/DebugInfo/Generic/cu-range-hole.ll b/llvm/test/DebugInfo/Generic/cu-range-hole.ll new file mode 100644 index 00000000000..96b5380d97c --- /dev/null +++ b/llvm/test/DebugInfo/Generic/cu-range-hole.ll @@ -0,0 +1,74 @@ +; REQUIRES: object-emission +; RUN: %llc_dwarf -O0 -filetype=obj %s -o %t +; RUN: llvm-dwarfdump %t | FileCheck %s + +; Check that we emit ranges for this CU since we have a function with and +; without debug info. +; Note: This depends upon the order of output in the .o file. Currently it's +; in order of the output to make sure that the CU has multiple ranges since +; there's a function in the middle. If they were together then it would have +; a single range and no DW_AT_ranges. +; CHECK: DW_TAG_compile_unit +; CHECK: DW_AT_ranges +; CHECK: DW_TAG_subprogram +; CHECK: DW_TAG_subprogram + +; Function Attrs: nounwind uwtable +define i32 @b(i32 %c) #0 { +entry: + %c.addr = alloca i32, align 4 + store i32 %c, i32* %c.addr, align 4 + call void @llvm.dbg.declare(metadata i32* %c.addr, metadata !13, metadata !DIExpression()), !dbg !14 + %0 = load i32, i32* %c.addr, align 4, !dbg !14 + %add = add nsw i32 %0, 1, !dbg !14 + ret i32 %add, !dbg !14 +} + +; Function Attrs: nounwind uwtable +define i32 @a(i32 %b) #0 { +entry: + %b.addr = alloca i32, align 4 + store i32 %b, i32* %b.addr, align 4 + %0 = load i32, i32* %b.addr, align 4 + %add = add nsw i32 %0, 1 + ret i32 %add +} + +; Function Attrs: nounwind readnone +declare void @llvm.dbg.declare(metadata, metadata, metadata) #1 + +; Function Attrs: nounwind uwtable +define i32 @d(i32 %e) #0 { +entry: + %e.addr = alloca i32, align 4 + store i32 %e, i32* %e.addr, align 4 + call void @llvm.dbg.declare(metadata i32* %e.addr, metadata !15, metadata !DIExpression()), !dbg !16 + %0 = load i32, i32* %e.addr, align 4, !dbg !16 + %add = add nsw i32 %0, 1, !dbg !16 + ret i32 %add, !dbg !16 +} + +attributes #0 = { nounwind 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 = { nounwind readnone } + +!llvm.ident = !{!0, !0} +!llvm.dbg.cu = !{!1} +!llvm.module.flags = !{!11, !12} + +!0 = !{!"clang version 3.5.0 (trunk 204164) (llvm/trunk 204183)"} +!1 = distinct !DICompileUnit(language: DW_LANG_C99, producer: "clang version 3.5.0 (trunk 204164) (llvm/trunk 204183)", isOptimized: false, emissionKind: 1, file: !2, enums: !3, retainedTypes: !3, subprograms: !4, globals: !3, imports: !3) +!2 = !DIFile(filename: "b.c", directory: "/usr/local/google/home/echristo") +!3 = !{} +!4 = !{!5, !10} +!5 = distinct !DISubprogram(name: "b", line: 1, isLocal: false, isDefinition: true, virtualIndex: 6, flags: DIFlagPrototyped, isOptimized: false, scopeLine: 1, file: !2, scope: !6, type: !7, function: i32 (i32)* @b, variables: !3) +!6 = !DIFile(filename: "b.c", directory: "/usr/local/google/home/echristo") +!7 = !DISubroutineType(types: !8) +!8 = !{!9, !9} +!9 = !DIBasicType(tag: DW_TAG_base_type, name: "int", size: 32, align: 32, encoding: DW_ATE_signed) +!10 = distinct !DISubprogram(name: "d", line: 3, isLocal: false, isDefinition: true, virtualIndex: 6, flags: DIFlagPrototyped, isOptimized: false, scopeLine: 3, file: !2, scope: !6, type: !7, function: i32 (i32)* @d, variables: !3) +!11 = !{i32 2, !"Dwarf Version", i32 4} +!12 = !{i32 1, !"Debug Info Version", i32 3} +!13 = !DILocalVariable(name: "c", line: 1, arg: 1, scope: !5, file: !6, type: !9) +!14 = !DILocation(line: 1, scope: !5) +!15 = !DILocalVariable(name: "e", line: 3, arg: 1, scope: !10, file: !6, type: !9) +!16 = !DILocation(line: 3, scope: !10) diff --git a/llvm/test/DebugInfo/Generic/cu-ranges.ll b/llvm/test/DebugInfo/Generic/cu-ranges.ll new file mode 100644 index 00000000000..03ddb2708bc --- /dev/null +++ b/llvm/test/DebugInfo/Generic/cu-ranges.ll @@ -0,0 +1,71 @@ +; REQUIRES: object-emission +; RUN: %llc_dwarf -O0 -filetype=obj %s -o %t +; RUN: llvm-dwarfdump %t | FileCheck %s + +; Check that we emit ranges for this which has a non-traditional section and a normal section. + +; CHECK: DW_TAG_compile_unit +; CHECK: DW_AT_ranges +; CHECK: DW_TAG_subprogram +; CHECK: DW_AT_low_pc +; CHECK: DW_AT_high_pc +; CHECK: DW_TAG_subprogram +; CHECK: DW_AT_low_pc +; CHECK: DW_AT_high_pc + +; CHECK: .debug_ranges contents: +; FIXME: When we get better dumping facilities we'll want to elaborate here. +; CHECK: 00000000 <End of list> + +; Function Attrs: nounwind uwtable +define i32 @foo(i32 %a) #0 section "__TEXT,__foo" { +entry: + %a.addr = alloca i32, align 4 + store i32 %a, i32* %a.addr, align 4 + call void @llvm.dbg.declare(metadata i32* %a.addr, metadata !13, metadata !DIExpression()), !dbg !14 + %0 = load i32, i32* %a.addr, align 4, !dbg !15 + %add = add nsw i32 %0, 5, !dbg !15 + ret i32 %add, !dbg !15 +} + +; Function Attrs: nounwind readnone +declare void @llvm.dbg.declare(metadata, metadata, metadata) #1 + +; Function Attrs: nounwind uwtable +define i32 @bar(i32 %a) #0 { +entry: + %a.addr = alloca i32, align 4 + store i32 %a, i32* %a.addr, align 4 + call void @llvm.dbg.declare(metadata i32* %a.addr, metadata !16, metadata !DIExpression()), !dbg !17 + %0 = load i32, i32* %a.addr, align 4, !dbg !18 + %add = add nsw i32 %0, 5, !dbg !18 + ret i32 %add, !dbg !18 +} + +attributes #0 = { nounwind 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 = { nounwind readnone } + +!llvm.dbg.cu = !{!0} +!llvm.module.flags = !{!10, !11} +!llvm.ident = !{!12} + +!0 = distinct !DICompileUnit(language: DW_LANG_C99, producer: "clang version 3.5.0 (trunk 204164) (llvm/trunk 204183)", isOptimized: false, emissionKind: 1, file: !1, enums: !2, retainedTypes: !2, subprograms: !3, globals: !2, imports: !2) +!1 = !DIFile(filename: "foo.c", directory: "/usr/local/google/home/echristo") +!2 = !{} +!3 = !{!4, !9} +!4 = distinct !DISubprogram(name: "foo", line: 1, isLocal: false, isDefinition: true, virtualIndex: 6, flags: DIFlagPrototyped, isOptimized: false, scopeLine: 1, file: !1, scope: !5, type: !6, function: i32 (i32)* @foo, variables: !2) +!5 = !DIFile(filename: "foo.c", directory: "/usr/local/google/home/echristo") +!6 = !DISubroutineType(types: !7) +!7 = !{!8, !8} +!8 = !DIBasicType(tag: DW_TAG_base_type, name: "int", size: 32, align: 32, encoding: DW_ATE_signed) +!9 = distinct !DISubprogram(name: "bar", line: 5, isLocal: false, isDefinition: true, virtualIndex: 6, flags: DIFlagPrototyped, isOptimized: false, scopeLine: 5, file: !1, scope: !5, type: !6, function: i32 (i32)* @bar, variables: !2) +!10 = !{i32 2, !"Dwarf Version", i32 4} +!11 = !{i32 1, !"Debug Info Version", i32 3} +!12 = !{!"clang version 3.5.0 (trunk 204164) (llvm/trunk 204183)"} +!13 = !DILocalVariable(name: "a", line: 1, arg: 1, scope: !4, file: !5, type: !8) +!14 = !DILocation(line: 1, scope: !4) +!15 = !DILocation(line: 2, scope: !4) +!16 = !DILocalVariable(name: "a", line: 5, arg: 1, scope: !9, file: !5, type: !8) +!17 = !DILocation(line: 5, scope: !9) +!18 = !DILocation(line: 6, scope: !9) + diff --git a/llvm/test/DebugInfo/Generic/dbg-at-specficiation.ll b/llvm/test/DebugInfo/Generic/dbg-at-specficiation.ll new file mode 100644 index 00000000000..7302aaecb93 --- /dev/null +++ b/llvm/test/DebugInfo/Generic/dbg-at-specficiation.ll @@ -0,0 +1,21 @@ +; RUN: llc < %s | FileCheck %s +; Radar 10147769 +; Do not unnecessarily use AT_specification DIE. +; CHECK-NOT: AT_specification + +@a = common global [10 x i32] zeroinitializer, align 16 + +!llvm.dbg.cu = !{!0} +!llvm.module.flags = !{!12} + +!0 = distinct !DICompileUnit(language: DW_LANG_C99, producer: "clang version 3.0 (trunk 140253)", isOptimized: true, emissionKind: 0, file: !11, enums: !2, retainedTypes: !2, subprograms: !2, globals: !3) +!2 = !{} +!3 = !{!5} +!5 = !DIGlobalVariable(name: "a", line: 1, isLocal: false, isDefinition: true, scope: null, file: !6, type: !7, variable: [10 x i32]* @a) +!6 = !DIFile(filename: "x.c", directory: "/private/tmp") +!7 = !DICompositeType(tag: DW_TAG_array_type, size: 320, align: 32, baseType: !8, elements: !9) +!8 = !DIBasicType(tag: DW_TAG_base_type, name: "int", size: 32, align: 32, encoding: DW_ATE_signed) +!9 = !{!10} +!10 = !DISubrange(count: 10) +!11 = !DIFile(filename: "x.c", directory: "/private/tmp") +!12 = !{i32 1, !"Debug Info Version", i32 3} diff --git a/llvm/test/DebugInfo/Generic/dead-argument-order.ll b/llvm/test/DebugInfo/Generic/dead-argument-order.ll new file mode 100644 index 00000000000..b3ae5fe5e31 --- /dev/null +++ b/llvm/test/DebugInfo/Generic/dead-argument-order.ll @@ -0,0 +1,81 @@ +; REQUIRES: object-emission + +; RUN: %llc_dwarf -O0 -filetype=obj < %s | llvm-dwarfdump -debug-dump=info - | FileCheck %s + +; Built from the following source with clang -O1 +; struct S { int i; }; +; int function(struct S s, int i) { return s.i + i; } + +; Due to the X86_64 ABI, 's' is passed in registers and once optimized, the +; entirety of 's' is never reconstituted, since only the int is required, and +; thus the variable's location is unknown/dead to debug info. + +; Future/current work should enable us to describe partial variables, which, in +; this case, happens to be the entire variable. + +; CHECK: DW_TAG_subprogram +; CHECK-NOT: DW_TAG +; CHECK: DW_AT_name {{.*}} "function" +; CHECK-NOT: {{DW_TAG|NULL}} +; CHECK: DW_TAG_formal_parameter +; CHECK-NOT: DW_TAG +; CHECK: DW_AT_name {{.*}} "s" +; CHECK-NOT: DW_TAG +; FIXME: Even though 's' is never reconstituted into a struct, the one member +; variable is still live and used, and so we should be able to describe 's's +; location as the location of that int. +; CHECK-NOT: DW_AT_location +; CHECK-NOT: {{DW_TAG|NULL}} +; CHECK: DW_TAG_formal_parameter +; CHECK-NOT: DW_TAG +; CHECK: DW_AT_location +; CHECK-NOT: DW_TAG +; CHECK: DW_AT_name {{.*}} "i" + + +%struct.S = type { i32 } + +; Function Attrs: nounwind readnone uwtable +define i32 @_Z8function1Si(i32 %s.coerce, i32 %i) #0 { +entry: + tail call void @llvm.dbg.declare(metadata %struct.S* undef, metadata !14, metadata !DIExpression()), !dbg !20 + tail call void @llvm.dbg.value(metadata i32 %i, i64 0, metadata !15, metadata !DIExpression()), !dbg !20 + %add = add nsw i32 %i, %s.coerce, !dbg !20 + ret i32 %add, !dbg !20 +} + +; Function Attrs: nounwind readnone +declare void @llvm.dbg.declare(metadata, metadata, metadata) #1 + +; Function Attrs: nounwind readnone +declare void @llvm.dbg.value(metadata, i64, metadata, metadata) #1 + +attributes #0 = { nounwind readnone uwtable "less-precise-fpmad"="false" "no-frame-pointer-elim"="false" "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 = { nounwind readnone } + +!llvm.dbg.cu = !{!0} +!llvm.module.flags = !{!16, !17} +!llvm.ident = !{!18} + +!0 = distinct !DICompileUnit(language: DW_LANG_C_plus_plus, producer: "clang version 3.5.0 ", isOptimized: true, emissionKind: 1, file: !1, enums: !2, retainedTypes: !3, subprograms: !8, globals: !2, imports: !2) +!1 = !DIFile(filename: "dead-argument-order.cpp", directory: "/tmp/dbginfo") +!2 = !{} +!3 = !{!4} +!4 = !DICompositeType(tag: DW_TAG_structure_type, name: "S", line: 1, size: 32, align: 32, file: !1, elements: !5, identifier: "_ZTS1S") +!5 = !{!6} +!6 = !DIDerivedType(tag: DW_TAG_member, name: "i", line: 1, size: 32, align: 32, file: !1, scope: !"_ZTS1S", baseType: !7) +!7 = !DIBasicType(tag: DW_TAG_base_type, name: "int", size: 32, align: 32, encoding: DW_ATE_signed) +!8 = !{!9} +!9 = distinct !DISubprogram(name: "function", linkageName: "_Z8function1Si", line: 2, isLocal: false, isDefinition: true, virtualIndex: 6, flags: DIFlagPrototyped, isOptimized: true, scopeLine: 2, file: !1, scope: !10, type: !11, function: i32 (i32, i32)* @_Z8function1Si, variables: !13) +!10 = !DIFile(filename: "dead-argument-order.cpp", directory: "/tmp/dbginfo") +!11 = !DISubroutineType(types: !12) +!12 = !{!7, !4, !7} +!13 = !{!14, !15} +!14 = !DILocalVariable(name: "s", line: 2, arg: 1, scope: !9, file: !10, type: !"_ZTS1S") +!15 = !DILocalVariable(name: "i", line: 2, arg: 2, scope: !9, file: !10, type: !7) +!16 = !{i32 2, !"Dwarf Version", i32 4} +!17 = !{i32 2, !"Debug Info Version", i32 3} +!18 = !{!"clang version 3.5.0 "} +!19 = !{%struct.S* undef} +!20 = !DILocation(line: 2, scope: !9) + diff --git a/llvm/test/DebugInfo/Generic/debug-info-always-inline.ll b/llvm/test/DebugInfo/Generic/debug-info-always-inline.ll new file mode 100644 index 00000000000..5eaa6752218 --- /dev/null +++ b/llvm/test/DebugInfo/Generic/debug-info-always-inline.ll @@ -0,0 +1,143 @@ +; RUN: opt < %s -always-inline -S | FileCheck %s +; +; Generated from the following C++ source with: +; clang -cc1 -disable-llvm-optzns -emit-llvm -g -stack-protector 2 test.cpp +; +; /* BEGIN SOURCE */ +; int __attribute__((always_inline)) foo() +; { +; int arr[10]; +; arr[0] = 5; +; int sum = 4; +; return sum; +; } +; +; extern void bar(); +; +; int main() +; { +; bar(); +; int i = foo(); +; return i; +; } +; /* END SOURCE */ + +; The patch that includes this test case, is addressing the following issue: +; +; When functions are inlined, instructions without debug information +; are attributed with the call site's DebugLoc. After inlining, inlined static +; allocas are moved to the caller's entry block, adjacent to the caller's original +; static alloca instructions. By retaining the call site's DebugLoc, these instructions +; may cause instructions that are subsequently inserted at the entry block to pick +; up the same DebugLoc. +; +; In the offending case stack protection inserts an instruction at the caller's +; entry block, which inadvertently picks up the inlined call's DebugLoc, because +; the entry block's first instruction is the recently moved inlined alloca instruction. +; +; The stack protection instruction then becomes part of the function prologue, with the +; result that the line number that is associated with the stack protection instruction +; is deemed to be the end of the function prologue. Since this line number is the +; call site's line number, setting a breakpoint at the function in the debugger +; will make the user stop at the line of the inlined call. + +; Note that without the stack protection instruction this effect would not occur +; because the allocas all get collapsed into a single instruction that reserves +; stack space and have no further influence on the prologue's line number information. + + +; The selected solution is to not attribute static allocas with the call site's +; DebugLoc. + +; At some point in the future, it may be desirable to describe the inlining +; in the alloca instructions, but then the code that handles prologues must +; be able to handle this correctly, including the late insertion of instructions +; into it. + +; In this context it is also important to distingush between functions +; with the "nodebug" attribute and those without it. Alloca instructions from +; nodebug functions should continue to have no DebugLoc, whereas those from +; non-nodebug functions (i.e. functions with debug information) may want to +; have their DebugLocs augmented with inlining information. + + +; Make sure that after inlining the call to foo() the alloca instructions for +; arr.i and sum.i do not retain debug information. + +; CHECK: %arr.i = alloca [10 x i32], align {{[0-9]*$}} +; CHECK: %sum.i = alloca i32, align {{[0-9]*$}} + + +; ModuleID = 'test.cpp' +target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128" +target triple = "x86_64-unknown-linux-gnu" + +; Function Attrs: alwaysinline nounwind sspstrong +define i32 @_Z3foov() #0 { +entry: + %arr = alloca [10 x i32], align 16 + %sum = alloca i32, align 4 + call void @llvm.dbg.declare(metadata [10 x i32]* %arr, metadata !14), !dbg !18 + %arrayidx = getelementptr inbounds [10 x i32], [10 x i32]* %arr, i32 0, i64 0, !dbg !19 + store i32 5, i32* %arrayidx, align 4, !dbg !19 + call void @llvm.dbg.declare(metadata i32* %sum, metadata !20), !dbg !21 + store i32 4, i32* %sum, align 4, !dbg !21 + %0 = load i32, i32* %sum, align 4, !dbg !22 + ret i32 %0, !dbg !22 +} + +; Function Attrs: nounwind readnone +declare void @llvm.dbg.declare(metadata, metadata) #1 + +; Function Attrs: nounwind sspstrong +define i32 @main() #2 { +entry: + %retval = alloca i32, align 4 + %i = alloca i32, align 4 + store i32 0, i32* %retval + call void @_Z3barv(), !dbg !23 + call void @llvm.dbg.declare(metadata i32* %i, metadata !24), !dbg !25 + %call = call i32 @_Z3foov(), !dbg !25 + store i32 %call, i32* %i, align 4, !dbg !25 + %0 = load i32, i32* %i, align 4, !dbg !26 + ret i32 %0, !dbg !26 +} + +declare void @_Z3barv() #3 + +attributes #0 = { alwaysinline nounwind sspstrong "less-precise-fpmad"="false" "no-frame-pointer-elim"="false" "no-infs-fp-math"="false" "no-nans-fp-math"="false" "no-realign-stack" "stack-protector-buffer-size"="8" "unsafe-fp-math"="false" "use-soft-float"="false" } +attributes #1 = { nounwind readnone } +attributes #2 = { nounwind sspstrong "less-precise-fpmad"="false" "no-frame-pointer-elim"="false" "no-infs-fp-math"="false" "no-nans-fp-math"="false" "no-realign-stack" "stack-protector-buffer-size"="8" "unsafe-fp-math"="false" "use-soft-float"="false" } +attributes #3 = { "less-precise-fpmad"="false" "no-frame-pointer-elim"="false" "no-infs-fp-math"="false" "no-nans-fp-math"="false" "no-realign-stack" "stack-protector-buffer-size"="8" "unsafe-fp-math"="false" "use-soft-float"="false" } + +!llvm.dbg.cu = !{!0} +!llvm.module.flags = !{!11, !12} +!llvm.ident = !{!13} + +!0 = !{i32 786449, !1, i32 4, !"clang version 3.6.0 (217844)", i1 false, !"", i32 0, !2, !2, !3, !2, !2, !"", i32 1} ; [ DW_TAG_compile_unit ] [/home/user/test/<stdin>] [DW_LANG_C_plus_plus] +!1 = !{!"<stdin>", !"/home/user/test"} +!2 = !{} +!3 = !{!4, !10} +!4 = !{i32 786478, !5, !6, !"foo", !"foo", !"_Z3foov", i32 1, !7, i1 false, i1 true, i32 0, i32 0, null, i32 256, i1 false, i32 ()* @_Z3foov, null, null, !2, i32 2} ; [ DW_TAG_subprogram ] [line 1] [def] [scope 2] [foo] +!5 = !{!"test.cpp", !"/home/user/test"} +!6 = !{i32 786473, !5} ; [ DW_TAG_file_type ] [/home/user/test/test.cpp] +!7 = !{i32 786453, i32 0, null, !"", i32 0, i64 0, i64 0, i64 0, i32 0, null, !8, i32 0, null, null, null} ; [ DW_TAG_subroutine_type ] [line 0, size 0, align 0, offset 0] [from ] +!8 = !{!9} +!9 = !{i32 786468, null, null, !"int", i32 0, i64 32, i64 32, i64 0, i32 0, i32 5} ; [ DW_TAG_base_type ] [int] [line 0, size 32, align 32, offset 0, enc DW_ATE_signed] +!10 = !{i32 786478, !5, !6, !"main", !"main", !"", i32 11, !7, i1 false, i1 true, i32 0, i32 0, null, i32 256, i1 false, i32 ()* @main, null, null, !2, i32 12} ; [ DW_TAG_subprogram ] [line 11] [def] [scope 12] [main] +!11 = !{i32 2, !"Dwarf Version", i32 4} +!12 = !{i32 2, !"Debug Info Version", i32 1} +!13 = !{!"clang version 3.6.0 (217844)"} +!14 = !{i32 786688, !4, !"arr", !6, i32 3, !15, i32 0, i32 0} ; [ DW_TAG_auto_variable ] [arr] [line 3] +!15 = !{i32 786433, null, null, !"", i32 0, i64 320, i64 32, i32 0, i32 0, !9, !16, i32 0, null, null, null} ; [ DW_TAG_array_type ] [line 0, size 320, align 32, offset 0] [from int] +!16 = !{!17} +!17 = !{i32 786465, i64 0, i64 10} ; [ DW_TAG_subrange_type ] [0, 9] +!18 = !DILocation(line: 3, scope: !4) +!19 = !DILocation(line: 4, scope: !4) +!20 = !{i32 786688, !4, !"sum", !6, i32 5, !9, i32 0, i32 0} ; [ DW_TAG_auto_variable ] [sum] [line 5] +!21 = !DILocation(line: 5, scope: !4) +!22 = !DILocation(line: 6, scope: !4) +!23 = !DILocation(line: 13, scope: !10) +!24 = !{i32 786688, !10, !"i", !6, i32 14, !9, i32 0, i32 0} ; [ DW_TAG_auto_variable ] [i] [line 14] +!25 = !DILocation(line: 14, scope: !10) +!26 = !DILocation(line: 15, scope: !10) diff --git a/llvm/test/DebugInfo/Generic/debug-info-qualifiers.ll b/llvm/test/DebugInfo/Generic/debug-info-qualifiers.ll new file mode 100644 index 00000000000..c13a5ea731b --- /dev/null +++ b/llvm/test/DebugInfo/Generic/debug-info-qualifiers.ll @@ -0,0 +1,98 @@ +; REQUIRES: object-emission +; Test (r)value qualifiers on C++11 non-static member functions. +; Generated from tools/clang/test/CodeGenCXX/debug-info-qualifiers.cpp +; +; class A { +; public: +; void l() const &; +; void r() const &&; +; }; +; +; void g() { +; A a; +; auto pl = &A::l; +; auto pr = &A::r; +; } +; +; RUN: %llc_dwarf -filetype=obj -O0 < %s | llvm-dwarfdump - | FileCheck %s +; CHECK: DW_TAG_subroutine_type DW_CHILDREN_yes +; CHECK-NEXT: DW_AT_reference DW_FORM_flag_present +; CHECK: DW_TAG_subroutine_type DW_CHILDREN_yes +; CHECK-NEXT: DW_AT_rvalue_reference DW_FORM_flag_present +; +; CHECK: DW_TAG_subprogram +; CHECK-NOT: DW_TAG_subprogram +; CHECK: DW_AT_name {{.*}}"l" +; CHECK-NOT: DW_TAG_subprogram +; CHECK: DW_AT_reference [DW_FORM_flag_present] (true) + +; CHECK: DW_TAG_subprogram +; CHECK-NOT: DW_TAG_subprogram +; CHECK: DW_AT_name {{.*}}"r" +; CHECK-NOT: DW_TAG_subprogram +; CHECK: DW_AT_rvalue_reference [DW_FORM_flag_present] (true) + +%class.A = type { i8 } + +; Function Attrs: nounwind +define void @_Z1gv() #0 { + %a = alloca %class.A, align 1 + %pl = alloca { i64, i64 }, align 8 + %pr = alloca { i64, i64 }, align 8 + call void @llvm.dbg.declare(metadata %class.A* %a, metadata !24, metadata !DIExpression()), !dbg !25 + call void @llvm.dbg.declare(metadata { i64, i64 }* %pl, metadata !26, metadata !DIExpression()), !dbg !31 + store { i64, i64 } { i64 ptrtoint (void (%class.A*)* @_ZNKR1A1lEv to i64), i64 0 }, { i64, i64 }* %pl, align 8, !dbg !31 + call void @llvm.dbg.declare(metadata { i64, i64 }* %pr, metadata !32, metadata !DIExpression()), !dbg !35 + store { i64, i64 } { i64 ptrtoint (void (%class.A*)* @_ZNKO1A1rEv to i64), i64 0 }, { i64, i64 }* %pr, align 8, !dbg !35 + ret void, !dbg !36 +} + +; Function Attrs: nounwind readnone +declare void @llvm.dbg.declare(metadata, metadata, metadata) #1 + +declare void @_ZNKR1A1lEv(%class.A*) + +declare void @_ZNKO1A1rEv(%class.A*) + +attributes #0 = { nounwind } +attributes #1 = { nounwind readnone } + +!llvm.dbg.cu = !{!0} +!llvm.module.flags = !{!21, !22} +!llvm.ident = !{!23} + +!0 = distinct !DICompileUnit(language: DW_LANG_C_plus_plus, producer: "clang version 3.5 ", isOptimized: false, emissionKind: 0, file: !1, enums: !2, retainedTypes: !3, subprograms: !16, globals: !2, imports: !2) +!1 = !DIFile(filename: "debug-info-qualifiers.cpp", directory: "") +!2 = !{} +!3 = !{!4} +!4 = !DICompositeType(tag: DW_TAG_class_type, name: "A", line: 2, size: 8, align: 8, file: !5, elements: !6, identifier: "_ZTS1A") +!5 = !DIFile(filename: "debug-info-qualifiers.cpp", directory: "") +!6 = !{!7, !13} +!7 = !DISubprogram(name: "l", linkageName: "_ZNKR1A1lEv", line: 5, isLocal: false, isDefinition: false, virtualIndex: 6, flags: DIFlagPrototyped | DIFlagLValueReference, isOptimized: false, scopeLine: 5, file: !5, scope: !"_ZTS1A", type: !8) +!8 = !DISubroutineType(flags: DIFlagLValueReference, types: !9) +!9 = !{null, !10} +!10 = !DIDerivedType(tag: DW_TAG_pointer_type, size: 64, align: 64, flags: DIFlagArtificial | DIFlagObjectPointer, baseType: !11) +!11 = !DIDerivedType(tag: DW_TAG_const_type, baseType: !"_ZTS1A") +!13 = !DISubprogram(name: "r", linkageName: "_ZNKO1A1rEv", line: 7, isLocal: false, isDefinition: false, virtualIndex: 6, flags: DIFlagObjectPointer | DIFlagRValueReference, isOptimized: false, scopeLine: 7, file: !5, scope: !"_ZTS1A", type: !14) +!14 = !DISubroutineType(flags: DIFlagRValueReference, types: !9) +!16 = !{!17} +!17 = distinct !DISubprogram(name: "g", linkageName: "_Z1gv", line: 10, isLocal: false, isDefinition: true, virtualIndex: 6, flags: DIFlagPrototyped, isOptimized: false, scopeLine: 10, file: !5, scope: !18, type: !19, function: void ()* @_Z1gv, variables: !2) +!18 = !DIFile(filename: "debug-info-qualifiers.cpp", directory: "") +!19 = !DISubroutineType(types: !20) +!20 = !{null} +!21 = !{i32 2, !"Dwarf Version", i32 4} +!22 = !{i32 1, !"Debug Info Version", i32 3} +!23 = !{!"clang version 3.5 "} +!24 = !DILocalVariable(name: "a", line: 11, scope: !17, file: !18, type: !4) +!25 = !DILocation(line: 11, scope: !17) +!26 = !DILocalVariable(name: "pl", line: 16, scope: !17, file: !18, type: !27) +!27 = !DIDerivedType(tag: DW_TAG_ptr_to_member_type, baseType: !28, extraData: !"_ZTS1A") +!28 = !DISubroutineType(flags: DIFlagLValueReference, types: !29) +!29 = !{null, !30} +!30 = !DIDerivedType(tag: DW_TAG_pointer_type, size: 64, align: 64, flags: DIFlagArtificial | DIFlagObjectPointer, baseType: !"_ZTS1A") +!31 = !DILocation(line: 16, scope: !17) +!32 = !DILocalVariable(name: "pr", line: 21, scope: !17, file: !18, type: !33) +!33 = !DIDerivedType(tag: DW_TAG_ptr_to_member_type, baseType: !34, extraData: !"_ZTS1A") +!34 = !DISubroutineType(flags: DIFlagRValueReference, types: !29) +!35 = !DILocation(line: 21, scope: !17) +!36 = !DILocation(line: 22, scope: !17) diff --git a/llvm/test/DebugInfo/Generic/debuginfofinder-forward-declaration.ll b/llvm/test/DebugInfo/Generic/debuginfofinder-forward-declaration.ll new file mode 100644 index 00000000000..62c151bc8d7 --- /dev/null +++ b/llvm/test/DebugInfo/Generic/debuginfofinder-forward-declaration.ll @@ -0,0 +1,42 @@ +; RUN: opt -analyze -module-debuginfo < %s | FileCheck %s + + +; This module is generated from the following c-code: +; +; > union X; +; > +; > struct Y { +; > union X *x; +; > }; +; > +; > struct Y y; + + +; CHECK: Type: Y from /tmp/minimal.c:3 DW_TAG_structure_type +; CHECK: Type: x from /tmp/minimal.c:4 DW_TAG_member +; CHECK: Type: DW_TAG_pointer_type +; CHECK: Type: X from /tmp/minimal.c:1 DW_TAG_structure_type + + +%struct.Y = type { %struct.X* } +%struct.X = type opaque + +@y = common global %struct.Y zeroinitializer, align 8 + +!llvm.dbg.cu = !{!0} +!llvm.module.flags = !{!10, !11} +!llvm.ident = !{!12} + +!0 = distinct !DICompileUnit(language: DW_LANG_C99, file: !1, producer: "clang version 3.7.0 (http://llvm.org/git/clang.git 247b30a043eb8f39ea3708e7e995089da0a6b00f) (http://llvm.org/git/llvm.git 6ecc7365a89c771fd229bdd9ffcc178684ea1aa5)", isOptimized: false, runtimeVersion: 0, emissionKind: 1, enums: !2, retainedTypes: !2, subprograms: !2, globals: !3, imports: !2) +!1 = !DIFile(filename: "minimal.c", directory: "/tmp") +!2 = !{} +!3 = !{!4} +!4 = !DIGlobalVariable(name: "y", scope: !0, file: !1, line: 7, type: !5, isLocal: false, isDefinition: true, variable: %struct.Y* @y) +!5 = !DICompositeType(tag: DW_TAG_structure_type, name: "Y", file: !1, line: 3, size: 64, align: 64, elements: !6) +!6 = !{!7} +!7 = !DIDerivedType(tag: DW_TAG_member, name: "x", scope: !5, file: !1, line: 4, baseType: !8, size: 64, align: 64) +!8 = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: !9, size: 64, align: 64) +!9 = !DICompositeType(tag: DW_TAG_structure_type, name: "X", file: !1, line: 1, flags: DIFlagFwdDecl) +!10 = !{i32 2, !"Dwarf Version", i32 4} +!11 = !{i32 2, !"Debug Info Version", i32 3} +!12 = !{!"clang version 3.7.0 (http://llvm.org/git/clang.git 247b30a043eb8f39ea3708e7e995089da0a6b00f) (http://llvm.org/git/llvm.git 6ecc7365a89c771fd229bdd9ffcc178684ea1aa5)"} diff --git a/llvm/test/DebugInfo/Generic/debuginfofinder-multiple-cu.ll b/llvm/test/DebugInfo/Generic/debuginfofinder-multiple-cu.ll new file mode 100644 index 00000000000..06ed02a4ce0 --- /dev/null +++ b/llvm/test/DebugInfo/Generic/debuginfofinder-multiple-cu.ll @@ -0,0 +1,41 @@ +; RUN: opt -analyze -module-debuginfo < %s | FileCheck %s + +; Produced from linking: +; /tmp/test1.c containing f() +; /tmp/test2.c containing g() + +; Verify that both compile units and both their contained functions are +; listed by DebugInfoFinder: +;CHECK: Compile unit: DW_LANG_C99 from /tmp/test1.c +;CHECK: Compile unit: DW_LANG_C99 from /tmp/test2.c +;CHECK: Subprogram: f from /tmp/test1.c:1 +;CHECK: Subprogram: g from /tmp/test2.c:1 + +define void @f() { + ret void, !dbg !14 +} + +define void @g() { + ret void, !dbg !15 +} + +!llvm.dbg.cu = !{!0, !8} +!llvm.module.flags = !{!13, !16} + +!0 = distinct !DICompileUnit(language: DW_LANG_C99, producer: "clang version 3.4 (192092)", isOptimized: false, emissionKind: 0, file: !1, enums: !2, retainedTypes: !2, subprograms: !3, globals: !2, imports: !2) +!1 = !DIFile(filename: "test1.c", directory: "/tmp") +!2 = !{} +!3 = !{!4} +!4 = distinct !DISubprogram(name: "f", line: 1, isLocal: false, isDefinition: true, virtualIndex: 6, isOptimized: false, scopeLine: 1, file: !1, scope: !5, type: !6, function: void ()* @f, variables: !2) +!5 = !DIFile(filename: "test1.c", directory: "/tmp") +!6 = !DISubroutineType(types: !7) +!7 = !{null} +!8 = distinct !DICompileUnit(language: DW_LANG_C99, producer: "clang version 3.4 (192092)", isOptimized: false, emissionKind: 0, file: !9, enums: !2, retainedTypes: !2, subprograms: !10, globals: !2, imports: !2) +!9 = !DIFile(filename: "test2.c", directory: "/tmp") +!10 = !{!11} +!11 = distinct !DISubprogram(name: "g", line: 1, isLocal: false, isDefinition: true, virtualIndex: 6, isOptimized: false, scopeLine: 1, file: !9, scope: !12, type: !6, function: void ()* @g, variables: !2) +!12 = !DIFile(filename: "test2.c", directory: "/tmp") +!13 = !{i32 2, !"Dwarf Version", i32 4} +!14 = !DILocation(line: 1, scope: !4) +!15 = !DILocation(line: 1, scope: !11) +!16 = !{i32 1, !"Debug Info Version", i32 3} diff --git a/llvm/test/DebugInfo/Generic/dwarf-public-names.ll b/llvm/test/DebugInfo/Generic/dwarf-public-names.ll new file mode 100644 index 00000000000..c14412d3d81 --- /dev/null +++ b/llvm/test/DebugInfo/Generic/dwarf-public-names.ll @@ -0,0 +1,131 @@ +; REQUIRES: object-emission + +; RUN: %llc_dwarf -generate-dwarf-pub-sections=Enable -filetype=obj -o %t.o < %s +; RUN: llvm-dwarfdump -debug-dump=pubnames %t.o | FileCheck %s +; ModuleID = 'dwarf-public-names.cpp' +; +; Generated from: +; +; struct C { +; void member_function(); +; static int static_member_function(); +; static int static_member_variable; +; }; +; +; int C::static_member_variable = 0; +; +; void C::member_function() { +; static_member_variable = 0; +; } +; +; int C::static_member_function() { +; return static_member_variable; +; } +; +; C global_variable; +; +; int global_function() { +; return -1; +; } +; +; namespace ns { +; void global_namespace_function() { +; global_variable.member_function(); +; } +; int global_namespace_variable = 1; +; } + +; Skip the output to the header of the pubnames section. +; CHECK: debug_pubnames +; CHECK: version = 0x0002 + +; Check for each name in the output. +; CHECK-DAG: "ns" +; CHECK-DAG: "C::static_member_function" +; CHECK-DAG: "global_variable" +; CHECK-DAG: "ns::global_namespace_variable" +; CHECK-DAG: "ns::global_namespace_function" +; CHECK-DAG: "global_function" +; CHECK-DAG: "C::static_member_variable" +; CHECK-DAG: "C::member_function" + +%struct.C = type { i8 } + +@_ZN1C22static_member_variableE = global i32 0, align 4 +@global_variable = global %struct.C zeroinitializer, align 1 +@_ZN2ns25global_namespace_variableE = global i32 1, align 4 + +define void @_ZN1C15member_functionEv(%struct.C* %this) nounwind uwtable align 2 { +entry: + %this.addr = alloca %struct.C*, align 8 + store %struct.C* %this, %struct.C** %this.addr, align 8 + call void @llvm.dbg.declare(metadata %struct.C** %this.addr, metadata !28, metadata !DIExpression()), !dbg !30 + %this1 = load %struct.C*, %struct.C** %this.addr + store i32 0, i32* @_ZN1C22static_member_variableE, align 4, !dbg !31 + ret void, !dbg !32 +} + +declare void @llvm.dbg.declare(metadata, metadata, metadata) nounwind readnone + +define i32 @_ZN1C22static_member_functionEv() nounwind uwtable align 2 { +entry: + %0 = load i32, i32* @_ZN1C22static_member_variableE, align 4, !dbg !33 + ret i32 %0, !dbg !33 +} + +define i32 @_Z15global_functionv() nounwind uwtable { +entry: + ret i32 -1, !dbg !34 +} + +define void @_ZN2ns25global_namespace_functionEv() nounwind uwtable { +entry: + call void @_ZN1C15member_functionEv(%struct.C* @global_variable), !dbg !35 + ret void, !dbg !36 +} + +attributes #0 = { nounwind uwtable } +attributes #1 = { nounwind readnone } + +!llvm.dbg.cu = !{!0} +!llvm.module.flags = !{!38} + +!0 = distinct !DICompileUnit(language: DW_LANG_C_plus_plus, producer: "clang version 3.3 (http://llvm.org/git/clang.git a09cd8103a6a719cb2628cdf0c91682250a17bd2) (http://llvm.org/git/llvm.git 47d03cec0afca0c01ae42b82916d1d731716cd20)", isOptimized: false, emissionKind: 0, file: !37, enums: !1, retainedTypes: !1, subprograms: !2, globals: !24, imports: !1) +!1 = !{} +!2 = !{!3, !18, !19, !20} +!3 = distinct !DISubprogram(name: "member_function", linkageName: "_ZN1C15member_functionEv", line: 9, isLocal: false, isDefinition: true, virtualIndex: 6, flags: DIFlagPrototyped, isOptimized: false, scopeLine: 9, file: !4, scope: null, type: !5, function: void (%struct.C*)* @_ZN1C15member_functionEv, declaration: !12, variables: !1) +!4 = !DIFile(filename: "dwarf-public-names.cpp", directory: "/usr2/kparzysz/s.hex/t") +!5 = !DISubroutineType(types: !6) +!6 = !{null, !7} +!7 = !DIDerivedType(tag: DW_TAG_pointer_type, size: 64, align: 64, flags: DIFlagArtificial | DIFlagObjectPointer, baseType: !8) +!8 = !DICompositeType(tag: DW_TAG_structure_type, name: "C", line: 1, size: 8, align: 8, file: !37, elements: !9) +!9 = !{!10, !12, !14} +!10 = !DIDerivedType(tag: DW_TAG_member, name: "static_member_variable", line: 4, flags: DIFlagStaticMember, file: !37, scope: !8, baseType: !11) +!11 = !DIBasicType(tag: DW_TAG_base_type, name: "int", size: 32, align: 32, encoding: DW_ATE_signed) +!12 = !DISubprogram(name: "member_function", linkageName: "_ZN1C15member_functionEv", line: 2, isLocal: false, isDefinition: false, virtualIndex: 6, flags: DIFlagPrototyped, isOptimized: false, scopeLine: 2, file: !4, scope: !8, type: !5, variables: !13) +!13 = !{} ; previously: invalid DW_TAG_base_type +!14 = !DISubprogram(name: "static_member_function", linkageName: "_ZN1C22static_member_functionEv", line: 3, isLocal: false, isDefinition: false, virtualIndex: 6, flags: DIFlagPrototyped, isOptimized: false, scopeLine: 3, file: !4, scope: !8, type: !15, variables: !17) +!15 = !DISubroutineType(types: !16) +!16 = !{!11} +!17 = !{} ; previously: invalid DW_TAG_base_type +!18 = distinct !DISubprogram(name: "static_member_function", linkageName: "_ZN1C22static_member_functionEv", line: 13, isLocal: false, isDefinition: true, virtualIndex: 6, flags: DIFlagPrototyped, isOptimized: false, scopeLine: 13, file: !4, scope: null, type: !15, function: i32 ()* @_ZN1C22static_member_functionEv, declaration: !14, variables: !1) +!19 = distinct !DISubprogram(name: "global_function", linkageName: "_Z15global_functionv", line: 19, isLocal: false, isDefinition: true, virtualIndex: 6, flags: DIFlagPrototyped, isOptimized: false, scopeLine: 19, file: !4, scope: !4, type: !15, function: i32 ()* @_Z15global_functionv, variables: !1) +!20 = distinct !DISubprogram(name: "global_namespace_function", linkageName: "_ZN2ns25global_namespace_functionEv", line: 24, isLocal: false, isDefinition: true, virtualIndex: 6, flags: DIFlagPrototyped, isOptimized: false, scopeLine: 24, file: !4, scope: !21, type: !22, function: void ()* @_ZN2ns25global_namespace_functionEv, variables: !1) +!21 = !DINamespace(name: "ns", line: 23, file: !4, scope: null) +!22 = !DISubroutineType(types: !23) +!23 = !{null} +!24 = !{!25, !26, !27} +!25 = !DIGlobalVariable(name: "static_member_variable", linkageName: "_ZN1C22static_member_variableE", line: 7, isLocal: false, isDefinition: true, scope: !8, file: !4, type: !11, variable: i32* @_ZN1C22static_member_variableE, declaration: !10) +!26 = !DIGlobalVariable(name: "global_variable", line: 17, isLocal: false, isDefinition: true, scope: null, file: !4, type: !8, variable: %struct.C* @global_variable) +!27 = !DIGlobalVariable(name: "global_namespace_variable", linkageName: "_ZN2ns25global_namespace_variableE", line: 27, isLocal: false, isDefinition: true, scope: !21, file: !4, type: !11, variable: i32* @_ZN2ns25global_namespace_variableE) +!28 = !DILocalVariable(name: "this", line: 9, arg: 1, flags: DIFlagArtificial | DIFlagObjectPointer, scope: !3, file: !4, type: !29) +!29 = !DIDerivedType(tag: DW_TAG_pointer_type, size: 64, align: 64, baseType: !8) +!30 = !DILocation(line: 9, scope: !3) +!31 = !DILocation(line: 10, scope: !3) +!32 = !DILocation(line: 11, scope: !3) +!33 = !DILocation(line: 14, scope: !18) +!34 = !DILocation(line: 20, scope: !19) +!35 = !DILocation(line: 25, scope: !20) +!36 = !DILocation(line: 26, scope: !20) +!37 = !DIFile(filename: "dwarf-public-names.cpp", directory: "/usr2/kparzysz/s.hex/t") +!38 = !{i32 1, !"Debug Info Version", i32 3} diff --git a/llvm/test/DebugInfo/Generic/empty.ll b/llvm/test/DebugInfo/Generic/empty.ll new file mode 100644 index 00000000000..f787039885b --- /dev/null +++ b/llvm/test/DebugInfo/Generic/empty.ll @@ -0,0 +1,31 @@ +; REQUIRES: object-emission + +; RUN: %llc_dwarf < %s -filetype=obj | llvm-dwarfdump - | FileCheck %s +; RUN: %llc_dwarf -split-dwarf=Enable < %s -filetype=obj | llvm-dwarfdump - | FileCheck --check-prefix=FISSION %s + +; darwin has a workaround for a linker bug so it always emits one line table entry +; XFAIL: darwin + +; Expect no line table entry since there are no functions and file references in this compile unit +; CHECK: .debug_line contents: +; CHECK: Line table prologue: +; CHECK: total_length: 0x00000019 +; CHECK-NOT: file_names[ + +; CHECK: .debug_pubnames contents: +; CHECK-NOT: Offset + +; CHECK: .debug_pubtypes contents: +; CHECK-NOT: Offset + +; Don't emit DW_AT_addr_base when there are no addresses. +; FISSION-NOT: DW_AT_GNU_addr_base [DW_FORM_sec_offset] + +!llvm.dbg.cu = !{!0} +!llvm.module.flags = !{!5} + +!0 = distinct !DICompileUnit(language: DW_LANG_C99, producer: "clang version 3.1 (trunk 143523)", isOptimized: true, emissionKind: 0, file: !4, enums: !2, retainedTypes: !2, subprograms: !2, globals: !2) +!2 = !{} +!3 = !DIFile(filename: "empty.c", directory: "/home/nlewycky") +!4 = !DIFile(filename: "empty.c", directory: "/home/nlewycky") +!5 = !{i32 1, !"Debug Info Version", i32 3} diff --git a/llvm/test/DebugInfo/Generic/enum-types.ll b/llvm/test/DebugInfo/Generic/enum-types.ll new file mode 100644 index 00000000000..484f965384e --- /dev/null +++ b/llvm/test/DebugInfo/Generic/enum-types.ll @@ -0,0 +1,78 @@ +; REQUIRES: object-emission +; +; RUN: %llc_dwarf -filetype=obj -O0 -dwarf-linkage-names=Enable < %s | llvm-dwarfdump -debug-dump=info - | FileCheck %s + +; Make sure we can handle enums with the same identifier but in enum types of +; different compile units. +; rdar://17628609 + +; CHECK: DW_TAG_compile_unit +; CHECK: 0x[[ENUM:.*]]: DW_TAG_enumeration_type +; CHECK-NEXT: DW_AT_name {{.*}} "EA" +; CHECK: DW_TAG_subprogram +; CHECK: DW_AT_MIPS_linkage_name {{.*}} "_Z4topA2EA" +; CHECK: DW_TAG_formal_parameter +; CHECK: DW_AT_type [DW_FORM_ref4] (cu + 0x{{.*}} => {0x[[ENUM]]}) + +; CHECK: DW_TAG_compile_unit +; CHECK: DW_TAG_subprogram +; CHECK: DW_AT_MIPS_linkage_name {{.*}} "_Z4topB2EA" +; CHECK: DW_TAG_formal_parameter +; CHECK: DW_AT_type [DW_FORM_ref_addr] {{.*}}[[ENUM]] + +; Function Attrs: nounwind ssp uwtable +define void @_Z4topA2EA(i32 %sa) #0 { +entry: + %sa.addr = alloca i32, align 4 + store i32 %sa, i32* %sa.addr, align 4 + call void @llvm.dbg.declare(metadata i32* %sa.addr, metadata !22, metadata !DIExpression()), !dbg !23 + ret void, !dbg !24 +} + +; Function Attrs: nounwind readnone +declare void @llvm.dbg.declare(metadata, metadata, metadata) #1 + +; Function Attrs: nounwind ssp uwtable +define void @_Z4topB2EA(i32 %sa) #0 { +entry: + %sa.addr = alloca i32, align 4 + store i32 %sa, i32* %sa.addr, align 4 + call void @llvm.dbg.declare(metadata i32* %sa.addr, metadata !25, metadata !DIExpression()), !dbg !26 + ret void, !dbg !27 +} + +attributes #0 = { nounwind ssp 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 = { nounwind readnone } + +!llvm.dbg.cu = !{!0, !12} +!llvm.module.flags = !{!19, !20} +!llvm.ident = !{!21, !21} + +!0 = distinct !DICompileUnit(language: DW_LANG_C_plus_plus, producer: "clang version 3.5.0 (trunk 214102:214133) (llvm/trunk 214102:214132)", isOptimized: false, emissionKind: 1, file: !1, enums: !2, retainedTypes: !2, subprograms: !6, globals: !11, imports: !11) +!1 = !DIFile(filename: "a.cpp", directory: "") +!2 = !{!3} +!3 = !DICompositeType(tag: DW_TAG_enumeration_type, name: "EA", line: 1, size: 32, align: 32, file: !1, elements: !4, identifier: "_ZTS2EA") +!4 = !{!5} +!5 = !DIEnumerator(name: "EA_0", value: 0) ; [ DW_TAG_enumerator ] [EA_0 :: 0] +!6 = !{!7} +!7 = distinct !DISubprogram(name: "topA", linkageName: "_Z4topA2EA", line: 5, isLocal: false, isDefinition: true, virtualIndex: 6, flags: DIFlagPrototyped, isOptimized: false, scopeLine: 5, file: !1, scope: !8, type: !9, function: void (i32)* @_Z4topA2EA, variables: !11) +!8 = !DIFile(filename: "a.cpp", directory: "") +!9 = !DISubroutineType(types: !10) +!10 = !{null, !"_ZTS2EA"} +!11 = !{} +!12 = distinct !DICompileUnit(language: DW_LANG_C_plus_plus, producer: "clang version 3.5.0 (trunk 214102:214133) (llvm/trunk 214102:214132)", isOptimized: false, emissionKind: 1, file: !13, enums: !14, retainedTypes: !14, subprograms: !16, globals: !11, imports: !11) +!13 = !DIFile(filename: "b.cpp", directory: "") +!14 = !{!15} +!15 = !DICompositeType(tag: DW_TAG_enumeration_type, name: "EA", line: 1, size: 32, align: 32, file: !13, elements: !4, identifier: "_ZTS2EA") +!16 = !{!17} +!17 = distinct !DISubprogram(name: "topB", linkageName: "_Z4topB2EA", line: 5, isLocal: false, isDefinition: true, virtualIndex: 6, flags: DIFlagPrototyped, isOptimized: false, scopeLine: 5, file: !13, scope: !18, type: !9, function: void (i32)* @_Z4topB2EA, variables: !11) +!18 = !DIFile(filename: "b.cpp", directory: "") +!19 = !{i32 2, !"Dwarf Version", i32 2} +!20 = !{i32 2, !"Debug Info Version", i32 3} +!21 = !{!"clang version 3.5.0 (trunk 214102:214133) (llvm/trunk 214102:214132)"} +!22 = !DILocalVariable(name: "sa", line: 5, arg: 1, scope: !7, file: !8, type: !"_ZTS2EA") +!23 = !DILocation(line: 5, column: 14, scope: !7) +!24 = !DILocation(line: 6, column: 1, scope: !7) +!25 = !DILocalVariable(name: "sa", line: 5, arg: 1, scope: !17, file: !18, type: !"_ZTS2EA") +!26 = !DILocation(line: 5, column: 14, scope: !17) +!27 = !DILocation(line: 6, column: 1, scope: !17) diff --git a/llvm/test/DebugInfo/Generic/enum.ll b/llvm/test/DebugInfo/Generic/enum.ll new file mode 100644 index 00000000000..8d91c4e3943 --- /dev/null +++ b/llvm/test/DebugInfo/Generic/enum.ll @@ -0,0 +1,80 @@ +; REQUIRES: object-emission + +; RUN: %llc_dwarf -O0 -filetype=obj < %s > %t +; RUN: llvm-dwarfdump %t | FileCheck %s + +; IR generated from the following code compiled with clang -g: +; enum e1 { I, J = 0xffffffffU, K = 0xf000000000000000ULL } a; +; enum e2 { X }; +; void func() { +; int b = X; +; } + +; These values were previously being truncated to -1 and 0 respectively. + +; CHECK: debug_info contents +; CHECK: DW_TAG_enumeration_type +; CHECK-NEXT: DW_AT_name{{.*}} = "e1" +; CHECK-NOT: NULL +; CHECK: DW_TAG_enumerator +; CHECK-NOT: NULL +; CHECK: DW_TAG_enumerator +; CHECK-NEXT: DW_AT_name{{.*}} = "J" +; CHECK-NEXT: DW_AT_const_value [DW_FORM_sdata] (4294967295) +; CHECK-NOT: NULL +; CHECK: DW_TAG_enumerator +; CHECK-NEXT: DW_AT_name{{.*}} = "K" +; CHECK-NEXT: DW_AT_const_value [DW_FORM_sdata] (-1152921504606846976) + +; Check that we retain enums that aren't referenced by any variables, etc +; CHECK: DW_TAG_enumeration_type +; CHECK-NEXT: DW_AT_name{{.*}} = "e2" +; CHECK-NOT: NULL +; CHECK: DW_TAG_enumerator +; CHECK-NEXT: DW_AT_name{{.*}} = "X" + +@a = global i64 0, align 8 + +; Function Attrs: nounwind uwtable +define void @_Z4funcv() #0 { +entry: + %b = alloca i32, align 4 + call void @llvm.dbg.declare(metadata i32* %b, metadata !20, metadata !DIExpression()), !dbg !22 + store i32 0, i32* %b, align 4, !dbg !22 + ret void, !dbg !23 +} + +; Function Attrs: nounwind readnone +declare void @llvm.dbg.declare(metadata, metadata, metadata) #1 + +attributes #0 = { nounwind 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" "unsafe-fp-math"="false" "use-soft-float"="false" } +attributes #1 = { nounwind readnone } + +!llvm.dbg.cu = !{!0} +!llvm.module.flags = !{!19, !24} + +!0 = distinct !DICompileUnit(language: DW_LANG_C_plus_plus, producer: "clang version 3.4 ", isOptimized: false, emissionKind: 0, file: !1, enums: !2, retainedTypes: !11, subprograms: !12, globals: !17, imports: !11) +!1 = !DIFile(filename: "enum.cpp", directory: "/tmp") +!2 = !{!3, !8} +!3 = !DICompositeType(tag: DW_TAG_enumeration_type, name: "e1", line: 1, size: 64, align: 64, file: !1, elements: !4) +!4 = !{!5, !6, !7} +!5 = !DIEnumerator(name: "I", value: 0) ; [ DW_TAG_enumerator ] [I :: 0] +!6 = !DIEnumerator(name: "J", value: 4294967295) ; [ DW_TAG_enumerator ] [J :: 4294967295] +!7 = !DIEnumerator(name: "K", value: -1152921504606846976) ; [ DW_TAG_enumerator ] [K :: 17293822569102704640] +!8 = !DICompositeType(tag: DW_TAG_enumeration_type, name: "e2", line: 2, size: 32, align: 32, file: !1, elements: !9) +!9 = !{!10} +!10 = !DIEnumerator(name: "X", value: 0) ; [ DW_TAG_enumerator ] [X :: 0] +!11 = !{} +!12 = !{!13} +!13 = distinct !DISubprogram(name: "func", linkageName: "_Z4funcv", line: 3, isLocal: false, isDefinition: true, virtualIndex: 6, flags: DIFlagPrototyped, isOptimized: false, scopeLine: 3, file: !1, scope: !14, type: !15, function: void ()* @_Z4funcv, variables: !11) +!14 = !DIFile(filename: "enum.cpp", directory: "/tmp") +!15 = !DISubroutineType(types: !16) +!16 = !{null} +!17 = !{!18} +!18 = !DIGlobalVariable(name: "a", line: 1, isLocal: false, isDefinition: true, scope: null, file: !14, type: !3, variable: i64* @a) +!19 = !{i32 2, !"Dwarf Version", i32 3} +!20 = !DILocalVariable(name: "b", line: 4, scope: !13, file: !14, type: !21) +!21 = !DIBasicType(tag: DW_TAG_base_type, name: "int", size: 32, align: 32, encoding: DW_ATE_signed) +!22 = !DILocation(line: 4, scope: !13) +!23 = !DILocation(line: 5, scope: !13) +!24 = !{i32 1, !"Debug Info Version", i32 3} diff --git a/llvm/test/DebugInfo/Generic/global.ll b/llvm/test/DebugInfo/Generic/global.ll new file mode 100644 index 00000000000..ed8091a6832 --- /dev/null +++ b/llvm/test/DebugInfo/Generic/global.ll @@ -0,0 +1,42 @@ +; REQUIRES: object-emission + +; RUN: %llc_dwarf -O0 -filetype=obj < %s > %t +; RUN: llvm-dwarfdump %t | FileCheck %s + +; Also test that the null streamer doesn't crash with debug info. +; RUN: %llc_dwarf -O0 -filetype=null < %s + +; generated from the following source compiled to bitcode with clang -g -O1 +; static int i; +; int main() { +; (void)&i; +; } + +; CHECK: debug_info contents +; CHECK: DW_TAG_variable + +; Function Attrs: nounwind readnone uwtable +define i32 @main() #0 { +entry: + ret i32 0, !dbg !12 +} + +attributes #0 = { nounwind readnone uwtable "less-precise-fpmad"="false" "no-frame-pointer-elim"="false" "no-infs-fp-math"="false" "no-nans-fp-math"="false" "unsafe-fp-math"="false" "use-soft-float"="false" } + +!llvm.dbg.cu = !{!0} +!llvm.module.flags = !{!11, !13} + +!0 = distinct !DICompileUnit(language: DW_LANG_C_plus_plus, producer: "clang version 3.4 ", isOptimized: true, emissionKind: 0, file: !1, enums: !2, retainedTypes: !2, subprograms: !3, globals: !9, imports: !2) +!1 = !DIFile(filename: "global.cpp", directory: "/tmp") +!2 = !{} +!3 = !{!4} +!4 = distinct !DISubprogram(name: "main", line: 2, isLocal: false, isDefinition: true, virtualIndex: 6, flags: DIFlagPrototyped, isOptimized: true, scopeLine: 2, file: !1, scope: !5, type: !6, function: i32 ()* @main, variables: !2) +!5 = !DIFile(filename: "global.cpp", directory: "/tmp") +!6 = !DISubroutineType(types: !7) +!7 = !{!8} +!8 = !DIBasicType(tag: DW_TAG_base_type, name: "int", size: 32, align: 32, encoding: DW_ATE_signed) +!9 = !{!10} +!10 = !DIGlobalVariable(name: "i", linkageName: "_ZL1i", line: 1, isLocal: true, isDefinition: true, scope: null, file: !5, type: !8) +!11 = !{i32 2, !"Dwarf Version", i32 3} +!12 = !DILocation(line: 4, scope: !4) +!13 = !{i32 1, !"Debug Info Version", i32 3} diff --git a/llvm/test/DebugInfo/Generic/gmlt.test b/llvm/test/DebugInfo/Generic/gmlt.test new file mode 100644 index 00000000000..0514dbfc461 --- /dev/null +++ b/llvm/test/DebugInfo/Generic/gmlt.test @@ -0,0 +1,5 @@ +; REQUIRES: object-emission +; RUN: %llc_dwarf -O0 -filetype=obj < %S/Inputs/gmlt.ll | llvm-dwarfdump - | FileCheck %S/Inputs/gmlt.ll + +; There's a darwin specific test in X86/gmlt, so it's okay to XFAIL this here. +; XFAIL: darwin diff --git a/llvm/test/DebugInfo/Generic/gvn.ll b/llvm/test/DebugInfo/Generic/gvn.ll new file mode 100644 index 00000000000..1b32918dd34 --- /dev/null +++ b/llvm/test/DebugInfo/Generic/gvn.ll @@ -0,0 +1,114 @@ +; RUN: opt < %s -gvn -S | FileCheck %s +; +; Produced at -O2 from: +; int a, b; +; void f1(int *p1) { +; if (b) +; a = 1; +; if (a && *p1) +; f4(); +; } +; int f2(int); +; void f3(void) { +; a = f2(1); +; f1(&a); +; } +target datalayout = "e-m:o-i64:64-i128:128-n32:64-S128" +target triple = "arm64-apple-ios" + +@a = common global i32 0, align 4 +@b = common global i32 0, align 4 + +; Function Attrs: nounwind +define void @f3() #0 { +entry: + ; Verify that the call still has a debug location after GVN. + ; CHECK: %call = tail call i32 @f2(i32 1) #{{[0-9]}}, !dbg + %call = tail call i32 @f2(i32 1) #3, !dbg !36 + store i32 %call, i32* @a, align 4, !dbg !36, !tbaa !25 + tail call void @llvm.dbg.value(metadata i32* @a, i64 0, metadata !11, metadata !21) #3, !dbg !39 + %0 = load i32, i32* @b, align 4, !dbg !39, !tbaa !25 + %tobool.i = icmp eq i32 %0, 0, !dbg !39 + br i1 %tobool.i, label %if.end.i, label %land.lhs.true.i.thread, !dbg !40 + +land.lhs.true.i.thread: ; preds = %entry + store i32 1, i32* @a, align 4, !dbg !41, !tbaa !25 + br label %if.then.3.i, !dbg !42 + +if.end.i: ; preds = %entry + ; This instruction has no debug location -- in this + ; particular case it was removed by a bug in SimplifyCFG. + %.pr = load i32, i32* @a, align 4 + + ; GVN is supposed to replace the load of %.pr with a direct reference to %call. + ; CHECK: %tobool2.i = icmp eq i32 %call, 0, !dbg + %tobool2.i = icmp eq i32 %.pr, 0, !dbg !43 + br i1 %tobool2.i, label %f1.exit, label %if.then.3.i, !dbg !43 + +if.then.3.i: ; preds = %if.end.i, %land.lhs.true.i.thread + %call.i = tail call i32 bitcast (i32 (...)* @f4 to i32 ()*)() #3, !dbg !44 + br label %f1.exit, !dbg !44 + +f1.exit: ; preds = %if.end.i, %if.then.3.i + ret void, !dbg !45 +} + +declare i32 @f2(i32) +declare i32 @f4(...) + +; Function Attrs: nounwind readnone +declare void @llvm.dbg.value(metadata, i64, metadata, metadata) #2 + +attributes #0 = { nounwind } +attributes #2 = { nounwind readnone } +attributes #3 = { nounwind } + +!llvm.dbg.cu = !{!0} +!llvm.module.flags = !{!18, !19} +!llvm.ident = !{!20} + +!0 = distinct !DICompileUnit(language: DW_LANG_C99, file: !1, producer: "clang version 3.8.0 (trunk 245562) (llvm/trunk 245569)", isOptimized: true, runtimeVersion: 0, emissionKind: 1, enums: !2, subprograms: !3, globals: !15) +!1 = !DIFile(filename: "test.c", directory: "/") +!2 = !{} +!3 = !{!4, !12} +!4 = distinct !DISubprogram(name: "f1", scope: !1, file: !1, line: 2, type: !6, isLocal: false, isDefinition: true, scopeLine: 2, flags: DIFlagPrototyped, isOptimized: true, variables: !10) +!6 = !DISubroutineType(types: !7) +!7 = !{null, !8} +!8 = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: !9, size: 64, align: 64) +!9 = !DIBasicType(name: "int", size: 32, align: 32, encoding: DW_ATE_signed) +!10 = !{!11} +!11 = !DILocalVariable(name: "p1", arg: 1, scope: !4, file: !1, line: 2, type: !8) +!12 = distinct !DISubprogram(name: "f3", scope: !1, file: !1, line: 9, type: !13, isLocal: false, isDefinition: true, scopeLine: 9, flags: DIFlagPrototyped, isOptimized: true, function: void ()* @f3, variables: !2) +!13 = !DISubroutineType(types: !14) +!14 = !{null} +!15 = !{!16, !17} +!16 = !DIGlobalVariable(name: "a", scope: !0, file: !1, line: 1, type: !9, isLocal: false, isDefinition: true, variable: i32* @a) +!17 = !DIGlobalVariable(name: "b", scope: !0, file: !1, line: 1, type: !9, isLocal: false, isDefinition: true, variable: i32* @b) +!18 = !{i32 2, !"Dwarf Version", i32 2} +!19 = !{i32 2, !"Debug Info Version", i32 3} +!20 = !{!"clang version 3.8.0 (trunk 245562) (llvm/trunk 245569)"} +!21 = !DIExpression() +!22 = !DILocation(line: 2, scope: !4) +!23 = !DILocation(line: 3, scope: !24) +!24 = distinct !DILexicalBlock(scope: !4, file: !1, line: 3) +!25 = !{!26, !26, i64 0} +!26 = !{!"int", !27, i64 0} +!27 = !{!"omnipotent char", !28, i64 0} +!28 = !{!"Simple C/C++ TBAA"} +!29 = !DILocation(line: 3, scope: !4) +!30 = !DILocation(line: 4, scope: !24) +!31 = !DILocation(line: 5, scope: !32) +!32 = distinct !DILexicalBlock(scope: !4, file: !1, line: 5) +!33 = !DILocation(line: 5, scope: !4) +!34 = !DILocation(line: 6, scope: !32) +!35 = !DILocation(line: 7, scope: !4) +!36 = !DILocation(line: 5, scope: !32, inlinedAt: !37) +!37 = distinct !DILocation(line: 11, scope: !12) +!38 = !DILocation(line: 10, scope: !12) +!39 = !DILocation(line: 2, scope: !4, inlinedAt: !37) +!40 = !DILocation(line: 3, scope: !24, inlinedAt: !37) +!41 = !DILocation(line: 3, scope: !4, inlinedAt: !37) +!42 = !DILocation(line: 4, scope: !24, inlinedAt: !37) +!43 = !DILocation(line: 5, scope: !4, inlinedAt: !37) +!44 = !DILocation(line: 6, scope: !32, inlinedAt: !37) +!45 = !DILocation(line: 12, scope: !12) diff --git a/llvm/test/DebugInfo/Generic/incorrect-variable-debugloc.ll b/llvm/test/DebugInfo/Generic/incorrect-variable-debugloc.ll new file mode 100644 index 00000000000..b5787923d1c --- /dev/null +++ b/llvm/test/DebugInfo/Generic/incorrect-variable-debugloc.ll @@ -0,0 +1,391 @@ +; REQUIRES: object-emission + +; RUN: %llc_dwarf -O2 -filetype=obj < %s | llvm-dwarfdump -debug-dump=info - | FileCheck %s + +; This is a test case that's as reduced as I can get it, though I haven't fully +; understood the mechanisms by which this bug occurs, so perhaps there's further +; simplification to be had (it's certainly a bit non-obvious what's going on). I +; hesitate to hand-craft or otherwise simplify the IR compared to what Clang +; generates as this is a particular tickling of optimizations and debug location +; propagation I want a realistic example of. + +; Generated with clang-tot -cc1 -g -O2 -w -std=c++11 -fsanitize=address,use-after-return -fcxx-exceptions -fexceptions -x c++ incorrect-variable-debug-loc.cpp -emit-llvm + +; struct A { +; int m_fn1(); +; }; +; +; struct B { +; void __attribute__((always_inline)) m_fn2() { i = 0; } +; int i; +; }; +; +; struct C { +; void m_fn3(); +; int j; +; B b; +; }; +; +; int fn1() { +; C A; +; A.b.m_fn2(); +; A.m_fn3(); +; } +; void C::m_fn3() { +; A().m_fn1(); +; b.m_fn2(); +; } + +; CHECK: DW_TAG_structure_type +; CHECK-NEXT: DW_AT_name {{.*}} "C" +; CHECK: [[M_FN3_DECL:.*]]: DW_TAG_subprogram +; CHECK-NOT: {{DW_TAG|NULL}} +; CHECK: DW_AT_name {{.*}} "m_fn3" + +; CHECK: DW_AT_specification {{.*}} {[[M_FN3_DECL]]} +; CHECK-NOT: DW_TAG +; CHECK: DW_TAG_formal_parameter +; CHECK-NOT: DW_TAG +; CHECK: DW_AT_name {{.*}} "this" + +%struct.C = type { i32, %struct.B } +%struct.B = type { i32 } +%struct.A = type { i8 } + +@llvm.global_ctors = appending global [1 x { i32, void ()* }] [{ i32, void ()* } { i32 1, void ()* @asan.module_ctor }] +@__asan_option_detect_stack_use_after_return = external global i32 +@__asan_gen_ = private unnamed_addr constant [11 x i8] c"1 32 8 1 A\00", align 1 +@__asan_gen_1 = private unnamed_addr constant [13 x i8] c"1 32 1 3 tmp\00", align 1 + +; Function Attrs: noreturn sanitize_address +define i32 @_Z3fn1v() #0 { +entry: + %MyAlloca = alloca [64 x i8], align 32, !dbg !39 + %0 = ptrtoint [64 x i8]* %MyAlloca to i64, !dbg !39 + %1 = load i32, i32* @__asan_option_detect_stack_use_after_return, !dbg !39 + %2 = icmp ne i32 %1, 0, !dbg !39 + br i1 %2, label %3, label %5 + +; <label>:3 ; preds = %entry + %4 = call i64 @__asan_stack_malloc_0(i64 64, i64 %0), !dbg !39 + br label %5 + +; <label>:5 ; preds = %entry, %3 + %6 = phi i64 [ %0, %entry ], [ %4, %3 ], !dbg !39 + %7 = add i64 %6, 32, !dbg !39 + %8 = inttoptr i64 %7 to %struct.C*, !dbg !39 + %9 = inttoptr i64 %6 to i64*, !dbg !39 + store i64 1102416563, i64* %9, !dbg !39 + %10 = add i64 %6, 8, !dbg !39 + %11 = inttoptr i64 %10 to i64*, !dbg !39 + store i64 ptrtoint ([11 x i8]* @__asan_gen_ to i64), i64* %11, !dbg !39 + %12 = add i64 %6, 16, !dbg !39 + %13 = inttoptr i64 %12 to i64*, !dbg !39 + store i64 ptrtoint (i32 ()* @_Z3fn1v to i64), i64* %13, !dbg !39 + %14 = lshr i64 %6, 3, !dbg !39 + %15 = add i64 %14, 2147450880, !dbg !39 + %16 = add i64 %15, 0, !dbg !39 + %17 = inttoptr i64 %16 to i64*, !dbg !39 + store i64 -868083117767659023, i64* %17, !dbg !39 + %i.i = getelementptr inbounds %struct.C, %struct.C* %8, i64 0, i32 1, i32 0, !dbg !39 + %18 = ptrtoint i32* %i.i to i64, !dbg !39 + %19 = lshr i64 %18, 3, !dbg !39 + %20 = add i64 %19, 2147450880, !dbg !39 + %21 = inttoptr i64 %20 to i8*, !dbg !39 + %22 = load i8, i8* %21, !dbg !39 + %23 = icmp ne i8 %22, 0, !dbg !39 + br i1 %23, label %24, label %30, !dbg !39 + +; <label>:24 ; preds = %5 + %25 = and i64 %18, 7, !dbg !39 + %26 = add i64 %25, 3, !dbg !39 + %27 = trunc i64 %26 to i8, !dbg !39 + %28 = icmp sge i8 %27, %22, !dbg !39 + br i1 %28, label %29, label %30 + +; <label>:29 ; preds = %24 + call void @__asan_report_store4(i64 %18), !dbg !39 + call void asm sideeffect "", ""() + unreachable + +; <label>:30 ; preds = %24, %5 + store i32 0, i32* %i.i, align 4, !dbg !39, !tbaa !41 + tail call void @llvm.dbg.value(metadata %struct.C* %8, i64 0, metadata !27, metadata !DIExpression()), !dbg !46 + call void @_ZN1C5m_fn3Ev(%struct.C* %8), !dbg !47 + unreachable, !dbg !47 +} + +; Function Attrs: sanitize_address +define void @_ZN1C5m_fn3Ev(%struct.C* nocapture %this) #1 align 2 { +entry: + %MyAlloca = alloca [64 x i8], align 32, !dbg !48 + %0 = ptrtoint [64 x i8]* %MyAlloca to i64, !dbg !48 + %1 = load i32, i32* @__asan_option_detect_stack_use_after_return, !dbg !48 + %2 = icmp ne i32 %1, 0, !dbg !48 + br i1 %2, label %3, label %5 + +; <label>:3 ; preds = %entry + %4 = call i64 @__asan_stack_malloc_0(i64 64, i64 %0), !dbg !48 + br label %5 + +; <label>:5 ; preds = %entry, %3 + %6 = phi i64 [ %0, %entry ], [ %4, %3 ], !dbg !48 + %7 = add i64 %6, 32, !dbg !48 + %8 = inttoptr i64 %7 to %struct.A*, !dbg !48 + %9 = inttoptr i64 %6 to i64*, !dbg !48 + store i64 1102416563, i64* %9, !dbg !48 + %10 = add i64 %6, 8, !dbg !48 + %11 = inttoptr i64 %10 to i64*, !dbg !48 + store i64 ptrtoint ([13 x i8]* @__asan_gen_1 to i64), i64* %11, !dbg !48 + %12 = add i64 %6, 16, !dbg !48 + %13 = inttoptr i64 %12 to i64*, !dbg !48 + store i64 ptrtoint (void (%struct.C*)* @_ZN1C5m_fn3Ev to i64), i64* %13, !dbg !48 + %14 = lshr i64 %6, 3, !dbg !48 + %15 = add i64 %14, 2147450880, !dbg !48 + %16 = add i64 %15, 0, !dbg !48 + %17 = inttoptr i64 %16 to i64*, !dbg !48 + store i64 -868083113472691727, i64* %17, !dbg !48 + tail call void @llvm.dbg.value(metadata %struct.C* %this, i64 0, metadata !30, metadata !DIExpression()), !dbg !48 + %call = call i32 @_ZN1A5m_fn1Ev(%struct.A* %8), !dbg !49 + %i.i = getelementptr inbounds %struct.C, %struct.C* %this, i64 0, i32 1, i32 0, !dbg !50 + %18 = ptrtoint i32* %i.i to i64, !dbg !50 + %19 = lshr i64 %18, 3, !dbg !50 + %20 = add i64 %19, 2147450880, !dbg !50 + %21 = inttoptr i64 %20 to i8*, !dbg !50 + %22 = load i8, i8* %21, !dbg !50 + %23 = icmp ne i8 %22, 0, !dbg !50 + br i1 %23, label %24, label %30, !dbg !50 + +; <label>:24 ; preds = %5 + %25 = and i64 %18, 7, !dbg !50 + %26 = add i64 %25, 3, !dbg !50 + %27 = trunc i64 %26 to i8, !dbg !50 + %28 = icmp sge i8 %27, %22, !dbg !50 + br i1 %28, label %29, label %30 + +; <label>:29 ; preds = %24 + call void @__asan_report_store4(i64 %18), !dbg !50 + call void asm sideeffect "", ""() + unreachable + +; <label>:30 ; preds = %24, %5 + store i32 0, i32* %i.i, align 4, !dbg !50, !tbaa !41 + store i64 1172321806, i64* %9, !dbg !52 + %31 = icmp ne i64 %6, %0, !dbg !52 + br i1 %31, label %32, label %39, !dbg !52 + +; <label>:32 ; preds = %30 + %33 = add i64 %15, 0, !dbg !52 + %34 = inttoptr i64 %33 to i64*, !dbg !52 + store i64 -723401728380766731, i64* %34, !dbg !52 + %35 = add i64 %6, 56, !dbg !52 + %36 = inttoptr i64 %35 to i64*, !dbg !52 + %37 = load i64, i64* %36, !dbg !52 + %38 = inttoptr i64 %37 to i8*, !dbg !52 + store i8 0, i8* %38, !dbg !52 + br label %42, !dbg !52 + +; <label>:39 ; preds = %30 + %40 = add i64 %15, 0, !dbg !52 + %41 = inttoptr i64 %40 to i64*, !dbg !52 + store i64 0, i64* %41, !dbg !52 + br label %42, !dbg !52 + +; <label>:42 ; preds = %39, %32 + ret void, !dbg !52 +} + +declare i32 @_ZN1A5m_fn1Ev(%struct.A*) #2 + +; Function Attrs: nounwind readnone +declare void @llvm.dbg.value(metadata, i64, metadata, metadata) #3 + +define internal void @asan.module_ctor() { + tail call void @__asan_init_v3() + ret void +} + +declare void @__asan_init_v3() + +declare void @__asan_report_load1(i64) + +declare void @__asan_load1(i64) + +declare void @__asan_report_load2(i64) + +declare void @__asan_load2(i64) + +declare void @__asan_report_load4(i64) + +declare void @__asan_load4(i64) + +declare void @__asan_report_load8(i64) + +declare void @__asan_load8(i64) + +declare void @__asan_report_load16(i64) + +declare void @__asan_load16(i64) + +declare void @__asan_report_store1(i64) + +declare void @__asan_store1(i64) + +declare void @__asan_report_store2(i64) + +declare void @__asan_store2(i64) + +declare void @__asan_report_store4(i64) + +declare void @__asan_store4(i64) + +declare void @__asan_report_store8(i64) + +declare void @__asan_store8(i64) + +declare void @__asan_report_store16(i64) + +declare void @__asan_store16(i64) + +declare void @__asan_report_load_n(i64, i64) + +declare void @__asan_report_store_n(i64, i64) + +declare void @__asan_loadN(i64, i64) + +declare void @__asan_storeN(i64, i64) + +declare i8* @__asan_memmove(i8*, i8*, i64) + +declare i8* @__asan_memcpy(i8*, i8*, i64) + +declare i8* @__asan_memset(i8*, i32, i64) + +declare void @__asan_handle_no_return() + +declare void @__sanitizer_cov() + +declare void @__sanitizer_ptr_cmp(i64, i64) + +declare void @__sanitizer_ptr_sub(i64, i64) + +declare i64 @__asan_stack_malloc_0(i64, i64) + +declare void @__asan_stack_free_0(i64, i64, i64) + +declare i64 @__asan_stack_malloc_1(i64, i64) + +declare void @__asan_stack_free_1(i64, i64, i64) + +declare i64 @__asan_stack_malloc_2(i64, i64) + +declare void @__asan_stack_free_2(i64, i64, i64) + +declare i64 @__asan_stack_malloc_3(i64, i64) + +declare void @__asan_stack_free_3(i64, i64, i64) + +declare i64 @__asan_stack_malloc_4(i64, i64) + +declare void @__asan_stack_free_4(i64, i64, i64) + +declare i64 @__asan_stack_malloc_5(i64, i64) + +declare void @__asan_stack_free_5(i64, i64, i64) + +declare i64 @__asan_stack_malloc_6(i64, i64) + +declare void @__asan_stack_free_6(i64, i64, i64) + +declare i64 @__asan_stack_malloc_7(i64, i64) + +declare void @__asan_stack_free_7(i64, i64, i64) + +declare i64 @__asan_stack_malloc_8(i64, i64) + +declare void @__asan_stack_free_8(i64, i64, i64) + +declare i64 @__asan_stack_malloc_9(i64, i64) + +declare void @__asan_stack_free_9(i64, i64, i64) + +declare i64 @__asan_stack_malloc_10(i64, i64) + +declare void @__asan_stack_free_10(i64, i64, i64) + +declare void @__asan_poison_stack_memory(i64, i64) + +declare void @__asan_unpoison_stack_memory(i64, i64) + +declare void @__asan_before_dynamic_init(i64) + +declare void @__asan_after_dynamic_init() + +declare void @__asan_register_globals(i64, i64) + +declare void @__asan_unregister_globals(i64, i64) + +declare void @__sanitizer_cov_module_init(i64) + +attributes #0 = { noreturn sanitize_address "less-precise-fpmad"="false" "no-frame-pointer-elim"="false" "no-infs-fp-math"="false" "no-nans-fp-math"="false" "no-realign-stack" "stack-protector-buffer-size"="8" "unsafe-fp-math"="false" "use-soft-float"="false" } +attributes #1 = { sanitize_address "less-precise-fpmad"="false" "no-frame-pointer-elim"="false" "no-infs-fp-math"="false" "no-nans-fp-math"="false" "no-realign-stack" "stack-protector-buffer-size"="8" "unsafe-fp-math"="false" "use-soft-float"="false" } +attributes #2 = { "less-precise-fpmad"="false" "no-frame-pointer-elim"="false" "no-infs-fp-math"="false" "no-nans-fp-math"="false" "no-realign-stack" "stack-protector-buffer-size"="8" "unsafe-fp-math"="false" "use-soft-float"="false" } +attributes #3 = { nounwind readnone } + +!llvm.dbg.cu = !{!0} +!llvm.module.flags = !{!36, !37} +!llvm.ident = !{!38} + +!0 = distinct !DICompileUnit(language: DW_LANG_C_plus_plus, producer: "clang version 3.5.0 ", isOptimized: true, emissionKind: 1, file: !1, enums: !2, retainedTypes: !3, subprograms: !21, globals: !2, imports: !2) +!1 = !DIFile(filename: "<stdin>", directory: "/tmp/dbginfo") +!2 = !{} +!3 = !{!4, !14} +!4 = !DICompositeType(tag: DW_TAG_structure_type, name: "C", line: 10, size: 64, align: 32, file: !5, elements: !6, identifier: "_ZTS1C") +!5 = !DIFile(filename: "incorrect-variable-debug-loc.cpp", directory: "/tmp/dbginfo") +!6 = !{!7, !9, !10} +!7 = !DIDerivedType(tag: DW_TAG_member, name: "j", line: 12, size: 32, align: 32, file: !5, scope: !"_ZTS1C", baseType: !8) +!8 = !DIBasicType(tag: DW_TAG_base_type, name: "int", size: 32, align: 32, encoding: DW_ATE_signed) +!9 = !DIDerivedType(tag: DW_TAG_member, name: "b", line: 13, size: 32, align: 32, offset: 32, file: !5, scope: !"_ZTS1C", baseType: !"_ZTS1B") +!10 = !DISubprogram(name: "m_fn3", linkageName: "_ZN1C5m_fn3Ev", line: 11, isLocal: false, isDefinition: false, virtualIndex: 6, flags: DIFlagPrototyped, isOptimized: true, scopeLine: 11, file: !5, scope: !"_ZTS1C", type: !11) +!11 = !DISubroutineType(types: !12) +!12 = !{null, !13} +!13 = !DIDerivedType(tag: DW_TAG_pointer_type, size: 64, align: 64, flags: DIFlagArtificial | DIFlagObjectPointer, baseType: !"_ZTS1C") +!14 = !DICompositeType(tag: DW_TAG_structure_type, name: "B", line: 5, size: 32, align: 32, file: !5, elements: !15, identifier: "_ZTS1B") +!15 = !{!16, !17} +!16 = !DIDerivedType(tag: DW_TAG_member, name: "i", line: 7, size: 32, align: 32, file: !5, scope: !"_ZTS1B", baseType: !8) +!17 = !DISubprogram(name: "m_fn2", linkageName: "_ZN1B5m_fn2Ev", line: 6, isLocal: false, isDefinition: false, virtualIndex: 6, flags: DIFlagPrototyped, isOptimized: true, scopeLine: 6, file: !5, scope: !"_ZTS1B", type: !18) +!18 = !DISubroutineType(types: !19) +!19 = !{null, !20} +!20 = !DIDerivedType(tag: DW_TAG_pointer_type, size: 64, align: 64, flags: DIFlagArtificial | DIFlagObjectPointer, baseType: !"_ZTS1B") +!21 = !{!22, !28, !32} +!22 = distinct !DISubprogram(name: "fn1", linkageName: "_Z3fn1v", line: 16, isLocal: false, isDefinition: true, virtualIndex: 6, flags: DIFlagPrototyped, isOptimized: true, scopeLine: 16, file: !5, scope: !23, type: !24, function: i32 ()* @_Z3fn1v, variables: !26) +!23 = !DIFile(filename: "incorrect-variable-debug-loc.cpp", directory: "/tmp/dbginfo") +!24 = !DISubroutineType(types: !25) +!25 = !{!8} +!26 = !{!27} +!27 = !DILocalVariable(name: "A", line: 17, scope: !22, file: !23, type: !"_ZTS1C") +!28 = distinct !DISubprogram(name: "m_fn3", linkageName: "_ZN1C5m_fn3Ev", line: 21, isLocal: false, isDefinition: true, virtualIndex: 6, flags: DIFlagPrototyped, isOptimized: true, scopeLine: 21, file: !5, scope: !"_ZTS1C", type: !11, function: void (%struct.C*)* @_ZN1C5m_fn3Ev, declaration: !10, variables: !29) +!29 = !{!30} +!30 = !DILocalVariable(name: "this", arg: 1, flags: DIFlagArtificial | DIFlagObjectPointer, scope: !28, type: !31) +!31 = !DIDerivedType(tag: DW_TAG_pointer_type, size: 64, align: 64, baseType: !"_ZTS1C") +!32 = distinct !DISubprogram(name: "m_fn2", linkageName: "_ZN1B5m_fn2Ev", line: 6, isLocal: false, isDefinition: true, virtualIndex: 6, flags: DIFlagPrototyped, isOptimized: true, scopeLine: 6, file: !5, scope: !"_ZTS1B", type: !18, declaration: !17, variables: !33) +!33 = !{!34} +!34 = !DILocalVariable(name: "this", arg: 1, flags: DIFlagArtificial | DIFlagObjectPointer, scope: !32, type: !35) +!35 = !DIDerivedType(tag: DW_TAG_pointer_type, size: 64, align: 64, baseType: !"_ZTS1B") +!36 = !{i32 2, !"Dwarf Version", i32 4} +!37 = !{i32 2, !"Debug Info Version", i32 3} +!38 = !{!"clang version 3.5.0 "} +!39 = !DILocation(line: 6, scope: !32, inlinedAt: !40) +!40 = !DILocation(line: 18, scope: !22) +!41 = !{!42, !43, i64 0} +!42 = !{!"_ZTS1B", !43, i64 0} +!43 = !{!"int", !44, i64 0} +!44 = !{!"omnipotent char", !45, i64 0} +!45 = !{!"Simple C/C++ TBAA"} +!46 = !DILocation(line: 17, scope: !22) +!47 = !DILocation(line: 19, scope: !22) +!48 = !DILocation(line: 0, scope: !28) +!49 = !DILocation(line: 22, scope: !28) +!50 = !DILocation(line: 6, scope: !32, inlinedAt: !51) +!51 = !DILocation(line: 23, scope: !28) +!52 = !DILocation(line: 24, scope: !28) diff --git a/llvm/test/DebugInfo/Generic/incorrect-variable-debugloc1.ll b/llvm/test/DebugInfo/Generic/incorrect-variable-debugloc1.ll new file mode 100644 index 00000000000..7d40e404ce1 --- /dev/null +++ b/llvm/test/DebugInfo/Generic/incorrect-variable-debugloc1.ll @@ -0,0 +1,77 @@ +; REQUIRES: object-emission +; This test is failing for powerpc64, because a location list for the +; variable 'c' is not generated at all. Temporary marking this test as XFAIL +; for powerpc, until PR21881 is fixed. +; XFAIL: powerpc64 + +; RUN: %llc_dwarf -O2 -dwarf-version 2 -filetype=obj < %s | llvm-dwarfdump - | FileCheck %s --check-prefix=DWARF23 +; RUN: %llc_dwarf -O2 -dwarf-version 3 -filetype=obj < %s | llvm-dwarfdump - | FileCheck %s --check-prefix=DWARF23 +; RUN: %llc_dwarf -O2 -dwarf-version 4 -filetype=obj < %s | llvm-dwarfdump - | FileCheck %s --check-prefix=DWARF4 + +; This is a test for PR21176. +; DW_OP_const <const> doesn't describe a constant value, but a value at a constant address. +; The proper way to describe a constant value is DW_OP_constu <const>, DW_OP_stack_value. + +; Generated with clang -S -emit-llvm -g -O2 test.cpp + +; extern int func(); +; +; int main() +; { +; volatile int c = 13; +; c = func(); +; return c; +; } + +; DWARF23: Location description: 10 0d {{$}} +; DWARF4: Location description: 10 0d 9f + +; Function Attrs: uwtable +define i32 @main() #0 { +entry: + %c = alloca i32, align 4 + tail call void @llvm.dbg.value(metadata i32 13, i64 0, metadata !10, metadata !16), !dbg !17 + store volatile i32 13, i32* %c, align 4, !dbg !18 + %call = tail call i32 @_Z4funcv(), !dbg !19 + tail call void @llvm.dbg.value(metadata i32 %call, i64 0, metadata !10, metadata !16), !dbg !17 + store volatile i32 %call, i32* %c, align 4, !dbg !19 + tail call void @llvm.dbg.value(metadata i32* %c, i64 0, metadata !10, metadata !16), !dbg !17 + %c.0.c.0. = load volatile i32, i32* %c, align 4, !dbg !20 + ret i32 %c.0.c.0., !dbg !20 +} + +declare i32 @_Z4funcv() #1 + +; Function Attrs: nounwind readnone +declare void @llvm.dbg.value(metadata, i64, metadata, metadata) #2 + +attributes #0 = { uwtable "less-precise-fpmad"="false" "no-frame-pointer-elim"="false" "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"="false" "no-infs-fp-math"="false" "no-nans-fp-math"="false" "stack-protector-buffer-size"="8" "unsafe-fp-math"="false" "use-soft-float"="false" } +attributes #2 = { nounwind readnone } + +!llvm.dbg.cu = !{!0} +!llvm.module.flags = !{!12, !13} +!llvm.ident = !{!14} + +!0 = distinct !DICompileUnit(language: DW_LANG_C_plus_plus, producer: "clang version 3.6.0 (trunk 223522)", isOptimized: true, emissionKind: 1, file: !1, enums: !2, retainedTypes: !2, subprograms: !3, globals: !2, imports: !2) +!1 = !DIFile(filename: "test.cpp", directory: "/home/kromanova/ngh/ToT_latest/llvm/test/DebugInfo") +!2 = !{} +!3 = !{!4} +!4 = distinct !DISubprogram(name: "main", line: 3, isLocal: false, isDefinition: true, flags: DIFlagPrototyped, isOptimized: true, scopeLine: 4, file: !1, scope: !5, type: !6, function: i32 ()* @main, variables: !9) +!5 = !DIFile(filename: "test.cpp", directory: "/home/kromanova/ngh/ToT_latest/llvm/test/DebugInfo") +!6 = !DISubroutineType(types: !7) +!7 = !{!8} +!8 = !DIBasicType(tag: DW_TAG_base_type, name: "int", size: 32, align: 32, encoding: DW_ATE_signed) +!9 = !{!10} +!10 = !DILocalVariable(name: "c", line: 5, scope: !4, file: !5, type: !11) +!11 = !DIDerivedType(tag: DW_TAG_volatile_type, baseType: !8) +!12 = !{i32 2, !"Dwarf Version", i32 2} +!13 = !{i32 2, !"Debug Info Version", i32 3} +!14 = !{!"clang version 3.6.0 (trunk 223522)"} +!15 = !{i32 13} +!16 = !DIExpression() +!17 = !DILocation(line: 5, column: 16, scope: !4) +!18 = !DILocation(line: 5, column: 3, scope: !4) +!19 = !DILocation(line: 6, column: 7, scope: !4) +!20 = !DILocation(line: 7, column: 3, scope: !4) + diff --git a/llvm/test/DebugInfo/Generic/inheritance.ll b/llvm/test/DebugInfo/Generic/inheritance.ll new file mode 100644 index 00000000000..802c4f195d4 --- /dev/null +++ b/llvm/test/DebugInfo/Generic/inheritance.ll @@ -0,0 +1,154 @@ +; RUN: llc %s -o /dev/null +; PR 2613. + +%struct.__class_type_info_pseudo = type { %struct.__type_info_pseudo } +%struct.__type_info_pseudo = type { i8*, i8* } +%struct.test1 = type { i32 (...)** } + +@_ZTV5test1 = weak_odr constant [4 x i32 (...)*] [i32 (...)* null, i32 (...)* bitcast (%struct.__class_type_info_pseudo* @_ZTI5test1 to i32 (...)*), i32 (...)* bitcast (void (%struct.test1*)* @_ZN5test1D1Ev to i32 (...)*), i32 (...)* bitcast (void (%struct.test1*)* @_ZN5test1D0Ev to i32 (...)*)], align 32 ; <[4 x i32 (...)*]*> [#uses=1] +@_ZTI5test1 = weak_odr constant %struct.__class_type_info_pseudo { %struct.__type_info_pseudo { i8* inttoptr (i64 add (i64 ptrtoint ([0 x i32 (...)*]* @_ZTVN10__cxxabiv117__class_type_infoE to i64), i64 16) to i8*), i8* getelementptr inbounds ([7 x i8], [7 x i8]* @_ZTS5test1, i64 0, i64 0) } }, align 16 ; <%struct.__class_type_info_pseudo*> [#uses=1] +@_ZTVN10__cxxabiv117__class_type_infoE = external constant [0 x i32 (...)*] ; <[0 x i32 (...)*]*> [#uses=1] +@_ZTS5test1 = weak_odr constant [7 x i8] c"5test1\00" ; <[7 x i8]*> [#uses=2] + +define i32 @main() nounwind ssp { +entry: + %retval = alloca i32 ; <i32*> [#uses=2] + %0 = alloca i32 ; <i32*> [#uses=2] + %tst = alloca %struct.test1 ; <%struct.test1*> [#uses=1] + %"alloca point" = bitcast i32 0 to i32 ; <i32> [#uses=0] + call void @llvm.dbg.declare(metadata %struct.test1* %tst, metadata !0, metadata !DIExpression()), !dbg !21 + call void @_ZN5test1C1Ev(%struct.test1* %tst) nounwind, !dbg !22 + store i32 0, i32* %0, align 4, !dbg !23 + %1 = load i32, i32* %0, align 4, !dbg !23 ; <i32> [#uses=1] + store i32 %1, i32* %retval, align 4, !dbg !23 + br label %return, !dbg !23 + +return: ; preds = %entry + %retval1 = load i32, i32* %retval, !dbg !23 ; <i32> [#uses=1] + ret i32 %retval1, !dbg !23 +} + +define linkonce_odr void @_ZN5test1C1Ev(%struct.test1* %this) nounwind ssp align 2 { +entry: + %this_addr = alloca %struct.test1* ; <%struct.test1**> [#uses=2] + %"alloca point" = bitcast i32 0 to i32 ; <i32> [#uses=0] + call void @llvm.dbg.declare(metadata %struct.test1** %this_addr, metadata !24, metadata !DIExpression()), !dbg !28 + store %struct.test1* %this, %struct.test1** %this_addr + %0 = load %struct.test1*, %struct.test1** %this_addr, align 8, !dbg !28 ; <%struct.test1*> [#uses=1] + %1 = getelementptr inbounds %struct.test1, %struct.test1* %0, i32 0, i32 0, !dbg !28 ; <i32 (...)***> [#uses=1] + store i32 (...)** getelementptr inbounds ([4 x i32 (...)*], [4 x i32 (...)*]* @_ZTV5test1, i64 0, i64 2), i32 (...)*** %1, align 8, !dbg !28 + br label %return, !dbg !28 + +return: ; preds = %entry + ret void, !dbg !29 +} + +declare void @llvm.dbg.declare(metadata, metadata, metadata) nounwind readnone + +define linkonce_odr void @_ZN5test1D1Ev(%struct.test1* %this) nounwind ssp align 2 { +entry: + %this_addr = alloca %struct.test1* ; <%struct.test1**> [#uses=3] + %"alloca point" = bitcast i32 0 to i32 ; <i32> [#uses=0] + call void @llvm.dbg.declare(metadata %struct.test1** %this_addr, metadata !32, metadata !DIExpression()), !dbg !34 + store %struct.test1* %this, %struct.test1** %this_addr + %0 = load %struct.test1*, %struct.test1** %this_addr, align 8, !dbg !35 ; <%struct.test1*> [#uses=1] + %1 = getelementptr inbounds %struct.test1, %struct.test1* %0, i32 0, i32 0, !dbg !35 ; <i32 (...)***> [#uses=1] + store i32 (...)** getelementptr inbounds ([4 x i32 (...)*], [4 x i32 (...)*]* @_ZTV5test1, i64 0, i64 2), i32 (...)*** %1, align 8, !dbg !35 + br label %bb, !dbg !37 + +bb: ; preds = %entry + %2 = trunc i32 0 to i8, !dbg !37 ; <i8> [#uses=1] + %toBool = icmp ne i8 %2, 0, !dbg !37 ; <i1> [#uses=1] + br i1 %toBool, label %bb1, label %bb2, !dbg !37 + +bb1: ; preds = %bb + %3 = load %struct.test1*, %struct.test1** %this_addr, align 8, !dbg !37 ; <%struct.test1*> [#uses=1] + %4 = bitcast %struct.test1* %3 to i8*, !dbg !37 ; <i8*> [#uses=1] + call void @_ZdlPv(i8* %4) nounwind, !dbg !37 + br label %bb2, !dbg !37 + +bb2: ; preds = %bb1, %bb + br label %return, !dbg !37 + +return: ; preds = %bb2 + ret void, !dbg !37 +} + +define linkonce_odr void @_ZN5test1D0Ev(%struct.test1* %this) nounwind ssp align 2 { +entry: + %this_addr = alloca %struct.test1* ; <%struct.test1**> [#uses=3] + %"alloca point" = bitcast i32 0 to i32 ; <i32> [#uses=0] + call void @llvm.dbg.declare(metadata %struct.test1** %this_addr, metadata !38, metadata !DIExpression()), !dbg !40 + store %struct.test1* %this, %struct.test1** %this_addr + %0 = load %struct.test1*, %struct.test1** %this_addr, align 8, !dbg !41 ; <%struct.test1*> [#uses=1] + %1 = getelementptr inbounds %struct.test1, %struct.test1* %0, i32 0, i32 0, !dbg !41 ; <i32 (...)***> [#uses=1] + store i32 (...)** getelementptr inbounds ([4 x i32 (...)*], [4 x i32 (...)*]* @_ZTV5test1, i64 0, i64 2), i32 (...)*** %1, align 8, !dbg !41 + br label %bb, !dbg !43 + +bb: ; preds = %entry + %2 = trunc i32 1 to i8, !dbg !43 ; <i8> [#uses=1] + %toBool = icmp ne i8 %2, 0, !dbg !43 ; <i1> [#uses=1] + br i1 %toBool, label %bb1, label %bb2, !dbg !43 + +bb1: ; preds = %bb + %3 = load %struct.test1*, %struct.test1** %this_addr, align 8, !dbg !43 ; <%struct.test1*> [#uses=1] + %4 = bitcast %struct.test1* %3 to i8*, !dbg !43 ; <i8*> [#uses=1] + call void @_ZdlPv(i8* %4) nounwind, !dbg !43 + br label %bb2, !dbg !43 + +bb2: ; preds = %bb1, %bb + br label %return, !dbg !43 + +return: ; preds = %bb2 + ret void, !dbg !43 +} + +declare void @_ZdlPv(i8*) nounwind + +!0 = !DILocalVariable(name: "tst", line: 13, scope: !1, file: !4, type: !8) +!1 = distinct !DILexicalBlock(line: 0, column: 0, file: !44, scope: !2) +!2 = distinct !DILexicalBlock(line: 0, column: 0, file: !44, scope: !3) +!3 = distinct !DISubprogram(name: "main", linkageName: "main", line: 11, isLocal: false, isDefinition: true, virtualIndex: 6, isOptimized: false, scope: !4, type: !5) +!4 = distinct !DICompileUnit(language: DW_LANG_C_plus_plus, producer: "4.2.1 (Based on Apple Inc. build 5658) (LLVM build)", isOptimized: true, emissionKind: 0, file: !44, enums: !45, retainedTypes: !45) +!5 = !DISubroutineType(types: !6) +!6 = !{!7} +!7 = !DIBasicType(tag: DW_TAG_base_type, name: "int", size: 32, align: 32, encoding: DW_ATE_signed) +!8 = !DICompositeType(tag: DW_TAG_structure_type, name: "test1", line: 1, size: 64, align: 64, file: !44, scope: !4, elements: !9, vtableHolder: !8) +!9 = !{!10, !14, !18} +!10 = !DIDerivedType(tag: DW_TAG_member, name: "_vptr$test1", line: 1, size: 64, align: 64, file: !44, scope: !8, baseType: !11) +!11 = !DIDerivedType(tag: DW_TAG_pointer_type, size: 64, align: 64, file: !4, baseType: !12) +!12 = !DIDerivedType(tag: DW_TAG_pointer_type, name: "__vtbl_ptr_type", scope: !4, baseType: !5) +!13 = distinct !DICompileUnit(language: DW_LANG_C_plus_plus, producer: "4.2.1 (Based on Apple Inc. build 5658) (LLVM build)", isOptimized: false, emissionKind: 0, file: !46, enums: !45, retainedTypes: !45) +!14 = !DISubprogram(name: "test1", line: 1, isLocal: false, isDefinition: false, virtualIndex: 6, flags: DIFlagPrivate, isOptimized: false, scope: !8, type: !15) +!15 = !DISubroutineType(types: !16) +!16 = !{null, !17} +!17 = !DIDerivedType(tag: DW_TAG_pointer_type, size: 64, align: 64, flags: DIFlagArtificial, file: !4, baseType: !8) +!18 = !DISubprogram(name: "~test1", line: 4, isLocal: false, isDefinition: false, virtuality: DW_VIRTUALITY_virtual, virtualIndex: 6, isOptimized: false, scope: !8, type: !19, containingType: !8) +!19 = !DISubroutineType(types: !20) +!20 = !{null, !17, !7} +!21 = !DILocation(line: 11, scope: !1) +!22 = !DILocation(line: 13, scope: !1) +!23 = !DILocation(line: 14, scope: !1) +!24 = !DILocalVariable(name: "this", line: 13, arg: 1, scope: !25, file: !4, type: !26) +!25 = distinct !DISubprogram(name: "test1", linkageName: "_ZN5test1C1Ev", line: 1, isLocal: false, isDefinition: true, virtualIndex: 6, isOptimized: false, scope: !4, type: !15) +!26 = !DIDerivedType(tag: DW_TAG_const_type, size: 64, align: 64, flags: DIFlagArtificial, file: !4, baseType: !27) +!27 = !DIDerivedType(tag: DW_TAG_pointer_type, size: 64, align: 64, file: !4, baseType: !8) +!28 = !DILocation(line: 1, scope: !25) +!29 = !DILocation(line: 1, scope: !30) +!30 = distinct !DILexicalBlock(line: 0, column: 0, file: !44, scope: !31) +!31 = distinct !DILexicalBlock(line: 0, column: 0, file: !44, scope: !25) +!32 = !DILocalVariable(name: "this", line: 4, arg: 1, scope: !33, file: !4, type: !26) +!33 = distinct !DISubprogram(name: "~test1", linkageName: "_ZN5test1D1Ev", line: 4, isLocal: false, isDefinition: true, virtuality: DW_VIRTUALITY_virtual, virtualIndex: 6, isOptimized: false, scope: !8, type: !15, containingType: !8) +!34 = !DILocation(line: 4, scope: !33) +!35 = !DILocation(line: 5, scope: !36) +!36 = distinct !DILexicalBlock(line: 0, column: 0, file: !44, scope: !33) +!37 = !DILocation(line: 6, scope: !36) +!38 = !DILocalVariable(name: "this", line: 4, arg: 1, scope: !39, file: !4, type: !26) +!39 = distinct !DISubprogram(name: "~test1", linkageName: "_ZN5test1D0Ev", line: 4, isLocal: false, isDefinition: true, virtuality: DW_VIRTUALITY_virtual, virtualIndex: 6, isOptimized: false, scope: !8, type: !15, containingType: !8) +!40 = !DILocation(line: 4, scope: !39) +!41 = !DILocation(line: 5, scope: !42) +!42 = distinct !DILexicalBlock(line: 0, column: 0, file: !44, scope: !39) +!43 = !DILocation(line: 6, scope: !42) +!44 = !DIFile(filename: "inheritance.cpp", directory: "/tmp/") +!45 = !{i32 0} +!46 = !DIFile(filename: "<built-in>", directory: "/tmp/") diff --git a/llvm/test/DebugInfo/Generic/inline-debug-info-multiret.ll b/llvm/test/DebugInfo/Generic/inline-debug-info-multiret.ll new file mode 100644 index 00000000000..e1ed553022c --- /dev/null +++ b/llvm/test/DebugInfo/Generic/inline-debug-info-multiret.ll @@ -0,0 +1,156 @@ +; RUN: opt -inline -S < %s | FileCheck %s +; +; A hand-edited version of inline-debug-info.ll to test inlining of a +; function with multiple returns. +; +; Make sure the branch instructions created during inlining has a debug location, +; so the range of the inlined function is correct. +; CHECK: br label %_Z4testi.exit, !dbg ![[MD:[0-9]+]] +; CHECK: br label %_Z4testi.exit, !dbg ![[MD]] +; CHECK: br label %invoke.cont, !dbg ![[MD]] +; The branch instruction has the source location of line 9 and its inlined location +; has the source location of line 14. +; CHECK: ![[INL:[0-9]+]] = distinct !DILocation(line: 14, scope: {{.*}}) +; CHECK: ![[MD]] = !DILocation(line: 9, scope: {{.*}}, inlinedAt: ![[INL]]) + +; ModuleID = 'test.cpp' +target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-n8:16:32:64-S128" +target triple = "x86_64-apple-darwin12.0.0" + +@_ZTIi = external constant i8* +@global_var = external global i32 + +; copy of above function with multiple returns +define i32 @_Z4testi(i32 %k) { +entry: + %retval = alloca i32, align 4 + %k.addr = alloca i32, align 4 + %k2 = alloca i32, align 4 + store i32 %k, i32* %k.addr, align 4 + call void @llvm.dbg.declare(metadata i32* %k.addr, metadata !13, metadata !DIExpression()), !dbg !14 + call void @llvm.dbg.declare(metadata i32* %k2, metadata !15, metadata !DIExpression()), !dbg !16 + %0 = load i32, i32* %k.addr, align 4, !dbg !16 + %call = call i32 @_Z8test_exti(i32 %0), !dbg !16 + store i32 %call, i32* %k2, align 4, !dbg !16 + %1 = load i32, i32* %k2, align 4, !dbg !17 + %cmp = icmp sgt i32 %1, 100, !dbg !17 + br i1 %cmp, label %if.then, label %if.end, !dbg !17 + +if.then: ; preds = %entry + %2 = load i32, i32* %k2, align 4, !dbg !18 + store i32 %2, i32* %retval, !dbg !18 + br label %return, !dbg !18 + +if.end: ; preds = %entry + store i32 0, i32* %retval, !dbg !19 + %3 = load i32, i32* %retval, !dbg !20 ; hand-edited + ret i32 %3, !dbg !20 ; hand-edited + +return: ; preds = %if.end, %if.then + %4 = load i32, i32* %retval, !dbg !20 + ret i32 %4, !dbg !20 +} + + +; Function Attrs: nounwind readnone +declare void @llvm.dbg.declare(metadata, metadata, metadata) #1 + +declare i32 @_Z8test_exti(i32) + +define i32 @_Z5test2v() personality i8* bitcast (i32 (...)* @__gxx_personality_v0 to i8*) { +entry: + %exn.slot = alloca i8* + %ehselector.slot = alloca i32 + %e = alloca i32, align 4 + %0 = load i32, i32* @global_var, align 4, !dbg !21 + %call = invoke i32 @_Z4testi(i32 %0) + to label %invoke.cont unwind label %lpad, !dbg !21 + +invoke.cont: ; preds = %entry + br label %try.cont, !dbg !23 + +lpad: ; preds = %entry + %1 = landingpad { i8*, i32 } + catch i8* bitcast (i8** @_ZTIi to i8*), !dbg !21 + %2 = extractvalue { i8*, i32 } %1, 0, !dbg !21 + store i8* %2, i8** %exn.slot, !dbg !21 + %3 = extractvalue { i8*, i32 } %1, 1, !dbg !21 + store i32 %3, i32* %ehselector.slot, !dbg !21 + br label %catch.dispatch, !dbg !21 + +catch.dispatch: ; preds = %lpad + %sel = load i32, i32* %ehselector.slot, !dbg !23 + %4 = call i32 @llvm.eh.typeid.for(i8* bitcast (i8** @_ZTIi to i8*)) #2, !dbg !23 + %matches = icmp eq i32 %sel, %4, !dbg !23 + br i1 %matches, label %catch, label %eh.resume, !dbg !23 + +catch: ; preds = %catch.dispatch + call void @llvm.dbg.declare(metadata i32* %e, metadata !24, metadata !DIExpression()), !dbg !25 + %exn = load i8*, i8** %exn.slot, !dbg !23 + %5 = call i8* @__cxa_begin_catch(i8* %exn) #2, !dbg !23 + %6 = bitcast i8* %5 to i32*, !dbg !23 + %7 = load i32, i32* %6, align 4, !dbg !23 + store i32 %7, i32* %e, align 4, !dbg !23 + store i32 0, i32* @global_var, align 4, !dbg !26 + call void @__cxa_end_catch() #2, !dbg !28 + br label %try.cont, !dbg !28 + +try.cont: ; preds = %catch, %invoke.cont + store i32 1, i32* @global_var, align 4, !dbg !29 + ret i32 0, !dbg !30 + +eh.resume: ; preds = %catch.dispatch + %exn1 = load i8*, i8** %exn.slot, !dbg !23 + %sel2 = load i32, i32* %ehselector.slot, !dbg !23 + %lpad.val = insertvalue { i8*, i32 } undef, i8* %exn1, 0, !dbg !23 + %lpad.val3 = insertvalue { i8*, i32 } %lpad.val, i32 %sel2, 1, !dbg !23 + resume { i8*, i32 } %lpad.val3, !dbg !23 +} + +declare i32 @__gxx_personality_v0(...) + +; Function Attrs: nounwind readnone +declare i32 @llvm.eh.typeid.for(i8*) #1 + +declare i8* @__cxa_begin_catch(i8*) + +declare void @__cxa_end_catch() + +attributes #1 = { nounwind readnone } +attributes #2 = { nounwind } + +!llvm.dbg.cu = !{!0} +!llvm.module.flags = !{!31} + +!0 = distinct !DICompileUnit(language: DW_LANG_C_plus_plus, producer: "clang version 3.3 ", isOptimized: false, emissionKind: 0, file: !1, enums: !2, retainedTypes: !2, subprograms: !3, globals: !2, imports: !2) +!1 = !DIFile(filename: "<unknown>", directory: "") +!2 = !{} +!3 = !{!4, !10} +!4 = distinct !DISubprogram(name: "test", linkageName: "_Z4testi", line: 4, isLocal: false, isDefinition: true, virtualIndex: 6, flags: DIFlagPrototyped, isOptimized: false, scopeLine: 4, file: !5, scope: !6, type: !7, function: i32 (i32)* @_Z4testi, variables: !2) +!5 = !DIFile(filename: "test.cpp", directory: "") +!6 = !DIFile(filename: "test.cpp", directory: "") +!7 = !DISubroutineType(types: !8) +!8 = !{!9, !9} +!9 = !DIBasicType(tag: DW_TAG_base_type, name: "int", size: 32, align: 32, encoding: DW_ATE_signed) +!10 = distinct !DISubprogram(name: "test2", linkageName: "_Z5test2v", line: 11, isLocal: false, isDefinition: true, virtualIndex: 6, flags: DIFlagPrototyped, isOptimized: false, scopeLine: 11, file: !5, scope: !6, type: !11, function: i32 ()* @_Z5test2v, variables: !2) +!11 = !DISubroutineType(types: !12) +!12 = !{!9} +!13 = !DILocalVariable(name: "k", line: 4, arg: 1, scope: !4, file: !6, type: !9) +!14 = !DILocation(line: 4, scope: !4) +!15 = !DILocalVariable(name: "k2", line: 5, scope: !4, file: !6, type: !9) +!16 = !DILocation(line: 5, scope: !4) +!17 = !DILocation(line: 6, scope: !4) +!18 = !DILocation(line: 7, scope: !4) +!19 = !DILocation(line: 8, scope: !4) +!20 = !DILocation(line: 9, scope: !4) +!21 = !DILocation(line: 14, scope: !22) +!22 = distinct !DILexicalBlock(line: 13, column: 0, file: !5, scope: !10) +!23 = !DILocation(line: 15, scope: !22) +!24 = !DILocalVariable(name: "e", line: 16, scope: !10, file: !6, type: !9) +!25 = !DILocation(line: 16, scope: !10) +!26 = !DILocation(line: 17, scope: !27) +!27 = distinct !DILexicalBlock(line: 16, column: 0, file: !5, scope: !10) +!28 = !DILocation(line: 18, scope: !27) +!29 = !DILocation(line: 19, scope: !10) +!30 = !DILocation(line: 20, scope: !10) +!31 = !{i32 1, !"Debug Info Version", i32 3} diff --git a/llvm/test/DebugInfo/Generic/inline-debug-info.ll b/llvm/test/DebugInfo/Generic/inline-debug-info.ll new file mode 100644 index 00000000000..baadc39a9f7 --- /dev/null +++ b/llvm/test/DebugInfo/Generic/inline-debug-info.ll @@ -0,0 +1,174 @@ +; RUN: opt -inline -S < %s | FileCheck %s + +; Created from source +; +; +; 1 // test.cpp +; 2 extern int global_var; +; 3 extern int test_ext(int k); +; 4 int test (int k) { +; 5 int k2 = test_ext(k); +; 6 if (k2 > 100) +; 7 return k2; +; 8 return 0; +; 9 } +; 10 +; 11 int test2() { +; 12 try +; 13 { +; 14 test(global_var); +; 15 } +; 16 catch (int e) { +; 17 global_var = 0; +; 18 } +; 19 global_var = 1; +; 20 return 0; +; 21 } + +; CHECK: _Z4testi.exit: +; Make sure the branch instruction created during inlining has a debug location, +; so the range of the inlined function is correct. +; CHECK: br label %invoke.cont, !dbg [[MD:![0-9]+]] +; The branch instruction has the source location of line 9 and its inlined location +; has the source location of line 14. +; CHECK: [[INL:![0-9]*]] = distinct !DILocation(line: 14, scope: {{.*}}) +; CHECK: [[MD]] = !DILocation(line: 9, scope: {{.*}}, inlinedAt: [[INL]]) + +; ModuleID = 'test.cpp' +target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-n8:16:32:64-S128" +target triple = "x86_64-apple-darwin12.0.0" + +@_ZTIi = external constant i8* +@global_var = external global i32 + +define i32 @_Z4testi(i32 %k) { +entry: + %retval = alloca i32, align 4 + %k.addr = alloca i32, align 4 + %k2 = alloca i32, align 4 + store i32 %k, i32* %k.addr, align 4 + call void @llvm.dbg.declare(metadata i32* %k.addr, metadata !13, metadata !DIExpression()), !dbg !14 + call void @llvm.dbg.declare(metadata i32* %k2, metadata !15, metadata !DIExpression()), !dbg !16 + %0 = load i32, i32* %k.addr, align 4, !dbg !16 + %call = call i32 @_Z8test_exti(i32 %0), !dbg !16 + store i32 %call, i32* %k2, align 4, !dbg !16 + %1 = load i32, i32* %k2, align 4, !dbg !17 + %cmp = icmp sgt i32 %1, 100, !dbg !17 + br i1 %cmp, label %if.then, label %if.end, !dbg !17 + +if.then: ; preds = %entry + %2 = load i32, i32* %k2, align 4, !dbg !18 + store i32 %2, i32* %retval, !dbg !18 + br label %return, !dbg !18 + +if.end: ; preds = %entry + store i32 0, i32* %retval, !dbg !19 + br label %return, !dbg !19 + +return: ; preds = %if.end, %if.then + %3 = load i32, i32* %retval, !dbg !20 + ret i32 %3, !dbg !20 +} + +; Function Attrs: nounwind readnone +declare void @llvm.dbg.declare(metadata, metadata, metadata) #1 + +declare i32 @_Z8test_exti(i32) + +define i32 @_Z5test2v() personality i8* bitcast (i32 (...)* @__gxx_personality_v0 to i8*) { +entry: + %exn.slot = alloca i8* + %ehselector.slot = alloca i32 + %e = alloca i32, align 4 + %0 = load i32, i32* @global_var, align 4, !dbg !21 + %call = invoke i32 @_Z4testi(i32 %0) + to label %invoke.cont unwind label %lpad, !dbg !21 + +invoke.cont: ; preds = %entry + br label %try.cont, !dbg !23 + +lpad: ; preds = %entry + %1 = landingpad { i8*, i32 } + catch i8* bitcast (i8** @_ZTIi to i8*), !dbg !21 + %2 = extractvalue { i8*, i32 } %1, 0, !dbg !21 + store i8* %2, i8** %exn.slot, !dbg !21 + %3 = extractvalue { i8*, i32 } %1, 1, !dbg !21 + store i32 %3, i32* %ehselector.slot, !dbg !21 + br label %catch.dispatch, !dbg !21 + +catch.dispatch: ; preds = %lpad + %sel = load i32, i32* %ehselector.slot, !dbg !23 + %4 = call i32 @llvm.eh.typeid.for(i8* bitcast (i8** @_ZTIi to i8*)) #2, !dbg !23 + %matches = icmp eq i32 %sel, %4, !dbg !23 + br i1 %matches, label %catch, label %eh.resume, !dbg !23 + +catch: ; preds = %catch.dispatch + call void @llvm.dbg.declare(metadata i32* %e, metadata !24, metadata !DIExpression()), !dbg !25 + %exn = load i8*, i8** %exn.slot, !dbg !23 + %5 = call i8* @__cxa_begin_catch(i8* %exn) #2, !dbg !23 + %6 = bitcast i8* %5 to i32*, !dbg !23 + %7 = load i32, i32* %6, align 4, !dbg !23 + store i32 %7, i32* %e, align 4, !dbg !23 + store i32 0, i32* @global_var, align 4, !dbg !26 + call void @__cxa_end_catch() #2, !dbg !28 + br label %try.cont, !dbg !28 + +try.cont: ; preds = %catch, %invoke.cont + store i32 1, i32* @global_var, align 4, !dbg !29 + ret i32 0, !dbg !30 + +eh.resume: ; preds = %catch.dispatch + %exn1 = load i8*, i8** %exn.slot, !dbg !23 + %sel2 = load i32, i32* %ehselector.slot, !dbg !23 + %lpad.val = insertvalue { i8*, i32 } undef, i8* %exn1, 0, !dbg !23 + %lpad.val3 = insertvalue { i8*, i32 } %lpad.val, i32 %sel2, 1, !dbg !23 + resume { i8*, i32 } %lpad.val3, !dbg !23 +} + +declare i32 @__gxx_personality_v0(...) + +; Function Attrs: nounwind readnone +declare i32 @llvm.eh.typeid.for(i8*) #1 + +declare i8* @__cxa_begin_catch(i8*) + +declare void @__cxa_end_catch() + +attributes #1 = { nounwind readnone } +attributes #2 = { nounwind } + +!llvm.dbg.cu = !{!0} +!llvm.module.flags = !{!31} + +!0 = distinct !DICompileUnit(language: DW_LANG_C_plus_plus, producer: "clang version 3.3 ", isOptimized: false, emissionKind: 0, file: !1, enums: !2, retainedTypes: !2, subprograms: !3, globals: !2, imports: !2) +!1 = !DIFile(filename: "<unknown>", directory: "") +!2 = !{} +!3 = !{!4, !10} +!4 = distinct !DISubprogram(name: "test", linkageName: "_Z4testi", line: 4, isLocal: false, isDefinition: true, virtualIndex: 6, flags: DIFlagPrototyped, isOptimized: false, scopeLine: 4, file: !5, scope: !6, type: !7, function: i32 (i32)* @_Z4testi, variables: !2) +!5 = !DIFile(filename: "test.cpp", directory: "") +!6 = !DIFile(filename: "test.cpp", directory: "") +!7 = !DISubroutineType(types: !8) +!8 = !{!9, !9} +!9 = !DIBasicType(tag: DW_TAG_base_type, name: "int", size: 32, align: 32, encoding: DW_ATE_signed) +!10 = distinct !DISubprogram(name: "test2", linkageName: "_Z5test2v", line: 11, isLocal: false, isDefinition: true, virtualIndex: 6, flags: DIFlagPrototyped, isOptimized: false, scopeLine: 11, file: !5, scope: !6, type: !11, function: i32 ()* @_Z5test2v, variables: !2) +!11 = !DISubroutineType(types: !12) +!12 = !{!9} +!13 = !DILocalVariable(name: "k", line: 4, arg: 1, scope: !4, file: !6, type: !9) +!14 = !DILocation(line: 4, scope: !4) +!15 = !DILocalVariable(name: "k2", line: 5, scope: !4, file: !6, type: !9) +!16 = !DILocation(line: 5, scope: !4) +!17 = !DILocation(line: 6, scope: !4) +!18 = !DILocation(line: 7, scope: !4) +!19 = !DILocation(line: 8, scope: !4) +!20 = !DILocation(line: 9, scope: !4) +!21 = !DILocation(line: 14, scope: !22) +!22 = distinct !DILexicalBlock(line: 13, column: 0, file: !5, scope: !10) +!23 = !DILocation(line: 15, scope: !22) +!24 = !DILocalVariable(name: "e", line: 16, scope: !10, file: !6, type: !9) +!25 = !DILocation(line: 16, scope: !10) +!26 = !DILocation(line: 17, scope: !27) +!27 = distinct !DILexicalBlock(line: 16, column: 0, file: !5, scope: !10) +!28 = !DILocation(line: 18, scope: !27) +!29 = !DILocation(line: 19, scope: !10) +!30 = !DILocation(line: 20, scope: !10) +!31 = !{i32 1, !"Debug Info Version", i32 3} diff --git a/llvm/test/DebugInfo/Generic/inline-no-debug-info.ll b/llvm/test/DebugInfo/Generic/inline-no-debug-info.ll new file mode 100644 index 00000000000..a46146761a2 --- /dev/null +++ b/llvm/test/DebugInfo/Generic/inline-no-debug-info.ll @@ -0,0 +1,70 @@ +; RUN: opt < %s -inline -S | FileCheck %s + +; This was generated from the following source: +; int a, b; +; __attribute__((__always_inline__)) static void callee2() { b = 2; } +; __attribute__((__nodebug__)) void callee() { a = 1; callee2(); } +; void caller() { callee(); } +; by running +; clang -S test.c -emit-llvm -O1 -gline-tables-only -fno-strict-aliasing + +; CHECK-LABEL: @caller( + +; This instruction did not have a !dbg metadata in the callee. +; CHECK: store i32 1, {{.*}}, !dbg [[A:!.*]] + +; This instruction came from callee with a !dbg metadata. +; CHECK: store i32 2, {{.*}}, !dbg [[B:!.*]] + +; The remaining instruction from the caller. +; CHECK: ret void, !dbg [[A]] + +; Debug location of the code in caller() and of the inlined code that did not +; have any debug location before. +; CHECK-DAG: [[A]] = !DILocation(line: 4, scope: !{{[0-9]+}}) + +; Debug location of the inlined code. +; CHECK-DAG: [[B]] = !DILocation(line: 2, scope: !{{[0-9]+}}, inlinedAt: [[A_INL:![0-9]*]]) +; CHECK-DAG: [[A_INL]] = distinct !DILocation(line: 4, scope: !{{[0-9]+}}) + + +target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128" +target triple = "x86_64-unknown-linux-gnu" + +@a = common global i32 0, align 4 +@b = common global i32 0, align 4 + +; Function Attrs: nounwind uwtable +define void @callee() #0 { +entry: + store i32 1, i32* @a, align 4 + store i32 2, i32* @b, align 4, !dbg !11 + ret void +} + +; Function Attrs: nounwind uwtable +define void @caller() #0 { +entry: + tail call void @callee(), !dbg !12 + ret void, !dbg !12 +} + +attributes #0 = { nounwind uwtable "less-precise-fpmad"="false" "no-frame-pointer-elim"="false" "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 = !{!8, !9} +!llvm.ident = !{!10} + +!0 = distinct !DICompileUnit(language: DW_LANG_C99, producer: "clang version 3.5.0 (210174)", isOptimized: true, emissionKind: 2, file: !1, enums: !2, retainedTypes: !2, subprograms: !3, globals: !2, imports: !2) +!1 = !DIFile(filename: "test.c", directory: "/code/llvm/build0") +!2 = !{} +!3 = !{!4, !7} +!4 = distinct !DISubprogram(name: "caller", line: 4, isLocal: false, isDefinition: true, virtualIndex: 6, isOptimized: true, scopeLine: 4, file: !1, scope: !5, type: !6, function: void ()* @caller, variables: !2) +!5 = !DIFile(filename: "test.c", directory: "/code/llvm/build0") +!6 = !DISubroutineType(types: !2) +!7 = distinct !DISubprogram(name: "callee2", line: 2, isLocal: true, isDefinition: true, virtualIndex: 6, isOptimized: true, scopeLine: 2, file: !1, scope: !5, type: !6, variables: !2) +!8 = !{i32 2, !"Dwarf Version", i32 4} +!9 = !{i32 2, !"Debug Info Version", i32 3} +!10 = !{!"clang version 3.5.0 (210174)"} +!11 = !DILocation(line: 2, scope: !7) +!12 = !DILocation(line: 4, scope: !4) diff --git a/llvm/test/DebugInfo/Generic/inline-scopes.ll b/llvm/test/DebugInfo/Generic/inline-scopes.ll new file mode 100644 index 00000000000..266d03e93e0 --- /dev/null +++ b/llvm/test/DebugInfo/Generic/inline-scopes.ll @@ -0,0 +1,130 @@ +; REQUIRES: object-emission + +; RUN: %llc_dwarf -O0 -filetype=obj < %s | llvm-dwarfdump -debug-dump=info - | FileCheck %s + +; bool f(); +; inline __attribute__((always_inline)) int f1() { +; if (bool b = f()) +; return 1; +; return 2; +; } +; +; inline __attribute__((always_inline)) int f2() { +; # 2 "y.cc" +; if (bool b = f()) +; return 3; +; return 4; +; } +; +; int main() { +; f1(); +; f2(); +; } + +; Ensure that lexical_blocks within inlined_subroutines are preserved/emitted. +; CHECK: DW_TAG_inlined_subroutine +; CHECK-NOT: DW_TAG +; CHECK-NOT: NULL +; CHECK: DW_TAG_lexical_block +; CHECK-NOT: DW_TAG +; CHECK-NOT: NULL +; CHECK: DW_TAG_variable +; Ensure that file changes don't interfere with creating inlined subroutines. +; (see the line directive inside 'f2' in thesource) +; CHECK: DW_TAG_inlined_subroutine +; CHECK: DW_TAG_variable +; CHECK-NOT: DW_TAG +; CHECK: DW_AT_abstract_origin + +; Function Attrs: uwtable +define i32 @main() #0 { +entry: + %retval.i2 = alloca i32, align 4 + %b.i3 = alloca i8, align 1 + %retval.i = alloca i32, align 4 + %b.i = alloca i8, align 1 + call void @llvm.dbg.declare(metadata i8* %b.i, metadata !16, metadata !DIExpression()), !dbg !19 + %call.i = call zeroext i1 @_Z1fv(), !dbg !19 + %frombool.i = zext i1 %call.i to i8, !dbg !19 + store i8 %frombool.i, i8* %b.i, align 1, !dbg !19 + %0 = load i8, i8* %b.i, align 1, !dbg !19 + %tobool.i = trunc i8 %0 to i1, !dbg !19 + br i1 %tobool.i, label %if.then.i, label %if.end.i, !dbg !19 + +if.then.i: ; preds = %entry + store i32 1, i32* %retval.i, !dbg !21 + br label %_Z2f1v.exit, !dbg !21 + +if.end.i: ; preds = %entry + store i32 2, i32* %retval.i, !dbg !22 + br label %_Z2f1v.exit, !dbg !22 + +_Z2f1v.exit: ; preds = %if.then.i, %if.end.i + %1 = load i32, i32* %retval.i, !dbg !23 + call void @llvm.dbg.declare(metadata i8* %b.i3, metadata !24, metadata !DIExpression()), !dbg !27 + %call.i4 = call zeroext i1 @_Z1fv(), !dbg !27 + %frombool.i5 = zext i1 %call.i4 to i8, !dbg !27 + store i8 %frombool.i5, i8* %b.i3, align 1, !dbg !27 + %2 = load i8, i8* %b.i3, align 1, !dbg !27 + %tobool.i6 = trunc i8 %2 to i1, !dbg !27 + br i1 %tobool.i6, label %if.then.i7, label %if.end.i8, !dbg !27 + +if.then.i7: ; preds = %_Z2f1v.exit + store i32 3, i32* %retval.i2, !dbg !29 + br label %_Z2f2v.exit, !dbg !29 + +if.end.i8: ; preds = %_Z2f1v.exit + store i32 4, i32* %retval.i2, !dbg !30 + br label %_Z2f2v.exit, !dbg !30 + +_Z2f2v.exit: ; preds = %if.then.i7, %if.end.i8 + %3 = load i32, i32* %retval.i2, !dbg !31 + ret i32 0, !dbg !32 +} + +; Function Attrs: nounwind readnone +declare void @llvm.dbg.declare(metadata, metadata, metadata) #1 + +declare zeroext i1 @_Z1fv() #2 + +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 = { nounwind readnone } +attributes #2 = { "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 = !{!13, !14} +!llvm.ident = !{!15} + +!0 = distinct !DICompileUnit(language: DW_LANG_C_plus_plus, producer: "clang version 3.5.0 ", isOptimized: false, emissionKind: 1, file: !1, enums: !2, retainedTypes: !2, subprograms: !3, globals: !2, imports: !2) +!1 = !DIFile(filename: "inline-scopes.cpp", directory: "/tmp/dbginfo") +!2 = !{} +!3 = !{!4, !10, !12} +!4 = distinct !DISubprogram(name: "main", line: 7, isLocal: false, isDefinition: true, virtualIndex: 6, flags: DIFlagPrototyped, isOptimized: false, scopeLine: 7, file: !5, scope: !6, type: !7, function: i32 ()* @main, variables: !2) +!5 = !DIFile(filename: "y.cc", directory: "/tmp/dbginfo") +!6 = !DIFile(filename: "y.cc", directory: "/tmp/dbginfo") +!7 = !DISubroutineType(types: !8) +!8 = !{!9} +!9 = !DIBasicType(tag: DW_TAG_base_type, name: "int", size: 32, align: 32, encoding: DW_ATE_signed) +!10 = distinct !DISubprogram(name: "f2", linkageName: "_Z2f2v", line: 8, isLocal: false, isDefinition: true, virtualIndex: 6, flags: DIFlagPrototyped, isOptimized: false, scopeLine: 8, file: !1, scope: !11, type: !7, variables: !2) +!11 = !DIFile(filename: "inline-scopes.cpp", directory: "/tmp/dbginfo") +!12 = distinct !DISubprogram(name: "f1", linkageName: "_Z2f1v", line: 2, isLocal: false, isDefinition: true, virtualIndex: 6, flags: DIFlagPrototyped, isOptimized: false, scopeLine: 2, file: !1, scope: !11, type: !7, variables: !2) +!13 = !{i32 2, !"Dwarf Version", i32 4} +!14 = !{i32 1, !"Debug Info Version", i32 3} +!15 = !{!"clang version 3.5.0 "} +!16 = !DILocalVariable(name: "b", line: 3, scope: !17, file: !11, type: !18) +!17 = distinct !DILexicalBlock(line: 3, column: 0, file: !1, scope: !12) +!18 = !DIBasicType(tag: DW_TAG_base_type, name: "bool", size: 8, align: 8, encoding: DW_ATE_boolean) +!19 = !DILocation(line: 3, scope: !17, inlinedAt: !20) +!20 = !DILocation(line: 8, scope: !4) +!21 = !DILocation(line: 4, scope: !17, inlinedAt: !20) +!22 = !DILocation(line: 5, scope: !12, inlinedAt: !20) +!23 = !DILocation(line: 6, scope: !12, inlinedAt: !20) +!24 = !DILocalVariable(name: "b", line: 2, scope: !25, file: !6, type: !18) +!25 = distinct !DILexicalBlock(line: 2, column: 0, file: !5, scope: !26) +!26 = !DILexicalBlockFile(discriminator: 0, file: !5, scope: !10) +!27 = !DILocation(line: 2, scope: !25, inlinedAt: !28) +!28 = !DILocation(line: 9, scope: !4) +!29 = !DILocation(line: 3, scope: !25, inlinedAt: !28) +!30 = !DILocation(line: 4, scope: !26, inlinedAt: !28) +!31 = !DILocation(line: 5, scope: !26, inlinedAt: !28) +!32 = !DILocation(line: 10, scope: !4) diff --git a/llvm/test/DebugInfo/Generic/inlined-arguments.ll b/llvm/test/DebugInfo/Generic/inlined-arguments.ll new file mode 100644 index 00000000000..69825faa8b9 --- /dev/null +++ b/llvm/test/DebugInfo/Generic/inlined-arguments.ll @@ -0,0 +1,79 @@ +; REQUIRES: object-emission + +; RUN: %llc_dwarf -filetype=obj < %s > %t +; RUN: llvm-dwarfdump %t | FileCheck %s + +; IR generated from clang -O -g with the following source +; +; void f1(int x, int y); +; void f3(int line); +; void f2() { +; f1(1, 2); +; } +; void f1(int x, int y) { +; f3(y); +; } + +; CHECK: DW_AT_name{{.*}}"f1" +; CHECK: DW_TAG_formal_parameter +; CHECK-NOT: DW_TAG +; CHECK: DW_AT_name{{.*}}"x" +; CHECK: DW_TAG_formal_parameter +; CHECK-NOT: DW_TAG +; CHECK: DW_AT_name{{.*}}"y" + +; Function Attrs: uwtable +define void @_Z2f2v() #0 { + tail call void @llvm.dbg.value(metadata i32 undef, i64 0, metadata !16, metadata !DIExpression()), !dbg !18 + tail call void @llvm.dbg.value(metadata i32 2, i64 0, metadata !20, metadata !DIExpression()), !dbg !18 + tail call void @_Z2f3i(i32 2), !dbg !21 + ret void, !dbg !22 +} + +; Function Attrs: uwtable +define void @_Z2f1ii(i32 %x, i32 %y) #0 { + tail call void @llvm.dbg.value(metadata i32 %x, i64 0, metadata !13, metadata !DIExpression()), !dbg !23 + tail call void @llvm.dbg.value(metadata i32 %y, i64 0, metadata !14, metadata !DIExpression()), !dbg !23 + tail call void @_Z2f3i(i32 %y), !dbg !24 + ret void, !dbg !25 +} + +declare void @_Z2f3i(i32) #1 + +; Function Attrs: nounwind readnone +declare void @llvm.dbg.value(metadata, i64, metadata, metadata) #2 + +attributes #0 = { uwtable "less-precise-fpmad"="false" "no-frame-pointer-elim"="false" "no-infs-fp-math"="false" "no-nans-fp-math"="false" "unsafe-fp-math"="false" "use-soft-float"="false" } +attributes #1 = { "less-precise-fpmad"="false" "no-frame-pointer-elim"="false" "no-infs-fp-math"="false" "no-nans-fp-math"="false" "unsafe-fp-math"="false" "use-soft-float"="false" } +attributes #2 = { nounwind readnone } + +!llvm.dbg.cu = !{!0} +!llvm.module.flags = !{!26} + +!0 = distinct !DICompileUnit(language: DW_LANG_C_plus_plus, producer: "clang version 3.4 ", isOptimized: true, emissionKind: 1, file: !1, enums: !2, retainedTypes: !2, subprograms: !3, globals: !2, imports: !2) +!1 = !DIFile(filename: "exp.cpp", directory: "/usr/local/google/home/blaikie/dev/scratch") +!2 = !{} +!3 = !{!4, !8} +!4 = distinct !DISubprogram(name: "f2", linkageName: "_Z2f2v", line: 3, isLocal: false, isDefinition: true, virtualIndex: 6, flags: DIFlagPrototyped, isOptimized: true, scopeLine: 3, file: !1, scope: !5, type: !6, function: void ()* @_Z2f2v, variables: !2) +!5 = !DIFile(filename: "exp.cpp", directory: "/usr/local/google/home/blaikie/dev/scratch") +!6 = !DISubroutineType(types: !7) +!7 = !{null} +!8 = distinct !DISubprogram(name: "f1", linkageName: "_Z2f1ii", line: 6, isLocal: false, isDefinition: true, virtualIndex: 6, flags: DIFlagPrototyped, isOptimized: true, scopeLine: 6, file: !1, scope: !5, type: !9, function: void (i32, i32)* @_Z2f1ii, variables: !12) +!9 = !DISubroutineType(types: !10) +!10 = !{null, !11, !11} +!11 = !DIBasicType(tag: DW_TAG_base_type, name: "int", size: 32, align: 32, encoding: DW_ATE_signed) +!12 = !{!13, !14} +!13 = !DILocalVariable(name: "x", line: 6, arg: 1, scope: !8, file: !5, type: !11) +!14 = !DILocalVariable(name: "y", line: 6, arg: 2, scope: !8, file: !5, type: !11) +!15 = !{i32 undef} +!16 = !DILocalVariable(name: "x", line: 6, arg: 1, scope: !8, file: !5, type: !11) +!17 = !DILocation(line: 4, scope: !4) +!18 = !DILocation(line: 6, scope: !8, inlinedAt: !17) +!19 = !{i32 2} +!20 = !DILocalVariable(name: "y", line: 6, arg: 2, scope: !8, file: !5, type: !11) +!21 = !DILocation(line: 7, scope: !8, inlinedAt: !17) +!22 = !DILocation(line: 5, scope: !4) +!23 = !DILocation(line: 6, scope: !8) +!24 = !DILocation(line: 7, scope: !8) +!25 = !DILocation(line: 8, scope: !8) +!26 = !{i32 1, !"Debug Info Version", i32 3} diff --git a/llvm/test/DebugInfo/Generic/inlined-vars.ll b/llvm/test/DebugInfo/Generic/inlined-vars.ll new file mode 100644 index 00000000000..05e7f7d2beb --- /dev/null +++ b/llvm/test/DebugInfo/Generic/inlined-vars.ll @@ -0,0 +1,56 @@ +; RUN: %llc_dwarf -O0 < %s | FileCheck %s -check-prefix ARGUMENT +; RUN: %llc_dwarf -O0 < %s | FileCheck %s -check-prefix VARIABLE +; PR 13202 + +define i32 @main() uwtable { +entry: + tail call void @llvm.dbg.value(metadata i32 0, i64 0, metadata !18, metadata !DIExpression()), !dbg !21 + tail call void @llvm.dbg.value(metadata i32 0, i64 0, metadata !22, metadata !DIExpression()), !dbg !23 + tail call void @smth(i32 0), !dbg !24 + tail call void @smth(i32 0), !dbg !25 + ret i32 0, !dbg !19 +} + +declare void @smth(i32) + +declare void @llvm.dbg.value(metadata, i64, metadata, metadata) nounwind readnone + +!llvm.dbg.cu = !{!0} +!llvm.module.flags = !{!27} + +!0 = distinct !DICompileUnit(language: DW_LANG_C_plus_plus, producer: "clang version 3.2 (trunk 159419)", isOptimized: true, emissionKind: 0, file: !26, enums: !2, retainedTypes: !2, subprograms: !3, globals: !2, imports: !2) +!1 = !{i32 0} +!2 = !{} +!3 = !{!5, !10} +!5 = distinct !DISubprogram(name: "main", line: 10, isLocal: false, isDefinition: true, virtualIndex: 6, flags: DIFlagPrototyped, isOptimized: true, scopeLine: 10, file: !26, scope: !6, type: !7, function: i32 ()* @main, variables: !2) +!6 = !DIFile(filename: "inline-bug.cc", directory: "/tmp/dbginfo/pr13202") +!7 = !DISubroutineType(types: !8) +!8 = !{!9} +!9 = !DIBasicType(tag: DW_TAG_base_type, name: "int", size: 32, align: 32, encoding: DW_ATE_signed) +!10 = distinct !DISubprogram(name: "f", linkageName: "_ZL1fi", line: 3, isLocal: true, isDefinition: true, virtualIndex: 6, flags: DIFlagPrototyped, isOptimized: true, scopeLine: 3, file: !26, scope: !6, type: !11, variables: !13) +!11 = !DISubroutineType(types: !12) +!12 = !{!9, !9} +!13 = !{!15, !16} +!15 = !DILocalVariable(name: "argument", line: 3, arg: 1, scope: !10, file: !6, type: !9) + +; Two DW_TAG_formal_parameter: one abstract and one inlined. +; ARGUMENT: {{.*Abbrev.*DW_TAG_formal_parameter}} +; ARGUMENT: {{.*Abbrev.*DW_TAG_formal_parameter}} +; ARGUMENT-NOT: {{.*Abbrev.*DW_TAG_formal_parameter}} + +!16 = !DILocalVariable(name: "local", line: 4, scope: !10, file: !6, type: !9) + +; Two DW_TAG_variable: one abstract and one inlined. +; VARIABLE: {{.*Abbrev.*DW_TAG_variable}} +; VARIABLE: {{.*Abbrev.*DW_TAG_variable}} +; VARIABLE-NOT: {{.*Abbrev.*DW_TAG_variable}} + +!18 = !DILocalVariable(name: "argument", line: 3, arg: 1, scope: !10, file: !6, type: !9) +!19 = !DILocation(line: 11, column: 10, scope: !5) +!21 = !DILocation(line: 3, column: 25, scope: !10, inlinedAt: !19) +!22 = !DILocalVariable(name: "local", line: 4, scope: !10, file: !6, type: !9) +!23 = !DILocation(line: 4, column: 16, scope: !10, inlinedAt: !19) +!24 = !DILocation(line: 5, column: 3, scope: !10, inlinedAt: !19) +!25 = !DILocation(line: 6, column: 3, scope: !10, inlinedAt: !19) +!26 = !DIFile(filename: "inline-bug.cc", directory: "/tmp/dbginfo/pr13202") +!27 = !{i32 1, !"Debug Info Version", i32 3} diff --git a/llvm/test/DebugInfo/Generic/lit.local.cfg b/llvm/test/DebugInfo/Generic/lit.local.cfg new file mode 100644 index 00000000000..f22d4aabd73 --- /dev/null +++ b/llvm/test/DebugInfo/Generic/lit.local.cfg @@ -0,0 +1,3 @@ +if not config.target_triple: + config.unsupported = True + diff --git a/llvm/test/DebugInfo/Generic/location-verifier.ll b/llvm/test/DebugInfo/Generic/location-verifier.ll new file mode 100644 index 00000000000..a767ab903c3 --- /dev/null +++ b/llvm/test/DebugInfo/Generic/location-verifier.ll @@ -0,0 +1,33 @@ +; RUN: not llvm-as -disable-output -verify-debug-info < %s 2>&1 | FileCheck %s +; ModuleID = 'test.c' +target datalayout = "e-m:o-i64:64-f80:128-n8:16:32:64-S128" +target triple = "x86_64-apple-macosx10.10.0" + +; Function Attrs: nounwind ssp uwtable +define i32 @foo() #0 { +entry: + ret i32 42, !dbg !13 +} + +attributes #0 = { nounwind ssp uwtable } + +!llvm.dbg.cu = !{!0} +!llvm.module.flags = !{!9, !10, !11} +!llvm.ident = !{!12} + +!0 = distinct !DICompileUnit(language: DW_LANG_C99, producer: "clang version 3.7.0 ", isOptimized: false, emissionKind: 1, file: !1, enums: !2, retainedTypes: !2, subprograms: !3, globals: !2, imports: !2) +!1 = !DIFile(filename: "test.c", directory: "") +!2 = !{} +!3 = !{!4} +!4 = distinct !DISubprogram(name: "foo", line: 1, isLocal: false, isDefinition: true, isOptimized: false, scopeLine: 1, file: !1, scope: !5, type: !6, function: i32 ()* @foo, variables: !2) +!5 = !DIFile(filename: "test.c", directory: "") +!6 = !DISubroutineType(types: !7) +!7 = !{!8} +!8 = !DIBasicType(tag: DW_TAG_base_type, name: "int", size: 32, align: 32, encoding: DW_ATE_signed) +!9 = !{i32 2, !"Dwarf Version", i32 2} +!10 = !{i32 2, !"Debug Info Version", i32 3} +!11 = !{i32 1, !"PIC Level", i32 2} +!12 = !{!"clang version 3.7.0 "} +; An old-style DILocation should not pass verify. +; CHECK: invalid !dbg metadata attachment +!13 = !{i32 2, i32 2, !4, null} diff --git a/llvm/test/DebugInfo/Generic/lto-comp-dir.ll b/llvm/test/DebugInfo/Generic/lto-comp-dir.ll new file mode 100644 index 00000000000..f20383d5636 --- /dev/null +++ b/llvm/test/DebugInfo/Generic/lto-comp-dir.ll @@ -0,0 +1,84 @@ +; REQUIRES: object-emission + +; RUN: %llc_dwarf < %s -filetype=obj | llvm-dwarfdump -debug-dump=line - | FileCheck %s +; RUN: %llc_dwarf < %s -filetype=asm | FileCheck --check-prefix=ASM %s + +; If multiple line tables are emitted, one per CU, those line tables can +; unambiguously rely on the comp_dir of their owning CU and use directory '0' +; to refer to it. + +; CHECK: .debug_line contents: +; CHECK-NEXT: Line table prologue: +; CHECK-NOT: include_directories +; CHECK: file_names[ 1] 0 {{.*}} a.cpp +; CHECK-NOT: file_names + +; CHECK: Line table prologue: +; CHECK-NOT: include_directories +; CHECK: file_names[ 1] 0 {{.*}} b.cpp +; CHECK-NOT: file_names + +; However, if a single line table is emitted and shared between CUs, the +; comp_dir is ambiguous and relying on it would lead to different path +; interpretations depending on which CU lead to the table - so ensure that +; full paths are always emitted in this case, never comp_dir relative. + +; ASM: .file 1 "/tmp/dbginfo/a{{[/\\]+}}a.cpp" +; ASM: .file 2 "/tmp/dbginfo/b{{[/\\]+}}b.cpp" + +; Generated from the following source compiled to bitcode from within their +; respective directories (with debug info) and linked together with llvm-link + +; a/a.cpp +; void func() { +; } + +; b/b.cpp +; void func(); +; int main() { +; func(); +; } + +; Function Attrs: nounwind uwtable +define void @_Z4funcv() #0 { +entry: + ret void, !dbg !19 +} + +; Function Attrs: uwtable +define i32 @main() #1 { +entry: + call void @_Z4funcv(), !dbg !20 + ret i32 0, !dbg !21 +} + +attributes #0 = { nounwind 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 = { 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" } + +!llvm.dbg.cu = !{!0, !8} +!llvm.module.flags = !{!16, !17} +!llvm.ident = !{!18, !18} + +!0 = distinct !DICompileUnit(language: DW_LANG_C_plus_plus, producer: "clang version 3.5.0 ", isOptimized: false, emissionKind: 1, file: !1, enums: !2, retainedTypes: !2, subprograms: !3, globals: !2, imports: !2) +!1 = !DIFile(filename: "a.cpp", directory: "/tmp/dbginfo/a") +!2 = !{} +!3 = !{!4} +!4 = distinct !DISubprogram(name: "func", linkageName: "_Z4funcv", line: 1, isLocal: false, isDefinition: true, virtualIndex: 6, flags: DIFlagPrototyped, isOptimized: false, scopeLine: 1, file: !1, scope: !5, type: !6, function: void ()* @_Z4funcv, variables: !2) +!5 = !DIFile(filename: "a.cpp", directory: "/tmp/dbginfo/a") +!6 = !DISubroutineType(types: !7) +!7 = !{null} +!8 = distinct !DICompileUnit(language: DW_LANG_C_plus_plus, producer: "clang version 3.5.0 ", isOptimized: false, emissionKind: 1, file: !9, enums: !2, retainedTypes: !2, subprograms: !10, globals: !2, imports: !2) +!9 = !DIFile(filename: "b.cpp", directory: "/tmp/dbginfo/b") +!10 = !{!11} +!11 = distinct !DISubprogram(name: "main", line: 2, isLocal: false, isDefinition: true, virtualIndex: 6, flags: DIFlagPrototyped, isOptimized: false, scopeLine: 2, file: !9, scope: !12, type: !13, function: i32 ()* @main, variables: !2) +!12 = !DIFile(filename: "b.cpp", directory: "/tmp/dbginfo/b") +!13 = !DISubroutineType(types: !14) +!14 = !{!15} +!15 = !DIBasicType(tag: DW_TAG_base_type, name: "int", size: 32, align: 32, encoding: DW_ATE_signed) +!16 = !{i32 2, !"Dwarf Version", i32 4} +!17 = !{i32 1, !"Debug Info Version", i32 3} +!18 = !{!"clang version 3.5.0 "} +!19 = !DILocation(line: 2, scope: !4) +!20 = !DILocation(line: 3, scope: !11) +!21 = !DILocation(line: 4, scope: !11) + diff --git a/llvm/test/DebugInfo/Generic/member-order.ll b/llvm/test/DebugInfo/Generic/member-order.ll new file mode 100644 index 00000000000..4c1f6b6c0ba --- /dev/null +++ b/llvm/test/DebugInfo/Generic/member-order.ll @@ -0,0 +1,66 @@ +; REQUIRES: object-emission + +; RUN: %llc_dwarf -filetype=obj -O0 < %s | llvm-dwarfdump -debug-dump=info - | FileCheck %s + +; generated by clang from: +; struct foo { +; void f1(); +; void f2(); +; }; +; +; void foo::f1() { +; } + +; CHECK: DW_TAG_structure_type +; CHECK-NEXT: DW_AT_name {{.*}} "foo" +; CHECK-NOT: NULL +; CHECK: DW_TAG_subprogram +; CHECK-NOT: NULL +; CHECK: DW_AT_name {{.*}} "f1" +; CHECK: DW_TAG_subprogram +; CHECK-NOT: NULL +; CHECK: DW_AT_name {{.*}} "f2" + + +%struct.foo = type { i8 } + +; Function Attrs: nounwind uwtable +define void @_ZN3foo2f1Ev(%struct.foo* %this) #0 align 2 { +entry: + %this.addr = alloca %struct.foo*, align 8 + store %struct.foo* %this, %struct.foo** %this.addr, align 8 + call void @llvm.dbg.declare(metadata %struct.foo** %this.addr, metadata !16, metadata !DIExpression()), !dbg !18 + %this1 = load %struct.foo*, %struct.foo** %this.addr + ret void, !dbg !19 +} + +; Function Attrs: nounwind readnone +declare void @llvm.dbg.declare(metadata, metadata, metadata) #1 + +attributes #0 = { nounwind 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 = { nounwind readnone } + +!llvm.dbg.cu = !{!0} +!llvm.module.flags = !{!15, !20} + +!0 = distinct !DICompileUnit(language: DW_LANG_C_plus_plus, producer: "clang version 3.4 ", isOptimized: false, emissionKind: 0, file: !1, enums: !2, retainedTypes: !3, subprograms: !13, globals: !2, imports: !2) +!1 = !DIFile(filename: "member-order.cpp", directory: "/tmp/dbginfo") +!2 = !{} +!3 = !{!4} +!4 = !DICompositeType(tag: DW_TAG_structure_type, name: "foo", line: 1, size: 8, align: 8, file: !1, elements: !5, identifier: "_ZTS3foo") +!5 = !{!6, !11} +!6 = !DISubprogram(name: "f1", linkageName: "_ZN3foo2f1Ev", line: 2, isLocal: false, isDefinition: false, virtualIndex: 6, flags: DIFlagPrototyped, isOptimized: false, scopeLine: 2, file: !1, scope: !4, type: !7) +!7 = !DISubroutineType(types: !8) +!8 = !{null, !9} +!9 = !DIDerivedType(tag: DW_TAG_pointer_type, size: 64, align: 64, flags: DIFlagArtificial | DIFlagObjectPointer, baseType: !"_ZTS3foo") +!10 = !{i32 786468} +!11 = !DISubprogram(name: "f2", linkageName: "_ZN3foo2f2Ev", line: 3, isLocal: false, isDefinition: false, virtualIndex: 6, flags: DIFlagPrototyped, isOptimized: false, scopeLine: 3, file: !1, scope: !4, type: !7) +!12 = !{i32 786468} +!13 = !{!14} +!14 = distinct !DISubprogram(name: "f1", linkageName: "_ZN3foo2f1Ev", line: 6, isLocal: false, isDefinition: true, virtualIndex: 6, flags: DIFlagPrototyped, isOptimized: false, scopeLine: 6, file: !1, scope: null, type: !7, function: void (%struct.foo*)* @_ZN3foo2f1Ev, declaration: !6, variables: !2) +!15 = !{i32 2, !"Dwarf Version", i32 4} +!16 = !DILocalVariable(name: "this", arg: 1, flags: DIFlagArtificial | DIFlagObjectPointer, scope: !14, type: !17) +!17 = !DIDerivedType(tag: DW_TAG_pointer_type, size: 64, align: 64, baseType: !"_ZTS3foo") +!18 = !DILocation(line: 0, scope: !14) +!19 = !DILocation(line: 7, scope: !14) +!20 = !{i32 1, !"Debug Info Version", i32 3} diff --git a/llvm/test/DebugInfo/Generic/member-pointers.ll b/llvm/test/DebugInfo/Generic/member-pointers.ll new file mode 100644 index 00000000000..1570c07ddb2 --- /dev/null +++ b/llvm/test/DebugInfo/Generic/member-pointers.ll @@ -0,0 +1,40 @@ +; REQUIRES: object-emission +; XFAIL: hexagon + +; RUN: %llc_dwarf -filetype=obj -O0 < %s > %t +; RUN: llvm-dwarfdump -debug-dump=info %t | FileCheck %s +; CHECK: DW_TAG_ptr_to_member_type +; CHECK: DW_TAG_ptr_to_member_type +; CHECK-NEXT: DW_AT_type [DW_FORM_ref4] (cu + {{.*}} => {[[TYPE:0x[0-9a-f]+]]}) +; CHECK: [[TYPE]]: DW_TAG_subroutine_type +; CHECK: DW_TAG_formal_parameter +; CHECK-NEXT: DW_AT_type +; CHECK-NEXT: DW_AT_artificial [DW_FORM_flag +; IR generated from clang -g with the following source: +; struct S { +; }; +; +; int S::*x = 0; +; void (S::*y)(int) = 0; + +@x = global i64 -1, align 8 +@y = global { i64, i64 } zeroinitializer, align 8 + +!llvm.dbg.cu = !{!0} +!llvm.module.flags = !{!16} + +!0 = distinct !DICompileUnit(language: DW_LANG_C_plus_plus, producer: "clang version 3.3 ", isOptimized: false, emissionKind: 0, file: !15, enums: !1, retainedTypes: !1, subprograms: !1, globals: !3, imports: !1) +!1 = !{} +!3 = !{!5, !10} +!5 = !DIGlobalVariable(name: "x", line: 4, isLocal: false, isDefinition: true, scope: null, file: !6, type: !7, variable: i64* @x) +!6 = !DIFile(filename: "simple.cpp", directory: "/home/blaikie/Development/scratch") +!7 = !DIDerivedType(tag: DW_TAG_ptr_to_member_type, baseType: !8, extraData: !9) +!8 = !DIBasicType(tag: DW_TAG_base_type, name: "int", size: 32, align: 32, encoding: DW_ATE_signed) +!9 = !DICompositeType(tag: DW_TAG_structure_type, name: "S", line: 1, size: 8, align: 8, file: !15, elements: !1) +!10 = !DIGlobalVariable(name: "y", line: 5, isLocal: false, isDefinition: true, scope: null, file: !6, type: !11, variable: { i64, i64 }* @y) +!11 = !DIDerivedType(tag: DW_TAG_ptr_to_member_type, baseType: !12, extraData: !9) +!12 = !DISubroutineType(types: !13) +!13 = !{null, !14, !8} +!14 = !DIDerivedType(tag: DW_TAG_pointer_type, size: 64, align: 64, flags: DIFlagArtificial | DIFlagObjectPointer, baseType: !9) +!15 = !DIFile(filename: "simple.cpp", directory: "/home/blaikie/Development/scratch") +!16 = !{i32 1, !"Debug Info Version", i32 3} diff --git a/llvm/test/DebugInfo/Generic/missing-abstract-variable.ll b/llvm/test/DebugInfo/Generic/missing-abstract-variable.ll new file mode 100644 index 00000000000..0ebb5a28edc --- /dev/null +++ b/llvm/test/DebugInfo/Generic/missing-abstract-variable.ll @@ -0,0 +1,182 @@ +; REQUIRES: object-emission + +; RUN: %llc_dwarf -O0 -filetype=obj < %s | llvm-dwarfdump -debug-dump=info - | FileCheck %s + +; The formal parameter 'b' for Function 'x' when inlined within 'a' is lost on +; mips and powerpc64 (and on x86_64 at at least -O2). Presumably this is a +; SelectionDAG issue (do mips/powerpc64 use FastISel?). +; XFAIL: mips, powerpc64, s390x, sparc + +; Build from the following source with clang -O2. + +; The important details are that 'x's abstract definition is first built during +; the definition of 'b', where the parameter to 'x' is constant and so 'x's 's' +; variable is optimized away. No abstract definition DIE for 's' is constructed. +; Then, during 'a' emission, the abstract DbgVariable for 's' is created, but +; the abstract DIE isn't (since the abstract definition for 'b' is already +; built). This results in 's' inlined in 'a' being emitted with its name, line, +; file there, rather than referencing an abstract definition. + +; extern int t; +; +; void f(int); +; +; inline void x(bool b) { +; if (b) { +; int s = t; +; f(s); +; } +; f(0); +; } +; +; void b() { +; x(false); +; } +; +; void a(bool u) { +; x(u); +; } + +; CHECK: [[X_DECL:.*]]: DW_TAG_subprogram +; CHECK-NOT: DW_TAG +; CHECK: DW_AT_name {{.*}} "x" +; CHECK-NOT: {{DW_TAG|NULL}} +; CHECK: DW_TAG_formal_parameter +; CHECK-NOT: DW_TAG +; CHECK: DW_AT_name {{.*}} "b" +; CHECK-NOT: {{DW_TAG|NULL}} +; CHECK: DW_TAG_lexical_block +; CHECK-NOT: {{DW_TAG|NULL}} +; CHECK: DW_TAG_variable +; CHECK-NOT: DW_TAG +; CHECK: DW_AT_name {{.*}} "s" + +; CHECK: DW_TAG_subprogram +; CHECK-NOT: DW_TAG +; CHECK: DW_AT_name {{.*}} "b" +; CHECK-NOT: {{DW_TAG|NULL}} +; CHECK: DW_TAG_inlined_subroutine +; CHECK-NOT: DW_TAG +; CHECK: DW_AT_abstract_origin {{.*}} {[[X_DECL]]} +; CHECK-NOT: {{DW_TAG|NULL}} +; CHECK: DW_TAG_formal_parameter +; CHECK-NOT: DW_TAG +; CHECK: DW_AT_abstract_origin {{.*}} "b" +; Notice 'x's local variable 's' is missing. Not necessarily a bug here, +; since it's been optimized entirely away and it should be described in +; abstract subprogram. +; CHECK-NOT: DW_TAG +; CHECK: NULL +; CHECK-NOT: DW_TAG +; CHECK: NULL + +; CHECK: DW_TAG_subprogram +; CHECK-NOT: DW_TAG +; CHECK: DW_AT_name {{.*}} "a" +; CHECK-NOT: {{DW_TAG|NULL}} +; CHECK: DW_TAG_formal_parameter +; CHECK-NOT: {{DW_TAG|NULL}} +; CHECK: DW_TAG_inlined_subroutine +; CHECK-NOT: DW_TAG +; CHECK: DW_AT_abstract_origin {{.*}} {[[X_DECL]]} +; CHECK-NOT: {{DW_TAG|NULL}} +; FIXME: This formal parameter goes missing at least at -O2 (& on +; mips/powerpc), maybe before that. Perhaps SelectionDAG is to blame (and +; fastisel succeeds). +; CHECK: DW_TAG_formal_parameter +; CHECK-NOT: DW_TAG +; CHECK: DW_AT_abstract_origin {{.*}} "b" + +; CHECK-NOT: {{DW_TAG|NULL}} +; CHECK: DW_TAG_lexical_block +; CHECK-NOT: {{DW_TAG|NULL}} +; CHECK: DW_TAG_variable +; CHECK-NOT: DW_TAG +; CHECK: DW_AT_abstract_origin {{.*}} "s" + +@t = external global i32 + +; Function Attrs: uwtable +define void @_Z1bv() #0 { +entry: + tail call void @llvm.dbg.value(metadata i1 false, i64 0, metadata !25, metadata !DIExpression()), !dbg !27 + tail call void @_Z1fi(i32 0), !dbg !28 + ret void, !dbg !29 +} + +; Function Attrs: uwtable +define void @_Z1ab(i1 zeroext %u) #0 { +entry: + tail call void @llvm.dbg.value(metadata i1 %u, i64 0, metadata !13, metadata !DIExpression()), !dbg !30 + tail call void @llvm.dbg.value(metadata i1 %u, i64 0, metadata !31, metadata !DIExpression()), !dbg !33 + br i1 %u, label %if.then.i, label %_Z1xb.exit, !dbg !34 + +if.then.i: ; preds = %entry + %0 = load i32, i32* @t, align 4, !dbg !35, !tbaa !36 + tail call void @llvm.dbg.value(metadata i32 %0, i64 0, metadata !40, metadata !DIExpression()), !dbg !35 + tail call void @_Z1fi(i32 %0), !dbg !41 + br label %_Z1xb.exit, !dbg !42 + +_Z1xb.exit: ; preds = %entry, %if.then.i + tail call void @_Z1fi(i32 0), !dbg !43 + ret void, !dbg !44 +} + +declare void @_Z1fi(i32) #1 + +; Function Attrs: nounwind readnone +declare void @llvm.dbg.value(metadata, i64, metadata, metadata) #2 + +attributes #0 = { uwtable "less-precise-fpmad"="false" "no-frame-pointer-elim"="false" "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"="false" "no-infs-fp-math"="false" "no-nans-fp-math"="false" "stack-protector-buffer-size"="8" "unsafe-fp-math"="false" "use-soft-float"="false" } +attributes #2 = { nounwind readnone } + +!llvm.dbg.cu = !{!0} +!llvm.module.flags = !{!21, !22} +!llvm.ident = !{!23} + +!0 = distinct !DICompileUnit(language: DW_LANG_C_plus_plus, producer: "clang version 3.5.0 ", isOptimized: true, emissionKind: 1, file: !1, enums: !2, retainedTypes: !2, subprograms: !3, globals: !2, imports: !2) +!1 = !DIFile(filename: "missing-abstract-variables.cc", directory: "/tmp/dbginfo") +!2 = !{} +!3 = !{!4, !8, !14} +!4 = distinct !DISubprogram(name: "b", linkageName: "_Z1bv", line: 13, isLocal: false, isDefinition: true, virtualIndex: 6, flags: DIFlagPrototyped, isOptimized: true, scopeLine: 13, file: !1, scope: !5, type: !6, function: void ()* @_Z1bv, variables: !2) +!5 = !DIFile(filename: "missing-abstract-variables.cc", directory: "/tmp/dbginfo") +!6 = !DISubroutineType(types: !7) +!7 = !{null} +!8 = distinct !DISubprogram(name: "a", linkageName: "_Z1ab", line: 17, isLocal: false, isDefinition: true, virtualIndex: 6, flags: DIFlagPrototyped, isOptimized: true, scopeLine: 17, file: !1, scope: !5, type: !9, function: void (i1)* @_Z1ab, variables: !12) +!9 = !DISubroutineType(types: !10) +!10 = !{null, !11} +!11 = !DIBasicType(tag: DW_TAG_base_type, name: "bool", size: 8, align: 8, encoding: DW_ATE_boolean) +!12 = !{!13} +!13 = !DILocalVariable(name: "u", line: 17, arg: 1, scope: !8, file: !5, type: !11) +!14 = distinct !DISubprogram(name: "x", linkageName: "_Z1xb", line: 5, isLocal: false, isDefinition: true, virtualIndex: 6, flags: DIFlagPrototyped, isOptimized: true, scopeLine: 5, file: !1, scope: !5, type: !9, variables: !15) +!15 = !{!16, !17} +!16 = !DILocalVariable(name: "b", line: 5, arg: 1, scope: !14, file: !5, type: !11) +!17 = !DILocalVariable(name: "s", line: 7, scope: !18, file: !5, type: !20) +!18 = distinct !DILexicalBlock(line: 6, column: 0, file: !1, scope: !19) +!19 = distinct !DILexicalBlock(line: 6, column: 0, file: !1, scope: !14) +!20 = !DIBasicType(tag: DW_TAG_base_type, name: "int", size: 32, align: 32, encoding: DW_ATE_signed) +!21 = !{i32 2, !"Dwarf Version", i32 4} +!22 = !{i32 2, !"Debug Info Version", i32 3} +!23 = !{!"clang version 3.5.0 "} +!24 = !{i1 false} +!25 = !DILocalVariable(name: "b", line: 5, arg: 1, scope: !14, file: !5, type: !11) +!26 = !DILocation(line: 14, scope: !4) +!27 = !DILocation(line: 5, scope: !14, inlinedAt: !26) +!28 = !DILocation(line: 10, scope: !14, inlinedAt: !26) +!29 = !DILocation(line: 15, scope: !4) +!30 = !DILocation(line: 17, scope: !8) +!31 = !DILocalVariable(name: "b", line: 5, arg: 1, scope: !14, file: !5, type: !11) +!32 = !DILocation(line: 18, scope: !8) +!33 = !DILocation(line: 5, scope: !14, inlinedAt: !32) +!34 = !DILocation(line: 6, scope: !19, inlinedAt: !32) +!35 = !DILocation(line: 7, scope: !18, inlinedAt: !32) +!36 = !{!37, !37, i64 0} +!37 = !{!"int", !38, i64 0} +!38 = !{!"omnipotent char", !39, i64 0} +!39 = !{!"Simple C/C++ TBAA"} +!40 = !DILocalVariable(name: "s", line: 7, scope: !18, file: !5, type: !20) +!41 = !DILocation(line: 8, scope: !18, inlinedAt: !32) +!42 = !DILocation(line: 9, scope: !18, inlinedAt: !32) +!43 = !DILocation(line: 10, scope: !14, inlinedAt: !32) +!44 = !DILocation(line: 19, scope: !8) diff --git a/llvm/test/DebugInfo/Generic/multiline.ll b/llvm/test/DebugInfo/Generic/multiline.ll new file mode 100644 index 00000000000..aaad0326477 --- /dev/null +++ b/llvm/test/DebugInfo/Generic/multiline.ll @@ -0,0 +1,82 @@ +; RUN: llc -filetype=asm -asm-verbose=0 -O0 < %s | FileCheck %s +; RUN: llc -filetype=obj -O0 < %s | llvm-dwarfdump -debug-dump=line - | FileCheck %s --check-prefix=INT +; XFAIL: hexagon + +; Check that the assembly output properly handles is_stmt changes. And since +; we're testing anyway, check the integrated assembler too. + +; Generated with clang from multiline.c: +; void f1(); +; void f2() { +; f1(); f1(); f1(); +; f1(); f1(); f1(); +; } + + +; CHECK: .loc 1 2 0{{$}} +; CHECK-NOT: .loc{{ }} +; CHECK: .loc 1 3 3 prologue_end{{$}} +; CHECK-NOT: .loc +; CHECK: .loc 1 3 9 is_stmt 0{{$}} +; CHECK-NOT: .loc +; CHECK: .loc 1 3 15{{$}} +; CHECK-NOT: .loc +; CHECK: .loc 1 4 3 is_stmt 1{{$}} +; CHECK-NOT: .loc +; CHECK: .loc 1 4 9 is_stmt 0{{$}} +; CHECK-NOT: .loc +; CHECK: .loc 1 4 15{{$}} +; CHECK-NOT: .loc +; CHECK: .loc 1 5 1 is_stmt 1{{$}} + +; INT: {{^}}Address +; INT: ----- +; INT-NEXT: 2 0 1 0 0 is_stmt{{$}} +; INT-NEXT: 3 3 1 0 0 is_stmt prologue_end{{$}} +; INT-NEXT: 3 9 1 0 0 {{$}} +; INT-NEXT: 3 15 1 0 0 {{$}} +; INT-NEXT: 4 3 1 0 0 is_stmt{{$}} +; INT-NEXT: 4 9 1 0 0 {{$}} +; INT-NEXT: 4 15 1 0 0 {{$}} +; INT-NEXT: 5 1 1 0 0 is_stmt{{$}} + + +; Function Attrs: nounwind uwtable +define void @f2() #0 { +entry: + call void (...) @f1(), !dbg !11 + call void (...) @f1(), !dbg !12 + call void (...) @f1(), !dbg !13 + call void (...) @f1(), !dbg !14 + call void (...) @f1(), !dbg !15 + call void (...) @f1(), !dbg !16 + ret void, !dbg !17 +} + +declare void @f1(...) #1 + +attributes #0 = { nounwind 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 = !{!8, !9} +!llvm.ident = !{!10} + +!0 = distinct !DICompileUnit(language: DW_LANG_C99, producer: "clang version 3.6.0 (trunk 225000) (llvm/trunk 224999)", isOptimized: false, emissionKind: 1, file: !1, enums: !2, retainedTypes: !2, subprograms: !3, globals: !2, imports: !2) +!1 = !DIFile(filename: "multiline.c", directory: "/tmp/dbginfo") +!2 = !{} +!3 = !{!4} +!4 = distinct !DISubprogram(name: "f2", line: 2, isLocal: false, isDefinition: true, isOptimized: false, scopeLine: 2, file: !1, scope: !5, type: !6, function: void ()* @f2, variables: !2) +!5 = !DIFile(filename: "multiline.c", directory: "/tmp/dbginfo") +!6 = !DISubroutineType(types: !7) +!7 = !{null} +!8 = !{i32 2, !"Dwarf Version", i32 4} +!9 = !{i32 2, !"Debug Info Version", i32 3} +!10 = !{!"clang version 3.6.0 (trunk 225000) (llvm/trunk 224999)"} +!11 = !DILocation(line: 3, column: 3, scope: !4) +!12 = !DILocation(line: 3, column: 9, scope: !4) +!13 = !DILocation(line: 3, column: 15, scope: !4) +!14 = !DILocation(line: 4, column: 3, scope: !4) +!15 = !DILocation(line: 4, column: 9, scope: !4) +!16 = !DILocation(line: 4, column: 15, scope: !4) +!17 = !DILocation(line: 5, column: 1, scope: !4) diff --git a/llvm/test/DebugInfo/Generic/namespace.ll b/llvm/test/DebugInfo/Generic/namespace.ll new file mode 100644 index 00000000000..5554c9ff48e --- /dev/null +++ b/llvm/test/DebugInfo/Generic/namespace.ll @@ -0,0 +1,365 @@ +; REQUIRES: object-emission + +; RUN: %llc_dwarf -O0 -filetype=obj -dwarf-linkage-names=Enable < %s | llvm-dwarfdump - | FileCheck %s +; CHECK: debug_info contents +; CHECK: [[NS1:0x[0-9a-f]*]]:{{ *}}DW_TAG_namespace +; CHECK-NEXT: DW_AT_name{{.*}} = "A" +; CHECK-NEXT: DW_AT_decl_file{{.*}}([[F1:".*debug-info-namespace.cpp"]]) +; CHECK-NEXT: DW_AT_decl_line{{.*}}(5) +; CHECK-NOT: NULL +; CHECK: [[NS2:0x[0-9a-f]*]]:{{ *}}DW_TAG_namespace +; CHECK-NEXT: DW_AT_name{{.*}} = "B" +; CHECK-NEXT: DW_AT_decl_file{{.*}}([[F2:".*foo.cpp"]]) +; CHECK-NEXT: DW_AT_decl_line{{.*}}(1) +; CHECK-NOT: NULL +; CHECK: [[I:0x[0-9a-f]*]]:{{ *}}DW_TAG_variable +; CHECK-NEXT: DW_AT_name{{.*}}= "i" +; CHECK: [[VAR_FWD:0x[0-9a-f]*]]:{{ *}}DW_TAG_variable +; CHECK-NEXT: DW_AT_name{{.*}}= "var_fwd" +; CHECK-NOT: NULL +; CHECK: [[FOO:0x[0-9a-f]*]]:{{ *}}DW_TAG_structure_type +; CHECK-NEXT: DW_AT_name{{.*}}= "foo" +; CHECK-NEXT: DW_AT_declaration +; CHECK-NOT: NULL +; CHECK: [[BAR:0x[0-9a-f]*]]:{{ *}}DW_TAG_structure_type +; CHECK-NEXT: DW_AT_name{{.*}}= "bar" +; CHECK: [[FUNC1:.*]]: DW_TAG_subprogram +; CHECK-NOT: DW_TAG +; CHECK: DW_AT_MIPS_linkage_name +; CHECK-NOT: DW_TAG +; CHECK: DW_AT_name{{.*}}= "f1" +; CHECK: [[BAZ:0x[0-9a-f]*]]:{{.*}}DW_TAG_typedef +; CHECK-NOT: DW_TAG +; CHECK: DW_AT_name{{.*}}= "baz" +; CHECK: [[VAR_DECL:0x[0-9a-f]*]]:{{.*}}DW_TAG_variable +; CHECK-NOT: DW_TAG +; CHECK: DW_AT_name{{.*}}= "var_decl" +; CHECK-NOT: DW_TAG +; CHECK: DW_AT_declaration +; CHECK: [[FUNC_DECL:0x[0-9a-f]*]]:{{.*}}DW_TAG_subprogram +; CHECK-NOT: DW_TAG +; CHECK: DW_AT_name{{.*}}= "func_decl" +; CHECK-NOT: DW_TAG +; CHECK: DW_AT_declaration +; CHECK: [[FUNC_FWD:0x[0-9a-f]*]]:{{.*}}DW_TAG_subprogram +; CHECK-NOT: DW_TAG +; CHECK: DW_AT_name{{.*}}= "func_fwd" +; CHECK-NOT: DW_AT_declaration +; CHECK: DW_TAG_subprogram +; CHECK-NOT: DW_TAG +; CHECK: DW_AT_MIPS_linkage_name +; CHECK-NOT: DW_TAG +; CHECK: DW_AT_name{{.*}}= "f1" +; CHECK: NULL + +; CHECK-NOT: NULL +; CHECK: DW_TAG_imported_module +; This is a bug, it should be in F2 but it inherits the file from its +; enclosing scope +; CHECK-NEXT: DW_AT_decl_file{{.*}}([[F1]]) +; CHECK-NEXT: DW_AT_decl_line{{.*}}(15) +; CHECK-NEXT: DW_AT_import{{.*}}=> {[[NS2]]}) +; CHECK: NULL +; CHECK-NOT: NULL + +; CHECK: DW_TAG_imported_module +; Same bug as above, this should be F2, not F1 +; CHECK-NEXT: DW_AT_decl_file{{.*}}([[F1]]) +; CHECK-NEXT: DW_AT_decl_line{{.*}}(18) +; CHECK-NEXT: DW_AT_import{{.*}}=> {[[NS1]]}) +; CHECK-NOT: NULL + +; CHECK: DW_TAG_subprogram +; CHECK-NOT: DW_TAG +; CHECK: DW_AT_MIPS_linkage_name +; CHECK-NOT: DW_TAG +; CHECK: DW_AT_name{{.*}}= "func" +; CHECK-NOT: NULL +; CHECK: DW_TAG_imported_module +; CHECK-NEXT: DW_AT_decl_file{{.*}}([[F2]]) +; CHECK-NEXT: DW_AT_decl_line{{.*}}(26) +; CHECK-NEXT: DW_AT_import{{.*}}=> {[[NS1]]}) +; CHECK-NOT: NULL +; CHECK: DW_TAG_imported_declaration +; CHECK-NEXT: DW_AT_decl_file{{.*}}([[F2]]) +; CHECK-NEXT: DW_AT_decl_line{{.*}}(27) +; CHECK-NEXT: DW_AT_import{{.*}}=> {[[FOO]]}) +; CHECK-NOT: NULL +; CHECK: DW_TAG_imported_declaration +; CHECK-NEXT: DW_AT_decl_file{{.*}}([[F2]]) +; CHECK-NEXT: DW_AT_decl_line{{.*}}(28) +; CHECK-NEXT: DW_AT_import{{.*}}=> {[[BAR]]}) +; CHECK-NOT: NULL +; CHECK: DW_TAG_imported_declaration +; CHECK-NEXT: DW_AT_decl_file{{.*}}([[F2]]) +; CHECK-NEXT: DW_AT_decl_line{{.*}}(29) +; CHECK-NEXT: DW_AT_import{{.*}}=> {[[FUNC1]]}) +; CHECK-NOT: NULL +; CHECK: DW_TAG_imported_declaration +; CHECK-NEXT: DW_AT_decl_file{{.*}}([[F2]]) +; CHECK-NEXT: DW_AT_decl_line{{.*}}(30) +; CHECK-NEXT: DW_AT_import{{.*}}=> {[[I]]}) +; CHECK-NOT: NULL +; CHECK: DW_TAG_imported_declaration +; CHECK-NEXT: DW_AT_decl_file{{.*}}([[F2]]) +; CHECK-NEXT: DW_AT_decl_line{{.*}}(31) +; CHECK-NEXT: DW_AT_import{{.*}}=> {[[BAZ]]}) +; CHECK-NOT: NULL +; CHECK: [[X:0x[0-9a-f]*]]:{{ *}}DW_TAG_imported_declaration +; CHECK-NEXT: DW_AT_decl_file{{.*}}([[F2]]) +; CHECK-NEXT: DW_AT_decl_line{{.*}}(32) +; CHECK-NEXT: DW_AT_import{{.*}}=> {[[NS1]]}) +; CHECK-NEXT: DW_AT_name{{.*}}"X" +; CHECK-NOT: NULL +; CHECK: DW_TAG_imported_declaration +; CHECK-NEXT: DW_AT_decl_file{{.*}}([[F2]]) +; CHECK-NEXT: DW_AT_decl_line{{.*}}(33) +; CHECK-NEXT: DW_AT_import{{.*}}=> {[[X]]}) +; CHECK-NEXT: DW_AT_name{{.*}}"Y" +; CHECK-NOT: NULL +; CHECK: DW_TAG_imported_declaration +; CHECK-NEXT: DW_AT_decl_file{{.*}}([[F2]]) +; CHECK-NEXT: DW_AT_decl_line{{.*}}(34) +; CHECK-NEXT: DW_AT_import{{.*}}=> {[[VAR_DECL]]}) +; CHECK: DW_TAG_imported_declaration +; CHECK-NEXT: DW_AT_decl_file{{.*}}([[F2]]) +; CHECK-NEXT: DW_AT_decl_line{{.*}}(35) +; CHECK-NEXT: DW_AT_import{{.*}}=> {[[FUNC_DECL]]}) +; CHECK: DW_TAG_imported_declaration +; CHECK-NEXT: DW_AT_decl_file{{.*}}([[F2]]) +; CHECK-NEXT: DW_AT_decl_line{{.*}}(36) +; CHECK-NEXT: DW_AT_import{{.*}}=> {[[VAR_FWD]]}) +; CHECK: DW_TAG_imported_declaration +; CHECK-NEXT: DW_AT_decl_file{{.*}}([[F2]]) +; CHECK-NEXT: DW_AT_decl_line{{.*}}(37) +; CHECK-NEXT: DW_AT_import{{.*}}=> {[[FUNC_FWD]]}) + +; CHECK: DW_TAG_lexical_block +; CHECK-NOT: NULL +; CHECK: DW_TAG_imported_module +; CHECK-NEXT: DW_AT_decl_file{{.*}}([[F2]]) +; CHECK-NEXT: DW_AT_decl_line{{.*}}(23) +; CHECK-NEXT: DW_AT_import{{.*}}=> +; CHECK: NULL +; CHECK: NULL +; CHECK: NULL + +; IR generated from clang/test/CodeGenCXX/debug-info-namespace.cpp, file paths +; changed to protect the guilty. The C++ source code is: +; // RUN... +; // RUN... +; // RUN... +; +; namespace A { +; #line 1 "foo.cpp" +; namespace B { +; extern int i; +; int f1() { return 0; } +; void f1(int) { } +; struct foo; +; struct bar { }; +; typedef bar baz; +; extern int var_decl; +; void func_decl(void); +; extern int var_fwd; +; void func_fwd(void); +; } +; } +; namespace A { +; using namespace B; +; } +; +; using namespace A; +; namespace E = A; +; int B::i = f1(); +; int func(bool b) { +; if (b) { +; using namespace A::B; +; return i; +; } +; using namespace A; +; using B::foo; +; using B::bar; +; using B::f1; +; using B::i; +; using B::baz; +; namespace X = A; +; namespace Y = X; +; using B::var_decl; +; using B::func_decl; +; using B::var_fwd; +; using B::func_fwd; +; return i + X::B::i + Y::B::i; +; } +; +; namespace A { +; using B::i; +; namespace B { +; int var_fwd = i; +; } +; } +; void B::func_fwd() {} + +@_ZN1A1B1iE = global i32 0, align 4 +@_ZN1A1B7var_fwdE = global i32 0, align 4 +@llvm.global_ctors = appending global [1 x { i32, void ()*, i8* }] [{ i32, void ()*, i8* } { i32 65535, void ()* @_GLOBAL__sub_I_debug_info_namespace.cpp, i8* null }] + +; Function Attrs: nounwind ssp uwtable +define i32 @_ZN1A1B2f1Ev() #0 { +entry: + ret i32 0, !dbg !60 +} + +; Function Attrs: nounwind ssp uwtable +define void @_ZN1A1B2f1Ei(i32) #0 { +entry: + %.addr = alloca i32, align 4 + store i32 %0, i32* %.addr, align 4 + call void @llvm.dbg.declare(metadata i32* %.addr, metadata !61, metadata !62), !dbg !63 + ret void, !dbg !64 +} + +; Function Attrs: nounwind readnone +declare void @llvm.dbg.declare(metadata, metadata, metadata) #1 + +define internal void @__cxx_global_var_init() section "__TEXT,__StaticInit,regular,pure_instructions" { +entry: + %call = call i32 @_ZN1A1B2f1Ev(), !dbg !65 + store i32 %call, i32* @_ZN1A1B1iE, align 4, !dbg !65 + ret void, !dbg !65 +} + +; Function Attrs: nounwind ssp uwtable +define i32 @_Z4funcb(i1 zeroext %b) #0 { +entry: + %retval = alloca i32, align 4 + %b.addr = alloca i8, align 1 + %frombool = zext i1 %b to i8 + store i8 %frombool, i8* %b.addr, align 1 + call void @llvm.dbg.declare(metadata i8* %b.addr, metadata !66, metadata !62), !dbg !67 + %0 = load i8, i8* %b.addr, align 1, !dbg !68 + %tobool = trunc i8 %0 to i1, !dbg !68 + br i1 %tobool, label %if.then, label %if.end, !dbg !68 + +if.then: ; preds = %entry + %1 = load i32, i32* @_ZN1A1B1iE, align 4, !dbg !69 + store i32 %1, i32* %retval, !dbg !69 + br label %return, !dbg !69 + +if.end: ; preds = %entry + %2 = load i32, i32* @_ZN1A1B1iE, align 4, !dbg !70 + %3 = load i32, i32* @_ZN1A1B1iE, align 4, !dbg !70 + %add = add nsw i32 %2, %3, !dbg !70 + %4 = load i32, i32* @_ZN1A1B1iE, align 4, !dbg !70 + %add1 = add nsw i32 %add, %4, !dbg !70 + store i32 %add1, i32* %retval, !dbg !70 + br label %return, !dbg !70 + +return: ; preds = %if.end, %if.then + %5 = load i32, i32* %retval, !dbg !71 + ret i32 %5, !dbg !71 +} + +define internal void @__cxx_global_var_init1() section "__TEXT,__StaticInit,regular,pure_instructions" { +entry: + %0 = load i32, i32* @_ZN1A1B1iE, align 4, !dbg !72 + store i32 %0, i32* @_ZN1A1B7var_fwdE, align 4, !dbg !72 + ret void, !dbg !72 +} + +; Function Attrs: nounwind ssp uwtable +define void @_ZN1A1B8func_fwdEv() #0 { +entry: + ret void, !dbg !73 +} + +define internal void @_GLOBAL__sub_I_debug_info_namespace.cpp() section "__TEXT,__StaticInit,regular,pure_instructions" { +entry: + call void @__cxx_global_var_init(), !dbg !74 + call void @__cxx_global_var_init1(), !dbg !74 + ret void, !dbg !74 +} + +attributes #0 = { nounwind ssp 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 = { nounwind readnone } + +!llvm.dbg.cu = !{!0} +!llvm.module.flags = !{!57, !58} +!llvm.ident = !{!59} + +!0 = distinct !DICompileUnit(language: DW_LANG_C_plus_plus, producer: "clang version 3.6.0 ", isOptimized: false, emissionKind: 1, file: !1, enums: !2, retainedTypes: !3, subprograms: !9, globals: !30, imports: !33) +!1 = !DIFile(filename: "debug-info-namespace.cpp", directory: "/tmp") +!2 = !{} +!3 = !{!4, !8} +!4 = !DICompositeType(tag: DW_TAG_structure_type, name: "foo", line: 5, flags: DIFlagFwdDecl, file: !5, scope: !6, identifier: "_ZTSN1A1B3fooE") +!5 = !DIFile(filename: "foo.cpp", directory: "/tmp") +!6 = !DINamespace(name: "B", line: 1, file: !5, scope: !7) +!7 = !DINamespace(name: "A", line: 5, file: !1, scope: null) +!8 = !DICompositeType(tag: DW_TAG_structure_type, name: "bar", line: 6, size: 8, align: 8, file: !5, scope: !6, elements: !2, identifier: "_ZTSN1A1B3barE") +!9 = !{!10, !14, !17, !21, !25, !26, !27} +!10 = distinct !DISubprogram(name: "f1", linkageName: "_ZN1A1B2f1Ev", line: 3, isLocal: false, isDefinition: true, flags: DIFlagPrototyped, isOptimized: false, scopeLine: 3, file: !5, scope: !6, type: !11, function: i32 ()* @_ZN1A1B2f1Ev, variables: !2) +!11 = !DISubroutineType(types: !12) +!12 = !{!13} +!13 = !DIBasicType(tag: DW_TAG_base_type, name: "int", size: 32, align: 32, encoding: DW_ATE_signed) +!14 = distinct !DISubprogram(name: "f1", linkageName: "_ZN1A1B2f1Ei", line: 4, isLocal: false, isDefinition: true, flags: DIFlagPrototyped, isOptimized: false, scopeLine: 4, file: !5, scope: !6, type: !15, function: void (i32)* @_ZN1A1B2f1Ei, variables: !2) +!15 = !DISubroutineType(types: !16) +!16 = !{null, !13} +!17 = distinct !DISubprogram(name: "__cxx_global_var_init", line: 20, isLocal: true, isDefinition: true, flags: DIFlagPrototyped, isOptimized: false, scopeLine: 20, file: !5, scope: !18, type: !19, function: void ()* @__cxx_global_var_init, variables: !2) +!18 = !DIFile(filename: "foo.cpp", directory: "/tmp") +!19 = !DISubroutineType(types: !20) +!20 = !{null} +!21 = distinct !DISubprogram(name: "func", linkageName: "_Z4funcb", line: 21, isLocal: false, isDefinition: true, flags: DIFlagPrototyped, isOptimized: false, scopeLine: 21, file: !5, scope: !18, type: !22, function: i32 (i1)* @_Z4funcb, variables: !2) +!22 = !DISubroutineType(types: !23) +!23 = !{!13, !24} +!24 = !DIBasicType(tag: DW_TAG_base_type, name: "bool", size: 8, align: 8, encoding: DW_ATE_boolean) +!25 = distinct !DISubprogram(name: "__cxx_global_var_init1", line: 44, isLocal: true, isDefinition: true, flags: DIFlagPrototyped, isOptimized: false, scopeLine: 44, file: !5, scope: !18, type: !19, function: void ()* @__cxx_global_var_init1, variables: !2) +!26 = distinct !DISubprogram(name: "func_fwd", linkageName: "_ZN1A1B8func_fwdEv", line: 47, isLocal: false, isDefinition: true, flags: DIFlagPrototyped, isOptimized: false, scopeLine: 47, file: !5, scope: !6, type: !19, function: void ()* @_ZN1A1B8func_fwdEv, variables: !2) +!27 = distinct !DISubprogram(name: "", linkageName: "_GLOBAL__sub_I_debug_info_namespace.cpp", isLocal: true, isDefinition: true, flags: DIFlagArtificial, isOptimized: false, file: !1, scope: !28, type: !29, function: void ()* @_GLOBAL__sub_I_debug_info_namespace.cpp, variables: !2) +!28 = !DIFile(filename: "debug-info-namespace.cpp", directory: "/tmp") +!29 = !DISubroutineType(types: !2) +!30 = !{!31, !32} +!31 = !DIGlobalVariable(name: "i", linkageName: "_ZN1A1B1iE", line: 20, isLocal: false, isDefinition: true, scope: !6, file: !18, type: !13, variable: i32* @_ZN1A1B1iE) +!32 = !DIGlobalVariable(name: "var_fwd", linkageName: "_ZN1A1B7var_fwdE", line: 44, isLocal: false, isDefinition: true, scope: !6, file: !18, type: !13, variable: i32* @_ZN1A1B7var_fwdE) +!33 = !{!34, !35, !36, !37, !40, !41, !42, !43, !44, !45, !47, !48, !49, !51, !54, !55, !56} +!34 = !DIImportedEntity(tag: DW_TAG_imported_module, line: 15, scope: !7, entity: !6) +!35 = !DIImportedEntity(tag: DW_TAG_imported_module, line: 18, scope: !0, entity: !7) +!36 = !DIImportedEntity(tag: DW_TAG_imported_declaration, line: 19, name: "E", scope: !0, entity: !7) +!37 = !DIImportedEntity(tag: DW_TAG_imported_module, line: 23, scope: !38, entity: !6) +!38 = distinct !DILexicalBlock(line: 22, column: 10, file: !5, scope: !39) +!39 = distinct !DILexicalBlock(line: 22, column: 7, file: !5, scope: !21) +!40 = !DIImportedEntity(tag: DW_TAG_imported_module, line: 26, scope: !21, entity: !7) +!41 = !DIImportedEntity(tag: DW_TAG_imported_declaration, line: 27, scope: !21, entity: !"_ZTSN1A1B3fooE") +!42 = !DIImportedEntity(tag: DW_TAG_imported_declaration, line: 28, scope: !21, entity: !"_ZTSN1A1B3barE") +!43 = !DIImportedEntity(tag: DW_TAG_imported_declaration, line: 29, scope: !21, entity: !14) +!44 = !DIImportedEntity(tag: DW_TAG_imported_declaration, line: 30, scope: !21, entity: !31) +!45 = !DIImportedEntity(tag: DW_TAG_imported_declaration, line: 31, scope: !21, entity: !46) +!46 = !DIDerivedType(tag: DW_TAG_typedef, name: "baz", line: 7, file: !5, scope: !6, baseType: !"_ZTSN1A1B3barE") +!47 = !DIImportedEntity(tag: DW_TAG_imported_declaration, line: 32, name: "X", scope: !21, entity: !7) +!48 = !DIImportedEntity(tag: DW_TAG_imported_declaration, line: 33, name: "Y", scope: !21, entity: !47) +!49 = !DIImportedEntity(tag: DW_TAG_imported_declaration, line: 34, scope: !21, entity: !50) +!50 = !DIGlobalVariable(name: "var_decl", linkageName: "_ZN1A1B8var_declE", line: 8, isLocal: false, isDefinition: false, scope: !6, file: !18, type: !13) +!51 = !DIImportedEntity(tag: DW_TAG_imported_declaration, line: 35, scope: !21, entity: !52) +!52 = !DISubprogram(name: "func_decl", linkageName: "_ZN1A1B9func_declEv", line: 9, isLocal: false, isDefinition: false, flags: DIFlagPrototyped, isOptimized: false, file: !5, scope: !6, type: !19, variables: !53) +!53 = !{} ; previously: invalid DW_TAG_base_type +!54 = !DIImportedEntity(tag: DW_TAG_imported_declaration, line: 36, scope: !21, entity: !32) +!55 = !DIImportedEntity(tag: DW_TAG_imported_declaration, line: 37, scope: !21, entity: !26) +!56 = !DIImportedEntity(tag: DW_TAG_imported_declaration, line: 42, scope: !7, entity: !31) +!57 = !{i32 2, !"Dwarf Version", i32 2} +!58 = !{i32 2, !"Debug Info Version", i32 3} +!59 = !{!"clang version 3.6.0 "} +!60 = !DILocation(line: 3, column: 12, scope: !10) +!61 = !DILocalVariable(name: "", line: 4, arg: 1, scope: !14, file: !18, type: !13) +!62 = !DIExpression() +!63 = !DILocation(line: 4, column: 12, scope: !14) +!64 = !DILocation(line: 4, column: 16, scope: !14) +!65 = !DILocation(line: 20, column: 12, scope: !17) +!66 = !DILocalVariable(name: "b", line: 21, arg: 1, scope: !21, file: !18, type: !24) +!67 = !DILocation(line: 21, column: 15, scope: !21) +!68 = !DILocation(line: 22, column: 7, scope: !21) +!69 = !DILocation(line: 24, column: 5, scope: !38) +!70 = !DILocation(line: 38, column: 3, scope: !21) +!71 = !DILocation(line: 39, column: 1, scope: !21) +!72 = !DILocation(line: 44, column: 15, scope: !25) +!73 = !DILocation(line: 47, column: 21, scope: !26) +!74 = !DILocation(line: 0, scope: !75) +!75 = !DILexicalBlockFile(discriminator: 0, file: !5, scope: !27) diff --git a/llvm/test/DebugInfo/Generic/namespace_function_definition.ll b/llvm/test/DebugInfo/Generic/namespace_function_definition.ll new file mode 100644 index 00000000000..f7a34c1827d --- /dev/null +++ b/llvm/test/DebugInfo/Generic/namespace_function_definition.ll @@ -0,0 +1,44 @@ +; REQUIRES: object-emission + +; RUN: %llc_dwarf -O0 -filetype=obj -dwarf-linkage-names=Enable < %s | llvm-dwarfdump -debug-dump=info - | FileCheck %s + +; Generated from clang with the following source: +; namespace ns { +; void func() { +; } +; } + +; CHECK: DW_TAG_namespace +; CHECK-NEXT: DW_AT_name {{.*}} "ns" +; CHECK: DW_TAG_subprogram +; CHECK-NOT: DW_TAG +; CHECK: DW_AT_low_pc +; CHECK-NOT: DW_TAG +; CHECK: DW_AT_linkage_name {{.*}} "_ZN2ns4funcEv" +; CHECK: NULL +; CHECK: NULL + +; Function Attrs: nounwind uwtable +define void @_ZN2ns4funcEv() #0 { +entry: + ret void, !dbg !11 +} + +attributes #0 = { nounwind 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" } + +!llvm.dbg.cu = !{!0} +!llvm.module.flags = !{!8, !9} +!llvm.ident = !{!10} + +!0 = distinct !DICompileUnit(language: DW_LANG_C_plus_plus, producer: "clang version 3.5.0 ", isOptimized: false, emissionKind: 1, file: !1, enums: !2, retainedTypes: !2, subprograms: !3, globals: !2, imports: !2) +!1 = !DIFile(filename: "namespace_function_definition.cpp", directory: "/tmp/dbginfo") +!2 = !{} +!3 = !{!4} +!4 = distinct !DISubprogram(name: "func", linkageName: "_ZN2ns4funcEv", line: 2, isLocal: false, isDefinition: true, virtualIndex: 6, flags: DIFlagPrototyped, isOptimized: false, scopeLine: 2, file: !1, scope: !5, type: !6, function: void ()* @_ZN2ns4funcEv, variables: !2) +!5 = !DINamespace(name: "ns", line: 1, file: !1, scope: null) +!6 = !DISubroutineType(types: !7) +!7 = !{null} +!8 = !{i32 2, !"Dwarf Version", i32 4} +!9 = !{i32 1, !"Debug Info Version", i32 3} +!10 = !{!"clang version 3.5.0 "} +!11 = !DILocation(line: 3, scope: !4) diff --git a/llvm/test/DebugInfo/Generic/namespace_inline_function_definition.ll b/llvm/test/DebugInfo/Generic/namespace_inline_function_definition.ll new file mode 100644 index 00000000000..bc606198ce9 --- /dev/null +++ b/llvm/test/DebugInfo/Generic/namespace_inline_function_definition.ll @@ -0,0 +1,95 @@ +; REQUIRES: object-emission + +; RUN: %llc_dwarf -O0 -filetype=obj -dwarf-linkage-names=Enable < %s | llvm-dwarfdump -debug-dump=info - | FileCheck %s + +; Generate from clang with the following source. Note that the definition of +; the inline function follows its use to workaround another bug that should be +; fixed soon. +; namespace ns { +; int func(int i); +; } +; extern int x; +; int main() { return ns::func(x); } +; int __attribute__((always_inline)) ns::func(int i) { return i * 2; } + +; CHECK: DW_TAG_namespace +; CHECK-NEXT: DW_AT_name {{.*}} "ns" +; CHECK-NOT: DW_TAG +; CHECK: DW_TAG_subprogram +; CHECK-NOT: DW_TAG +; CHECK: DW_AT_linkage_name {{.*}} "_ZN2ns4funcEi" +; CHECK-NOT: DW_TAG +; CHECK: DW_TAG_formal_parameter +; CHECK: NULL +; CHECK-NOT: NULL +; CHECK: DW_TAG_subprogram +; CHECK-NOT: DW_TAG +; CHECK: DW_AT_abstract_origin {{.*}} "_ZN2ns4funcEi" +; CHECK-NOT: DW_TAG +; CHECK: DW_TAG_formal_parameter +; CHECK: DW_AT_abstract_origin {{.*}} "i" +; CHECK: NULL +; CHECK: NULL +; CHECK: NULL + +@x = external global i32 + +; Function Attrs: uwtable +define i32 @main() #0 { +entry: + %i.addr.i = alloca i32, align 4 + %retval = alloca i32, align 4 + store i32 0, i32* %retval + %0 = load i32, i32* @x, align 4, !dbg !16 + store i32 %0, i32* %i.addr.i, align 4 + call void @llvm.dbg.declare(metadata i32* %i.addr.i, metadata !117, metadata !DIExpression()), !dbg !18 + %1 = load i32, i32* %i.addr.i, align 4, !dbg !18 + %mul.i = mul nsw i32 %1, 2, !dbg !18 + ret i32 %mul.i, !dbg !16 +} + +; Function Attrs: alwaysinline nounwind uwtable +define i32 @_ZN2ns4funcEi(i32 %i) #1 { +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 !17, metadata !DIExpression()), !dbg !19 + %0 = load i32, i32* %i.addr, align 4, !dbg !19 + %mul = mul nsw i32 %0, 2, !dbg !19 + ret i32 %mul, !dbg !19 +} + +; Function Attrs: nounwind readnone +declare void @llvm.dbg.declare(metadata, metadata, metadata) #2 + +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 = { alwaysinline nounwind 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 #2 = { nounwind readnone } + +!llvm.dbg.cu = !{!0} +!llvm.module.flags = !{!13, !14} +!llvm.ident = !{!15} + +!0 = distinct !DICompileUnit(language: DW_LANG_C_plus_plus, producer: "clang version 3.5.0 ", isOptimized: false, emissionKind: 1, file: !1, enums: !2, retainedTypes: !2, subprograms: !3, globals: !2, imports: !2) +!1 = !DIFile(filename: "namespace_inline_function_definition.cpp", directory: "/tmp/dbginfo") +!2 = !{} +!3 = !{!4, !9} +!4 = distinct !DISubprogram(name: "main", line: 5, isLocal: false, isDefinition: true, virtualIndex: 6, flags: DIFlagPrototyped, isOptimized: false, scopeLine: 5, file: !1, scope: !5, type: !6, function: i32 ()* @main, variables: !2) +!5 = !DIFile(filename: "namespace_inline_function_definition.cpp", directory: "/tmp/dbginfo") +!6 = !DISubroutineType(types: !7) +!7 = !{!8} +!8 = !DIBasicType(tag: DW_TAG_base_type, name: "int", size: 32, align: 32, encoding: DW_ATE_signed) +!9 = distinct !DISubprogram(name: "func", linkageName: "_ZN2ns4funcEi", line: 6, isLocal: false, isDefinition: true, virtualIndex: 6, flags: DIFlagPrototyped, isOptimized: false, scopeLine: 6, file: !1, scope: !10, type: !11, function: i32 (i32)* @_ZN2ns4funcEi, variables: !2) +!10 = !DINamespace(name: "ns", line: 1, file: !1, scope: null) +!11 = !DISubroutineType(types: !12) +!12 = !{!8, !8} +!13 = !{i32 2, !"Dwarf Version", i32 4} +!14 = !{i32 2, !"Debug Info Version", i32 3} +!15 = !{!"clang version 3.5.0 "} +!16 = !DILocation(line: 5, scope: !4) +!17 = !DILocalVariable(name: "i", line: 6, arg: 1, scope: !9, file: !5, type: !8) + +!117 = !DILocalVariable(name: "i", line: 6, arg: 1, scope: !9, file: !5, type: !8) + +!18 = !DILocation(line: 6, scope: !9, inlinedAt: !16) +!19 = !DILocation(line: 6, scope: !9) diff --git a/llvm/test/DebugInfo/Generic/nodebug.ll b/llvm/test/DebugInfo/Generic/nodebug.ll new file mode 100644 index 00000000000..6f20aecaaf5 --- /dev/null +++ b/llvm/test/DebugInfo/Generic/nodebug.ll @@ -0,0 +1,51 @@ +; REQUIRES: object-emission + +; RUN: %llc_dwarf < %s -filetype=obj | llvm-dwarfdump -debug-dump=info - | FileCheck %s + +; Test that a nodebug function (a function not appearing in the debug info IR +; metadata subprogram list) with DebugLocs on its IR doesn't cause crashes/does +; the right thing. + +; Build with clang from the following: +; extern int i; +; inline __attribute__((always_inline)) void f1() { +; i = 3; +; } +; +; __attribute__((nodebug)) void f2() { +; f1(); +; } + +; Check that there's only one DW_TAG_subprogram, nothing for the 'f2' function. +; CHECK: DW_TAG_subprogram +; CHECK-NOT: DW_TAG +; CHECK: DW_AT_name {{.*}} "f1" +; CHECK-NOT: DW_TAG_subprogram + +@i = external global i32 + +; Function Attrs: uwtable +define void @_Z2f2v() #0 { +entry: + store i32 3, i32* @i, align 4, !dbg !11 + ret void +} + +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" } + +!llvm.dbg.cu = !{!0} +!llvm.module.flags = !{!8, !9} +!llvm.ident = !{!10} + +!0 = distinct !DICompileUnit(language: DW_LANG_C_plus_plus, producer: "clang version 3.5.0 ", isOptimized: false, emissionKind: 1, file: !1, enums: !2, retainedTypes: !2, subprograms: !3, globals: !2, imports: !2) +!1 = !DIFile(filename: "nodebug.cpp", directory: "/tmp/dbginfo") +!2 = !{} +!3 = !{!4} +!4 = distinct !DISubprogram(name: "f1", linkageName: "_Z2f1v", line: 2, isLocal: false, isDefinition: true, virtualIndex: 6, flags: DIFlagPrototyped, isOptimized: false, scopeLine: 2, file: !1, scope: !5, type: !6, variables: !2) +!5 = !DIFile(filename: "nodebug.cpp", directory: "/tmp/dbginfo") +!6 = !DISubroutineType(types: !7) +!7 = !{null} +!8 = !{i32 2, !"Dwarf Version", i32 4} +!9 = !{i32 2, !"Debug Info Version", i32 3} +!10 = !{!"clang version 3.5.0 "} +!11 = !DILocation(line: 3, scope: !4) diff --git a/llvm/test/DebugInfo/Generic/piece-verifier.ll b/llvm/test/DebugInfo/Generic/piece-verifier.ll new file mode 100644 index 00000000000..20d8e897e66 --- /dev/null +++ b/llvm/test/DebugInfo/Generic/piece-verifier.ll @@ -0,0 +1,56 @@ +; RUN: not llvm-as -disable-output < %s 2>&1 | FileCheck %s +target datalayout = "e-m:o-i64:64-f80:128-n8:16:32:64-S128" +target triple = "x86_64-apple-macosx10.9.0" + +; Function Attrs: nounwind ssp uwtable +define i32 @foo(i64 %s.coerce0, i32 %s.coerce1) #0 { +entry: + call void @llvm.dbg.value(metadata i64 %s.coerce0, i64 0, metadata !20, metadata !24), !dbg !21 + call void @llvm.dbg.value(metadata i32 %s.coerce1, i64 0, metadata !22, metadata !27), !dbg !21 + ret i32 %s.coerce1, !dbg !23 +} + +; Function Attrs: nounwind readnone +declare void @llvm.dbg.declare(metadata, metadata, metadata) #1 + +; Function Attrs: nounwind readnone +declare void @llvm.dbg.value(metadata, i64, metadata, metadata) #1 + +attributes #0 = { nounwind ssp uwtable "no-frame-pointer-elim"="true" "no-frame-pointer-elim-non-leaf" } +attributes #1 = { nounwind readnone } + +!llvm.dbg.cu = !{!0} +!llvm.module.flags = !{!17, !18} +!llvm.ident = !{!19} + +!0 = distinct !DICompileUnit(language: DW_LANG_C99, producer: "clang version 3.5 ", isOptimized: true, emissionKind: 1, file: !1, enums: !2, retainedTypes: !2, subprograms: !3, globals: !2, imports: !2) +!1 = !DIFile(filename: "pieces.c", directory: "") +!2 = !{} +!3 = !{!4} +!4 = distinct !DISubprogram(name: "foo", line: 3, isLocal: false, isDefinition: true, virtualIndex: 6, flags: DIFlagPrototyped, isOptimized: true, scopeLine: 3, file: !1, scope: !5, type: !6, function: i32 (i64, i32)* @foo, variables: !15) +!5 = !DIFile(filename: "pieces.c", directory: "") +!6 = !DISubroutineType(types: !7) +!7 = !{!8, !9} +!8 = !DIBasicType(tag: DW_TAG_base_type, name: "int", size: 32, align: 32, encoding: DW_ATE_signed) +!9 = !DIDerivedType(tag: DW_TAG_typedef, name: "S", line: 1, file: !1, baseType: !10) +!10 = !DICompositeType(tag: DW_TAG_structure_type, line: 1, size: 128, align: 64, file: !1, elements: !11) +!11 = !{!12, !14} +!12 = !DIDerivedType(tag: DW_TAG_member, name: "a", line: 1, size: 64, align: 64, file: !1, scope: !10, baseType: !13) +!13 = !DIBasicType(tag: DW_TAG_base_type, name: "long int", size: 64, align: 64, encoding: DW_ATE_signed) +!14 = !DIDerivedType(tag: DW_TAG_member, name: "b", line: 1, size: 32, align: 32, offset: 64, file: !1, scope: !10, baseType: !8) +!15 = !{!16} +!16 = !DILocalVariable(name: "s", line: 3, arg: 1, scope: !4, file: !5, type: !9) +!17 = !{i32 2, !"Dwarf Version", i32 4} +!18 = !{i32 1, !"Debug Info Version", i32 3} +!19 = !{!"clang version 3.5 "} +!20 = !DILocalVariable(name: "s", line: 3, arg: 1, scope: !4, file: !5, type: !9) +!21 = !DILocation(line: 3, scope: !4) +!22 = !DILocalVariable(name: "s", line: 3, arg: 1, scope: !4, file: !5, type: !9) +!23 = !DILocation(line: 4, scope: !4) +!24 = !DIExpression(DW_OP_deref, DW_OP_bit_piece, 0, 64) +!25 = !{} +; This expression has elements after DW_OP_bit_piece. +; CHECK: invalid expression +; CHECK-NEXT: !DIExpression({{[0-9]+}}, 64, 32, {{[0-9]+}}) +; CHECK-NOT: invalid expression +!27 = !DIExpression(DW_OP_bit_piece, 64, 32, DW_OP_deref) diff --git a/llvm/test/DebugInfo/Generic/recursive_inlining.ll b/llvm/test/DebugInfo/Generic/recursive_inlining.ll new file mode 100644 index 00000000000..c1fc70b689b --- /dev/null +++ b/llvm/test/DebugInfo/Generic/recursive_inlining.ll @@ -0,0 +1,275 @@ +; REQUIRES: object-emission + +; RUN: %llc_dwarf -filetype=obj -O0 < %s | llvm-dwarfdump -debug-dump=info - | FileCheck %s + +; This isn't a very pretty test case - I imagine there might be other ways to +; tickle the optimizers into producing the desired code, but I haven't found +; them. + +; The issue is when a function is inlined into itself, the inlined argument +; accidentally overwrote the concrete argument and was lost. + +; IR generated from the following source compiled with clang -g: +; void fn1(void *); +; void fn2(int, int, int, int); +; void fn3(); +; void fn8(); +; struct C { +; int b; +; void m_fn2() { +; fn8(); +; if (b) fn2(0, 0, 0, 0); +; fn3(); +; } +; }; +; C *x; +; inline void fn7() {} +; void fn6() { +; fn8(); +; x->m_fn2(); +; fn7(); +; } +; void fn3() { fn6(); } +; void fn4() { x->m_fn2(); } +; void fn5() { x->m_fn2(); } + +; The definition of C and declaration of C::m_fn2 +; CHECK: DW_TAG_structure_type +; CHECK-NOT: {{DW_TAG|NULL}} +; CHECK: DW_TAG_member +; CHECK-NOT: {{DW_TAG|NULL}} +; CHECK: [[M_FN2_DECL:.*]]: DW_TAG_subprogram +; CHECK-NOT: DW_TAG +; CHECK: DW_AT_name {{.*}} "m_fn2" +; CHECK-NOT: {{DW_TAG|NULL}} +; CHECK: DW_TAG_formal_parameter + +; The abstract definition of C::m_fn2 +; CHECK: [[M_FN2_ABS_DEF:.*]]: DW_TAG_subprogram +; CHECK-NOT: DW_TAG +; CHECK: DW_AT_specification {{.*}} {[[M_FN2_DECL]]} +; CHECK-NOT: DW_TAG +; CHECK: DW_AT_inline +; CHECK-NOT: {{DW_TAG|NULL}} +; CHECK: [[M_FN2_THIS_ABS_DEF:.*]]: DW_TAG_formal_parameter +; CHECK-NOT: DW_TAG +; CHECK: DW_AT_name {{.*}} "this" + +; Skip some other functions +; CHECK: DW_TAG_subprogram +; CHECK: DW_TAG_subprogram +; CHECK: DW_TAG_subprogram + +; The concrete definition of C::m_fn2 +; CHECK: DW_TAG_subprogram +; CHECK-NOT: DW_TAG +; CHECK: DW_AT_abstract_origin {{.*}} {[[M_FN2_ABS_DEF]]} +; CHECK-NOT: {{DW_TAG|NULL}} +; CHECK: DW_TAG_formal_parameter +; CHECK-NOT: DW_TAG +; CHECK: DW_AT_abstract_origin {{.*}} {[[M_FN2_THIS_ABS_DEF]]} +; CHECK-NOT: {{DW_TAG|NULL}} +; Inlined fn3: +; CHECK: DW_TAG_inlined_subroutine +; CHECK-NOT: {{DW_TAG|NULL}} +; Inlined fn6: +; CHECK: DW_TAG_inlined_subroutine +; CHECK-NOT: {{DW_TAG|NULL}} +; Inlined C::m_fn2: +; CHECK: DW_TAG_inlined_subroutine +; CHECK-NOT: DW_TAG +; CHECK: DW_AT_abstract_origin {{.*}} {[[M_FN2_ABS_DEF]]} +; CHECK-NOT: {{DW_TAG|NULL}} +; CHECK: DW_TAG_formal_parameter +; CHECK-NOT: DW_TAG +; CHECK: DW_AT_abstract_origin {{.*}} {[[M_FN2_THIS_ABS_DEF]]} + + + +%struct.C = type { i32 } + +@x = global %struct.C* null, align 8 + +; Function Attrs: nounwind +define void @_Z3fn6v() #0 { +entry: + tail call void @_Z3fn8v() #3, !dbg !31 + %0 = load %struct.C*, %struct.C** @x, align 8, !dbg !32, !tbaa !33 + tail call void @llvm.dbg.value(metadata %struct.C* %0, i64 0, metadata !37, metadata !DIExpression()) #3, !dbg !38 + tail call void @_Z3fn8v() #3, !dbg !39 + %b.i = getelementptr inbounds %struct.C, %struct.C* %0, i64 0, i32 0, !dbg !40 + %1 = load i32, i32* %b.i, align 4, !dbg !40, !tbaa !42 + %tobool.i = icmp eq i32 %1, 0, !dbg !40 + br i1 %tobool.i, label %_ZN1C5m_fn2Ev.exit, label %if.then.i, !dbg !40 + +if.then.i: ; preds = %entry + tail call void @_Z3fn2iiii(i32 0, i32 0, i32 0, i32 0) #3, !dbg !45 + br label %_ZN1C5m_fn2Ev.exit, !dbg !45 + +_ZN1C5m_fn2Ev.exit: ; preds = %entry, %if.then.i + tail call void @_Z3fn3v() #3, !dbg !47 + ret void, !dbg !48 +} + +declare void @_Z3fn8v() #1 + +; Function Attrs: nounwind +define linkonce_odr void @_ZN1C5m_fn2Ev(%struct.C* nocapture readonly %this) #0 align 2 { +entry: + tail call void @llvm.dbg.value(metadata %struct.C* %this, i64 0, metadata !24, metadata !DIExpression()), !dbg !49 + tail call void @_Z3fn8v() #3, !dbg !50 + %b = getelementptr inbounds %struct.C, %struct.C* %this, i64 0, i32 0, !dbg !51 + %0 = load i32, i32* %b, align 4, !dbg !51, !tbaa !42 + %tobool = icmp eq i32 %0, 0, !dbg !51 + br i1 %tobool, label %if.end, label %if.then, !dbg !51 + +if.then: ; preds = %entry + tail call void @_Z3fn2iiii(i32 0, i32 0, i32 0, i32 0) #3, !dbg !52 + br label %if.end, !dbg !52 + +if.end: ; preds = %entry, %if.then + tail call void @_Z3fn8v() #3, !dbg !53 + %1 = load %struct.C*, %struct.C** @x, align 8, !dbg !56, !tbaa !33 + tail call void @llvm.dbg.value(metadata %struct.C* %1, i64 0, metadata !57, metadata !DIExpression()) #3, !dbg !58 + tail call void @_Z3fn8v() #3, !dbg !59 + %b.i.i = getelementptr inbounds %struct.C, %struct.C* %1, i64 0, i32 0, !dbg !60 + %2 = load i32, i32* %b.i.i, align 4, !dbg !60, !tbaa !42 + %tobool.i.i = icmp eq i32 %2, 0, !dbg !60 + br i1 %tobool.i.i, label %_Z3fn6v.exit, label %if.then.i.i, !dbg !60 + +if.then.i.i: ; preds = %if.end + tail call void @_Z3fn2iiii(i32 0, i32 0, i32 0, i32 0) #3, !dbg !61 + br label %_Z3fn6v.exit, !dbg !61 + +_Z3fn6v.exit: ; preds = %if.end, %if.then.i.i + tail call void @_Z3fn3v() #3, !dbg !62 + ret void, !dbg !63 +} + +; Function Attrs: nounwind +define void @_Z3fn3v() #0 { +entry: + br label %tailrecurse + +tailrecurse: ; preds = %tailrecurse.backedge, %entry + tail call void @_Z3fn8v() #3, !dbg !64 + %0 = load %struct.C*, %struct.C** @x, align 8, !dbg !66, !tbaa !33 + tail call void @llvm.dbg.value(metadata %struct.C* %0, i64 0, metadata !67, metadata !DIExpression()) #3, !dbg !68 + tail call void @_Z3fn8v() #3, !dbg !69 + %b.i.i = getelementptr inbounds %struct.C, %struct.C* %0, i64 0, i32 0, !dbg !70 + %1 = load i32, i32* %b.i.i, align 4, !dbg !70, !tbaa !42 + %tobool.i.i = icmp eq i32 %1, 0, !dbg !70 + br i1 %tobool.i.i, label %tailrecurse.backedge, label %if.then.i.i, !dbg !70 + +tailrecurse.backedge: ; preds = %tailrecurse, %if.then.i.i + br label %tailrecurse + +if.then.i.i: ; preds = %tailrecurse + tail call void @_Z3fn2iiii(i32 0, i32 0, i32 0, i32 0) #3, !dbg !71 + br label %tailrecurse.backedge, !dbg !71 +} + +; Function Attrs: nounwind +define void @_Z3fn4v() #0 { +entry: + %0 = load %struct.C*, %struct.C** @x, align 8, !dbg !72, !tbaa !33 + tail call void @_ZN1C5m_fn2Ev(%struct.C* %0), !dbg !72 + ret void, !dbg !72 +} + +; Function Attrs: nounwind +define void @_Z3fn5v() #0 { +entry: + %0 = load %struct.C*, %struct.C** @x, align 8, !dbg !73, !tbaa !33 + tail call void @_ZN1C5m_fn2Ev(%struct.C* %0), !dbg !73 + ret void, !dbg !73 +} + +declare void @_Z3fn2iiii(i32, i32, i32, i32) #1 + +; Function Attrs: nounwind readnone +declare void @llvm.dbg.value(metadata, i64, metadata, metadata) #2 + +attributes #0 = { nounwind "less-precise-fpmad"="false" "no-frame-pointer-elim"="false" "no-infs-fp-math"="false" "no-nans-fp-math"="false" "no-realign-stack" "stack-protector-buffer-size"="8" "unsafe-fp-math"="false" "use-soft-float"="false" } +attributes #1 = { "less-precise-fpmad"="false" "no-frame-pointer-elim"="false" "no-infs-fp-math"="false" "no-nans-fp-math"="false" "no-realign-stack" "stack-protector-buffer-size"="8" "unsafe-fp-math"="false" "use-soft-float"="false" } +attributes #2 = { nounwind readnone } +attributes #3 = { nounwind } + +!llvm.dbg.cu = !{!0} +!llvm.module.flags = !{!28, !29} +!llvm.ident = !{!30} + +!0 = distinct !DICompileUnit(language: DW_LANG_C_plus_plus, producer: "clang version 3.6.0 ", isOptimized: true, emissionKind: 1, file: !1, enums: !2, retainedTypes: !3, subprograms: !13, globals: !26, imports: !2) +!1 = !DIFile(filename: "<stdin>", directory: "/usr/local/google/home/blaikie/dev/scratch/missing_concrete_variable_on_darwin/reduce") +!2 = !{} +!3 = !{!4} +!4 = !DICompositeType(tag: DW_TAG_structure_type, name: "C", line: 5, size: 32, align: 32, file: !5, elements: !6, identifier: "_ZTS1C") +!5 = !DIFile(filename: "recursive_inlining.cpp", directory: "/usr/local/google/home/blaikie/dev/scratch/missing_concrete_variable_on_darwin/reduce") +!6 = !{!7, !9} +!7 = !DIDerivedType(tag: DW_TAG_member, name: "b", line: 6, size: 32, align: 32, file: !5, scope: !"_ZTS1C", baseType: !8) +!8 = !DIBasicType(tag: DW_TAG_base_type, name: "int", size: 32, align: 32, encoding: DW_ATE_signed) +!9 = !DISubprogram(name: "m_fn2", linkageName: "_ZN1C5m_fn2Ev", line: 7, isLocal: false, isDefinition: false, virtualIndex: 6, flags: DIFlagPrototyped, isOptimized: true, scopeLine: 7, file: !5, scope: !"_ZTS1C", type: !10) +!10 = !DISubroutineType(types: !11) +!11 = !{null, !12} +!12 = !DIDerivedType(tag: DW_TAG_pointer_type, size: 64, align: 64, flags: DIFlagArtificial | DIFlagObjectPointer, baseType: !"_ZTS1C") +!13 = !{!14, !18, !19, !20, !21, !22} +!14 = distinct !DISubprogram(name: "fn6", linkageName: "_Z3fn6v", line: 15, isLocal: false, isDefinition: true, virtualIndex: 6, flags: DIFlagPrototyped, isOptimized: true, scopeLine: 15, file: !5, scope: !15, type: !16, function: void ()* @_Z3fn6v, variables: !2) +!15 = !DIFile(filename: "recursive_inlining.cpp", directory: "/usr/local/google/home/blaikie/dev/scratch/missing_concrete_variable_on_darwin/reduce") +!16 = !DISubroutineType(types: !17) +!17 = !{null} +!18 = distinct !DISubprogram(name: "fn3", linkageName: "_Z3fn3v", line: 20, isLocal: false, isDefinition: true, virtualIndex: 6, flags: DIFlagPrototyped, isOptimized: true, scopeLine: 20, file: !5, scope: !15, type: !16, function: void ()* @_Z3fn3v, variables: !2) +!19 = distinct !DISubprogram(name: "fn4", linkageName: "_Z3fn4v", line: 21, isLocal: false, isDefinition: true, virtualIndex: 6, flags: DIFlagPrototyped, isOptimized: true, scopeLine: 21, file: !5, scope: !15, type: !16, function: void ()* @_Z3fn4v, variables: !2) +!20 = distinct !DISubprogram(name: "fn5", linkageName: "_Z3fn5v", line: 22, isLocal: false, isDefinition: true, virtualIndex: 6, flags: DIFlagPrototyped, isOptimized: true, scopeLine: 22, file: !5, scope: !15, type: !16, function: void ()* @_Z3fn5v, variables: !2) +!21 = distinct !DISubprogram(name: "fn7", linkageName: "_Z3fn7v", line: 14, isLocal: false, isDefinition: true, virtualIndex: 6, flags: DIFlagPrototyped, isOptimized: true, scopeLine: 14, file: !5, scope: !15, type: !16, variables: !2) +!22 = distinct !DISubprogram(name: "m_fn2", linkageName: "_ZN1C5m_fn2Ev", line: 7, isLocal: false, isDefinition: true, virtualIndex: 6, flags: DIFlagPrototyped, isOptimized: true, scopeLine: 7, file: !5, scope: !"_ZTS1C", type: !10, function: void (%struct.C*)* @_ZN1C5m_fn2Ev, declaration: !9, variables: !23) +!23 = !{!24} +!24 = !DILocalVariable(name: "this", arg: 1, flags: DIFlagArtificial | DIFlagObjectPointer, scope: !22, type: !25) +!25 = !DIDerivedType(tag: DW_TAG_pointer_type, size: 64, align: 64, baseType: !"_ZTS1C") +!26 = !{!27} +!27 = !DIGlobalVariable(name: "x", line: 13, isLocal: false, isDefinition: true, scope: null, file: !15, type: !25, variable: %struct.C** @x) +!28 = !{i32 2, !"Dwarf Version", i32 4} +!29 = !{i32 2, !"Debug Info Version", i32 3} +!30 = !{!"clang version 3.6.0 "} +!31 = !DILocation(line: 16, scope: !14) +!32 = !DILocation(line: 17, scope: !14) +!33 = !{!34, !34, i64 0} +!34 = !{!"any pointer", !35, i64 0} +!35 = !{!"omnipotent char", !36, i64 0} +!36 = !{!"Simple C/C++ TBAA"} +!37 = !DILocalVariable(name: "this", arg: 1, flags: DIFlagArtificial | DIFlagObjectPointer, scope: !22, type: !25) +!38 = !DILocation(line: 0, scope: !22, inlinedAt: !32) +!39 = !DILocation(line: 8, scope: !22, inlinedAt: !32) +!40 = !DILocation(line: 9, scope: !41, inlinedAt: !32) +!41 = distinct !DILexicalBlock(line: 9, column: 0, file: !5, scope: !22) +!42 = !{!43, !44, i64 0} +!43 = !{!"_ZTS1C", !44, i64 0} +!44 = !{!"int", !35, i64 0} +!45 = !DILocation(line: 9, scope: !46, inlinedAt: !32) +!46 = distinct !DILexicalBlock(line: 9, column: 0, file: !5, scope: !41) +!47 = !DILocation(line: 10, scope: !22, inlinedAt: !32) +!48 = !DILocation(line: 19, scope: !14) +!49 = !DILocation(line: 0, scope: !22) +!50 = !DILocation(line: 8, scope: !22) +!51 = !DILocation(line: 9, scope: !41) +!52 = !DILocation(line: 9, scope: !46) +!53 = !DILocation(line: 16, scope: !14, inlinedAt: !54) +!54 = !DILocation(line: 20, scope: !18, inlinedAt: !55) +!55 = !DILocation(line: 10, scope: !22) +!56 = !DILocation(line: 17, scope: !14, inlinedAt: !54) +!57 = !DILocalVariable(name: "this", arg: 1, flags: DIFlagArtificial | DIFlagObjectPointer, scope: !22, type: !25) +!58 = !DILocation(line: 0, scope: !22, inlinedAt: !56) +!59 = !DILocation(line: 8, scope: !22, inlinedAt: !56) +!60 = !DILocation(line: 9, scope: !41, inlinedAt: !56) +!61 = !DILocation(line: 9, scope: !46, inlinedAt: !56) +!62 = !DILocation(line: 10, scope: !22, inlinedAt: !56) +!63 = !DILocation(line: 11, scope: !22) +!64 = !DILocation(line: 16, scope: !14, inlinedAt: !65) +!65 = !DILocation(line: 20, scope: !18) +!66 = !DILocation(line: 17, scope: !14, inlinedAt: !65) +!67 = !DILocalVariable(name: "this", arg: 1, flags: DIFlagArtificial | DIFlagObjectPointer, scope: !22, type: !25) +!68 = !DILocation(line: 0, scope: !22, inlinedAt: !66) +!69 = !DILocation(line: 8, scope: !22, inlinedAt: !66) +!70 = !DILocation(line: 9, scope: !41, inlinedAt: !66) +!71 = !DILocation(line: 9, scope: !46, inlinedAt: !66) +!72 = !DILocation(line: 21, scope: !19) +!73 = !DILocation(line: 22, scope: !20) diff --git a/llvm/test/DebugInfo/Generic/restrict.ll b/llvm/test/DebugInfo/Generic/restrict.ll new file mode 100644 index 00000000000..49401712ccd --- /dev/null +++ b/llvm/test/DebugInfo/Generic/restrict.ll @@ -0,0 +1,53 @@ +; REQUIRES: object-emission + +; RUN: %llc_dwarf -dwarf-version=2 -O0 -filetype=obj < %s | llvm-dwarfdump -debug-dump=info - | FileCheck --check-prefix=CHECK --check-prefix=V2 %s +; RUN: %llc_dwarf -dwarf-version=3 -O0 -filetype=obj < %s | llvm-dwarfdump -debug-dump=info - | FileCheck --check-prefix=CHECK --check-prefix=V3 %s + +; CHECK: DW_AT_name {{.*}} "dst" +; V2: DW_AT_type {{.*}} {[[PTR:0x.*]]} +; V3: DW_AT_type {{.*}} {[[RESTRICT:0x.*]]} +; V3: [[RESTRICT]]: {{.*}}DW_TAG_restrict_type +; V3-NEXT: DW_AT_type {{.*}} {[[PTR:0x.*]]} +; CHECK: [[PTR]]: {{.*}}DW_TAG_pointer_type +; CHECK-NOT: DW_AT_type + +; Generated with clang from: +; void foo(void* __restrict__ dst) { +; } + + +; Function Attrs: nounwind uwtable +define void @_Z3fooPv(i8* noalias %dst) #0 { +entry: + %dst.addr = alloca i8*, align 8 + store i8* %dst, i8** %dst.addr, align 8 + call void @llvm.dbg.declare(metadata i8** %dst.addr, metadata !13, metadata !DIExpression()), !dbg !14 + ret void, !dbg !15 +} + +; Function Attrs: nounwind readnone +declare void @llvm.dbg.declare(metadata, metadata, metadata) #1 + +attributes #0 = { nounwind 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 = { nounwind readnone } + +!llvm.dbg.cu = !{!0} +!llvm.module.flags = !{!10, !11} +!llvm.ident = !{!12} + +!0 = distinct !DICompileUnit(language: DW_LANG_C_plus_plus, producer: "clang version 3.5.0 ", isOptimized: false, emissionKind: 1, file: !1, enums: !2, retainedTypes: !2, subprograms: !3, globals: !2, imports: !2) +!1 = !DIFile(filename: "restrict.c", directory: "/tmp/dbginfo") +!2 = !{} +!3 = !{!4} +!4 = distinct !DISubprogram(name: "foo", linkageName: "_Z3fooPv", line: 1, isLocal: false, isDefinition: true, virtualIndex: 6, flags: DIFlagPrototyped, isOptimized: false, scopeLine: 1, file: !1, scope: !5, type: !6, function: void (i8*)* @_Z3fooPv, variables: !2) +!5 = !DIFile(filename: "restrict.c", directory: "/tmp/dbginfo") +!6 = !DISubroutineType(types: !7) +!7 = !{null, !8} +!8 = !DIDerivedType(tag: DW_TAG_restrict_type, baseType: !9) +!9 = !DIDerivedType(tag: DW_TAG_pointer_type, size: 64, align: 64, baseType: null) +!10 = !{i32 2, !"Dwarf Version", i32 4} +!11 = !{i32 1, !"Debug Info Version", i32 3} +!12 = !{!"clang version 3.5.0 "} +!13 = !DILocalVariable(name: "dst", line: 1, arg: 1, scope: !4, file: !5, type: !8) +!14 = !DILocation(line: 1, scope: !4) +!15 = !DILocation(line: 2, scope: !4) diff --git a/llvm/test/DebugInfo/Generic/skeletoncu.ll b/llvm/test/DebugInfo/Generic/skeletoncu.ll new file mode 100644 index 00000000000..74ffec4519e --- /dev/null +++ b/llvm/test/DebugInfo/Generic/skeletoncu.ll @@ -0,0 +1,15 @@ +; RUN: %llc_dwarf %s -filetype=obj -o %t +; RUN: llvm-dwarfdump -debug-dump=info %t | FileCheck %s +; CHECK: DW_TAG_compile_unit +; CHECK: DW_AT_GNU_dwo_id {{.*}}abcd +; CHECK: DW_AT_GNU_dwo_name {{.*}}"my.dwo" + +!llvm.dbg.cu = !{!0} +!llvm.module.flags = !{!3, !4} + +!0 = distinct !DICompileUnit(language: DW_LANG_C99, file: !1, producer: "LLVM", isOptimized: false, runtimeVersion: 2, splitDebugFilename: "my.dwo", emissionKind: 1, enums: !2, retainedTypes: !2, subprograms: !2, globals: !2, imports: !2, dwoId: 43981) +!1 = !DIFile(filename: "<stdin>", directory: "/") +!2 = !{} +!3 = !{i32 2, !"Dwarf Version", i32 4} +!4 = !{i32 2, !"Debug Info Version", i32 3} + diff --git a/llvm/test/DebugInfo/Generic/sugared-constants.ll b/llvm/test/DebugInfo/Generic/sugared-constants.ll new file mode 100644 index 00000000000..7a344736e43 --- /dev/null +++ b/llvm/test/DebugInfo/Generic/sugared-constants.ll @@ -0,0 +1,82 @@ +; REQUIRES: object-emission + +; RUN: %llc_dwarf -O0 -filetype=obj %s -o - | llvm-dwarfdump -debug-dump=info - | FileCheck %s +; Use correct signedness when emitting constants of derived (sugared) types. + +; Test compiled to IR from clang with -O1 and the following source: + +; void func(int); +; void func(unsigned); +; void func(char16_t); +; int main() { +; const int i = 42; +; func(i); +; const unsigned j = 117; +; func(j); +; char16_t c = 7; +; func(c); +; } + +; CHECK: DW_AT_const_value [DW_FORM_sdata] (42) +; CHECK: DW_AT_const_value [DW_FORM_udata] (117) +; CHECK: DW_AT_const_value [DW_FORM_udata] (7) + +; Function Attrs: uwtable +define i32 @main() #0 { +entry: + tail call void @llvm.dbg.value(metadata i32 42, i64 0, metadata !10, metadata !DIExpression()), !dbg !21 + tail call void @_Z4funci(i32 42), !dbg !22 + tail call void @llvm.dbg.value(metadata i32 117, i64 0, metadata !12, metadata !DIExpression()), !dbg !24 + tail call void @_Z4funcj(i32 117), !dbg !25 + tail call void @llvm.dbg.value(metadata i16 7, i64 0, metadata !15, metadata !DIExpression()), !dbg !27 + tail call void @_Z4funcDs(i16 zeroext 7), !dbg !28 + ret i32 0, !dbg !29 +} + +declare void @_Z4funci(i32) #1 + +declare void @_Z4funcj(i32) #1 + +declare void @_Z4funcDs(i16 zeroext) #1 + +; Function Attrs: nounwind readnone +declare void @llvm.dbg.value(metadata, i64, metadata, metadata) #2 + +attributes #0 = { uwtable "less-precise-fpmad"="false" "no-frame-pointer-elim"="false" "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"="false" "no-infs-fp-math"="false" "no-nans-fp-math"="false" "stack-protector-buffer-size"="8" "unsafe-fp-math"="false" "use-soft-float"="false" } +attributes #2 = { nounwind readnone } + +!llvm.dbg.cu = !{!0} +!llvm.module.flags = !{!17, !18} +!llvm.ident = !{!19} + +!0 = distinct !DICompileUnit(language: DW_LANG_C_plus_plus, producer: "clang version 3.5.0 ", isOptimized: true, emissionKind: 1, file: !1, enums: !2, retainedTypes: !2, subprograms: !3, globals: !2, imports: !2) +!1 = !DIFile(filename: "const.cpp", directory: "/tmp/dbginfo") +!2 = !{} +!3 = !{!4} +!4 = distinct !DISubprogram(name: "main", line: 4, isLocal: false, isDefinition: true, virtualIndex: 6, flags: DIFlagPrototyped, isOptimized: true, scopeLine: 4, file: !1, scope: !5, type: !6, function: i32 ()* @main, variables: !9) +!5 = !DIFile(filename: "const.cpp", directory: "/tmp/dbginfo") +!6 = !DISubroutineType(types: !7) +!7 = !{!8} +!8 = !DIBasicType(tag: DW_TAG_base_type, name: "int", size: 32, align: 32, encoding: DW_ATE_signed) +!9 = !{!10, !12, !15} +!10 = !DILocalVariable(name: "i", line: 5, scope: !4, file: !5, type: !11) +!11 = !DIDerivedType(tag: DW_TAG_const_type, baseType: !8) +!12 = !DILocalVariable(name: "j", line: 7, scope: !4, file: !5, type: !13) +!13 = !DIDerivedType(tag: DW_TAG_const_type, baseType: !14) +!14 = !DIBasicType(tag: DW_TAG_base_type, name: "unsigned int", size: 32, align: 32, encoding: DW_ATE_unsigned) +!15 = !DILocalVariable(name: "c", line: 9, scope: !4, file: !5, type: !16) +!16 = !DIBasicType(tag: DW_TAG_base_type, name: "char16_t", size: 16, align: 16, encoding: 16) +!17 = !{i32 2, !"Dwarf Version", i32 4} +!18 = !{i32 1, !"Debug Info Version", i32 3} +!19 = !{!"clang version 3.5.0 "} +!20 = !{i32 42} +!21 = !DILocation(line: 5, scope: !4) +!22 = !DILocation(line: 6, scope: !4) +!23 = !{i32 117} +!24 = !DILocation(line: 7, scope: !4) +!25 = !DILocation(line: 8, scope: !4) +!26 = !{i16 7} +!27 = !DILocation(line: 9, scope: !4) +!28 = !DILocation(line: 10, scope: !4) +!29 = !DILocation(line: 11, scope: !4) diff --git a/llvm/test/DebugInfo/Generic/template-recursive-void.ll b/llvm/test/DebugInfo/Generic/template-recursive-void.ll new file mode 100644 index 00000000000..645f1795c76 --- /dev/null +++ b/llvm/test/DebugInfo/Generic/template-recursive-void.ll @@ -0,0 +1,61 @@ +; REQUIRES: object-emission + +; RUN: %llc_dwarf -O0 -filetype=obj < %s > %t +; RUN: llvm-dwarfdump %t | FileCheck %s + +; This was pulled from clang's debug-info-template-recursive.cpp test. +; class base { }; + +; template <class T> class foo : public base { +; void operator=(const foo r) { } +; }; + +; class bar : public foo<void> { }; +; bar filters; + +; CHECK: DW_TAG_template_type_parameter [{{.*}}] +; CHECK-NEXT: DW_AT_name{{.*}}"T" +; CHECK-NOT: DW_AT_type +; CHECK: NULL + +%class.bar = type { i8 } + +@filters = global %class.bar zeroinitializer, align 1 + +!llvm.dbg.cu = !{!0} +!llvm.module.flags = !{!36, !37} + +!0 = distinct !DICompileUnit(language: DW_LANG_C_plus_plus, producer: "clang version 3.4 (trunk 187958) (llvm/trunk 187964)", isOptimized: false, emissionKind: 0, file: !1, enums: !2, retainedTypes: !2, subprograms: !2, globals: !3, imports: !2) +!1 = !DIFile(filename: "debug-info-template-recursive.cpp", directory: "/usr/local/google/home/echristo/tmp") +!2 = !{} +!3 = !{!4} +!4 = !DIGlobalVariable(name: "filters", line: 10, isLocal: false, isDefinition: true, scope: null, file: !5, type: !6, variable: %class.bar* @filters) +!5 = !DIFile(filename: "debug-info-template-recursive.cpp", directory: "/usr/local/google/home/echristo/tmp") +!6 = !DICompositeType(tag: DW_TAG_class_type, name: "bar", line: 9, size: 8, align: 8, file: !1, elements: !7) +!7 = !{!8, !31} +!8 = !DIDerivedType(tag: DW_TAG_inheritance, scope: !6, baseType: !9) +!9 = !DICompositeType(tag: DW_TAG_class_type, name: "foo<void>", line: 5, size: 8, align: 8, file: !1, elements: !10, templateParams: !29) +!10 = !{!11, !19, !25} +!11 = !DIDerivedType(tag: DW_TAG_inheritance, scope: !9, baseType: !12) +!12 = !DICompositeType(tag: DW_TAG_class_type, name: "base", line: 3, size: 8, align: 8, file: !1, elements: !13) +!13 = !{!14} +!14 = !DISubprogram(name: "base", line: 3, isLocal: false, isDefinition: false, virtualIndex: 6, flags: DIFlagArtificial | DIFlagPrototyped, isOptimized: false, scopeLine: 3, file: !1, scope: !12, type: !15) +!15 = !DISubroutineType(types: !16) +!16 = !{null, !17} +!17 = !DIDerivedType(tag: DW_TAG_pointer_type, size: 64, align: 64, flags: DIFlagArtificial | DIFlagObjectPointer, baseType: !12) +!19 = !DISubprogram(name: "operator=", linkageName: "_ZN3fooIvEaSES0_", line: 6, isLocal: false, isDefinition: false, virtualIndex: 6, flags: DIFlagPrivate | DIFlagPrototyped, isOptimized: false, scopeLine: 6, file: !1, scope: !9, type: !20) +!20 = !DISubroutineType(types: !21) +!21 = !{null, !22, !23} +!22 = !DIDerivedType(tag: DW_TAG_pointer_type, size: 64, align: 64, flags: DIFlagArtificial | DIFlagObjectPointer, baseType: !9) +!23 = !DIDerivedType(tag: DW_TAG_const_type, baseType: !9) +!25 = !DISubprogram(name: "foo", line: 5, isLocal: false, isDefinition: false, virtualIndex: 6, flags: DIFlagArtificial | DIFlagPrototyped, isOptimized: false, scopeLine: 5, file: !1, scope: !9, type: !26) +!26 = !DISubroutineType(types: !27) +!27 = !{null, !22} +!29 = !{!30} +!30 = !DITemplateTypeParameter(name: "T", type: null) +!31 = !DISubprogram(name: "bar", line: 9, isLocal: false, isDefinition: false, virtualIndex: 6, flags: DIFlagArtificial | DIFlagPrototyped, isOptimized: false, scopeLine: 9, file: !1, scope: !6, type: !32) +!32 = !DISubroutineType(types: !33) +!33 = !{null, !34} +!34 = !DIDerivedType(tag: DW_TAG_pointer_type, size: 64, align: 64, flags: DIFlagArtificial | DIFlagObjectPointer, baseType: !6) +!36 = !{i32 2, !"Dwarf Version", i32 3} +!37 = !{i32 1, !"Debug Info Version", i32 3} diff --git a/llvm/test/DebugInfo/Generic/tu-composite.ll b/llvm/test/DebugInfo/Generic/tu-composite.ll new file mode 100644 index 00000000000..4df4ea8219d --- /dev/null +++ b/llvm/test/DebugInfo/Generic/tu-composite.ll @@ -0,0 +1,184 @@ +; REQUIRES: object-emission + +; RUN: %llc_dwarf -filetype=obj -O0 < %s > %t +; RUN: llvm-dwarfdump -debug-dump=info %t | FileCheck %s +; CHECK: [[TYPE:.*]]: DW_TAG_structure_type +; Make sure we correctly handle containing type of a struct being a type identifier. +; CHECK-NEXT: DW_AT_containing_type [DW_FORM_ref4] (cu + {{.*}} => {[[TYPE]]}) +; CHECK-NEXT: DW_AT_name [DW_FORM_strp] {{.*}}= "C") + +; Make sure we correctly handle context of a subprogram being a type identifier. +; CHECK: [[SP:.*]]: DW_TAG_subprogram +; CHECK: DW_AT_name [DW_FORM_strp] {{.*}}= "foo") +; Make sure we correctly handle containing type of a subprogram being a type identifier. +; CHECK: DW_AT_containing_type [DW_FORM_ref4] (cu + {{.*}} => {[[TYPE]]}) +; CHECK: DW_TAG_formal_parameter +; CHECK: NULL +; CHECK: NULL + +; CHECK: [[TYPE2:.*]]: DW_TAG_structure_type +; CHECK: DW_AT_name [DW_FORM_strp] {{.*}}= "bar") +; CHECK: DW_TAG_structure_type +; CHECK: DW_AT_name [DW_FORM_strp] {{.*}}= "D") +; CHECK: DW_TAG_member +; CHECK: DW_AT_name [DW_FORM_strp] {{.*}}= "a") +; Make sure we correctly handle context of a struct being a type identifier. +; CHECK: DW_TAG_structure_type +; CHECK-NEXT: DW_AT_name [DW_FORM_strp] {{.*}}= "Nested") +; CHECK: DW_TAG_structure_type +; CHECK-NEXT: DW_AT_name [DW_FORM_strp] {{.*}}= "Nested2") +; CHECK-NEXT: DW_AT_declaration [DW_FORM_flag] (0x01) +; CHECK: DW_TAG_structure_type +; CHECK-NEXT: DW_AT_name [DW_FORM_strp] {{.*}}= "virt<bar>") +; Make sure we correctly handle type of a template_type being a type identifier. +; CHECK: DW_TAG_template_type_parameter +; CHECK-NEXT: DW_AT_type [DW_FORM_ref4] (cu + {{.*}} => {[[TYPE2]]}) +; CHECK-NEXT: DW_AT_name [DW_FORM_strp] {{.*}}= "T") +; Make sure we correctly handle derived-from of a typedef being a type identifier. +; CHECK: DW_TAG_typedef +; CHECK-NEXT: DW_AT_type [DW_FORM_ref4] (cu + {{.*}} => {[[TYPE2]]}) +; CHECK: DW_AT_name [DW_FORM_strp] {{.*}}= "baz2") +; Make sure we correctly handle derived-from of a pointer type being a type identifier. +; CHECK: DW_TAG_pointer_type +; CHECK: DW_AT_type [DW_FORM_ref4] (cu + {{.*}} => {[[TYPE]]}) +; CHECK: DW_TAG_typedef +; CHECK-NEXT: DW_AT_type [DW_FORM_ref4] (cu + {{.*}} => {[[TYPE2]]}) +; CHECK: DW_AT_name [DW_FORM_strp] {{.*}}= "baz") +; Make sure we correctly handle derived-from of an array type being a type identifier. +; CHECK: DW_TAG_array_type +; CHECK-NEXT: DW_AT_type [DW_FORM_ref4] (cu + {{.*}} => {[[TYPE2]]}) +; IR generated from clang -g with the following source: +; struct C { +; virtual void foo(); +; }; +; void C::foo() { +; } +; +; struct bar { }; +; typedef bar baz; +; struct D { +; typedef bar baz2; +; static int a; +; struct Nested { }; +; struct Nested2 { }; +; template <typename T> +; struct virt { +; T* values; +; }; +; }; +; void test() { +; baz B; +; bar A[3]; +; D::baz2 B2; +; D::Nested e; +; D::Nested2 *p; +; D::virt<bar> t; +; } + +%struct.C = type { i32 (...)** } +%struct.bar = type { i8 } +%"struct.D::Nested" = type { i8 } +%"struct.D::Nested2" = type { i8 } +%"struct.D::virt" = type { %struct.bar* } + +@_ZTV1C = unnamed_addr constant [3 x i8*] [i8* null, i8* bitcast ({ i8*, i8* }* @_ZTI1C to i8*), i8* bitcast (void (%struct.C*)* @_ZN1C3fooEv to i8*)] +@_ZTVN10__cxxabiv117__class_type_infoE = external global i8* +@_ZTS1C = constant [3 x i8] c"1C\00" +@_ZTI1C = unnamed_addr constant { i8*, i8* } { i8* bitcast (i8** getelementptr inbounds (i8*, i8** @_ZTVN10__cxxabiv117__class_type_infoE, i64 2) to i8*), i8* getelementptr inbounds ([3 x i8], [3 x i8]* @_ZTS1C, i32 0, i32 0) } + +; Function Attrs: nounwind ssp uwtable +define void @_ZN1C3fooEv(%struct.C* %this) unnamed_addr #0 align 2 { +entry: + %this.addr = alloca %struct.C*, align 8 + store %struct.C* %this, %struct.C** %this.addr, align 8 + call void @llvm.dbg.declare(metadata %struct.C** %this.addr, metadata !36, metadata !DIExpression()), !dbg !38 + %this1 = load %struct.C*, %struct.C** %this.addr + ret void, !dbg !39 +} + +; Function Attrs: nounwind readnone +declare void @llvm.dbg.declare(metadata, metadata, metadata) #1 + +; Function Attrs: nounwind ssp uwtable +define void @_Z4testv() #0 { +entry: + %B = alloca %struct.bar, align 1 + %A = alloca [3 x %struct.bar], align 1 + %B2 = alloca %struct.bar, align 1 + %e = alloca %"struct.D::Nested", align 1 + %p = alloca %"struct.D::Nested2"*, align 8 + %t = alloca %"struct.D::virt", align 8 + call void @llvm.dbg.declare(metadata %struct.bar* %B, metadata !40, metadata !DIExpression()), !dbg !42 + call void @llvm.dbg.declare(metadata [3 x %struct.bar]* %A, metadata !43, metadata !DIExpression()), !dbg !47 + call void @llvm.dbg.declare(metadata %struct.bar* %B2, metadata !48, metadata !DIExpression()), !dbg !50 + call void @llvm.dbg.declare(metadata %"struct.D::Nested"* %e, metadata !51, metadata !DIExpression()), !dbg !52 + call void @llvm.dbg.declare(metadata %"struct.D::Nested2"** %p, metadata !53, metadata !DIExpression()), !dbg !55 + call void @llvm.dbg.declare(metadata %"struct.D::virt"* %t, metadata !56, metadata !DIExpression()), !dbg !57 + ret void, !dbg !58 +} + +attributes #0 = { nounwind ssp 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 = { nounwind readnone } + +!llvm.dbg.cu = !{!0} +!llvm.module.flags = !{!35, !59} + +!0 = distinct !DICompileUnit(language: DW_LANG_C_plus_plus, producer: "clang version 3.4", isOptimized: false, emissionKind: 0, file: !1, enums: !2, retainedTypes: !3, subprograms: !30, globals: !2, imports: !2) +!1 = !DIFile(filename: "tmp.cpp", directory: ".") +!2 = !{} +!3 = !{!4, !18, !19, !22, !23, !24} +!4 = !DICompositeType(tag: DW_TAG_structure_type, name: "C", line: 1, size: 64, align: 64, file: !1, elements: !5, vtableHolder: !"_ZTS1C", identifier: "_ZTS1C") +!5 = !{!6, !13} +!6 = !DIDerivedType(tag: DW_TAG_member, name: "_vptr$C", size: 64, flags: DIFlagArtificial, file: !1, scope: !7, baseType: !8) +!7 = !DIFile(filename: "tmp.cpp", directory: ".") +!8 = !DIDerivedType(tag: DW_TAG_pointer_type, size: 64, baseType: !9) +!9 = !DIDerivedType(tag: DW_TAG_pointer_type, name: "__vtbl_ptr_type", size: 64, baseType: !10) +!10 = !DISubroutineType(types: !11) +!11 = !{!12} +!12 = !DIBasicType(tag: DW_TAG_base_type, name: "int", size: 32, align: 32, encoding: DW_ATE_signed) +!13 = !DISubprogram(name: "foo", linkageName: "_ZN1C3fooEv", line: 2, isLocal: false, isDefinition: false, virtuality: DW_VIRTUALITY_virtual, virtualIndex: 6, flags: DIFlagPrototyped, isOptimized: false, scopeLine: 2, file: !1, scope: !"_ZTS1C", type: !14, containingType: !"_ZTS1C") +!14 = !DISubroutineType(types: !15) +!15 = !{null, !16} +!16 = !DIDerivedType(tag: DW_TAG_pointer_type, size: 64, align: 64, flags: DIFlagArtificial | DIFlagObjectPointer, baseType: !"_ZTS1C") +!18 = !DICompositeType(tag: DW_TAG_structure_type, name: "bar", line: 7, size: 8, align: 8, file: !1, elements: !2, identifier: "_ZTS3bar") +!19 = !DICompositeType(tag: DW_TAG_structure_type, name: "D", line: 9, size: 8, align: 8, file: !1, elements: !20, identifier: "_ZTS1D") +!20 = !{!21} +!21 = !DIDerivedType(tag: DW_TAG_member, name: "a", line: 11, flags: DIFlagStaticMember, file: !1, scope: !"_ZTS1D", baseType: !12) +!22 = !DICompositeType(tag: DW_TAG_structure_type, name: "Nested", line: 12, size: 8, align: 8, file: !1, scope: !"_ZTS1D", elements: !2, identifier: "_ZTSN1D6NestedE") +!23 = !DICompositeType(tag: DW_TAG_structure_type, name: "Nested2", line: 13, flags: DIFlagFwdDecl, file: !1, scope: !"_ZTS1D", identifier: "_ZTSN1D7Nested2E") +!24 = !DICompositeType(tag: DW_TAG_structure_type, name: "virt<bar>", line: 15, size: 64, align: 64, file: !1, scope: !"_ZTS1D", elements: !25, templateParams: !28, identifier: "_ZTSN1D4virtI3barEE") +!25 = !{!26} +!26 = !DIDerivedType(tag: DW_TAG_member, name: "values", line: 16, size: 64, align: 64, file: !1, scope: !"_ZTSN1D4virtI3barEE", baseType: !27) +!27 = !DIDerivedType(tag: DW_TAG_pointer_type, size: 64, align: 64, baseType: !"_ZTS3bar") +!28 = !{!29} +!29 = !DITemplateTypeParameter(name: "T", type: !"_ZTS3bar") +!30 = !{!31, !32} +!31 = distinct !DISubprogram(name: "foo", linkageName: "_ZN1C3fooEv", line: 4, isLocal: false, isDefinition: true, virtualIndex: 6, flags: DIFlagPrototyped, isOptimized: false, scopeLine: 4, file: !1, scope: null, type: !14, function: void (%struct.C*)* @_ZN1C3fooEv, declaration: !13, variables: !2) +!32 = distinct !DISubprogram(name: "test", linkageName: "_Z4testv", line: 20, isLocal: false, isDefinition: true, virtualIndex: 6, flags: DIFlagPrototyped, isOptimized: false, scopeLine: 20, file: !1, scope: !7, type: !33, function: void ()* @_Z4testv, variables: !2) +!33 = !DISubroutineType(types: !34) +!34 = !{null} +!35 = !{i32 2, !"Dwarf Version", i32 2} +!36 = !DILocalVariable(name: "this", arg: 1, flags: DIFlagArtificial | DIFlagObjectPointer, scope: !31, type: !37) +!37 = !DIDerivedType(tag: DW_TAG_pointer_type, size: 64, align: 64, baseType: !"_ZTS1C") +!38 = !DILocation(line: 0, scope: !31) +!39 = !DILocation(line: 5, scope: !31) +!40 = !DILocalVariable(name: "B", line: 21, scope: !32, file: !7, type: !41) +!41 = !DIDerivedType(tag: DW_TAG_typedef, name: "baz", line: 8, file: !1, baseType: !"_ZTS3bar") +!42 = !DILocation(line: 21, scope: !32) +!43 = !DILocalVariable(name: "A", line: 22, scope: !32, file: !7, type: !44) +!44 = !DICompositeType(tag: DW_TAG_array_type, size: 24, align: 8, baseType: !"_ZTS3bar", elements: !45) +!45 = !{!46} +!46 = !DISubrange(count: 3) +!47 = !DILocation(line: 22, scope: !32) +!48 = !DILocalVariable(name: "B2", line: 23, scope: !32, file: !7, type: !49) +!49 = !DIDerivedType(tag: DW_TAG_typedef, name: "baz2", line: 10, file: !1, scope: !"_ZTS1D", baseType: !"_ZTS3bar") +!50 = !DILocation(line: 23, scope: !32) +!51 = !DILocalVariable(name: "e", line: 24, scope: !32, file: !7, type: !22) +!52 = !DILocation(line: 24, scope: !32) +!53 = !DILocalVariable(name: "p", line: 25, scope: !32, file: !7, type: !54) +!54 = !DIDerivedType(tag: DW_TAG_pointer_type, size: 64, align: 64, baseType: !"_ZTSN1D7Nested2E") +!55 = !DILocation(line: 25, scope: !32) +!56 = !DILocalVariable(name: "t", line: 26, scope: !32, file: !7, type: !24) +!57 = !DILocation(line: 26, scope: !32) +!58 = !DILocation(line: 27, scope: !32) +!59 = !{i32 1, !"Debug Info Version", i32 3} diff --git a/llvm/test/DebugInfo/Generic/tu-member-pointer.ll b/llvm/test/DebugInfo/Generic/tu-member-pointer.ll new file mode 100644 index 00000000000..8b1eb3bb6d1 --- /dev/null +++ b/llvm/test/DebugInfo/Generic/tu-member-pointer.ll @@ -0,0 +1,30 @@ +; REQUIRES: object-emission + +; RUN: %llc_dwarf -filetype=obj -O0 < %s > %t +; RUN: llvm-dwarfdump -debug-dump=info %t | FileCheck %s +; CHECK: DW_TAG_ptr_to_member_type +; CHECK-NEXT: DW_AT_type [DW_FORM_ref4] (cu + {{.*}} => {[[TYPE:0x[0-9a-f]+]]}) +; CHECK: [[TYPE]]: DW_TAG_base_type +; IR generated from clang -g with the following source: +; struct Foo { +; int e; +; }; +; int Foo:*x = 0; + +@x = global i64 -1, align 8 + +!llvm.dbg.cu = !{!0} +!llvm.module.flags = !{!10, !11} + +!0 = distinct !DICompileUnit(language: DW_LANG_C_plus_plus, producer: "clang version 3.4", isOptimized: false, emissionKind: 0, file: !1, enums: !2, retainedTypes: !3, subprograms: !2, globals: !5, imports: !2) +!1 = !DIFile(filename: "foo.cpp", directory: ".") +!2 = !{} +!3 = !{!4} +!4 = !DICompositeType(tag: DW_TAG_structure_type, name: "Foo", line: 1, flags: DIFlagFwdDecl, file: !1, identifier: "_ZTS3Foo") +!5 = !{!6} +!6 = !DIGlobalVariable(name: "x", line: 4, isLocal: false, isDefinition: true, scope: null, file: !7, type: !8, variable: i64* @x) +!7 = !DIFile(filename: "foo.cpp", directory: ".") +!8 = !DIDerivedType(tag: DW_TAG_ptr_to_member_type, baseType: !9, extraData: !"_ZTS3Foo") +!9 = !DIBasicType(tag: DW_TAG_base_type, name: "int", size: 32, align: 32, encoding: DW_ATE_signed) +!10 = !{i32 2, !"Dwarf Version", i32 2} +!11 = !{i32 1, !"Debug Info Version", i32 3} diff --git a/llvm/test/DebugInfo/Generic/two-cus-from-same-file.ll b/llvm/test/DebugInfo/Generic/two-cus-from-same-file.ll new file mode 100644 index 00000000000..4aeaaac22d2 --- /dev/null +++ b/llvm/test/DebugInfo/Generic/two-cus-from-same-file.ll @@ -0,0 +1,73 @@ +; For http://llvm.org/bugs/show_bug.cgi?id=12942 +; There are two CUs coming from /tmp/foo.c in this module. Make sure it doesn't +; blow llc up and produces something reasonable. +; + +; REQUIRES: object-emission + +; RUN: %llc_dwarf %s -o %t -filetype=obj -O0 +; RUN: llvm-dwarfdump -debug-dump=info %t | FileCheck %s + +; ModuleID = 'test.bc' + +@str = private unnamed_addr constant [4 x i8] c"FOO\00" +@str1 = private unnamed_addr constant [6 x i8] c"Main!\00" + +define void @foo() nounwind { +entry: + %puts = tail call i32 @puts(i8* getelementptr inbounds ([4 x i8], [4 x i8]* @str, i32 0, i32 0)), !dbg !23 + ret void, !dbg !25 +} + +declare i32 @puts(i8* nocapture) nounwind + +define i32 @main(i32 %argc, i8** nocapture %argv) nounwind { +entry: + tail call void @llvm.dbg.value(metadata i32 %argc, i64 0, metadata !21, metadata !DIExpression()), !dbg !26 + tail call void @llvm.dbg.value(metadata i8** %argv, i64 0, metadata !22, metadata !DIExpression()), !dbg !27 + %puts = tail call i32 @puts(i8* getelementptr inbounds ([6 x i8], [6 x i8]* @str1, i32 0, i32 0)), !dbg !28 + tail call void @foo() nounwind, !dbg !30 + ret i32 0, !dbg !31 +} + +declare void @llvm.dbg.value(metadata, i64, metadata, metadata) nounwind readnone + +!llvm.dbg.cu = !{!0, !9} +!llvm.module.flags = !{!33} + +!0 = distinct !DICompileUnit(language: DW_LANG_C99, producer: "clang version 3.2 (trunk 156513)", isOptimized: true, emissionKind: 1, file: !32, enums: !1, retainedTypes: !1, subprograms: !3, globals: !1, imports: !1) +!1 = !{} +!3 = !{!5} +!5 = distinct !DISubprogram(name: "foo", line: 5, isLocal: false, isDefinition: true, virtualIndex: 6, flags: DIFlagPrototyped, isOptimized: true, scopeLine: 5, file: !32, scope: !6, type: !7, function: void ()* @foo, variables: !1) +!6 = !DIFile(filename: "foo.c", directory: "/tmp") +!7 = !DISubroutineType(types: !8) +!8 = !{null} +!9 = distinct !DICompileUnit(language: DW_LANG_C99, producer: "clang version 3.2 (trunk 156513)", isOptimized: true, emissionKind: 1, file: !32, enums: !1, retainedTypes: !1, subprograms: !10, globals: !1, imports: !1) +!10 = !{!12} +!12 = distinct !DISubprogram(name: "main", line: 11, isLocal: false, isDefinition: true, virtualIndex: 6, flags: DIFlagPrototyped, isOptimized: true, scopeLine: 11, file: !32, scope: !6, type: !13, function: i32 (i32, i8**)* @main, variables: !19) +!13 = !DISubroutineType(types: !14) +!14 = !{!15, !15, !16} +!15 = !DIBasicType(tag: DW_TAG_base_type, name: "int", size: 32, align: 32, encoding: DW_ATE_signed) +!16 = !DIDerivedType(tag: DW_TAG_pointer_type, size: 32, align: 32, baseType: !17) +!17 = !DIDerivedType(tag: DW_TAG_pointer_type, size: 32, align: 32, baseType: !18) +!18 = !DIBasicType(tag: DW_TAG_base_type, name: "char", size: 8, align: 8, encoding: DW_ATE_signed_char) +!19 = !{!21, !22} +!21 = !DILocalVariable(name: "argc", line: 11, arg: 1, scope: !12, file: !6, type: !15) +!22 = !DILocalVariable(name: "argv", line: 11, arg: 2, scope: !12, file: !6, type: !16) +!23 = !DILocation(line: 6, column: 3, scope: !24) +!24 = distinct !DILexicalBlock(line: 5, column: 16, file: !32, scope: !5) +!25 = !DILocation(line: 7, column: 1, scope: !24) +!26 = !DILocation(line: 11, column: 14, scope: !12) +!27 = !DILocation(line: 11, column: 26, scope: !12) +!28 = !DILocation(line: 12, column: 3, scope: !29) +!29 = distinct !DILexicalBlock(line: 11, column: 34, file: !32, scope: !12) +!30 = !DILocation(line: 13, column: 3, scope: !29) +!31 = !DILocation(line: 14, column: 3, scope: !29) +!32 = !DIFile(filename: "foo.c", directory: "/tmp") + +; This test is simple to be cross platform (many targets don't yet have +; sufficiently good DWARF emission and/or dumping) +; CHECK: {{DW_TAG_compile_unit}} +; CHECK: {{foo\.c}} + +!33 = !{i32 1, !"Debug Info Version", i32 3} diff --git a/llvm/test/DebugInfo/Generic/typedef.ll b/llvm/test/DebugInfo/Generic/typedef.ll new file mode 100644 index 00000000000..3cf4dffe937 --- /dev/null +++ b/llvm/test/DebugInfo/Generic/typedef.ll @@ -0,0 +1,32 @@ +; REQUIRES: object-emission + +; RUN: %llc_dwarf -O0 -filetype=obj < %s | llvm-dwarfdump -debug-dump=info - | FileCheck %s + +; From source: +; typedef void x; +; x *y; + +; Check that a typedef with no DW_AT_type is produced. The absence of a type is used to imply the 'void' type. + +; CHECK: DW_TAG_typedef +; CHECK-NOT: DW_AT_type +; CHECK: {{DW_TAG|NULL}} + +@y = global i8* null, align 8 + +!llvm.dbg.cu = !{!0} +!llvm.module.flags = !{!8, !9} +!llvm.ident = !{!10} + +!0 = distinct !DICompileUnit(language: DW_LANG_C_plus_plus, producer: "clang version 3.5.0 ", isOptimized: false, emissionKind: 1, file: !1, enums: !2, retainedTypes: !2, subprograms: !2, globals: !3, imports: !2) +!1 = !DIFile(filename: "typedef.cpp", directory: "/tmp/dbginfo") +!2 = !{} +!3 = !{!4} +!4 = !DIGlobalVariable(name: "y", line: 2, isLocal: false, isDefinition: true, scope: null, file: !5, type: !6, variable: i8** @y) +!5 = !DIFile(filename: "typedef.cpp", directory: "/tmp/dbginfo") +!6 = !DIDerivedType(tag: DW_TAG_pointer_type, size: 64, align: 64, baseType: !7) +!7 = !DIDerivedType(tag: DW_TAG_typedef, name: "x", line: 1, file: !1, baseType: null) +!8 = !{i32 2, !"Dwarf Version", i32 4} +!9 = !{i32 1, !"Debug Info Version", i32 3} +!10 = !{!"clang version 3.5.0 "} + diff --git a/llvm/test/DebugInfo/Generic/unconditional-branch.ll b/llvm/test/DebugInfo/Generic/unconditional-branch.ll new file mode 100644 index 00000000000..d4d7fb82741 --- /dev/null +++ b/llvm/test/DebugInfo/Generic/unconditional-branch.ll @@ -0,0 +1,65 @@ +; REQUIRES: object-emission +; PR 19261 + +; RUN: %llc_dwarf -fast-isel=false -O0 -filetype=obj %s -o %t +; RUN: llvm-dwarfdump %t | FileCheck %s + +; CHECK: {{0x[0-9a-f]+}} 1 0 1 0 0 is_stmt +; CHECK: {{0x[0-9a-f]+}} 2 0 1 0 0 is_stmt +; CHECK: {{0x[0-9a-f]+}} 4 0 1 0 0 is_stmt + +; IR generated from clang -O0 -g with the following source: +;void foo(int i){ +; switch(i){ +; default: +; break; +; } +; return; +;} + +; Function Attrs: nounwind +define void @foo(i32 %i) #0 { +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 !12, metadata !DIExpression()), !dbg !13 + %0 = load i32, i32* %i.addr, align 4, !dbg !14 + switch i32 %0, label %sw.default [ + ], !dbg !14 + +sw.epilog: ; preds = %sw.default + ret void, !dbg !17 + +sw.default: ; preds = %entry + br label %sw.epilog, !dbg !15 + +} + +; Function Attrs: nounwind readnone +declare void @llvm.dbg.declare(metadata, metadata, metadata) #1 + +attributes #0 = { nounwind "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 = { nounwind readnone } + +!llvm.dbg.cu = !{!0} +!llvm.module.flags = !{!9, !10} +!llvm.ident = !{!11} + +!0 = distinct !DICompileUnit(language: DW_LANG_C99, producer: "clang version 3.5.0 (204712)", isOptimized: false, emissionKind: 1, file: !1, enums: !2, retainedTypes: !2, subprograms: !3, globals: !2, imports: !2) +!1 = !DIFile(filename: "test.c", directory: "D:\5Cwork\5CEPRs\5C396363") +!2 = !{} +!3 = !{!4} +!4 = distinct !DISubprogram(name: "foo", line: 1, isLocal: false, isDefinition: true, virtualIndex: 6, flags: DIFlagPrototyped, isOptimized: false, scopeLine: 1, file: !1, scope: !5, type: !6, function: void (i32)* @foo, variables: !2) +!5 = !DIFile(filename: "test.c", directory: "D:CworkCEPRsC396363") +!6 = !DISubroutineType(types: !7) +!7 = !{null, !8} +!8 = !DIBasicType(tag: DW_TAG_base_type, name: "int", size: 32, align: 32, encoding: DW_ATE_signed) +!9 = !{i32 2, !"Dwarf Version", i32 4} +!10 = !{i32 1, !"Debug Info Version", i32 3} +!11 = !{!"clang version 3.5.0 (204712)"} +!12 = !DILocalVariable(name: "i", line: 1, arg: 1, scope: !4, file: !5, type: !8) +!13 = !DILocation(line: 1, scope: !4) +!14 = !DILocation(line: 2, scope: !4) +!15 = !DILocation(line: 4, scope: !16) +!16 = distinct !DILexicalBlock(line: 2, column: 0, file: !1, scope: !4) +!17 = !DILocation(line: 6, scope: !4) diff --git a/llvm/test/DebugInfo/Generic/varargs.ll b/llvm/test/DebugInfo/Generic/varargs.ll new file mode 100644 index 00000000000..1b5a921ad53 --- /dev/null +++ b/llvm/test/DebugInfo/Generic/varargs.ll @@ -0,0 +1,101 @@ +; RUN: %llc_dwarf -O0 -filetype=obj -o %t.o %s +; RUN: llvm-dwarfdump -debug-dump=info %t.o | FileCheck %s +; REQUIRES: object-emission +; +; Test debug info for variadic function arguments. +; Created from tools/clang/tests/CodeGenCXX/debug-info-varargs.cpp +; +; The ... parameter of variadic should be emitted as +; DW_TAG_unspecified_parameters. +; +; Normal variadic function. +; void b(int c, ...); +; +; CHECK: DW_TAG_subprogram +; CHECK-NOT: DW_TAG +; CHECK: DW_AT_name {{.*}} "a" +; CHECK-NOT: DW_TAG +; CHECK: DW_TAG_formal_parameter +; CHECK-NOT: DW_TAG +; CHECK: DW_TAG_formal_parameter +; CHECK-NOT: DW_TAG +; CHECK: DW_TAG_unspecified_parameters +; +; CHECK: DW_TAG_subprogram +; CHECK-NOT: DW_TAG +; CHECK: DW_AT_name {{.*}} "b" +; CHECK-NOT: DW_TAG +; CHECK: DW_TAG_formal_parameter +; CHECK-NOT: DW_TAG +; CHECK: DW_TAG_variable +; CHECK-NOT: DW_TAG +; CHECK: DW_TAG_variable +; CHECK-NOT: DW_TAG +; CHECK: DW_TAG_unspecified_parameters +; +; Variadic C++ member function. +; struct A { void a(int c, ...); } +; +; Variadic function pointer. +; void (*fptr)(int, ...); +; +; CHECK: DW_TAG_subroutine_type +; CHECK-NOT: DW_TAG +; CHECK: DW_TAG_formal_parameter +; CHECK-NOT: DW_TAG +; CHECK: DW_TAG_unspecified_parameters +; +; ModuleID = 'llvm/tools/clang/test/CodeGenCXX/debug-info-varargs.cpp' + +%struct.A = type { i8 } + +; Function Attrs: nounwind ssp uwtable +define void @_Z1biz(i32 %c, ...) #0 { + %1 = alloca i32, align 4 + %a = alloca %struct.A, align 1 + %fptr = alloca void (i32, ...)*, align 8 + store i32 %c, i32* %1, align 4 + call void @llvm.dbg.declare(metadata i32* %1, metadata !21, metadata !DIExpression()), !dbg !22 + call void @llvm.dbg.declare(metadata %struct.A* %a, metadata !23, metadata !DIExpression()), !dbg !24 + call void @llvm.dbg.declare(metadata void (i32, ...)** %fptr, metadata !25, metadata !DIExpression()), !dbg !27 + store void (i32, ...)* @_Z1biz, void (i32, ...)** %fptr, align 8, !dbg !27 + ret void, !dbg !28 +} + +; Function Attrs: nounwind readnone +declare void @llvm.dbg.declare(metadata, metadata, metadata) #1 + +attributes #0 = { nounwind ssp uwtable } +attributes #1 = { nounwind readnone } + +!llvm.dbg.cu = !{!0} +!llvm.module.flags = !{!18, !19} +!llvm.ident = !{!20} + +!0 = distinct !DICompileUnit(language: DW_LANG_C_plus_plus, producer: "clang version 3.5 ", isOptimized: false, emissionKind: 0, file: !1, enums: !2, retainedTypes: !3, subprograms: !13, globals: !2, imports: !2) +!1 = !DIFile(filename: "llvm/tools/clang/test/CodeGenCXX/debug-info-varargs.cpp", directory: "radar/13690847") +!2 = !{} +!3 = !{!4} +!4 = !DICompositeType(tag: DW_TAG_structure_type, name: "A", line: 3, size: 8, align: 8, file: !1, elements: !5, identifier: "_ZTS1A") +!5 = !{!6} +!6 = !DISubprogram(name: "a", linkageName: "_ZN1A1aEiz", line: 6, isLocal: false, isDefinition: false, virtualIndex: 6, flags: DIFlagPrototyped, isOptimized: false, scopeLine: 6, file: !1, scope: !"_ZTS1A", type: !7) +!7 = !DISubroutineType(types: !8) +!8 = !{null, !9, !10, null} +!9 = !DIDerivedType(tag: DW_TAG_pointer_type, size: 64, align: 64, flags: DIFlagArtificial | DIFlagObjectPointer, baseType: !"_ZTS1A") +!10 = !DIBasicType(tag: DW_TAG_base_type, name: "int", size: 32, align: 32, encoding: DW_ATE_signed) +!13 = !{!14} +!14 = distinct !DISubprogram(name: "b", linkageName: "_Z1biz", line: 13, isLocal: false, isDefinition: true, virtualIndex: 6, flags: DIFlagPrototyped, isOptimized: false, scopeLine: 13, file: !1, scope: !15, type: !16, function: void (i32, ...)* @_Z1biz, variables: !2) +!15 = !DIFile(filename: "llvm/tools/clang/test/CodeGenCXX/debug-info-varargs.cpp", directory: "radar/13690847") +!16 = !DISubroutineType(types: !17) +!17 = !{null, !10, null} +!18 = !{i32 2, !"Dwarf Version", i32 2} +!19 = !{i32 1, !"Debug Info Version", i32 3} +!20 = !{!"clang version 3.5 "} +!21 = !DILocalVariable(name: "c", line: 13, arg: 1, scope: !14, file: !15, type: !10) +!22 = !DILocation(line: 13, scope: !14) +!23 = !DILocalVariable(name: "a", line: 16, scope: !14, file: !15, type: !4) +!24 = !DILocation(line: 16, scope: !14) +!25 = !DILocalVariable(name: "fptr", line: 18, scope: !14, file: !15, type: !26) +!26 = !DIDerivedType(tag: DW_TAG_pointer_type, size: 64, align: 64, baseType: !16) +!27 = !DILocation(line: 18, scope: !14) +!28 = !DILocation(line: 22, scope: !14) diff --git a/llvm/test/DebugInfo/Generic/version.ll b/llvm/test/DebugInfo/Generic/version.ll new file mode 100644 index 00000000000..d0caa295cc2 --- /dev/null +++ b/llvm/test/DebugInfo/Generic/version.ll @@ -0,0 +1,32 @@ +; REQUIRES: object-emission + +; RUN: %llc_dwarf -O0 -filetype=obj < %s > %t +; RUN: llvm-dwarfdump %t | FileCheck %s + +; Make sure we are generating DWARF version 3 when module flag says so. +; CHECK: Compile Unit: length = {{.*}} version = 0x0003 + +define i32 @main() #0 { +entry: + %retval = alloca i32, align 4 + store i32 0, i32* %retval + ret i32 0, !dbg !10 +} + +attributes #0 = { nounwind 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" "unsafe-fp-math"="false" "use-soft-float"="false" } + +!llvm.dbg.cu = !{!0} +!llvm.module.flags = !{!9, !11} + +!0 = distinct !DICompileUnit(language: DW_LANG_C99, producer: "clang version 3.4 (trunk 185475)", isOptimized: false, emissionKind: 0, file: !1, enums: !2, retainedTypes: !2, subprograms: !3, globals: !2, imports: !2) +!1 = !DIFile(filename: "CodeGen/dwarf-version.c", directory: "test") +!2 = !{} +!3 = !{!4} +!4 = distinct !DISubprogram(name: "main", line: 6, isLocal: false, isDefinition: true, virtualIndex: 6, flags: DIFlagPrototyped, isOptimized: false, scopeLine: 6, file: !1, scope: !5, type: !6, function: i32 ()* @main, variables: !2) +!5 = !DIFile(filename: "CodeGen/dwarf-version.c", directory: "test") +!6 = !DISubroutineType(types: !7) +!7 = !{!8} +!8 = !DIBasicType(tag: DW_TAG_base_type, name: "int", size: 32, align: 32, encoding: DW_ATE_signed) +!9 = !{i32 2, !"Dwarf Version", i32 3} +!10 = !DILocation(line: 7, scope: !4) +!11 = !{i32 1, !"Debug Info Version", i32 3} |