patch-r264826-llvm-r202188-variadic-fn-debug-info.diff revision 269000
1Merge LLVM r202188:
2
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
6  subroutine type.
7
8  Paired commit with CFE r202185.
9
10  rdar://problem/13690847
11
12  This re-applies r202184 + a bugfix in DwarfDebug's argument handling.
13
14This merge includes a change to use the LLVM 3.4 API in
15lib/CodeGen/AsmPrinter/DwarfCompileUnit.cpp:
16
17DwarfUnit -> CompileUnit
18
19Sponsored by:       DARPA, AFRL
20
21http://svnweb.freebsd.org/changeset/base/264826
22
23Index: include/llvm/DIBuilder.h
24===================================================================
25--- include/llvm/DIBuilder.h	(revision 264825)
26+++ include/llvm/DIBuilder.h	(revision 264826)
27@@ -439,7 +439,7 @@
28     /// through debug info anchors.
29     void retainType(DIType T);
30 
31-    /// createUnspecifiedParameter - Create unspeicified type descriptor
32+    /// createUnspecifiedParameter - Create unspecified type descriptor
33     /// for a subroutine type.
34     DIDescriptor createUnspecifiedParameter();
35 
36Index: lib/CodeGen/AsmPrinter/DwarfDebug.cpp
37===================================================================
38--- lib/CodeGen/AsmPrinter/DwarfDebug.cpp	(revision 264825)
39+++ lib/CodeGen/AsmPrinter/DwarfDebug.cpp	(revision 264826)
40@@ -404,15 +404,21 @@
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) {
46-            DIE *Arg =
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);
51+            } else {
52+              DIE *Arg =
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);
65+            }
66           }
67         DIE *SPDeclDie = SPDie;
68         SPDie =
69@@ -579,7 +585,7 @@
70     DIE *ObjectPointer = NULL;
71 
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])
77         if (DIE *Arg =
78@@ -588,6 +594,16 @@
79           if (ArgDV->isObjectPointer()) ObjectPointer = Arg;
80         }
81 
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);
89+    }
90+  }
91+
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)
95Index: 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);
101 }
102 
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);
110+      } else {
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);
115+      }
116+    }
117+}
118+
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);
124 
125     bool isPrototyped = true;
126-    // Add arguments.
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;
132-      } else {
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);
137-      }
138-    }
139+    if (Elements.getNumElements() == 2 &&
140+        Elements.getElement(1).isUnspecifiedParameter())
141+      isPrototyped = false;
142+
143+    constructSubprogramArguments(Buffer, Elements);
144+
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 @@
149 
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));
155-      addType(Arg, ATy);
156-      if (ATy.isArtificial())
157-        addFlag(Arg, dwarf::DW_AT_artificial);
158-    }
159+    constructSubprogramArguments(*SPDie, Args);
160   }
161 
162   if (SP.isArtificial())
163Index: lib/CodeGen/AsmPrinter/DwarfCompileUnit.h
164===================================================================
165--- lib/CodeGen/AsmPrinter/DwarfCompileUnit.h	(revision 264825)
166+++ lib/CodeGen/AsmPrinter/DwarfCompileUnit.h	(revision 264826)
167@@ -342,6 +342,9 @@
168   void emitHeader(const MCSection *ASection, const MCSymbol *ASectionSym);
169 
170 private:
171+  /// constructSubprogramArguments - Construct function argument DIEs.
172+  void constructSubprogramArguments(DIE &Buffer, DIArray Args);
173+
174   /// constructTypeDIE - Construct basic type die from DIBasicType.
175   void constructTypeDIE(DIE &Buffer, DIBasicType BTy);
176 
177