3 Debug info: Support variadic functions.
4 Variadic functions have an unspecified parameter tag after the last
5 argument. In IR this is represented as an unspecified parameter in the
8 Paired commit with CFE r202185.
10 rdar://problem/13690847
12 This re-applies r202184 + a bugfix in DwarfDebug's argument handling.
14 This merge includes a change to use the LLVM 3.4 API in
15 lib/CodeGen/AsmPrinter/DwarfCompileUnit.cpp:
17 DwarfUnit -> CompileUnit
19 Sponsored by: DARPA, AFRL
21 Introduced here: http://svnweb.freebsd.org/changeset/base/264826
23 Index: include/llvm/DIBuilder.h
24 ===================================================================
25 --- include/llvm/DIBuilder.h (revision 264825)
26 +++ include/llvm/DIBuilder.h (revision 264826)
28 /// through debug info anchors.
29 void retainType(DIType T);
31 - /// createUnspecifiedParameter - Create unspeicified type descriptor
32 + /// createUnspecifiedParameter - Create unspecified type descriptor
33 /// for a subroutine type.
34 DIDescriptor createUnspecifiedParameter();
36 Index: lib/CodeGen/AsmPrinter/DwarfDebug.cpp
37 ===================================================================
38 --- lib/CodeGen/AsmPrinter/DwarfDebug.cpp (revision 264825)
39 +++ lib/CodeGen/AsmPrinter/DwarfDebug.cpp (revision 264826)
41 DIArray Args = SPTy.getTypeArray();
42 uint16_t SPTag = SPTy.getTag();
43 if (SPTag == dwarf::DW_TAG_subroutine_type)
44 + // FIXME: Use DwarfUnit::constructSubprogramArguments() here.
45 for (unsigned i = 1, N = Args.getNumElements(); i < N; ++i) {
47 + DIType ATy(Args.getElement(i));
48 + if (ATy.isUnspecifiedParameter()) {
49 + assert(i == N-1 && "ellipsis must be the last argument");
50 + SPCU->createAndAddDIE(dwarf::DW_TAG_unspecified_parameters, *SPDie);
53 SPCU->createAndAddDIE(dwarf::DW_TAG_formal_parameter, *SPDie);
54 - DIType ATy(Args.getElement(i));
55 - SPCU->addType(Arg, ATy);
56 - if (ATy.isArtificial())
57 - SPCU->addFlag(Arg, dwarf::DW_AT_artificial);
58 - if (ATy.isObjectPointer())
59 - SPCU->addDIEEntry(SPDie, dwarf::DW_AT_object_pointer, Arg);
60 + SPCU->addType(Arg, ATy);
61 + if (ATy.isArtificial())
62 + SPCU->addFlag(Arg, dwarf::DW_AT_artificial);
63 + if (ATy.isObjectPointer())
64 + SPCU->addDIEEntry(SPDie, dwarf::DW_AT_object_pointer, Arg);
67 DIE *SPDeclDie = SPDie;
70 DIE *ObjectPointer = NULL;
72 // Collect arguments for current function.
73 - if (LScopes.isCurrentFunctionScope(Scope))
74 + if (LScopes.isCurrentFunctionScope(Scope)) {
75 for (unsigned i = 0, N = CurrentFnArguments.size(); i < N; ++i)
76 if (DbgVariable *ArgDV = CurrentFnArguments[i])
79 if (ArgDV->isObjectPointer()) ObjectPointer = Arg;
82 + // Create the unspecified parameter that marks a function as variadic.
83 + DISubprogram SP(Scope->getScopeNode());
84 + assert(SP.Verify());
85 + DIArray FnArgs = SP.getType().getTypeArray();
86 + if (FnArgs.getElement(FnArgs.getNumElements()-1).isUnspecifiedParameter()) {
87 + DIE *Ellipsis = new DIE(dwarf::DW_TAG_unspecified_parameters);
88 + Children.push_back(Ellipsis);
92 // Collect lexical scope children first.
93 const SmallVectorImpl<DbgVariable *> &Variables =ScopeVariables.lookup(Scope);
94 for (unsigned i = 0, N = Variables.size(); i < N; ++i)
95 Index: lib/CodeGen/AsmPrinter/DwarfCompileUnit.cpp
96 ===================================================================
97 --- lib/CodeGen/AsmPrinter/DwarfCompileUnit.cpp (revision 264825)
98 +++ lib/CodeGen/AsmPrinter/DwarfCompileUnit.cpp (revision 264826)
99 @@ -1116,6 +1116,22 @@
100 addSourceLine(&Buffer, DTy);
103 +/// constructSubprogramArguments - Construct function argument DIEs.
104 +void CompileUnit::constructSubprogramArguments(DIE &Buffer, DIArray Args) {
105 + for (unsigned i = 1, N = Args.getNumElements(); i < N; ++i) {
106 + DIDescriptor Ty = Args.getElement(i);
107 + if (Ty.isUnspecifiedParameter()) {
108 + assert(i == N-1 && "ellipsis must be the last argument");
109 + createAndAddDIE(dwarf::DW_TAG_unspecified_parameters, Buffer);
111 + DIE *Arg = createAndAddDIE(dwarf::DW_TAG_formal_parameter, Buffer);
112 + addType(Arg, DIType(Ty));
113 + if (DIType(Ty).isArtificial())
114 + addFlag(Arg, dwarf::DW_AT_artificial);
119 /// Return true if the type is appropriately scoped to be contained inside
120 /// its own type unit.
121 static bool isTypeUnitScoped(DIType Ty, const DwarfDebug *DD) {
122 @@ -1170,19 +1186,12 @@
123 addType(&Buffer, RTy);
125 bool isPrototyped = true;
127 - for (unsigned i = 1, N = Elements.getNumElements(); i < N; ++i) {
128 - DIDescriptor Ty = Elements.getElement(i);
129 - if (Ty.isUnspecifiedParameter()) {
130 - createAndAddDIE(dwarf::DW_TAG_unspecified_parameters, Buffer);
131 - isPrototyped = false;
133 - DIE *Arg = createAndAddDIE(dwarf::DW_TAG_formal_parameter, Buffer);
134 - addType(Arg, DIType(Ty));
135 - if (DIType(Ty).isArtificial())
136 - addFlag(Arg, dwarf::DW_AT_artificial);
139 + if (Elements.getNumElements() == 2 &&
140 + Elements.getElement(1).isUnspecifiedParameter())
141 + isPrototyped = false;
143 + constructSubprogramArguments(Buffer, Elements);
145 // Add prototype flag if we're dealing with a C language and the
146 // function has been prototyped.
147 uint16_t Language = getLanguage();
148 @@ -1475,13 +1484,7 @@
150 // Add arguments. Do not add arguments for subprogram definition. They will
151 // be handled while processing variables.
152 - for (unsigned i = 1, N = Args.getNumElements(); i < N; ++i) {
153 - DIE *Arg = createAndAddDIE(dwarf::DW_TAG_formal_parameter, *SPDie);
154 - DIType ATy(Args.getElement(i));
156 - if (ATy.isArtificial())
157 - addFlag(Arg, dwarf::DW_AT_artificial);
159 + constructSubprogramArguments(*SPDie, Args);
162 if (SP.isArtificial())
163 Index: lib/CodeGen/AsmPrinter/DwarfCompileUnit.h
164 ===================================================================
165 --- lib/CodeGen/AsmPrinter/DwarfCompileUnit.h (revision 264825)
166 +++ lib/CodeGen/AsmPrinter/DwarfCompileUnit.h (revision 264826)
168 void emitHeader(const MCSection *ASection, const MCSymbol *ASectionSym);
171 + /// constructSubprogramArguments - Construct function argument DIEs.
172 + void constructSubprogramArguments(DIE &Buffer, DIArray Args);
174 /// constructTypeDIE - Construct basic type die from DIBasicType.
175 void constructTypeDIE(DIE &Buffer, DIBasicType BTy);