1 // RUN: %clang_cc1 -fblocks -emit-llvm %s -o - -triple=i386-pc-win32 -std=c++11 | FileCheck %s
2 // RUN: %clang_cc1 -fblocks -emit-llvm %s -o - -triple=x86_64-pc-win32 -std=c++11| 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 
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);
34   foo(){}
35 // CHECK-DAG: @"\01??0foo@@QAE@XZ"
36 // X64-DAG:   @"\01??0foo@@QEAA@XZ"
37 
38   ~foo(){}
39 // CHECK-DAG: @"\01??1foo@@QAE@XZ"
40 // X64-DAG:   @"\01??1foo@@QEAA@XZ
41 
42   foo(int i){}
43 // CHECK-DAG: @"\01??0foo@@QAE@H@Z"
44 // X64-DAG:   @"\01??0foo@@QEAA@H@Z"
45 
46   foo(char *q){}
47 // CHECK-DAG: @"\01??0foo@@QAE@PAD@Z"
48 // X64-DAG:   @"\01??0foo@@QEAA@PEAD@Z"
49 
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 
72 foo bar() { return foo(); }
73 // CHECK-DAG: @"\01?bar@@YA?AVfoo@@XZ"
74 // X64-DAG:   @"\01?bar@@YA?AVfoo@@XZ"
75 
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 // Static functions are mangled, too.
121 // Also make sure calling conventions, arglists, and throw specs work.
122 static void __stdcall alpha(float a, double b) throw() {}
123 bool __fastcall beta(long long a, wchar_t b) throw(signed char, unsigned char) {
124 // CHECK-DAG: @"\01?beta@@YI_N_J_W@Z"
125 // X64-DAG:   @"\01?beta@@YA_N_J_W@Z"
126   alpha(0.f, 0.0);
127   return false;
128 }
129 
130 // CHECK-DAG: @"\01?alpha@@YGXMN@Z"
131 // X64-DAG:   @"\01?alpha@@YAXMN@Z"
132 
133 // Make sure tag-type mangling works.
134 void gamma(class foo, struct bar, union baz, enum quux) {}
135 // CHECK-DAG: @"\01?gamma@@YAXVfoo@@Ubar@@Tbaz@@W4quux@@@Z"
136 // X64-DAG:   @"\01?gamma@@YAXVfoo@@Ubar@@Tbaz@@W4quux@@@Z"
137 
138 // Make sure pointer/reference-type mangling works.
139 void delta(int * const a, const long &) {}
140 // CHECK-DAG: @"\01?delta@@YAXQAHABJ@Z"
141 // X64-DAG:   @"\01?delta@@YAXQEAHAEBJ@Z"
142 
143 // Array mangling.
144 void epsilon(int a[][10][20]) {}
145 // CHECK-DAG: @"\01?epsilon@@YAXQAY19BE@H@Z"
146 // X64-DAG:   @"\01?epsilon@@YAXQEAY19BE@H@Z"
147 
148 void zeta(int (*)(int, int)) {}
149 // CHECK-DAG: @"\01?zeta@@YAXP6AHHH@Z@Z"
150 // X64-DAG:   @"\01?zeta@@YAXP6AHHH@Z@Z"
151 
152 // Blocks mangling (Clang extension). A block should be mangled slightly
153 // differently from a similar function pointer.
154 void eta(int (^)(int, int)) {}
155 // CHECK-DAG: @"\01?eta@@YAXP_EAHHH@Z@Z"
156 
157 typedef int theta_arg(int,int);
158 void theta(theta_arg^ block) {}
159 // CHECK-DAG: @"\01?theta@@YAXP_EAHHH@Z@Z"
160 
161 void operator_new_delete() {
162   char *ptr = new char;
163 // CHECK-DAG: @"\01??2@YAPAXI@Z"
164 
165   delete ptr;
166 // CHECK-DAG: @"\01??3@YAXPAX@Z"
167 
168   char *array = new char[42];
169 // CHECK-DAG: @"\01??_U@YAPAXI@Z"
170 
171   delete [] array;
172 // CHECK-DAG: @"\01??_V@YAXPAX@Z"
173 }
174 
175 // PR13022
176 void (redundant_parens)();
177 void redundant_parens_use() { redundant_parens(); }
178 // CHECK-DAG: @"\01?redundant_parens@@YAXXZ"
179 // X64-DAG:   @"\01?redundant_parens@@YAXXZ"
180 
181 // PR13047
182 typedef double RGB[3];
183 RGB color1;
184 // CHECK-DAG: @"\01?color1@@3PANA"
185 extern const RGB color2 = {};
186 // CHECK-DAG: @"\01?color2@@3QBNB"
187 extern RGB const color3[5] = {};
188 // CHECK-DAG: @"\01?color3@@3QAY02$$CBNA"
189 extern RGB const ((color4)[5]) = {};
190 // CHECK-DAG: @"\01?color4@@3QAY02$$CBNA"
191 
192 struct B;
193 volatile int B::* volatile memptr1;
194 // X64-DAG: @"\01?memptr1@@3RESB@@HES1@"
195 volatile int B::* memptr2;
196 // X64-DAG: @"\01?memptr2@@3PESB@@HES1@"
197 int B::* volatile memptr3;
198 // X64-DAG: @"\01?memptr3@@3REQB@@HEQ1@"
199 typedef int (*fun)();
200 volatile fun B::* volatile funmemptr1;
201 // X64-DAG: @"\01?funmemptr1@@3RESB@@R6AHXZES1@"
202 volatile fun B::* funmemptr2;
203 // X64-DAG: @"\01?funmemptr2@@3PESB@@R6AHXZES1@"
204 fun B::* volatile funmemptr3;
205 // X64-DAG: @"\01?funmemptr3@@3REQB@@P6AHXZEQ1@"
206 void (B::* volatile memptrtofun1)();
207 // X64-DAG: @"\01?memptrtofun1@@3R8B@@EAAXXZEQ1@"
208 const void (B::* memptrtofun2)();
209 // X64-DAG: @"\01?memptrtofun2@@3P8B@@EAAXXZEQ1@"
210 volatile void (B::* memptrtofun3)();
211 // X64-DAG: @"\01?memptrtofun3@@3P8B@@EAAXXZEQ1@"
212 int (B::* volatile memptrtofun4)();
213 // X64-DAG: @"\01?memptrtofun4@@3R8B@@EAAHXZEQ1@"
214 volatile int (B::* memptrtofun5)();
215 // X64-DAG: @"\01?memptrtofun5@@3P8B@@EAA?CHXZEQ1@"
216 const int (B::* memptrtofun6)();
217 // X64-DAG: @"\01?memptrtofun6@@3P8B@@EAA?BHXZEQ1@"
218 fun (B::* volatile memptrtofun7)();
219 // X64-DAG: @"\01?memptrtofun7@@3R8B@@EAAP6AHXZXZEQ1@"
220 volatile fun (B::* memptrtofun8)();
221 // X64-DAG: @"\01?memptrtofun8@@3P8B@@EAAR6AHXZXZEQ1@"
222 const fun (B::* memptrtofun9)();
223 // X64-DAG: @"\01?memptrtofun9@@3P8B@@EAAQ6AHXZXZEQ1@"
224 
225 // PR12603
226 enum E {};
227 // CHECK-DAG: "\01?fooE@@YA?AW4E@@XZ"
228 // X64-DAG:   "\01?fooE@@YA?AW4E@@XZ"
229 E fooE() { return E(); }
230 
231 class X {};
232 // CHECK-DAG: "\01?fooX@@YA?AVX@@XZ"
233 // X64-DAG:   "\01?fooX@@YA?AVX@@XZ"
234 X fooX() { return X(); }
235 
236 namespace PR13182 {
237   extern char s0[];
238   // CHECK-DAG: @"\01?s0@PR13182@@3PADA"
239   extern char s1[42];
240   // CHECK-DAG: @"\01?s1@PR13182@@3PADA"
241   extern const char s2[];
242   // CHECK-DAG: @"\01?s2@PR13182@@3QBDB"
243   extern const char s3[42];
244   // CHECK-DAG: @"\01?s3@PR13182@@3QBDB"
245   extern volatile char s4[];
246   // CHECK-DAG: @"\01?s4@PR13182@@3RCDC"
247   extern const volatile char s5[];
248   // CHECK-DAG: @"\01?s5@PR13182@@3SDDD"
249   extern const char* const* s6;
250   // CHECK-DAG: @"\01?s6@PR13182@@3PBQBDB"
251 
252   char foo() {
253     return s0[0] + s1[0] + s2[0] + s3[0] + s4[0] + s5[0] + s6[0][0];
254   }
255 }
256 
257 namespace EnumMangling {
258   extern enum Enum01 { } Enum;
259   extern enum Enum02 : bool { } BoolEnum;
260   extern enum Enum03 : char { } CharEnum;
261   extern enum Enum04 : signed char { } SCharEnum;
262   extern enum Enum05 : unsigned char { } UCharEnum;
263   extern enum Enum06 : short { } SShortEnum;
264   extern enum Enum07 : unsigned short { } UShortEnum;
265   extern enum Enum08 : int { } SIntEnum;
266   extern enum Enum09 : unsigned int { } UIntEnum;
267   extern enum Enum10 : long { } SLongEnum;
268   extern enum Enum11 : unsigned long { } ULongEnum;
269   extern enum Enum12 : long long { } SLongLongEnum;
270   extern enum Enum13 : unsigned long long { } ULongLongEnum;
271 // CHECK-DAG: @"\01?Enum@EnumMangling@@3W4Enum01@1@A"
272 // CHECK-DAG: @"\01?BoolEnum@EnumMangling@@3W4Enum02@1@A
273 // CHECK-DAG: @"\01?CharEnum@EnumMangling@@3W4Enum03@1@A
274 // CHECK-DAG: @"\01?SCharEnum@EnumMangling@@3W4Enum04@1@A
275 // CHECK-DAG: @"\01?UCharEnum@EnumMangling@@3W4Enum05@1@A
276 // CHECK-DAG: @"\01?SShortEnum@EnumMangling@@3W4Enum06@1@A"
277 // CHECK-DAG: @"\01?UShortEnum@EnumMangling@@3W4Enum07@1@A"
278 // CHECK-DAG: @"\01?SIntEnum@EnumMangling@@3W4Enum08@1@A"
279 // CHECK-DAG: @"\01?UIntEnum@EnumMangling@@3W4Enum09@1@A"
280 // CHECK-DAG: @"\01?SLongEnum@EnumMangling@@3W4Enum10@1@A"
281 // CHECK-DAG: @"\01?ULongEnum@EnumMangling@@3W4Enum11@1@A"
282 // CHECK-DAG: @"\01?SLongLongEnum@EnumMangling@@3W4Enum12@1@A"
283 // CHECK-DAG: @"\01?ULongLongEnum@EnumMangling@@3W4Enum13@1@A"
284   decltype(Enum) *UseEnum() { return &Enum; }
285   decltype(BoolEnum) *UseBoolEnum() { return &BoolEnum; }
286   decltype(CharEnum) *UseCharEnum() { return &CharEnum; }
287   decltype(SCharEnum) *UseSCharEnum() { return &SCharEnum; }
288   decltype(UCharEnum) *UseUCharEnum() { return &UCharEnum; }
289   decltype(SShortEnum) *UseSShortEnum() { return &SShortEnum; }
290   decltype(UShortEnum) *UseUShortEnum() { return &UShortEnum; }
291   decltype(SIntEnum) *UseSIntEnum() { return &SIntEnum; }
292   decltype(UIntEnum) *UseUIntEnum() { return &UIntEnum; }
293   decltype(SLongEnum) *UseSLongEnum() { return &SLongEnum; }
294   decltype(ULongEnum) *UseULongEnum() { return &ULongEnum; }
295   decltype(SLongLongEnum) *UseSLongLongEnum() { return &SLongLongEnum; }
296   decltype(ULongLongEnum) *UseULongLongEnum() { return &ULongLongEnum; }
297   extern enum class EnumClass01 { } EnumClass;
298   extern enum class EnumClass02 : bool { } BoolEnumClass;
299   extern enum class EnumClass03 : char { } CharEnumClass;
300   extern enum class EnumClass04 : signed char { } SCharEnumClass;
301   extern enum class EnumClass05 : unsigned char { } UCharEnumClass;
302   extern enum class EnumClass06 : short { } SShortEnumClass;
303   extern enum class EnumClass07 : unsigned short { } UShortEnumClass;
304   extern enum class EnumClass08 : int { } SIntEnumClass;
305   extern enum class EnumClass09 : unsigned int { } UIntEnumClass;
306   extern enum class EnumClass10 : long { } SLongEnumClass;
307   extern enum class EnumClass11 : unsigned long { } ULongEnumClass;
308   extern enum class EnumClass12 : long long { } SLongLongEnumClass;
309   extern enum class EnumClass13 : unsigned long long { } ULongLongEnumClass;
310 // CHECK-DAG: @"\01?EnumClass@EnumMangling@@3W4EnumClass01@1@A"
311 // CHECK-DAG: @"\01?BoolEnumClass@EnumMangling@@3W4EnumClass02@1@A
312 // CHECK-DAG: @"\01?CharEnumClass@EnumMangling@@3W4EnumClass03@1@A
313 // CHECK-DAG: @"\01?SCharEnumClass@EnumMangling@@3W4EnumClass04@1@A
314 // CHECK-DAG: @"\01?UCharEnumClass@EnumMangling@@3W4EnumClass05@1@A
315 // CHECK-DAG: @"\01?SShortEnumClass@EnumMangling@@3W4EnumClass06@1@A"
316 // CHECK-DAG: @"\01?UShortEnumClass@EnumMangling@@3W4EnumClass07@1@A"
317 // CHECK-DAG: @"\01?SIntEnumClass@EnumMangling@@3W4EnumClass08@1@A"
318 // CHECK-DAG: @"\01?UIntEnumClass@EnumMangling@@3W4EnumClass09@1@A"
319 // CHECK-DAG: @"\01?SLongEnumClass@EnumMangling@@3W4EnumClass10@1@A"
320 // CHECK-DAG: @"\01?ULongEnumClass@EnumMangling@@3W4EnumClass11@1@A"
321 // CHECK-DAG: @"\01?SLongLongEnumClass@EnumMangling@@3W4EnumClass12@1@A"
322 // CHECK-DAG: @"\01?ULongLongEnumClass@EnumMangling@@3W4EnumClass13@1@A"
323   decltype(EnumClass) *UseEnumClass() { return &EnumClass; }
324   decltype(BoolEnumClass) *UseBoolEnumClass() { return &BoolEnumClass; }
325   decltype(CharEnumClass) *UseCharEnumClass() { return &CharEnumClass; }
326   decltype(SCharEnumClass) *UseSCharEnumClass() { return &SCharEnumClass; }
327   decltype(UCharEnumClass) *UseUCharEnumClass() { return &UCharEnumClass; }
328   decltype(SShortEnumClass) *UseSShortEnumClass() { return &SShortEnumClass; }
329   decltype(UShortEnumClass) *UseUShortEnumClass() { return &UShortEnumClass; }
330   decltype(SIntEnumClass) *UseSIntEnumClass() { return &SIntEnumClass; }
331   decltype(UIntEnumClass) *UseUIntEnumClass() { return &UIntEnumClass; }
332   decltype(SLongEnumClass) *UseSLongEnumClass() { return &SLongEnumClass; }
333   decltype(ULongEnumClass) *UseULongEnumClass() { return &ULongEnumClass; }
334   decltype(SLongLongEnumClass) *UseSLongLongEnumClass() { return &SLongLongEnumClass; }
335   decltype(ULongLongEnumClass) *UseULongLongEnumClass() { return &ULongLongEnumClass; }
336 }
337 
338 extern "C" inline void extern_c_func() {
339   static int local;
340 // CHECK-DAG: @"\01?local@?1??extern_c_func@@9@4HA"
341 // X64-DAG:   @"\01?local@?1??extern_c_func@@9@4HA"
342 }
343 
344 void call_extern_c_func() {
345   extern_c_func();
346 }
347 
348 int main() { return 0; }
349 // CHECK-DAG: @main
350 // X64-DAG:   @main
351 
352 int wmain() { return 0; }
353 // CHECK-DAG: @wmain
354 // X64-DAG:   @wmain
355 
356 int WinMain() { return 0; }
357 // CHECK-DAG: @WinMain
358 // X64-DAG:   @WinMain
359 
360 int wWinMain() { return 0; }
361 // CHECK-DAG: @wWinMain
362 // X64-DAG:   @wWinMain
363 
364 int DllMain() { return 0; }
365 // CHECK-DAG: @DllMain
366 // X64-DAG:   @DllMain
367 
368 inline int inline_function_with_local_type() {
369   static struct {
370     int a_field;
371   } static_variable_in_inline_function = { 20 }, second_static = { 40 };
372   // 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"
373 
374   return static_variable_in_inline_function.a_field + second_static.a_field;
375 }
376 
377 int call_inline_function_with_local_type() {
378   return inline_function_with_local_type();
379 }
380 
381 template <typename T>
382 inline int templated_inline_function_with_local_type() {
383   static struct {
384     int a_field;
385   } static_variable_in_templated_inline_function = { 20 },
386     second_static = { 40 };
387   // 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"
388 
389   return static_variable_in_templated_inline_function.a_field +
390          second_static.a_field;
391 }
392 
393 int call_templated_inline_function_with_local_type() {
394   return templated_inline_function_with_local_type<int>();
395 }
396 
397 // PR17371
398 struct OverloadedNewDelete {
399   // __cdecl
400   void *operator new(__SIZE_TYPE__);
401   void *operator new[](__SIZE_TYPE__);
402   void operator delete(void *);
403   void operator delete[](void *);
404   // __thiscall
405   int operator+(int);
406 };
407 
408 void *OverloadedNewDelete::operator new(__SIZE_TYPE__ s) { return 0; }
409 void *OverloadedNewDelete::operator new[](__SIZE_TYPE__ s) { return 0; }
410 void OverloadedNewDelete::operator delete(void *) { }
411 void OverloadedNewDelete::operator delete[](void *) { }
412 int OverloadedNewDelete::operator+(int x) { return x; };
413 
414 // CHECK-DAG: ??2OverloadedNewDelete@@SAPAXI@Z
415 // CHECK-DAG: ??_UOverloadedNewDelete@@SAPAXI@Z
416 // CHECK-DAG: ??3OverloadedNewDelete@@SAXPAX@Z
417 // CHECK-DAG: ??_VOverloadedNewDelete@@SAXPAX@Z
418 // CHECK-DAG: ??HOverloadedNewDelete@@QAEHH@Z
419 
420 // X64-DAG:   ??2OverloadedNewDelete@@SAPEAX_K@Z
421 // X64-DAG:   ??_UOverloadedNewDelete@@SAPEAX_K@Z
422 // X64-DAG:   ??3OverloadedNewDelete@@SAXPEAX@Z
423 // X64-DAG:   ??_VOverloadedNewDelete@@SAXPEAX@Z
424 // X64-DAG:   ??HOverloadedNewDelete@@QEAAHH@Z
425 
426 // Indirecting the function type through a typedef will require a calling
427 // convention adjustment before building the method decl.
428 
429 typedef void *__thiscall OperatorNewType(__SIZE_TYPE__);
430 typedef void __thiscall OperatorDeleteType(void *);
431 
432 struct TypedefNewDelete {
433   OperatorNewType operator new;
434   OperatorNewType operator new[];
435   OperatorDeleteType operator delete;
436   OperatorDeleteType operator delete[];
437 };
438 
439 void *TypedefNewDelete::operator new(__SIZE_TYPE__ s) { return 0; }
440 void *TypedefNewDelete::operator new[](__SIZE_TYPE__ s) { return 0; }
441 void TypedefNewDelete::operator delete(void *) { }
442 void TypedefNewDelete::operator delete[](void *) { }
443 
444 // CHECK-DAG: ??2TypedefNewDelete@@SAPAXI@Z
445 // CHECK-DAG: ??_UTypedefNewDelete@@SAPAXI@Z
446 // CHECK-DAG: ??3TypedefNewDelete@@SAXPAX@Z
447 // CHECK-DAG: ??_VTypedefNewDelete@@SAXPAX@Z
448 
449 namespace PR18022 {
450 
451 struct { } a;
452 decltype(a) fun(decltype(a) x, decltype(a)) { return x; }
453 // CHECK-DAG: ?fun@PR18022@@YA?AU<unnamed-type-a>@1@U21@0@Z
454 
455 }
456