diff --git a/clang/lib/CodeGen/CGDebugInfo.cpp b/clang/lib/CodeGen/CGDebugInfo.cpp index 77d9960ab956..2227341f28d6 100644 --- a/clang/lib/CodeGen/CGDebugInfo.cpp +++ b/clang/lib/CodeGen/CGDebugInfo.cpp @@ -835,23 +835,15 @@ CollectCXXBases(const CXXRecordDecl *RD, llvm::DIFile Unit, } } -/// 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 - PU = TSpecial->getSpecializedTemplateOrPartial(); - - TemplateParameterList *TPList = PU.is() ? - PU.get()->getTemplateParameters() : - PU.get()->getTemplateParameters(); - const TemplateArgumentList &TAList = TSpecial->getTemplateInstantiationArgs(); +CollectTemplateParams(const TemplateParameterList *TPList, + const TemplateArgumentList &TAList, + llvm::DIFile Unit) { llvm::SmallVector 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 @@ CollectCXXTemplateParams(const ClassTemplateSpecializationDecl *TSpecial, 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 + PU = TSpecial->getSpecializedTemplateOrPartial(); + + TemplateParameterList *TPList = PU.is() ? + PU.get()->getTemplateParameters() : + PU.get()->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 @@ void CGDebugInfo::EmitFunctionStart(GlobalDecl GD, QualType FnType, unsigned Flags = 0; llvm::DIFile Unit = getOrCreateFile(CurLoc); llvm::DIDescriptor FDContext(Unit); + llvm::DIArray TParamsArray; if (const FunctionDecl *FD = dyn_cast(D)) { // If there is a DISubprogram for this function available then use it. llvm::DenseMap::iterator @@ -1561,6 +1583,9 @@ void CGDebugInfo::EmitFunctionStart(GlobalDecl GD, QualType FnType, if (const NamespaceDecl *NSDecl = dyn_cast_or_null(FD->getDeclContext())) FDContext = getOrCreateNameSpace(NSDecl); + + // Collect template parameters. + TParamsArray = CollectFunctionTemplateParams(FD, Unit); } else if (const ObjCMethodDecl *OMD = dyn_cast(D)) { Name = getObjCMethodName(OMD); Flags |= llvm::DIDescriptor::FlagPrototyped; @@ -1582,7 +1607,8 @@ void CGDebugInfo::EmitFunctionStart(GlobalDecl GD, QualType FnType, 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/clang/lib/CodeGen/CGDebugInfo.h b/clang/lib/CodeGen/CGDebugInfo.h index bb238aca07be..fbe4c1d2c003 100644 --- a/clang/lib/CodeGen/CGDebugInfo.h +++ b/clang/lib/CodeGen/CGDebugInfo.h @@ -123,7 +123,13 @@ class CGDebugInfo { llvm::DIFile F, llvm::SmallVectorImpl &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); diff --git a/clang/test/CodeGenCXX/debug-info-fn-template.cpp b/clang/test/CodeGenCXX/debug-info-fn-template.cpp new file mode 100644 index 000000000000..c8291af852d3 --- /dev/null +++ b/clang/test/CodeGenCXX/debug-info-fn-template.cpp @@ -0,0 +1,15 @@ +// RUN: %clang -emit-llvm -g -S %s -o - | FileCheck %s + +template +struct XF { + T member; +}; + +template +T fx(XF xi) { + return xi.member; +} + +//CHECK: DW_TAG_template_type_parameter +//CHECK: XF +template int fx(XF);