1 // RUN: %clang_cc1 -fblocks -emit-llvm %s -o - -triple=i386-pc-win32 -std=c++98 | FileCheck %s
2 // RUN: %clang_cc1 -fblocks -emit-llvm %s -o - -triple=x86_64-pc-win32 -std=c++98| FileCheck -check-prefix X64 %s
3
4 int a;
5 // CHECK-DAG: @"\01?a@@3HA"
6
7 namespace N {
8 int b;
9 // CHECK-DAG: @"\01?b@N@@3HA"
10
11 namespace {
12 int anonymous;
13 // CHECK-DAG: @"\01?anonymous@?A@N@@3HA"
14 }
15 }
16
17 static int c;
18 // CHECK-DAG: @c
19
_c(void)20 int _c(void) {return N::anonymous + c;}
21 // CHECK-DAG: @"\01?_c@@YAHXZ"
22 // X64-DAG: @"\01?_c@@YAHXZ"
23
24 class foo {
25 static const short d;
26 // CHECK-DAG: @"\01?d@foo@@0FB"
27 protected:
28 static volatile long e;
29 // CHECK-DAG: @"\01?e@foo@@1JC"
30 public:
31 static const volatile char f;
32 // CHECK-DAG: @"\01?f@foo@@2DD"
33 int operator+(int a);
foo()34 foo(){}
35 // CHECK-DAG: @"\01??0foo@@QAE@XZ"
36 // X64-DAG: @"\01??0foo@@QEAA@XZ"
37
~foo()38 ~foo(){}
39 // CHECK-DAG: @"\01??1foo@@QAE@XZ"
40 // X64-DAG: @"\01??1foo@@QEAA@XZ
41
foo(int i)42 foo(int i){}
43 // CHECK-DAG: @"\01??0foo@@QAE@H@Z"
44 // X64-DAG: @"\01??0foo@@QEAA@H@Z"
45
foo(char * q)46 foo(char *q){}
47 // CHECK-DAG: @"\01??0foo@@QAE@PAD@Z"
48 // X64-DAG: @"\01??0foo@@QEAA@PEAD@Z"
49
static_method()50 static foo* static_method() { return 0; }
51
52 }f,s1(1),s2((char*)0);
53
54 typedef foo (foo2);
55
56 struct bar {
57 static int g;
58 };
59
60 union baz {
61 int a;
62 char b;
63 double c;
64 };
65
66 enum quux {
67 qone,
68 qtwo,
69 qthree
70 };
71
bar()72 foo bar() { return foo(); }
73 // CHECK-DAG: @"\01?bar@@YA?AVfoo@@XZ"
74 // X64-DAG: @"\01?bar@@YA?AVfoo@@XZ"
75
operator +(int a)76 int foo::operator+(int a) {
77 // CHECK-DAG: @"\01??Hfoo@@QAEHH@Z"
78 // X64-DAG: @"\01??Hfoo@@QEAAHH@Z"
79
80 foo::static_method();
81 // CHECK-DAG: @"\01?static_method@foo@@SAPAV1@XZ"
82 // X64-DAG: @"\01?static_method@foo@@SAPEAV1@XZ"
83 bar();
84 return a;
85 }
86
87 const short foo::d = 0;
88 volatile long foo::e;
89 const volatile char foo::f = 'C';
90
91 int bar::g;
92 // CHECK-DAG: @"\01?g@bar@@2HA"
93
94 extern int * const h1 = &a;
95 // CHECK-DAG: @"\01?h1@@3QAHA"
96 extern const int * const h2 = &a;
97 // CHECK-DAG: @"\01?h2@@3QBHB"
98 extern int * const __restrict h3 = &a;
99 // CHECK-DAG: @"\01?h3@@3QIAHIA"
100 // X64-DAG: @"\01?h3@@3QEIAHEIA"
101
102 int i[10][20];
103 // CHECK-DAG: @"\01?i@@3PAY0BE@HA"
104
105 typedef int (*FunT)(int, int);
106 FunT FunArr[10][20];
107 // CHECK-DAG: @"\01?FunArr@@3PAY0BE@P6AHHH@ZA"
108 // X64-DAG: @"\01?FunArr@@3PAY0BE@P6AHHH@ZA"
109
110 int (__stdcall *j)(signed char, unsigned char);
111 // CHECK-DAG: @"\01?j@@3P6GHCE@ZA"
112
113 const volatile char foo2::*k;
114 // CHECK-DAG: @"\01?k@@3PTfoo@@DT1@"
115 // X64-DAG: @"\01?k@@3PETfoo@@DET1@"
116
117 int (foo2::*l)(int);
118 // CHECK-DAG: @"\01?l@@3P8foo@@AEHH@ZQ1@"
119
120 // Ensure typedef CV qualifiers are mangled correctly
121 typedef const int cInt;
122 typedef volatile int vInt;
123 typedef const volatile int cvInt;
124
125 extern cInt g_cInt = 1;
126 vInt g_vInt = 2;
127 cvInt g_cvInt = 3;
128
129 // CHECK-DAG: @"\01?g_cInt@@3HB"
130 // CHECK-DAG: @"\01?g_vInt@@3HC"
131 // CHECK-DAG: @"\01?g_cvInt@@3HD"
132
133 // Static functions are mangled, too.
134 // Also make sure calling conventions, arglists, and throw specs work.
alpha(float a,double b)135 static void __stdcall alpha(float a, double b) throw() {}
beta(long long a,wchar_t b)136 bool __fastcall beta(long long a, wchar_t b) throw(signed char, unsigned char) {
137 // CHECK-DAG: @"\01?beta@@YI_N_J_W@Z"
138 // X64-DAG: @"\01?beta@@YA_N_J_W@Z"
139 alpha(0.f, 0.0);
140 return false;
141 }
142
143 // CHECK-DAG: @"\01?alpha@@YGXMN@Z"
144 // X64-DAG: @"\01?alpha@@YAXMN@Z"
145
146 // Make sure tag-type mangling works.
gamma(class foo,struct bar,union baz,enum quux)147 void gamma(class foo, struct bar, union baz, enum quux) {}
148 // CHECK-DAG: @"\01?gamma@@YAXVfoo@@Ubar@@Tbaz@@W4quux@@@Z"
149 // X64-DAG: @"\01?gamma@@YAXVfoo@@Ubar@@Tbaz@@W4quux@@@Z"
150
151 // Make sure pointer/reference-type mangling works.
delta(int * const a,const long &)152 void delta(int * const a, const long &) {}
153 // CHECK-DAG: @"\01?delta@@YAXQAHABJ@Z"
154 // X64-DAG: @"\01?delta@@YAXQEAHAEBJ@Z"
155
156 // Array mangling.
epsilon(int a[][10][20])157 void epsilon(int a[][10][20]) {}
158 // CHECK-DAG: @"\01?epsilon@@YAXQAY19BE@H@Z"
159 // X64-DAG: @"\01?epsilon@@YAXQEAY19BE@H@Z"
160
zeta(int (*)(int,int))161 void zeta(int (*)(int, int)) {}
162 // CHECK-DAG: @"\01?zeta@@YAXP6AHHH@Z@Z"
163 // X64-DAG: @"\01?zeta@@YAXP6AHHH@Z@Z"
164
165 // Blocks mangling (Clang extension). A block should be mangled slightly
166 // differently from a similar function pointer.
167 void eta(int (^)(int, int)) {}
168 // CHECK-DAG: @"\01?eta@@YAXP_EAHHH@Z@Z"
169
170 typedef int theta_arg(int,int);
171 void theta(theta_arg^ block) {}
172 // CHECK-DAG: @"\01?theta@@YAXP_EAHHH@Z@Z"
173
operator_new_delete()174 void operator_new_delete() {
175 char *ptr = new char;
176 // CHECK-DAG: @"\01??2@YAPAXI@Z"
177
178 delete ptr;
179 // CHECK-DAG: @"\01??3@YAXPAX@Z"
180
181 char *array = new char[42];
182 // CHECK-DAG: @"\01??_U@YAPAXI@Z"
183
184 delete [] array;
185 // CHECK-DAG: @"\01??_V@YAXPAX@Z"
186 }
187
188 // PR13022
189 void (redundant_parens)();
redundant_parens_use()190 void redundant_parens_use() { redundant_parens(); }
191 // CHECK-DAG: @"\01?redundant_parens@@YAXXZ"
192 // X64-DAG: @"\01?redundant_parens@@YAXXZ"
193
194 // PR13047
195 typedef double RGB[3];
196 RGB color1;
197 // CHECK-DAG: @"\01?color1@@3PANA"
198 extern const RGB color2 = {};
199 // CHECK-DAG: @"\01?color2@@3QBNB"
200 extern RGB const color3[5] = {};
201 // CHECK-DAG: @"\01?color3@@3QAY02$$CBNA"
202 extern RGB const ((color4)[5]) = {};
203 // CHECK-DAG: @"\01?color4@@3QAY02$$CBNA"
204
205 struct B;
206 volatile int B::* volatile memptr1;
207 // X64-DAG: @"\01?memptr1@@3RESB@@HES1@"
208 volatile int B::* memptr2;
209 // X64-DAG: @"\01?memptr2@@3PESB@@HES1@"
210 int B::* volatile memptr3;
211 // X64-DAG: @"\01?memptr3@@3REQB@@HEQ1@"
212 typedef int (*fun)();
213 volatile fun B::* volatile funmemptr1;
214 // X64-DAG: @"\01?funmemptr1@@3RESB@@R6AHXZES1@"
215 volatile fun B::* funmemptr2;
216 // X64-DAG: @"\01?funmemptr2@@3PESB@@R6AHXZES1@"
217 fun B::* volatile funmemptr3;
218 // X64-DAG: @"\01?funmemptr3@@3REQB@@P6AHXZEQ1@"
219 void (B::* volatile memptrtofun1)();
220 // X64-DAG: @"\01?memptrtofun1@@3R8B@@EAAXXZEQ1@"
221 const void (B::* memptrtofun2)();
222 // X64-DAG: @"\01?memptrtofun2@@3P8B@@EAAXXZEQ1@"
223 volatile void (B::* memptrtofun3)();
224 // X64-DAG: @"\01?memptrtofun3@@3P8B@@EAAXXZEQ1@"
225 int (B::* volatile memptrtofun4)();
226 // X64-DAG: @"\01?memptrtofun4@@3R8B@@EAAHXZEQ1@"
227 volatile int (B::* memptrtofun5)();
228 // X64-DAG: @"\01?memptrtofun5@@3P8B@@EAA?CHXZEQ1@"
229 const int (B::* memptrtofun6)();
230 // X64-DAG: @"\01?memptrtofun6@@3P8B@@EAA?BHXZEQ1@"
231 fun (B::* volatile memptrtofun7)();
232 // X64-DAG: @"\01?memptrtofun7@@3R8B@@EAAP6AHXZXZEQ1@"
233 volatile fun (B::* memptrtofun8)();
234 // X64-DAG: @"\01?memptrtofun8@@3P8B@@EAAR6AHXZXZEQ1@"
235 const fun (B::* memptrtofun9)();
236 // X64-DAG: @"\01?memptrtofun9@@3P8B@@EAAQ6AHXZXZEQ1@"
237
238 // PR12603
239 enum E {};
240 // CHECK-DAG: "\01?fooE@@YA?AW4E@@XZ"
241 // X64-DAG: "\01?fooE@@YA?AW4E@@XZ"
fooE()242 E fooE() { return E(); }
243
244 class X {};
245 // CHECK-DAG: "\01?fooX@@YA?AVX@@XZ"
246 // X64-DAG: "\01?fooX@@YA?AVX@@XZ"
fooX()247 X fooX() { return X(); }
248
249 namespace PR13182 {
250 extern char s0[];
251 // CHECK-DAG: @"\01?s0@PR13182@@3PADA"
252 extern char s1[42];
253 // CHECK-DAG: @"\01?s1@PR13182@@3PADA"
254 extern const char s2[];
255 // CHECK-DAG: @"\01?s2@PR13182@@3QBDB"
256 extern const char s3[42];
257 // CHECK-DAG: @"\01?s3@PR13182@@3QBDB"
258 extern volatile char s4[];
259 // CHECK-DAG: @"\01?s4@PR13182@@3RCDC"
260 extern const volatile char s5[];
261 // CHECK-DAG: @"\01?s5@PR13182@@3SDDD"
262 extern const char* const* s6;
263 // CHECK-DAG: @"\01?s6@PR13182@@3PBQBDB"
264
foo()265 char foo() {
266 return s0[0] + s1[0] + s2[0] + s3[0] + s4[0] + s5[0] + s6[0][0];
267 }
268 }
269
extern_c_func()270 extern "C" inline void extern_c_func() {
271 static int local;
272 // CHECK-DAG: @"\01?local@?1??extern_c_func@@9@4HA"
273 // X64-DAG: @"\01?local@?1??extern_c_func@@9@4HA"
274 }
275
call_extern_c_func()276 void call_extern_c_func() {
277 extern_c_func();
278 }
279
main()280 int main() { return 0; }
281 // CHECK-DAG: @main
282 // X64-DAG: @main
283
wmain()284 int wmain() { return 0; }
285 // CHECK-DAG: @wmain
286 // X64-DAG: @wmain
287
WinMain()288 int WinMain() { return 0; }
289 // CHECK-DAG: @WinMain
290 // X64-DAG: @WinMain
291
wWinMain()292 int wWinMain() { return 0; }
293 // CHECK-DAG: @wWinMain
294 // X64-DAG: @wWinMain
295
DllMain()296 int DllMain() { return 0; }
297 // CHECK-DAG: @DllMain
298 // X64-DAG: @DllMain
299
inline_function_with_local_type()300 inline int inline_function_with_local_type() {
301 static struct {
302 int a_field;
303 } static_variable_in_inline_function = { 20 }, second_static = { 40 };
304 // CHECK: @"\01?static_variable_in_inline_function@?1??inline_function_with_local_type@@YAHXZ@4U<unnamed-type-static_variable_in_inline_function>@?1??1@YAHXZ@A"
305
306 return static_variable_in_inline_function.a_field + second_static.a_field;
307 }
308
call_inline_function_with_local_type()309 int call_inline_function_with_local_type() {
310 return inline_function_with_local_type();
311 }
312
313 template <typename T>
templated_inline_function_with_local_type()314 inline int templated_inline_function_with_local_type() {
315 static struct {
316 int a_field;
317 } static_variable_in_templated_inline_function = { 20 },
318 second_static = { 40 };
319 // CHECK: @"\01?static_variable_in_templated_inline_function@?1???$templated_inline_function_with_local_type@H@@YAHXZ@4U<unnamed-type-static_variable_in_templated_inline_function>@?1???$templated_inline_function_with_local_type@H@@YAHXZ@A"
320
321 return static_variable_in_templated_inline_function.a_field +
322 second_static.a_field;
323 }
324
call_templated_inline_function_with_local_type()325 int call_templated_inline_function_with_local_type() {
326 return templated_inline_function_with_local_type<int>();
327 }
328
329 // PR17371
330 struct OverloadedNewDelete {
331 // __cdecl
332 void *operator new(__SIZE_TYPE__);
333 void *operator new[](__SIZE_TYPE__);
334 void operator delete(void *);
335 void operator delete[](void *);
336 // __thiscall
337 int operator+(int);
338 };
339
operator new(__SIZE_TYPE__ s)340 void *OverloadedNewDelete::operator new(__SIZE_TYPE__ s) { return 0; }
operator new[](__SIZE_TYPE__ s)341 void *OverloadedNewDelete::operator new[](__SIZE_TYPE__ s) { return 0; }
operator delete(void *)342 void OverloadedNewDelete::operator delete(void *) { }
operator delete[](void *)343 void OverloadedNewDelete::operator delete[](void *) { }
operator +(int x)344 int OverloadedNewDelete::operator+(int x) { return x; };
345
346 // CHECK-DAG: ??2OverloadedNewDelete@@SAPAXI@Z
347 // CHECK-DAG: ??_UOverloadedNewDelete@@SAPAXI@Z
348 // CHECK-DAG: ??3OverloadedNewDelete@@SAXPAX@Z
349 // CHECK-DAG: ??_VOverloadedNewDelete@@SAXPAX@Z
350 // CHECK-DAG: ??HOverloadedNewDelete@@QAEHH@Z
351
352 // X64-DAG: ??2OverloadedNewDelete@@SAPEAX_K@Z
353 // X64-DAG: ??_UOverloadedNewDelete@@SAPEAX_K@Z
354 // X64-DAG: ??3OverloadedNewDelete@@SAXPEAX@Z
355 // X64-DAG: ??_VOverloadedNewDelete@@SAXPEAX@Z
356 // X64-DAG: ??HOverloadedNewDelete@@QEAAHH@Z
357
358 // Indirecting the function type through a typedef will require a calling
359 // convention adjustment before building the method decl.
360
361 typedef void *__thiscall OperatorNewType(__SIZE_TYPE__);
362 typedef void __thiscall OperatorDeleteType(void *);
363
364 struct TypedefNewDelete {
365 OperatorNewType operator new;
366 OperatorNewType operator new[];
367 OperatorDeleteType operator delete;
368 OperatorDeleteType operator delete[];
369 };
370
operator new(__SIZE_TYPE__ s)371 void *TypedefNewDelete::operator new(__SIZE_TYPE__ s) { return 0; }
operator new[](__SIZE_TYPE__ s)372 void *TypedefNewDelete::operator new[](__SIZE_TYPE__ s) { return 0; }
operator delete(void *)373 void TypedefNewDelete::operator delete(void *) { }
operator delete[](void *)374 void TypedefNewDelete::operator delete[](void *) { }
375
376 // CHECK-DAG: ??2TypedefNewDelete@@SAPAXI@Z
377 // CHECK-DAG: ??_UTypedefNewDelete@@SAPAXI@Z
378 // CHECK-DAG: ??3TypedefNewDelete@@SAXPAX@Z
379 // CHECK-DAG: ??_VTypedefNewDelete@@SAXPAX@Z
380
vector_func()381 void __vectorcall vector_func() { }
382 // CHECK-DAG: @"\01?vector_func@@YQXXZ"
383
384 template <void (*)(void)>
fn_tmpl()385 void fn_tmpl() {}
386
387 template void fn_tmpl<extern_c_func>();
388 // CHECK-DAG: @"\01??$fn_tmpl@$1?extern_c_func@@YAXXZ@@YAXXZ"
389
overloaded_fn()390 extern "C" void __attribute__((overloadable)) overloaded_fn() {}
391 // CHECK-DAG: @"\01?overloaded_fn@@$$J0YAXXZ"
392
393 namespace UnnamedType {
394 struct S {
395 typedef struct {} *T1[1];
396 typedef struct {} T2;
397 typedef struct {} *T3, T4;
398 using T5 = struct {};
399 using T6 = struct {} *;
400 };
f(S::T1)401 void f(S::T1) {}
f(S::T2)402 void f(S::T2) {}
f(S::T3)403 void f(S::T3) {}
f(S::T4)404 void f(S::T4) {}
f(S::T5)405 void f(S::T5) {}
f(S::T6)406 void f(S::T6) {}
407 // CHECK-DAG: @"\01?f@UnnamedType@@YAXQAPAU<unnamed-type-T1>@S@1@@Z"
408 // CHECK-DAG: @"\01?f@UnnamedType@@YAXUT2@S@1@@Z"
409 // CHECK-DAG: @"\01?f@UnnamedType@@YAXPAUT4@S@1@@Z"
410 // CHECK-DAG: @"\01?f@UnnamedType@@YAXUT4@S@1@@Z"
411 // CHECK-DAG: @"\01?f@UnnamedType@@YAXUT5@S@1@@Z"
412 // CHECK-DAG: @"\01?f@UnnamedType@@YAXPAU<unnamed-type-T6>@S@1@@Z"
413
414 // X64-DAG: @"\01?f@UnnamedType@@YAXQEAPEAU<unnamed-type-T1>@S@1@@Z"
415 // X64-DAG: @"\01?f@UnnamedType@@YAXUT2@S@1@@Z"
416 // X64-DAG: @"\01?f@UnnamedType@@YAXPEAUT4@S@1@@Z"(%"struct.UnnamedType::S::T4"
417 // X64-DAG: @"\01?f@UnnamedType@@YAXUT4@S@1@@Z"
418 // X64-DAG: @"\01?f@UnnamedType@@YAXUT5@S@1@@Z"
419 // X64-DAG: @"\01?f@UnnamedType@@YAXPEAU<unnamed-type-T6>@S@1@@Z"
420 }
421
422 namespace PassObjectSize {
423 // NOTE: This mangling is subject to change.
424 // Reiterating from the comment in MicrosoftMangle, the scheme is pretend a
425 // parameter of type __clang::__pass_object_sizeN exists after each pass object
426 // size param P, where N is the Type of the pass_object_size attribute on P.
427 //
428 // e.g. we want to mangle:
429 // void foo(void *const __attribute__((pass_object_size(0))));
430 // as if it were
431 // namespace __clang { enum __pass_object_size0 : size_t {}; }
432 // void foo(void *const, __clang::__pass_object_size0);
433 // where __clang is a top-level namespace.
434
435 // CHECK-DAG: define i32 @"\01?foo@PassObjectSize@@YAHQAHW4__pass_object_size0@__clang@@@Z"
foo(int * const i)436 int foo(int *const i __attribute__((pass_object_size(0)))) { return 0; }
437 // CHECK-DAG: define i32 @"\01?bar@PassObjectSize@@YAHQAHW4__pass_object_size1@__clang@@@Z"
bar(int * const i)438 int bar(int *const i __attribute__((pass_object_size(1)))) { return 0; }
439 }
440