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