[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