[cfe-commits] [PATCH] [VCPP] Mangle template parameters pack

pravic ehysta at gmail.com
Mon Nov 5 11:48:35 PST 2012


This patch enables mangling of the template parameters pack with microsoft compatibility mode.

Also it adds "__ptr64" qualifier under X64 as VC++ does.

Variadic templates for VC++ was introduced at CTP update (http://bit.ly/Ud918z), so we can use them too now.

Tests included here contains only compilable by VC++ parts.

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

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

Index: lib/AST/MicrosoftMangle.cpp
===================================================================
--- lib/AST/MicrosoftMangle.cpp
+++ lib/AST/MicrosoftMangle.cpp
@@ -825,9 +825,22 @@
       break;
     case TemplateArgument::Template:
     case TemplateArgument::TemplateExpansion:
-    case TemplateArgument::Declaration:
-    case TemplateArgument::NullPtr:
     case TemplateArgument::Pack: {
+      SourceRange loc = TAL.getSourceRange();
+      if(TA.pack_size() > 0){
+        // mangle pack as template types sequence
+        for (TemplateArgument::pack_iterator PA = TA.pack_begin(), PAEnd = TA.pack_end(); PA != PAEnd; ++PA){
+          mangleType(PA->getAsType(), loc);
+        }
+      }else{
+        // mangle empty pack
+        // <empty VT> ::= '@' "$$$V" '@'
+        Out << "$$$V";
+      }
+      break;
+      }
+    case TemplateArgument::Declaration:
+    case TemplateArgument::NullPtr: {
       // Issue a diagnostic.
       DiagnosticsEngine &Diags = Context.getDiags();
       unsigned DiagID = Diags.getCustomDiagID(DiagnosticsEngine::Error,
@@ -1218,6 +1231,11 @@
           Out << 'U';
         else
           Out << 'Q';
+
+        // mangle __ptr64
+        if(getASTContext().getTargetInfo().getPointerWidth(0) == 64)
+          Out << 'E';
+
     }
   } else
     Out << 'Y';
Index: test/CodeGenCXX/mangle-ms-variadic-templates.cpp
===================================================================
--- test/CodeGenCXX/mangle-ms-variadic-templates.cpp
+++ test/CodeGenCXX/mangle-ms-variadic-templates.cpp
@@ -0,0 +1,112 @@
+// RUN: %clang_cc1 -std=c++11 -emit-llvm -fms-extensions -Xclang -cxx-abi -Xclang microsoft -target i386-pc-win32 -o - %s | FileCheck %s
+// RUN: %clang_cc1 -std=c++11 -emit-llvm -fms-extensions -Xclang -cxx-abi -Xclang microsoft -target x86_64-pc-win32 -o - %s | FileCheck -check-prefix=CHK64 %s
+// expected-no-diagnostics
+
+// Simple mangling test
+template<typename... T> void va(T...);
+
+void test_va(){
+	// CHECK: call void @"\01??$va@$$$V@@YAXXZ"()
+	// CHK64: call void @"\01??$va@$$$V@@YAXXZ"()
+	va();
+	// CHECK: call void @"\01??$va at H@@YAXH at Z"(i32 1)
+	// CHK64: call void @"\01??$va at H@@YAXH at Z"(i32 1)
+	va(1);
+	// CHECK: call void @"\01??$va at HN@@YAXHN at Z"(i32 1, double 2.300000e+00)
+	// CHK64: call void @"\01??$va at HN@@YAXHN at Z"(i32 1, double 2.300000e+00)
+	va(1,2.3);
+	// CHECK: call void @"\01??$va at M@@YAXM at Z"(float 2.500000e+00)
+	// CHK64: call void @"\01??$va at M@@YAXM at Z"(float 2.500000e+00)
+	va(2.5f);
+}
+
+// Struct mangling
+template<class... T> struct VS
+{
+	VS(T...){}
+};
+
+void test_vs(){
+	// 'QAE':  __thiscall (x86)
+	// 'QAA':  __cdecl (x86)
+	// 'QEAA': __cdecl __ptr64 (x64)
+	// CHECK: %struct.VS* @"\01??0?$VS@$$$V@@QAE at XZ"(%struct.VS* %vs0)
+	// CHK64: %struct.VS* @"\01??0?$VS@$$$V@@QEAA at XZ"(%struct.VS* %vs0)
+	VS<> vs0;
+	// CHECK: %struct.VS.0* @"\01??0?$VS at H@@QAE at H@Z"(%struct.VS.0* %vs1, i32 1)
+	// CHK64: %struct.VS.0* @"\01??0?$VS at H@@QEAA at H@Z"(%struct.VS.0* %vs1, i32 1)
+	VS<int> vs1(1);
+	// CHECK: %struct.VS.2* @"\01??0?$VS at HN@@QAE at HN@Z"(%struct.VS.2* %vs2, i32 1, double 2.300000e+00)
+	// CHK64: %struct.VS.2* @"\01??0?$VS at HN@@QEAA at HN@Z"(%struct.VS.2* %vs2, i32 1, double 2.300000e+00)
+	VS<int, double> vs2(1, 2.3);
+}
+
+
+template<unsigned I, typename ...Types>
+struct X { };
+
+template<typename T> struct identity { };
+template<typename T> struct add_reference;
+template<typename ...Types> struct tuple { };
+template<int ...Values> struct int_tuple { };
+template<template<typename> class ...Templates> struct template_tuple { };
+
+template<typename ...Types>
+void f0(X<sizeof...(Types), Types&...>) { }
+
+//template void f0(X<0>);
+
+//template void f0<int, float, double>(X<3, int&, float&, double&>);
+
+// Mangling for template argument packs
+template<typename ...Types> void f1() {}
+// CHECK: define weak_odr void @"\01??$f1@$$$V@@YAXXZ"
+// CHK64: define weak_odr void @"\01??$f1@$$$V@@YAXXZ"
+template void f1<>();
+// CHECK: define weak_odr void @"\01??$f1 at H@@YAXXZ"
+// CHK64: define weak_odr void @"\01??$f1 at H@@YAXXZ"
+template void f1<int>();
+// CHECK: define weak_odr void @"\01??$f1 at HM@@YAXXZ"
+// CHK64: define weak_odr void @"\01??$f1 at HM@@YAXXZ"
+template void f1<int, float>();
+
+// Mangling function parameter packs
+template<typename ...Types> void f2(Types...) {}
+// CHECK: define weak_odr void @"\01??$f2@$$$V@@YAXXZ"
+// CHK64: define weak_odr void @"\01??$f2@$$$V@@YAXXZ"
+template void f2<>();
+
+//template void f2<int>(int);
+
+//template void f2<int, float>(int, float);
+
+// Mangling non-trivial function parameter packs
+template<typename ...Types> void f3(const Types *...) {}
+// CHECK: define weak_odr void @"\01??$f3@$$$V@@YAXXZ"
+// CHK64: define weak_odr void @"\01??$f3@$$$V@@YAXXZ"
+template void f3<>();
+
+//template void f3<int>(const int*);
+
+//template void f3<int, float>(const int*, const float*);
+
+// Mangling of type pack expansions in a template argument
+template<typename ...Types> tuple<Types...> f4() {}
+
+//template tuple<int, float, double> f4();
+
+// Mangling of type pack expansions in a function type
+template<typename R, typename ...ArgTypes> identity<R(ArgTypes...)> f5() {}
+
+//template identity<int(int, float, double)> f5();
+
+// Mangling of non-type template argument expansions
+template<int ...Values> int_tuple<Values...> f6() {}
+
+//template int_tuple<1, 2, 3> f6();
+
+// Mangling of template template argument expansions
+template<template<typename> class ...Templates> 
+template_tuple<Templates...> f7() {}
+
+//template template_tuple<identity, add_reference> f7();
-------------- next part --------------
A non-text attachment was scrubbed...
Name: D99.1.patch
Type: text/x-patch
Size: 5587 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/cfe-commits/attachments/20121105/105c033a/attachment.bin>


More information about the cfe-commits mailing list