Clang Project

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