llvm.org GIT mirror llvm / dbaa6ab
Debug info: Support variadic functions. Variadic functions have an unspecified parameter tag after the last argument. In IR this is represented as an unspecified parameter in the subroutine type. Paired commit with CFE r202185. rdar://problem/13690847 This re-applies r202184 + a bugfix in DwarfDebug's argument handling. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@202188 91177308-0d34-0410-b5e6-96231b3b80d8 Adrian Prantl 6 years ago
5 changed file(s) with 141 addition(s) and 29 deletion(s). Raw diff Collapse all Expand all
441441 /// through debug info anchors.
442442 void retainType(DIType T);
443443
444 /// createUnspecifiedParameter - Create unspeicified type descriptor
444 /// createUnspecifiedParameter - Create unspecified type descriptor
445445 /// for a subroutine type.
446446 DIDescriptor createUnspecifiedParameter();
447447
402402 DIArray Args = SPTy.getTypeArray();
403403 uint16_t SPTag = SPTy.getTag();
404404 if (SPTag == dwarf::DW_TAG_subroutine_type)
405 // FIXME: Use DwarfUnit::constructSubprogramArguments() here.
405406 for (unsigned i = 1, N = Args.getNumElements(); i < N; ++i) {
406 DIE *Arg =
407 DIType ATy(Args.getElement(i));
408 if (ATy.isUnspecifiedParameter()) {
409 assert(i == N-1 && "ellipsis must be the last argument");
410 SPCU->createAndAddDIE(dwarf::DW_TAG_unspecified_parameters, *SPDie);
411 } else {
412 DIE *Arg =
407413 SPCU->createAndAddDIE(dwarf::DW_TAG_formal_parameter, *SPDie);
408 DIType ATy(Args.getElement(i));
409 SPCU->addType(Arg, ATy);
410 if (ATy.isArtificial())
411 SPCU->addFlag(Arg, dwarf::DW_AT_artificial);
412 if (ATy.isObjectPointer())
413 SPCU->addDIEEntry(SPDie, dwarf::DW_AT_object_pointer, Arg);
414 SPCU->addType(Arg, ATy);
415 if (ATy.isArtificial())
416 SPCU->addFlag(Arg, dwarf::DW_AT_artificial);
417 if (ATy.isObjectPointer())
418 SPCU->addDIEEntry(SPDie, dwarf::DW_AT_object_pointer, Arg);
419 }
414420 }
415421 DIE *SPDeclDie = SPDie;
416422 SPDie = SPCU->createAndAddDIE(dwarf::DW_TAG_subprogram,
581587 DIE *ObjectPointer = NULL;
582588
583589 // Collect arguments for current function.
584 if (LScopes.isCurrentFunctionScope(Scope))
590 if (LScopes.isCurrentFunctionScope(Scope)) {
585591 for (unsigned i = 0, N = CurrentFnArguments.size(); i < N; ++i)
586592 if (DbgVariable *ArgDV = CurrentFnArguments[i])
587593 if (DIE *Arg =
590596 if (ArgDV->isObjectPointer())
591597 ObjectPointer = Arg;
592598 }
599
600 // Create the unspecified parameter that marks a function as variadic.
601 DISubprogram SP(Scope->getScopeNode());
602 assert(SP.Verify());
603 DIArray FnArgs = SP.getType().getTypeArray();
604 if (FnArgs.getElement(FnArgs.getNumElements()-1).isUnspecifiedParameter()) {
605 DIE *Ellipsis = new DIE(dwarf::DW_TAG_unspecified_parameters);
606 Children.push_back(Ellipsis);
607 }
608 }
593609
594610 // Collect lexical scope children first.
595611 const SmallVectorImpl &Variables =
11381138 addSourceLine(&Buffer, DTy);
11391139 }
11401140
1141 /// constructSubprogramArguments - Construct function argument DIEs.
1142 void DwarfUnit::constructSubprogramArguments(DIE &Buffer, DIArray Args) {
1143 for (unsigned i = 1, N = Args.getNumElements(); i < N; ++i) {
1144 DIDescriptor Ty = Args.getElement(i);
1145 if (Ty.isUnspecifiedParameter()) {
1146 assert(i == N-1 && "ellipsis must be the last argument");
1147 createAndAddDIE(dwarf::DW_TAG_unspecified_parameters, Buffer);
1148 } else {
1149 DIE *Arg = createAndAddDIE(dwarf::DW_TAG_formal_parameter, Buffer);
1150 addType(Arg, DIType(Ty));
1151 if (DIType(Ty).isArtificial())
1152 addFlag(Arg, dwarf::DW_AT_artificial);
1153 }
1154 }
1155 }
1156
11411157 /// constructTypeDIE - Construct type DIE from DICompositeType.
11421158 void DwarfUnit::constructTypeDIE(DIE &Buffer, DICompositeType CTy) {
11431159 // Add name if not anonymous or intermediate type.
11611177 addType(&Buffer, RTy);
11621178
11631179 bool isPrototyped = true;
1164 // Add arguments.
1165 for (unsigned i = 1, N = Elements.getNumElements(); i < N; ++i) {
1166 DIDescriptor Ty = Elements.getElement(i);
1167 if (Ty.isUnspecifiedParameter()) {
1168 createAndAddDIE(dwarf::DW_TAG_unspecified_parameters, Buffer);
1169 isPrototyped = false;
1170 } else {
1171 DIE *Arg = createAndAddDIE(dwarf::DW_TAG_formal_parameter, Buffer);
1172 addType(Arg, DIType(Ty));
1173 if (DIType(Ty).isArtificial())
1174 addFlag(Arg, dwarf::DW_AT_artificial);
1175 }
1176 }
1180 if (Elements.getNumElements() == 2 &&
1181 Elements.getElement(1).isUnspecifiedParameter())
1182 isPrototyped = false;
1183
1184 constructSubprogramArguments(Buffer, Elements);
1185
11771186 // Add prototype flag if we're dealing with a C language and the
11781187 // function has been prototyped.
11791188 uint16_t Language = getLanguage();
14561465
14571466 // Add arguments. Do not add arguments for subprogram definition. They will
14581467 // be handled while processing variables.
1459 for (unsigned i = 1, N = Args.getNumElements(); i < N; ++i) {
1460 DIE *Arg = createAndAddDIE(dwarf::DW_TAG_formal_parameter, *SPDie);
1461 DIType ATy(Args.getElement(i));
1462 addType(Arg, ATy);
1463 if (ATy.isArtificial())
1464 addFlag(Arg, dwarf::DW_AT_artificial);
1465 }
1468 constructSubprogramArguments(*SPDie, Args);
14661469 }
14671470
14681471 if (SP.isArtificial())
475475 DIE *getOrCreateStaticMemberDIE(DIDerivedType DT);
476476
477477 private:
478 /// constructSubprogramArguments - Construct function argument DIEs.
479 void constructSubprogramArguments(DIE &Buffer, DIArray Args);
480
478481 /// constructTypeDIE - Construct basic type die from DIBasicType.
479482 void constructTypeDIE(DIE &Buffer, DIBasicType BTy);
480483
0 ; RUN: llc -O0 -filetype=obj -o %t.o %s
1 ; RUN: llvm-dwarfdump -debug-dump=info %t.o | FileCheck %s
2 ;
3 ; Normal variadic function.
4 ;
5 ; CHECK: DW_TAG_subprogram
6 ; CHECK-NOT: DW_TAG
7 ; CHECK: DW_TAG_formal_parameter
8 ; CHECK-NOT: DW_TAG
9 ; CHECK: DW_TAG_unspecified_parameters
10 ;
11 ; Variadic C++ member function.
12 ;
13 ; CHECK: DW_TAG_subprogram
14 ; CHECK-NOT: DW_TAG
15 ; CHECK: DW_TAG_formal_parameter
16 ; CHECK-NOT: DW_TAG
17 ; CHECK: DW_TAG_formal_parameter
18 ; CHECK-NOT: DW_TAG
19 ; CHECK: DW_TAG_unspecified_parameters
20 ;
21 ; Variadic function pointer.
22 ;
23 ; CHECK: DW_TAG_subroutine_type
24 ; CHECK-NOT: DW_TAG
25 ; CHECK: DW_TAG_formal_parameter
26 ; CHECK-NOT: DW_TAG
27 ; CHECK: DW_TAG_unspecified_parameters
28 ;
29 ; Test debug info for variadic function arguments.
30 ; Created from tools/clang/tests/CodeGenCXX/debug-info-varargs.cpp
31 ;
32 ; ModuleID = 'llvm/tools/clang/test/CodeGenCXX/debug-info-varargs.cpp'
33 target datalayout = "e-m:o-i64:64-f80:128-n8:16:32:64-S128"
34 target triple = "x86_64-apple-macosx10.9.0"
35
36 %struct.A = type { i8 }
37
38 ; Function Attrs: nounwind ssp uwtable
39 define void @_Z1biz(i32 %c, ...) #0 {
40 %1 = alloca i32, align 4
41 %a = alloca %struct.A, align 1
42 %fptr = alloca void (i32, ...)*, align 8
43 store i32 %c, i32* %1, align 4
44 call void @llvm.dbg.declare(metadata !{i32* %1}, metadata !21), !dbg !22
45 call void @llvm.dbg.declare(metadata !{%struct.A* %a}, metadata !23), !dbg !24
46 call void @llvm.dbg.declare(metadata !{void (i32, ...)** %fptr}, metadata !25), !dbg !27
47 store void (i32, ...)* @_Z1biz, void (i32, ...)** %fptr, align 8, !dbg !27
48 ret void, !dbg !28
49 }
50
51 ; Function Attrs: nounwind readnone
52 declare void @llvm.dbg.declare(metadata, metadata) #1
53
54 attributes #0 = { nounwind ssp uwtable }
55 attributes #1 = { nounwind readnone }
56
57 !llvm.dbg.cu = !{!0}
58 !llvm.module.flags = !{!18, !19}
59 !llvm.ident = !{!20}
60
61 !0 = metadata !{i32 786449, metadata !1, i32 4, metadata !"clang version 3.5 ", i1 false, metadata !"", i32 0, metadata !2, metadata !3, metadata !13, metadata !2, metadata !2, metadata !""} ; [ DW_TAG_compile_unit ] [llvm/tools/clang/test/CodeGenCXX/debug-info-varargs.cpp] [DW_LANG_C_plus_plus]
62 !1 = metadata !{metadata !"llvm/tools/clang/test/CodeGenCXX/debug-info-varargs.cpp", metadata !"radar/13690847"}
63 !2 = metadata !{}
64 !3 = metadata !{metadata !4}
65 !4 = metadata !{i32 786451, metadata !1, null, metadata !"A", i32 3, i64 8, i64 8, i32 0, i32 0, null, metadata !5, i32 0, null, null, metadata !"_ZTS1A"} ; [ DW_TAG_structure_type ] [A] [line 3, size 8, align 8, offset 0] [def] [from ]
66 !5 = metadata !{metadata !6}
67 !6 = metadata !{i32 786478, metadata !1, metadata !"_ZTS1A", metadata !"a", metadata !"a", metadata !"_ZN1A1aEiz", i32 6, metadata !7, i1 false, i1 false, i32 0, i32 0, null, i32 256, i1 false, null, null, i32 0, metadata !12, i32 6} ; [ DW_TAG_subprogram ] [line 6] [a]
68 !7 = metadata !{i32 786453, i32 0, null, metadata !"", i32 0, i64 0, i64 0, i64 0, i32 0, null, metadata !8, i32 0, null, null, null} ; [ DW_TAG_subroutine_type ] [line 0, size 0, align 0, offset 0] [from ]
69 !8 = metadata !{null, metadata !9, metadata !10, metadata !11}
70 !9 = metadata !{i32 786447, null, null, metadata !"", i32 0, i64 64, i64 64, i64 0, i32 1088, metadata !"_ZTS1A"} ; [ DW_TAG_pointer_type ] [line 0, size 64, align 64, offset 0] [artificial] [from _ZTS1A]
71 !10 = metadata !{i32 786468, null, null, metadata !"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]
72 !11 = metadata !{i32 786456}
73 !12 = metadata !{i32 786468}
74 !13 = metadata !{metadata !14}
75 !14 = metadata !{i32 786478, metadata !1, metadata !15, metadata !"b", metadata !"b", metadata !"_Z1biz", i32 13, metadata !16, i1 false, i1 true, i32 0, i32 0, null, i32 256, i1 false, void (i32, ...)* @_Z1biz, null, null, metadata !2, i32 13} ; [ DW_TAG_subprogram ] [line 13] [def] [b]
76 !15 = metadata !{i32 786473, metadata !1} ; [ DW_TAG_file_type ] [llvm/tools/clang/test/CodeGenCXX/debug-info-varargs.cpp]
77 !16 = metadata !{i32 786453, i32 0, null, metadata !"", i32 0, i64 0, i64 0, i64 0, i32 0, null, metadata !17, i32 0, null, null, null} ; [ DW_TAG_subroutine_type ] [line 0, size 0, align 0, offset 0] [from ]
78 !17 = metadata !{null, metadata !10, metadata !11}
79 !18 = metadata !{i32 2, metadata !"Dwarf Version", i32 2}
80 !19 = metadata !{i32 1, metadata !"Debug Info Version", i32 1}
81 !20 = metadata !{metadata !"clang version 3.5 "}
82 !21 = metadata !{i32 786689, metadata !14, metadata !"c", metadata !15, i32 16777229, metadata !10, i32 0, i32 0} ; [ DW_TAG_arg_variable ] [c] [line 13]
83 !22 = metadata !{i32 13, i32 0, metadata !14, null}
84 !23 = metadata !{i32 786688, metadata !14, metadata !"a", metadata !15, i32 16, metadata !4, i32 0, i32 0} ; [ DW_TAG_auto_variable ] [a] [line 16]
85 !24 = metadata !{i32 16, i32 0, metadata !14, null}
86 !25 = metadata !{i32 786688, metadata !14, metadata !"fptr", metadata !15, i32 18, metadata !26, i32 0, i32 0} ; [ DW_TAG_auto_variable ] [fptr] [line 18]
87 !26 = metadata !{i32 786447, null, null, metadata !"", i32 0, i64 64, i64 64, i64 0, i32 0, metadata !16} ; [ DW_TAG_pointer_type ] [line 0, size 64, align 64, offset 0] [from ]
88 !27 = metadata !{i32 18, i32 0, metadata !14, null}
89 !28 = metadata !{i32 22, i32 0, metadata !14, null}