From 57fbc0c35fb143b0acce549f82e536ea4022634f Mon Sep 17 00:00:00 2001 From: David Majnemer Date: Tue, 5 Aug 2014 22:43:45 +0000 Subject: [PATCH] MS ABI: Mangle empty type parameter packs compatibly The MS mangling scheme apparently has separate manglings for type and non-type parameter packs when they are empty. Match template arguments with parameters during mangling; check the parameter to see if it was destined to hold type-ish things or nontype-ish things. Differential Revision: http://reviews.llvm.org/D4792 llvm-svn: 214932 --- clang/lib/AST/MicrosoftMangle.cpp | 23 ++++++++++++++++++----- clang/test/CodeGenCXX/mangle-ms-cxx11.cpp | 12 ++++++++++++ 2 files changed, 30 insertions(+), 5 deletions(-) diff --git a/clang/lib/AST/MicrosoftMangle.cpp b/clang/lib/AST/MicrosoftMangle.cpp index 7805ed5..ed22d27 100644 --- a/clang/lib/AST/MicrosoftMangle.cpp +++ b/clang/lib/AST/MicrosoftMangle.cpp @@ -279,7 +279,8 @@ private: void mangleTemplateArgs(const TemplateDecl *TD, const TemplateArgumentList &TemplateArgs); - void mangleTemplateArg(const TemplateDecl *TD, const TemplateArgument &TA); + void mangleTemplateArg(const TemplateDecl *TD, const TemplateArgument &TA, + const NamedDecl *Parm); }; } @@ -1104,12 +1105,18 @@ void MicrosoftCXXNameMangler::mangleExpression(const Expr *E) { void MicrosoftCXXNameMangler::mangleTemplateArgs( const TemplateDecl *TD, const TemplateArgumentList &TemplateArgs) { // ::= + + const TemplateParameterList *TPL = TD->getTemplateParameters(); + assert(TPL->size() == TemplateArgs.size() && + "size mismatch between args and parms!"); + + unsigned Idx = 0; for (const TemplateArgument &TA : TemplateArgs.asArray()) - mangleTemplateArg(TD, TA); + mangleTemplateArg(TD, TA, TPL->getParam(Idx++)); } void MicrosoftCXXNameMangler::mangleTemplateArg(const TemplateDecl *TD, - const TemplateArgument &TA) { + const TemplateArgument &TA, + const NamedDecl *Parm) { // ::= // ::= // ::= @@ -1172,10 +1179,16 @@ void MicrosoftCXXNameMangler::mangleTemplateArg(const TemplateDecl *TD, case TemplateArgument::Pack: { ArrayRef TemplateArgs = TA.getPackAsArray(); if (TemplateArgs.empty()) { - Out << "$S"; + if (isa(Parm) || + isa(Parm)) + Out << "$$V"; + else if (isa(Parm)) + Out << "$S"; + else + llvm_unreachable("unexpected template parameter decl!"); } else { for (const TemplateArgument &PA : TemplateArgs) - mangleTemplateArg(TD, PA); + mangleTemplateArg(TD, PA, Parm); } break; } diff --git a/clang/test/CodeGenCXX/mangle-ms-cxx11.cpp b/clang/test/CodeGenCXX/mangle-ms-cxx11.cpp index 8a528a6..490edd8 100644 --- a/clang/test/CodeGenCXX/mangle-ms-cxx11.cpp +++ b/clang/test/CodeGenCXX/mangle-ms-cxx11.cpp @@ -140,6 +140,18 @@ void templ_fun_with_pack() {} template void templ_fun_with_pack<>(); // CHECK-DAG: @"\01??$templ_fun_with_pack@$S@@YAXXZ" +template +void templ_fun_with_ty_pack() {} + +template void templ_fun_with_ty_pack<>(); +// CHECK-DAG: @"\01??$templ_fun_with_ty_pack@$$V@@YAXXZ" + +template