xref: /minix3/external/bsd/llvm/dist/clang/test/CodeGenCXX/mangle-ms-templates.cpp (revision f4a2713ac843a11c696ec80c0a5e3e5d80b4d338)
1*f4a2713aSLionel Sambuc // RUN: %clang_cc1 -std=c++11 -emit-llvm %s -o - -cxx-abi microsoft -fms-extensions -fdelayed-template-parsing -triple=i386-pc-win32 | FileCheck %s
2*f4a2713aSLionel Sambuc // RUN: %clang_cc1 -std=c++11 -emit-llvm %s -o - -cxx-abi microsoft -fms-extensions -fdelayed-template-parsing -triple=x86_64-pc-win32 | FileCheck -check-prefix X64 %s
3*f4a2713aSLionel Sambuc 
4*f4a2713aSLionel Sambuc template<typename T>
5*f4a2713aSLionel Sambuc class Class {
6*f4a2713aSLionel Sambuc  public:
7*f4a2713aSLionel Sambuc   Class() {}
8*f4a2713aSLionel Sambuc };
9*f4a2713aSLionel Sambuc 
10*f4a2713aSLionel Sambuc class Typename { };
11*f4a2713aSLionel Sambuc 
12*f4a2713aSLionel Sambuc template<typename T>
13*f4a2713aSLionel Sambuc class Nested { };
14*f4a2713aSLionel Sambuc 
15*f4a2713aSLionel Sambuc template<bool flag>
16*f4a2713aSLionel Sambuc class BoolTemplate {
17*f4a2713aSLionel Sambuc  public:
18*f4a2713aSLionel Sambuc   BoolTemplate() {}
19*f4a2713aSLionel Sambuc };
20*f4a2713aSLionel Sambuc 
21*f4a2713aSLionel Sambuc template<int param>
22*f4a2713aSLionel Sambuc class IntTemplate {
23*f4a2713aSLionel Sambuc  public:
24*f4a2713aSLionel Sambuc   IntTemplate() {}
25*f4a2713aSLionel Sambuc };
26*f4a2713aSLionel Sambuc 
27*f4a2713aSLionel Sambuc template<>
28*f4a2713aSLionel Sambuc class BoolTemplate<true> {
29*f4a2713aSLionel Sambuc  public:
30*f4a2713aSLionel Sambuc   BoolTemplate() {}
31*f4a2713aSLionel Sambuc   template<class T> void Foo(T arg) {}
32*f4a2713aSLionel Sambuc };
33*f4a2713aSLionel Sambuc 
34*f4a2713aSLionel Sambuc void template_mangling() {
35*f4a2713aSLionel Sambuc   Class<Typename> c1;
36*f4a2713aSLionel Sambuc // CHECK: call {{.*}} @"\01??0?$Class@VTypename@@@@QAE@XZ"
37*f4a2713aSLionel Sambuc // X64: call {{.*}} @"\01??0?$Class@VTypename@@@@QEAA@XZ"
38*f4a2713aSLionel Sambuc 
39*f4a2713aSLionel Sambuc   Class<const Typename> c1_const;
40*f4a2713aSLionel Sambuc // CHECK: call {{.*}} @"\01??0?$Class@$$CBVTypename@@@@QAE@XZ"
41*f4a2713aSLionel Sambuc // X64: call {{.*}} @"\01??0?$Class@$$CBVTypename@@@@QEAA@XZ"
42*f4a2713aSLionel Sambuc   Class<volatile Typename> c1_volatile;
43*f4a2713aSLionel Sambuc // CHECK: call {{.*}} @"\01??0?$Class@$$CCVTypename@@@@QAE@XZ"
44*f4a2713aSLionel Sambuc // X64: call {{.*}} @"\01??0?$Class@$$CCVTypename@@@@QEAA@XZ"
45*f4a2713aSLionel Sambuc   Class<const volatile Typename> c1_cv;
46*f4a2713aSLionel Sambuc // CHECK: call {{.*}} @"\01??0?$Class@$$CDVTypename@@@@QAE@XZ"
47*f4a2713aSLionel Sambuc // X64: call {{.*}} @"\01??0?$Class@$$CDVTypename@@@@QEAA@XZ"
48*f4a2713aSLionel Sambuc 
49*f4a2713aSLionel Sambuc   Class<Nested<Typename> > c2;
50*f4a2713aSLionel Sambuc // CHECK: call {{.*}} @"\01??0?$Class@V?$Nested@VTypename@@@@@@QAE@XZ"
51*f4a2713aSLionel Sambuc // X64: call {{.*}} @"\01??0?$Class@V?$Nested@VTypename@@@@@@QEAA@XZ"
52*f4a2713aSLionel Sambuc 
53*f4a2713aSLionel Sambuc   Class<int * const> c_intpc;
54*f4a2713aSLionel Sambuc // CHECK: call {{.*}} @"\01??0?$Class@QAH@@QAE@XZ"
55*f4a2713aSLionel Sambuc // X64: call {{.*}} @"\01??0?$Class@QEAH@@QEAA@XZ"
56*f4a2713aSLionel Sambuc   Class<int()> c_ft;
57*f4a2713aSLionel Sambuc // CHECK: call {{.*}} @"\01??0?$Class@$$A6AHXZ@@QAE@XZ"
58*f4a2713aSLionel Sambuc // X64: call {{.*}} @"\01??0?$Class@$$A6AHXZ@@QEAA@XZ"
59*f4a2713aSLionel Sambuc   Class<int[]> c_inti;
60*f4a2713aSLionel Sambuc // CHECK: call {{.*}} @"\01??0?$Class@$$BY0A@H@@QAE@XZ"
61*f4a2713aSLionel Sambuc // X64: call {{.*}} @"\01??0?$Class@$$BY0A@H@@QEAA@XZ"
62*f4a2713aSLionel Sambuc   Class<int[5]> c_int5;
63*f4a2713aSLionel Sambuc // CHECK: call {{.*}} @"\01??0?$Class@$$BY04H@@QAE@XZ"
64*f4a2713aSLionel Sambuc // X64: call {{.*}} @"\01??0?$Class@$$BY04H@@QEAA@XZ"
65*f4a2713aSLionel Sambuc   Class<const int[5]> c_intc5;
66*f4a2713aSLionel Sambuc // CHECK: call {{.*}} @"\01??0?$Class@$$BY04$$CBH@@QAE@XZ"
67*f4a2713aSLionel Sambuc // X64: call {{.*}} @"\01??0?$Class@$$BY04$$CBH@@QEAA@XZ"
68*f4a2713aSLionel Sambuc   Class<int * const[5]> c_intpc5;
69*f4a2713aSLionel Sambuc // CHECK: call {{.*}} @"\01??0?$Class@$$BY04QAH@@QAE@XZ"
70*f4a2713aSLionel Sambuc // X64: call {{.*}} @"\01??0?$Class@$$BY04QEAH@@QEAA@XZ"
71*f4a2713aSLionel Sambuc 
72*f4a2713aSLionel Sambuc   BoolTemplate<false> _false;
73*f4a2713aSLionel Sambuc // CHECK: call {{.*}} @"\01??0?$BoolTemplate@$0A@@@QAE@XZ"
74*f4a2713aSLionel Sambuc // X64: call {{.*}} @"\01??0?$BoolTemplate@$0A@@@QEAA@XZ"
75*f4a2713aSLionel Sambuc 
76*f4a2713aSLionel Sambuc   BoolTemplate<true> _true;
77*f4a2713aSLionel Sambuc   // PR13158
78*f4a2713aSLionel Sambuc   _true.Foo(1);
79*f4a2713aSLionel Sambuc // CHECK: call {{.*}} @"\01??0?$BoolTemplate@$00@@QAE@XZ"
80*f4a2713aSLionel Sambuc // X64: call {{.*}} @"\01??0?$BoolTemplate@$00@@QEAA@XZ"
81*f4a2713aSLionel Sambuc // CHECK: call {{.*}} @"\01??$Foo@H@?$BoolTemplate@$00@@QAEXH@Z"
82*f4a2713aSLionel Sambuc // X64: call {{.*}} @"\01??$Foo@H@?$BoolTemplate@$00@@QEAAXH@Z"
83*f4a2713aSLionel Sambuc 
84*f4a2713aSLionel Sambuc   IntTemplate<0> zero;
85*f4a2713aSLionel Sambuc // CHECK: call {{.*}} @"\01??0?$IntTemplate@$0A@@@QAE@XZ"
86*f4a2713aSLionel Sambuc // X64: call {{.*}} @"\01??0?$IntTemplate@$0A@@@QEAA@XZ"
87*f4a2713aSLionel Sambuc 
88*f4a2713aSLionel Sambuc   IntTemplate<5> five;
89*f4a2713aSLionel Sambuc // CHECK: call {{.*}} @"\01??0?$IntTemplate@$04@@QAE@XZ"
90*f4a2713aSLionel Sambuc // X64: call {{.*}} @"\01??0?$IntTemplate@$04@@QEAA@XZ"
91*f4a2713aSLionel Sambuc 
92*f4a2713aSLionel Sambuc   IntTemplate<11> eleven;
93*f4a2713aSLionel Sambuc // CHECK: call {{.*}} @"\01??0?$IntTemplate@$0L@@@QAE@XZ"
94*f4a2713aSLionel Sambuc // X64: call {{.*}} @"\01??0?$IntTemplate@$0L@@@QEAA@XZ"
95*f4a2713aSLionel Sambuc 
96*f4a2713aSLionel Sambuc   IntTemplate<256> _256;
97*f4a2713aSLionel Sambuc // CHECK: call {{.*}} @"\01??0?$IntTemplate@$0BAA@@@QAE@XZ"
98*f4a2713aSLionel Sambuc // X64: call {{.*}} @"\01??0?$IntTemplate@$0BAA@@@QEAA@XZ"
99*f4a2713aSLionel Sambuc 
100*f4a2713aSLionel Sambuc   IntTemplate<513> _513;
101*f4a2713aSLionel Sambuc // CHECK: call {{.*}} @"\01??0?$IntTemplate@$0CAB@@@QAE@XZ"
102*f4a2713aSLionel Sambuc // X64: call {{.*}} @"\01??0?$IntTemplate@$0CAB@@@QEAA@XZ"
103*f4a2713aSLionel Sambuc 
104*f4a2713aSLionel Sambuc   IntTemplate<1026> _1026;
105*f4a2713aSLionel Sambuc // CHECK: call {{.*}} @"\01??0?$IntTemplate@$0EAC@@@QAE@XZ"
106*f4a2713aSLionel Sambuc // X64: call {{.*}} @"\01??0?$IntTemplate@$0EAC@@@QEAA@XZ"
107*f4a2713aSLionel Sambuc 
108*f4a2713aSLionel Sambuc   IntTemplate<65535> ffff;
109*f4a2713aSLionel Sambuc // CHECK: call {{.*}} @"\01??0?$IntTemplate@$0PPPP@@@QAE@XZ"
110*f4a2713aSLionel Sambuc // X64: call {{.*}} @"\01??0?$IntTemplate@$0PPPP@@@QEAA@XZ"
111*f4a2713aSLionel Sambuc }
112*f4a2713aSLionel Sambuc 
113*f4a2713aSLionel Sambuc namespace space {
114*f4a2713aSLionel Sambuc   template<class T> const T& foo(const T& l) { return l; }
115*f4a2713aSLionel Sambuc }
116*f4a2713aSLionel Sambuc // CHECK: "\01??$foo@H@space@@YAABHABH@Z"
117*f4a2713aSLionel Sambuc // X64: "\01??$foo@H@space@@YAAEBHAEBH@Z"
118*f4a2713aSLionel Sambuc 
119*f4a2713aSLionel Sambuc void use() {
120*f4a2713aSLionel Sambuc   space::foo(42);
121*f4a2713aSLionel Sambuc }
122*f4a2713aSLionel Sambuc 
123*f4a2713aSLionel Sambuc // PR13455
124*f4a2713aSLionel Sambuc typedef void (*FunctionPointer)(void);
125*f4a2713aSLionel Sambuc 
126*f4a2713aSLionel Sambuc template <FunctionPointer function>
127*f4a2713aSLionel Sambuc void FunctionPointerTemplate() {
128*f4a2713aSLionel Sambuc   function();
129*f4a2713aSLionel Sambuc }
130*f4a2713aSLionel Sambuc 
131*f4a2713aSLionel Sambuc void spam() {
132*f4a2713aSLionel Sambuc   FunctionPointerTemplate<spam>();
133*f4a2713aSLionel Sambuc // CHECK: "\01??$FunctionPointerTemplate@$1?spam@@YAXXZ@@YAXXZ"
134*f4a2713aSLionel Sambuc // X64: "\01??$FunctionPointerTemplate@$1?spam@@YAXXZ@@YAXXZ"
135*f4a2713aSLionel Sambuc }
136*f4a2713aSLionel Sambuc 
137*f4a2713aSLionel Sambuc // Unlike Itanium, there is no character code to indicate an argument pack.
138*f4a2713aSLionel Sambuc // Tested with MSVC 2013, the first version which supports variadic templates.
139*f4a2713aSLionel Sambuc 
140*f4a2713aSLionel Sambuc template <typename ...Ts> void variadic_fn_template(const Ts &...args) { }
141*f4a2713aSLionel Sambuc void variadic_fn_instantiate() {
142*f4a2713aSLionel Sambuc   variadic_fn_template(0, 1, 3, 4);
143*f4a2713aSLionel Sambuc   variadic_fn_template(0, 1, 'a', "b");
144*f4a2713aSLionel Sambuc }
145*f4a2713aSLionel Sambuc // CHECK: "\01??$variadic_fn_template@HHHH@@YAXABH000@Z"
146*f4a2713aSLionel Sambuc // CHECK: "\01??$variadic_fn_template@HHD$$BY01D@@YAXABH0ABDAAY01$$CBD@Z"
147*f4a2713aSLionel Sambuc 
148*f4a2713aSLionel Sambuc template <typename ...Ts>
149*f4a2713aSLionel Sambuc struct VariadicClass {
150*f4a2713aSLionel Sambuc   VariadicClass() { }
151*f4a2713aSLionel Sambuc   int x;
152*f4a2713aSLionel Sambuc };
153*f4a2713aSLionel Sambuc void variadic_class_instantiate() {
154*f4a2713aSLionel Sambuc   VariadicClass<int, char, bool> a;
155*f4a2713aSLionel Sambuc   VariadicClass<bool, char, int> b;
156*f4a2713aSLionel Sambuc }
157*f4a2713aSLionel Sambuc // CHECK: call {{.*}} @"\01??0?$VariadicClass@HD_N@@QAE@XZ"
158*f4a2713aSLionel Sambuc // CHECK: call {{.*}} @"\01??0?$VariadicClass@_NDH@@QAE@XZ"
159*f4a2713aSLionel Sambuc 
160*f4a2713aSLionel Sambuc template <typename T>
161*f4a2713aSLionel Sambuc struct Second {};
162*f4a2713aSLionel Sambuc 
163*f4a2713aSLionel Sambuc template <typename T, template <class> class>
164*f4a2713aSLionel Sambuc struct Type {};
165*f4a2713aSLionel Sambuc 
166*f4a2713aSLionel Sambuc template <template <class> class T>
167*f4a2713aSLionel Sambuc struct Type2 {};
168*f4a2713aSLionel Sambuc 
169*f4a2713aSLionel Sambuc template <template <class> class T, bool B>
170*f4a2713aSLionel Sambuc struct Thing;
171*f4a2713aSLionel Sambuc 
172*f4a2713aSLionel Sambuc template <template <class> class T>
173*f4a2713aSLionel Sambuc struct Thing<T, false> { };
174*f4a2713aSLionel Sambuc 
175*f4a2713aSLionel Sambuc template <template <class> class T>
176*f4a2713aSLionel Sambuc struct Thing<T, true> { };
177*f4a2713aSLionel Sambuc 
178*f4a2713aSLionel Sambuc void template_template_fun(Type<Thing<Second, true>, Second>) { }
179*f4a2713aSLionel Sambuc // CHECK: "\01?template_template_fun@@YAXU?$Type@U?$Thing@USecond@@$00@@USecond@@@@@Z"
180*f4a2713aSLionel Sambuc 
181*f4a2713aSLionel Sambuc template <typename T>
182*f4a2713aSLionel Sambuc void template_template_specialization();
183*f4a2713aSLionel Sambuc 
184*f4a2713aSLionel Sambuc template <>
185*f4a2713aSLionel Sambuc void template_template_specialization<void (Type<Thing<Second, true>, Second>)>() {
186*f4a2713aSLionel Sambuc }
187*f4a2713aSLionel Sambuc // CHECK: "\01??$template_template_specialization@$$A6AXU?$Type@U?$Thing@USecond@@$00@@USecond@@@@@Z@@YAXXZ"
188*f4a2713aSLionel Sambuc 
189*f4a2713aSLionel Sambuc // PR16788
190*f4a2713aSLionel Sambuc template <decltype(nullptr)> struct S1 {};
191*f4a2713aSLionel Sambuc void f(S1<nullptr>) {}
192*f4a2713aSLionel Sambuc // CHECK: "\01?f@@YAXU?$S1@$0A@@@@Z"
193*f4a2713aSLionel Sambuc 
194*f4a2713aSLionel Sambuc struct record {
195*f4a2713aSLionel Sambuc   int first;
196*f4a2713aSLionel Sambuc   int second;
197*f4a2713aSLionel Sambuc };
198*f4a2713aSLionel Sambuc template <const record &>
199*f4a2713aSLionel Sambuc struct type1 {
200*f4a2713aSLionel Sambuc };
201*f4a2713aSLionel Sambuc extern const record inst;
202*f4a2713aSLionel Sambuc void recref(type1<inst>) {}
203*f4a2713aSLionel Sambuc // CHECK: "\01?recref@@YAXU?$type1@$E?inst@@3Urecord@@B@@@Z"
204*f4a2713aSLionel Sambuc 
205*f4a2713aSLionel Sambuc struct _GUID {};
206*f4a2713aSLionel Sambuc struct __declspec(uuid("{12345678-1234-1234-1234-1234567890aB}")) uuid;
207*f4a2713aSLionel Sambuc 
208*f4a2713aSLionel Sambuc template <typename T, const _GUID *G = &__uuidof(T)>
209*f4a2713aSLionel Sambuc struct UUIDType1 {};
210*f4a2713aSLionel Sambuc 
211*f4a2713aSLionel Sambuc template <typename T, const _GUID &G = __uuidof(T)>
212*f4a2713aSLionel Sambuc struct UUIDType2 {};
213*f4a2713aSLionel Sambuc 
214*f4a2713aSLionel Sambuc void fun(UUIDType1<uuid> a) {}
215*f4a2713aSLionel Sambuc // CHECK: "\01?fun@@YAXU?$UUIDType1@Uuuid@@$1?_GUID_12345678_1234_1234_1234_1234567890ab@@3U__s_GUID@@B@@@Z"
216*f4a2713aSLionel Sambuc void fun(UUIDType2<uuid> b) {}
217*f4a2713aSLionel Sambuc // CHECK: "\01?fun@@YAXU?$UUIDType2@Uuuid@@$E?_GUID_12345678_1234_1234_1234_1234567890ab@@3U__s_GUID@@B@@@Z"
218*f4a2713aSLionel Sambuc 
219*f4a2713aSLionel Sambuc template <typename T> struct TypeWithFriendDefinition {
220*f4a2713aSLionel Sambuc   friend void FunctionDefinedWithInjectedName(TypeWithFriendDefinition<T>) {}
221*f4a2713aSLionel Sambuc };
222*f4a2713aSLionel Sambuc // CHECK: call {{.*}} @"\01?FunctionDefinedWithInjectedName@@YAXU?$TypeWithFriendDefinition@H@@@Z"
223*f4a2713aSLionel Sambuc void CallFunctionDefinedWithInjectedName() {
224*f4a2713aSLionel Sambuc   FunctionDefinedWithInjectedName(TypeWithFriendDefinition<int>());
225*f4a2713aSLionel Sambuc }
226*f4a2713aSLionel Sambuc // CHECK: @"\01?FunctionDefinedWithInjectedName@@YAXU?$TypeWithFriendDefinition@H@@@Z"
227