Emit debug info for function template parameters.


git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@128948 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/lib/CodeGen/CGDebugInfo.cpp b/lib/CodeGen/CGDebugInfo.cpp
index 77d9960..2227341 100644
--- a/lib/CodeGen/CGDebugInfo.cpp
+++ b/lib/CodeGen/CGDebugInfo.cpp
@@ -835,23 +835,15 @@
   }
 }
 
-/// CollectCXXTemplateParams - A helper function to collect debug info for
-/// template parameters.
+/// CollectTemplateParams - A helper function to collect template parameters.
 llvm::DIArray CGDebugInfo::
-CollectCXXTemplateParams(const ClassTemplateSpecializationDecl *TSpecial,
-                         llvm::DIFile Unit) {
-  llvm::PointerUnion<ClassTemplateDecl *,
-                     ClassTemplatePartialSpecializationDecl *>
-    PU = TSpecial->getSpecializedTemplateOrPartial();
-  
-  TemplateParameterList *TPList = PU.is<ClassTemplateDecl *>() ?
-    PU.get<ClassTemplateDecl *>()->getTemplateParameters() :
-    PU.get<ClassTemplatePartialSpecializationDecl *>()->getTemplateParameters();
-  const TemplateArgumentList &TAList = TSpecial->getTemplateInstantiationArgs();
+CollectTemplateParams(const TemplateParameterList *TPList,
+                      const TemplateArgumentList &TAList,
+                      llvm::DIFile Unit) {
   llvm::SmallVector<llvm::Value *, 16> TemplateParams;  
   for (unsigned i = 0, e = TAList.size(); i != e; ++i) {
     const TemplateArgument &TA = TAList[i];
-    NamedDecl *ND = TPList->getParam(i);
+    const NamedDecl *ND = TPList->getParam(i);
     if (TA.getKind() == TemplateArgument::Type) {
       llvm::DIType TTy = getOrCreateType(TA.getAsType(), Unit);
       llvm::DITemplateTypeParameter TTP =
@@ -868,6 +860,35 @@
   return DBuilder.getOrCreateArray(TemplateParams.data(), TemplateParams.size());
 }
 
+/// CollectFunctionTemplateParams - A helper function to collect debug
+/// info for function template parameters.
+llvm::DIArray CGDebugInfo::
+CollectFunctionTemplateParams(const FunctionDecl *FD, llvm::DIFile Unit) {
+  if (FD->getTemplatedKind() == FunctionDecl::TK_FunctionTemplateSpecialization){
+    const TemplateParameterList *TList =
+      FD->getTemplateSpecializationInfo()->getTemplate()->getTemplateParameters();
+    return 
+      CollectTemplateParams(TList, *FD->getTemplateSpecializationArgs(), Unit);
+  }
+  return llvm::DIArray();
+}
+
+/// CollectCXXTemplateParams - A helper function to collect debug info for
+/// template parameters.
+llvm::DIArray CGDebugInfo::
+CollectCXXTemplateParams(const ClassTemplateSpecializationDecl *TSpecial,
+                         llvm::DIFile Unit) {
+  llvm::PointerUnion<ClassTemplateDecl *,
+                     ClassTemplatePartialSpecializationDecl *>
+    PU = TSpecial->getSpecializedTemplateOrPartial();
+  
+  TemplateParameterList *TPList = PU.is<ClassTemplateDecl *>() ?
+    PU.get<ClassTemplateDecl *>()->getTemplateParameters() :
+    PU.get<ClassTemplatePartialSpecializationDecl *>()->getTemplateParameters();
+  const TemplateArgumentList &TAList = TSpecial->getTemplateInstantiationArgs();
+  return CollectTemplateParams(TPList, TAList, Unit);
+}
+
 /// getOrCreateVTablePtrType - Return debug info descriptor for vtable.
 llvm::DIType CGDebugInfo::getOrCreateVTablePtrType(llvm::DIFile Unit) {
   if (VTablePtrType.isValid())
@@ -1538,6 +1559,7 @@
   unsigned Flags = 0;
   llvm::DIFile Unit = getOrCreateFile(CurLoc);
   llvm::DIDescriptor FDContext(Unit);
+  llvm::DIArray TParamsArray;
   if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(D)) {
     // If there is a DISubprogram for  this function available then use it.
     llvm::DenseMap<const FunctionDecl *, llvm::WeakVH>::iterator
@@ -1561,6 +1583,9 @@
     if (const NamespaceDecl *NSDecl =
         dyn_cast_or_null<NamespaceDecl>(FD->getDeclContext()))
       FDContext = getOrCreateNameSpace(NSDecl);
+
+    // Collect template parameters.
+    TParamsArray = CollectFunctionTemplateParams(FD, Unit);
   } else if (const ObjCMethodDecl *OMD = dyn_cast<ObjCMethodDecl>(D)) {
     Name = getObjCMethodName(OMD);
     Flags |= llvm::DIDescriptor::FlagPrototyped;
@@ -1582,7 +1607,8 @@
     DBuilder.createFunction(FDContext, Name, LinkageName, Unit,
                             LineNo, getOrCreateType(FnType, Unit),
                             Fn->hasInternalLinkage(), true/*definition*/,
-                            Flags, CGM.getLangOptions().Optimize, Fn);
+                            Flags, CGM.getLangOptions().Optimize, Fn,
+                            TParamsArray);
 
   // Push function on region stack.
   llvm::MDNode *SPN = SP;
diff --git a/lib/CodeGen/CGDebugInfo.h b/lib/CodeGen/CGDebugInfo.h
index bb238ac..fbe4c1d 100644
--- a/lib/CodeGen/CGDebugInfo.h
+++ b/lib/CodeGen/CGDebugInfo.h
@@ -123,7 +123,13 @@
                        llvm::DIFile F,
                        llvm::SmallVectorImpl<llvm::Value *> &EltTys,
                        llvm::DIType RecordTy);
-
+  
+  llvm::DIArray
+  CollectTemplateParams(const TemplateParameterList *TPList,
+                        const TemplateArgumentList &TAList,
+                        llvm::DIFile Unit);
+  llvm::DIArray
+  CollectFunctionTemplateParams(const FunctionDecl *FD, llvm::DIFile Unit);
   llvm::DIArray 
   CollectCXXTemplateParams(const ClassTemplateSpecializationDecl *TS,
                            llvm::DIFile F);