Debug info: Support variadic functions.
[oota-llvm.git] / lib / CodeGen / AsmPrinter / DwarfDebug.cpp
index 05006b33bc3d9a77ac3de94a9a3d48837337e4b8..3c5868111d76d9ee5d1909a1384a0255a79b7ba8 100644 (file)
@@ -38,6 +38,7 @@
 #include "llvm/Support/Dwarf.h"
 #include "llvm/Support/ErrorHandling.h"
 #include "llvm/Support/FormattedStream.h"
+#include "llvm/Support/LEB128.h"
 #include "llvm/Support/MD5.h"
 #include "llvm/Support/Path.h"
 #include "llvm/Support/Timer.h"
@@ -402,15 +403,21 @@ DIE *DwarfDebug::updateSubprogramScopeDIE(DwarfCompileUnit *SPCU,
         DIArray Args = SPTy.getTypeArray();
         uint16_t SPTag = SPTy.getTag();
         if (SPTag == dwarf::DW_TAG_subroutine_type)
+          // FIXME: Use DwarfUnit::constructSubprogramArguments() here.
           for (unsigned i = 1, N = Args.getNumElements(); i < N; ++i) {
-            DIE *Arg =
-                SPCU->createAndAddDIE(dwarf::DW_TAG_formal_parameter, *SPDie);
             DIType ATy(Args.getElement(i));
-            SPCU->addType(Arg, ATy);
-            if (ATy.isArtificial())
-              SPCU->addFlag(Arg, dwarf::DW_AT_artificial);
-            if (ATy.isObjectPointer())
-              SPCU->addDIEEntry(SPDie, dwarf::DW_AT_object_pointer, Arg);
+            if (ATy.isUnspecifiedParameter()) {
+              assert(i == N-1 && "ellipsis must be the last argument");
+              SPCU->createAndAddDIE(dwarf::DW_TAG_unspecified_parameters, *SPDie);
+            } else {
+              DIE *Arg =
+                SPCU->createAndAddDIE(dwarf::DW_TAG_formal_parameter, *SPDie);
+              SPCU->addType(Arg, ATy);
+              if (ATy.isArtificial())
+                SPCU->addFlag(Arg, dwarf::DW_AT_artificial);
+              if (ATy.isObjectPointer())
+                SPCU->addDIEEntry(SPDie, dwarf::DW_AT_object_pointer, Arg);
+            }
           }
         DIE *SPDeclDie = SPDie;
         SPDie = SPCU->createAndAddDIE(dwarf::DW_TAG_subprogram,
@@ -581,7 +588,7 @@ DIE *DwarfDebug::createScopeChildrenDIE(DwarfCompileUnit *TheCU,
   DIE *ObjectPointer = NULL;
 
   // Collect arguments for current function.
-  if (LScopes.isCurrentFunctionScope(Scope))
+  if (LScopes.isCurrentFunctionScope(Scope)) {
     for (unsigned i = 0, N = CurrentFnArguments.size(); i < N; ++i)
       if (DbgVariable *ArgDV = CurrentFnArguments[i])
         if (DIE *Arg =
@@ -591,6 +598,16 @@ DIE *DwarfDebug::createScopeChildrenDIE(DwarfCompileUnit *TheCU,
             ObjectPointer = Arg;
         }
 
+    // Create the unspecified parameter that marks a function as variadic.
+    DISubprogram SP(Scope->getScopeNode());
+    assert(SP.Verify());
+    DIArray FnArgs = SP.getType().getTypeArray();
+    if (FnArgs.getElement(FnArgs.getNumElements()-1).isUnspecifiedParameter()) {
+      DIE *Ellipsis = new DIE(dwarf::DW_TAG_unspecified_parameters);
+      Children.push_back(Ellipsis);
+    }
+  }
+
   // Collect lexical scope children first.
   const SmallVectorImpl<DbgVariable *> &Variables =
       ScopeVariables.lookup(Scope);
@@ -1876,7 +1893,7 @@ unsigned DwarfFile::computeSizeAndOffset(DIE *Die, unsigned Offset) {
   Die->setOffset(Offset);
 
   // Start the size with the size of abbreviation code.
-  Offset += MCAsmInfo::getULEB128Size(Die->getAbbrevNumber());
+  Offset += getULEB128Size(Die->getAbbrevNumber());
 
   const SmallVectorImpl<DIEValue *> &Values = Die->getValues();
   const SmallVectorImpl<DIEAbbrevData> &AbbrevData = Abbrev.getData();