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