r341755 - ms: Insert $$Z in mangling between directly consecutive parameter packs.
Nico Weber via cfe-commits
cfe-commits at lists.llvm.org
Sat Sep 8 13:58:39 PDT 2018
Author: nico
Date: Sat Sep 8 13:58:39 2018
New Revision: 341755
URL: http://llvm.org/viewvc/llvm-project?rev=341755&view=rev
Log:
ms: Insert $$Z in mangling between directly consecutive parameter packs.
Fixes PR38783.
Differential Revision: https://reviews.llvm.org/D51784
Modified:
cfe/trunk/lib/AST/MicrosoftMangle.cpp
cfe/trunk/test/CodeGenCXX/mangle-ms-templates.cpp
Modified: cfe/trunk/lib/AST/MicrosoftMangle.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/MicrosoftMangle.cpp?rev=341755&r1=341754&r2=341755&view=diff
==============================================================================
--- cfe/trunk/lib/AST/MicrosoftMangle.cpp (original)
+++ cfe/trunk/lib/AST/MicrosoftMangle.cpp Sat Sep 8 13:58:39 2018
@@ -1384,9 +1384,16 @@ void MicrosoftCXXNameMangler::mangleTemp
assert(TPL->size() == TemplateArgs.size() &&
"size mismatch between args and parms!");
- unsigned Idx = 0;
- for (const TemplateArgument &TA : TemplateArgs.asArray())
- mangleTemplateArg(TD, TA, TPL->getParam(Idx++));
+ for (size_t i = 0; i < TemplateArgs.size(); ++i) {
+ const TemplateArgument &TA = TemplateArgs[i];
+
+ // Separate consecutive packs by $$Z.
+ if (i > 0 && TA.getKind() == TemplateArgument::Pack &&
+ TemplateArgs[i - 1].getKind() == TemplateArgument::Pack)
+ Out << "$$Z";
+
+ mangleTemplateArg(TD, TA, TPL->getParam(i));
+ }
}
void MicrosoftCXXNameMangler::mangleTemplateArg(const TemplateDecl *TD,
Modified: cfe/trunk/test/CodeGenCXX/mangle-ms-templates.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGenCXX/mangle-ms-templates.cpp?rev=341755&r1=341754&r2=341755&view=diff
==============================================================================
--- cfe/trunk/test/CodeGenCXX/mangle-ms-templates.cpp (original)
+++ cfe/trunk/test/CodeGenCXX/mangle-ms-templates.cpp Sat Sep 8 13:58:39 2018
@@ -1,5 +1,5 @@
-// RUN: %clang_cc1 -std=c++11 -emit-llvm %s -o - -fms-extensions -fdelayed-template-parsing -triple=i386-pc-win32 | FileCheck %s
-// RUN: %clang_cc1 -std=c++11 -emit-llvm %s -o - -fms-extensions -fdelayed-template-parsing -triple=x86_64-pc-win32 | FileCheck -check-prefix X64 %s
+// RUN: %clang_cc1 -std=c++11 -fms-compatibility-version=19 -emit-llvm %s -o - -fms-extensions -fdelayed-template-parsing -triple=i386-pc-win32 | FileCheck %s
+// RUN: %clang_cc1 -std=c++11 -fms-compatibility-version=19 -emit-llvm %s -o - -fms-extensions -fdelayed-template-parsing -triple=x86_64-pc-win32 | FileCheck -check-prefix X64 %s
template<typename T>
class Class {
@@ -185,13 +185,35 @@ void spam() {
// Unlike Itanium, there is no character code to indicate an argument pack.
// Tested with MSVC 2013, the first version which supports variadic templates.
-template <typename ...Ts> void variadic_fn_template(const Ts &...args) { }
+template <typename ...Ts> void variadic_fn_template(const Ts &...args);
+template <typename... Ts, typename... Us>
+void multi_variadic_fn(Ts... ts, Us... us);
+template <typename... Ts, typename C, typename... Us>
+void multi_variadic_mixed(Ts... ts, C c, Us... us);
void variadic_fn_instantiate() {
variadic_fn_template(0, 1, 3, 4);
variadic_fn_template(0, 1, 'a', "b");
+
+ // Directlly consecutive packs are separated by $$Z...
+ multi_variadic_fn<int, int>(1, 2, 3, 4, 5);
+ multi_variadic_fn<int, int, int>(1, 2, 3, 4, 5);
+
+ // ...but not if another template parameter is between them.
+ multi_variadic_mixed<int, int>(1, 2, 3);
+ multi_variadic_mixed<int, int>(1, 2, 3, 4);
}
// CHECK: "??$variadic_fn_template at HHHH@@YAXABH000 at Z"
+// X64: "??$variadic_fn_template at HHHH@@YAXAEBH000 at Z"
// CHECK: "??$variadic_fn_template at HHD$$BY01D@@YAXABH0ABDAAY01$$CBD at Z"
+// X64: "??$variadic_fn_template at HHD$$BY01D@@YAXAEBH0AEBDAEAY01$$CBD at Z"
+// CHECK: "??$multi_variadic_fn at HH$$ZHHH@@YAXHHHHH at Z"
+// X64: "??$multi_variadic_fn at HH$$ZHHH@@YAXHHHHH at Z"
+// CHECK: "??$multi_variadic_fn at HHH$$ZHH@@YAXHHHHH at Z"
+// X64: "??$multi_variadic_fn at HHH$$ZHH@@YAXHHHHH at Z"
+// CHECK: "??$multi_variadic_mixed at HHH$$V@@YAXHHH at Z"
+// X64: "??$multi_variadic_mixed at HHH$$V@@YAXHHH at Z"
+// CHECK: "??$multi_variadic_mixed at HHHH@@YAXHHHH at Z"
+// X64: "??$multi_variadic_mixed at HHHH@@YAXHHHH at Z"
template <typename ...Ts>
struct VariadicClass {
More information about the cfe-commits
mailing list