[PATCH] [ms-cxxabi] Mangle variadic template parameter packs

Reid Kleckner rnk at google.com
Mon Jul 1 11:43:21 PDT 2013


Hi rjmccall,

Unlike Itanium, there is no code to indicate the beginning of a
parameter pack.  I tested this with MSVC 2013, which is the only version
that implements variadic templates so far.

This is needed to compile APInt.cpp for the MS C++ ABI.

http://llvm-reviews.chandlerc.com/D1077

Files:
  lib/AST/MicrosoftMangle.cpp
  test/CodeGenCXX/mangle-ms-templates.cpp

Index: lib/AST/MicrosoftMangle.cpp
===================================================================
--- lib/AST/MicrosoftMangle.cpp
+++ lib/AST/MicrosoftMangle.cpp
@@ -134,7 +134,7 @@
 
   void mangleTemplateArgs(const TemplateDecl *TD,
                           const TemplateArgumentList &TemplateArgs);
-
+  void mangleTemplateArg(const TemplateDecl *TD, const TemplateArgument &TA, int i);
 };
 
 /// MicrosoftMangleContext - Overrides the default MangleContext for the
@@ -848,44 +848,56 @@
   unsigned NumTemplateArgs = TemplateArgs.size();
   for (unsigned i = 0; i < NumTemplateArgs; ++i) {
     const TemplateArgument &TA = TemplateArgs[i];
-    switch (TA.getKind()) {
-    case TemplateArgument::Null:
-      llvm_unreachable("Can't mangle null template arguments!");
-    case TemplateArgument::Type: {
-      QualType T = TA.getAsType();
-      mangleType(T, SourceRange(), QMM_Escape);
-      break;
-    }
-    case TemplateArgument::Declaration:
-      mangle(cast<NamedDecl>(TA.getAsDecl()), "$1?");
-      break;
-    case TemplateArgument::Integral:
-      mangleIntegerLiteral(TA.getAsIntegral(),
-                           TA.getIntegralType()->isBooleanType());
-      break;
-    case TemplateArgument::Expression:
-      mangleExpression(TA.getAsExpr());
-      break;
-    case TemplateArgument::Template:
-    case TemplateArgument::TemplateExpansion:
-    case TemplateArgument::NullPtr:
-    case TemplateArgument::Pack: {
-      // Issue a diagnostic.
-      DiagnosticsEngine &Diags = Context.getDiags();
-      unsigned DiagID = Diags.getCustomDiagID(DiagnosticsEngine::Error,
-        "cannot mangle template argument %0 of kind %select{ERROR|ERROR|"
-        "pointer/reference|nullptr|integral|template|template pack expansion|"
-        "ERROR|parameter pack}1 yet");
-      Diags.Report(TD->getLocation(), DiagID)
-        << i + 1
-        << TA.getKind()
-        << TD->getSourceRange();
-    }
-    }
+    mangleTemplateArg(TD, TA, i);
   }
   Out << '@';
 }
 
+void MicrosoftCXXNameMangler::mangleTemplateArg(const TemplateDecl *TD,
+                                                const TemplateArgument &TA,
+                                                int i) {
+  switch (TA.getKind()) {
+  case TemplateArgument::Null:
+    llvm_unreachable("Can't mangle null template arguments!");
+  case TemplateArgument::Type: {
+    QualType T = TA.getAsType();
+    mangleType(T, SourceRange(), QMM_Escape);
+    break;
+  }
+  case TemplateArgument::Declaration:
+    mangle(cast<NamedDecl>(TA.getAsDecl()), "$1?");
+    break;
+  case TemplateArgument::Integral:
+    mangleIntegerLiteral(TA.getAsIntegral(),
+                         TA.getIntegralType()->isBooleanType());
+    break;
+  case TemplateArgument::Expression:
+    mangleExpression(TA.getAsExpr());
+    break;
+  case TemplateArgument::Pack:
+    // MSVC 2013 is the first version to support variadic templates, and it
+    // doesn't do anything special to mangle template parameter packs.
+    for (TemplateArgument::pack_iterator I = TA.pack_begin(), E = TA.pack_end();
+         I != E; ++I)
+      mangleTemplateArg(TD, *I, i);
+    break;
+  case TemplateArgument::Template:
+  case TemplateArgument::TemplateExpansion:
+  case TemplateArgument::NullPtr: {
+    // Issue a diagnostic.
+    DiagnosticsEngine &Diags = Context.getDiags();
+    unsigned DiagID = Diags.getCustomDiagID(DiagnosticsEngine::Error,
+      "cannot mangle template argument %0 of kind %select{ERROR|ERROR|"
+      "pointer/reference|nullptr|integral|template|template pack expansion|"
+      "ERROR|parameter pack}1 yet");
+    Diags.Report(TD->getLocation(), DiagID)
+      << i + 1
+      << TA.getKind()
+      << TD->getSourceRange();
+  }
+  }
+}
+
 void MicrosoftCXXNameMangler::mangleQualifiers(Qualifiers Quals,
                                                bool IsMember) {
   // <cvr-qualifiers> ::= [E] [F] [I] <base-cvr-qualifiers>
Index: test/CodeGenCXX/mangle-ms-templates.cpp
===================================================================
--- test/CodeGenCXX/mangle-ms-templates.cpp
+++ test/CodeGenCXX/mangle-ms-templates.cpp
@@ -133,3 +133,26 @@
 // CHECK: "\01??$FunctionPointerTemplate@$1?spam@@YAXXZ@@YAXXZ"
 // X64: "\01??$FunctionPointerTemplate@$1?spam@@YAXXZ@@YAXXZ"
 }
+
+// MSVC 2013 doesn't do anything special to mangle variadic template parameter
+// packs.
+
+template <typename ...Ts> void variadic_fn_template(const Ts &...args) { }
+void variadic_fn_instantiate() {
+  variadic_fn_template(0, 1, 3, 4);
+  variadic_fn_template(0, 1, 'a', "b");
+}
+// CHECK: "\01??$variadic_fn_template at HHHH@@YAXABH000 at Z"
+// CHECK: "\01??$variadic_fn_template at HHD$$BY01D@@YAXABH0ABDAAY01$$CBD at Z"
+
+template <typename ...Ts>
+struct VariadicClass {
+  VariadicClass() { }
+  int x;
+};
+void variadic_class_instantiate() {
+  VariadicClass<int, char, bool> a;
+  VariadicClass<bool, char, int> b;
+}
+// CHECK: call {{.*}} @"\01??0?$VariadicClass at HD_N@@QAE at XZ"
+// CHECK: call {{.*}} @"\01??0?$VariadicClass at _NDH@@QAE at XZ"
-------------- next part --------------
A non-text attachment was scrubbed...
Name: D1077.1.patch
Type: text/x-patch
Size: 5038 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/cfe-commits/attachments/20130701/13ed2452/attachment.bin>


More information about the cfe-commits mailing list