[PATCH] D22293: Fix MSVC mangling of consecutive pack template arguments
Dave Bartolomeo via cfe-commits
cfe-commits at lists.llvm.org
Tue Jul 12 18:16:58 PDT 2016
DaveBartolomeo created this revision.
DaveBartolomeo added reviewers: rnk, majnemer, cfe-commits.
When mangling a template specialization where two consecutive template arguments are both packs, MSVC inserts the separator "$$Z" between the two arguments to disambiguate between the case of { { int, int }, { int } } and { { int }, { int, int } }. I've updated Clang's MSVC mangler to do the same, and added a test case to check that the separator is inserted correctly.
http://reviews.llvm.org/D22293
Files:
lib/AST/MicrosoftMangle.cpp
test/CodeGenCXX/mangle-ms-cxx11.cpp
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 at unaligned_foo8_S@@QFCEXXZ"
+template<typename... T>
+struct my_tuple {};
+
+template<typename... A, typename... B>
+void print_tuples(const my_tuple<A...>& a, const my_tuple<B...>& b);
+
+void f() {
+ print_tuples(my_tuple<int>(), my_tuple<int, int>());
+ print_tuples(my_tuple<int, int>(), my_tuple<int>());
+}
+
+// CHECK-DAG: @"\01??$print_tuples at H$$ZHH@@YAXABU?$my_tuple at H@@ABU?$my_tuple at HH@@@Z"
+// CHECK-DAG: @"\01??$print_tuples at HH$$ZH@@YAXABU?$my_tuple at HH@@ABU?$my_tuple at H@@@Z"
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) {
// <template-arg> ::= <type>
// ::= <integer-literal>
// ::= <member-data-pointer>
@@ -1235,6 +1237,9 @@
// ::= $0A@
// ::= <template-args>
+ 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<TemplateArgument> TemplateArgs = TA.getPackAsArray();
if (TemplateArgs.empty()) {
if (isa<TemplateTypeParmDecl>(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;
}
-------------- next part --------------
A non-text attachment was scrubbed...
Name: D22293.63762.patch
Type: text/x-patch
Size: 3389 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/cfe-commits/attachments/20160713/e8e5502a/attachment.bin>
More information about the cfe-commits
mailing list