]> granicus.if.org Git - clang/commitdiff
MS ABI: Mangle empty type parameter packs compatibly
authorDavid Majnemer <david.majnemer@gmail.com>
Tue, 5 Aug 2014 22:43:45 +0000 (22:43 +0000)
committerDavid Majnemer <david.majnemer@gmail.com>
Tue, 5 Aug 2014 22:43:45 +0000 (22:43 +0000)
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

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@214932 91177308-0d34-0410-b5e6-96231b3b80d8

lib/AST/MicrosoftMangle.cpp
test/CodeGenCXX/mangle-ms-cxx11.cpp

index 7805ed500777a34f62a0a75934463a19d2329fd6..ed22d278499d75b6dba5d929ddce78905c2592ce 100644 (file)
@@ -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) {
   // <template-args> ::= <template-arg>+
+  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) {
   // <template-arg> ::= <type>
   //                ::= <integer-literal>
   //                ::= <member-data-pointer>
@@ -1172,10 +1179,16 @@ void MicrosoftCXXNameMangler::mangleTemplateArg(const TemplateDecl *TD,
   case TemplateArgument::Pack: {
     ArrayRef<TemplateArgument> TemplateArgs = TA.getPackAsArray();
     if (TemplateArgs.empty()) {
-      Out << "$S";
+      if (isa<TemplateTypeParmDecl>(Parm) ||
+          isa<TemplateTemplateParmDecl>(Parm))
+        Out << "$$V";
+      else if (isa<NonTypeTemplateParmDecl>(Parm))
+        Out << "$S";
+      else
+        llvm_unreachable("unexpected template parameter decl!");
     } else {
       for (const TemplateArgument &PA : TemplateArgs)
-        mangleTemplateArg(TD, PA);
+        mangleTemplateArg(TD, PA, Parm);
     }
     break;
   }
index 8a528a6bfd7c3c8810e8a808ba9cae22de9b8c02..490edd831b2dabaa9b0f0a61089063d1aad060c8 100644 (file)
@@ -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 <typename...>
+void templ_fun_with_ty_pack() {}
+
+template void templ_fun_with_ty_pack<>();
+// CHECK-DAG: @"\01??$templ_fun_with_ty_pack@$$V@@YAXXZ"
+
+template <template <class> class...>
+void templ_fun_with_templ_templ_pack() {}
+
+template void templ_fun_with_templ_templ_pack<>();
+// CHECK-DAG: @"\01??$templ_fun_with_templ_templ_pack@$$V@@YAXXZ"
+
 namespace PR20047 {
 template <typename T>
 struct A {};