Index: lib/AST/MicrosoftMangle.cpp =================================================================== --- lib/AST/MicrosoftMangle.cpp +++ lib/AST/MicrosoftMangle.cpp @@ -357,7 +357,7 @@ void mangleTemplateArgs(const TemplateDecl *TD, const TemplateArgumentList &TemplateArgs); void mangleTemplateArg(const TemplateDecl *TD, const TemplateArgument &TA, - const NamedDecl *Parm); + const NamedDecl *Parm, bool &PrevArgWasPack); }; } @@ -1219,13 +1219,15 @@ "size mismatch between args and parms!"); unsigned Idx = 0; + bool PrevArgWasPack = false; for (const TemplateArgument &TA : TemplateArgs.asArray()) - mangleTemplateArg(TD, TA, TPL->getParam(Idx++)); + mangleTemplateArg(TD, TA, TPL->getParam(Idx++), PrevArgWasPack); } void MicrosoftCXXNameMangler::mangleTemplateArg(const TemplateDecl *TD, const TemplateArgument &TA, - const NamedDecl *Parm) { + const NamedDecl *Parm, + bool &PrevArgWasPack) { // ::= // ::= // ::= @@ -1235,6 +1237,9 @@ // ::= $0A@ // ::= + bool NeedsSeparatorBeforePack = PrevArgWasPack; + PrevArgWasPack = false; + switch (TA.getKind()) { case TemplateArgument::Null: llvm_unreachable("Can't mangle null template arguments!"); @@ -1302,6 +1307,14 @@ mangleExpression(TA.getAsExpr()); break; case TemplateArgument::Pack: { + PrevArgWasPack = true; + if (NeedsSeparatorBeforePack) { + // If two consecutive template args are packs, we need to distinguish + // between {{int}, {int, int}} and {{int, int}, {int}}. We emit a + // separator ("$$Z") between the two packs to mark where one pack ends + // and the next begins. + Out << "$$Z"; + } ArrayRef TemplateArgs = TA.getPackAsArray(); if (TemplateArgs.empty()) { if (isa(Parm) || @@ -1317,8 +1330,9 @@ else llvm_unreachable("unexpected template parameter decl!"); } else { + bool PrevArgInPackWasPack = false; for (const TemplateArgument &PA : TemplateArgs) - mangleTemplateArg(TD, PA, Parm); + mangleTemplateArg(TD, PA, Parm, PrevArgInPackWasPack); } break; } Index: test/CodeGenCXX/mangle-ms-cxx11.cpp =================================================================== --- test/CodeGenCXX/mangle-ms-cxx11.cpp +++ test/CodeGenCXX/mangle-ms-cxx11.cpp @@ -318,3 +318,16 @@ // CHECK-DAG: @"\01?unaligned_foo8@unaligned_foo8_S@@QFCEXXZ" +template +struct my_tuple {}; + +template +void print_tuples(const my_tuple& a, const my_tuple& b); + +void f() { + print_tuples(my_tuple(), my_tuple()); + print_tuples(my_tuple(), my_tuple()); +} + +// CHECK-DAG: @"\01??$print_tuples@H$$ZHH@@YAXABU?$my_tuple@H@@ABU?$my_tuple@HH@@@Z" +// CHECK-DAG: @"\01??$print_tuples@HH$$ZH@@YAXABU?$my_tuple@HH@@ABU?$my_tuple@H@@@Z"