Index: cfe/trunk/lib/CodeGen/CGDebugInfo.cpp =================================================================== --- cfe/trunk/lib/CodeGen/CGDebugInfo.cpp +++ cfe/trunk/lib/CodeGen/CGDebugInfo.cpp @@ -1827,32 +1827,24 @@ } llvm::DINodeArray CGDebugInfo::CollectVarTemplateParams(const VarDecl *VL, - llvm::DIFile *Unit) { - if (auto *TS = dyn_cast(VL)) { - auto T = TS->getSpecializedTemplateOrPartial(); - auto TA = TS->getTemplateArgs().asArray(); - // Collect parameters for a partial specialization - if (T.is()) { - const TemplateParameterList *TList = - T.get() - ->getTemplateParameters(); - return CollectTemplateParams(TList, TA, Unit); - } - - // Collect parameters for an explicit specialization - if (T.is()) { - const TemplateParameterList *TList = T.get() - ->getTemplateParameters(); - return CollectTemplateParams(TList, TA, Unit); - } - } - return llvm::DINodeArray(); + llvm::DIFile *Unit) { + // Always get the full list of parameters, not just the ones from the + // specialization. A partial specialization may have fewer parameters than + // there are arguments. + auto *TS = dyn_cast(VL); + if (!TS) + return llvm::DINodeArray(); + VarTemplateDecl *T = TS->getSpecializedTemplate(); + const TemplateParameterList *TList = T->getTemplateParameters(); + auto TA = TS->getTemplateArgs().asArray(); + return CollectTemplateParams(TList, TA, Unit); } llvm::DINodeArray CGDebugInfo::CollectCXXTemplateParams( const ClassTemplateSpecializationDecl *TSpecial, llvm::DIFile *Unit) { - // Always get the full list of parameters, not just the ones from - // the specialization. + // Always get the full list of parameters, not just the ones from the + // specialization. A partial specialization may have fewer parameters than + // there are arguments. TemplateParameterList *TPList = TSpecial->getSpecializedTemplate()->getTemplateParameters(); const TemplateArgumentList &TAList = TSpecial->getTemplateArgs(); Index: cfe/trunk/test/CodeGenCXX/debug-info-template-member.cpp =================================================================== --- cfe/trunk/test/CodeGenCXX/debug-info-template-member.cpp +++ cfe/trunk/test/CodeGenCXX/debug-info-template-member.cpp @@ -30,7 +30,7 @@ // CHECK: {{![0-9]+}} = distinct !DIGlobalVariable( // CHECK-SAME: name: "var" // CHECK-SAME: templateParams: {{![0-9]+}} -// CHECK: !DITemplateTypeParameter(name: "P", type: {{![0-9]+}}) +// CHECK: !DITemplateTypeParameter(name: "T", type: {{![0-9]+}}) // CHECK: {{![0-9]+}} = distinct !DIGlobalVariable( // CHECK-SAME: name: "varray" // CHECK-SAME: templateParams: {{![0-9]+}} Index: cfe/trunk/test/CodeGenCXX/debug-info-var-template-partial.cpp =================================================================== --- cfe/trunk/test/CodeGenCXX/debug-info-var-template-partial.cpp +++ cfe/trunk/test/CodeGenCXX/debug-info-var-template-partial.cpp @@ -0,0 +1,17 @@ +// RUN: %clang_cc1 -emit-llvm -triple x86_64-linux-gnu %s -o - -debug-info-kind=limited | FileCheck %s + +template constexpr bool is_same_v = false; +template constexpr bool is_same_v = true; + +template constexpr bool is_same_v; +static_assert(is_same_v, "should get partial spec"); + +// Note that the template arguments for the instantiated variable use the +// parameter names from the primary template. The partial specialization might +// not have enough parameters. + +// CHECK: distinct !DIGlobalVariable(name: "is_same_v", linkageName: "_Z9is_same_vIiiE", {{.*}} templateParams: ![[PARAMS:[0-9]+]]) +// CHECK: ![[PARAMS]] = !{![[LHS:[0-9]+]], ![[RHS:[0-9]+]]} +// CHECK: ![[LHS]] = !DITemplateTypeParameter(name: "LHS", type: ![[INT:[0-9]+]]) +// CHECK: ![[INT]] = !DIBasicType(name: "int", size: 32, encoding: DW_ATE_signed) +// CHECK: ![[RHS]] = !DITemplateTypeParameter(name: "RHS", type: ![[INT]])