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 // RUN: %clang_cc1 -fblocks -emit-llvm %s -o - -triple=aarch64-pc-win32 -std=c++98 -DARM | FileCheck -check-prefixes=X64,ARM %s
6 // CHECK-DAG: @"?a@@3HA"
9 static int __attribute__((used
)) ignore_transparent_context
;
10 // CHECK-DAG: @ignore_transparent_context
15 // CHECK-DAG: @"?b@N@@3HA"
19 // CHECK-DAG: @"?anonymous@?A0x{{[^@]*}}@N@@3HA"
26 int _c(void) {return N::anonymous
+ c
;}
27 // CHECK-DAG: @"?_c@@YAHXZ"
28 // X64-DAG: @"?_c@@YAHXZ"
30 const int &NeedsReferenceTemporary
= 2;
31 // CHECK-DAG: @"?NeedsReferenceTemporary@@3ABHB" = dso_local constant i32* @"?$RT1@NeedsReferenceTemporary@@3ABHB"
32 // X64-DAG: @"?NeedsReferenceTemporary@@3AEBHEB" = dso_local constant i32* @"?$RT1@NeedsReferenceTemporary@@3AEBHEB"
36 // CHECK-DAG: @"?d@foo@@0FB"
38 static volatile long e
;
39 // CHECK-DAG: @"?e@foo@@1JC"
41 static const volatile char f
;
42 // CHECK-DAG: @"?f@foo@@2DD"
45 // CHECK-DAG: @"??0foo@@QAE@XZ"
46 // X64-DAG: @"??0foo@@QEAA@XZ"
49 // CHECK-DAG: @"??1foo@@QAE@XZ"
50 // X64-DAG: @"??1foo@@QEAA@XZ
53 // CHECK-DAG: @"??0foo@@QAE@H@Z"
54 // X64-DAG: @"??0foo@@QEAA@H@Z"
57 // CHECK-DAG: @"??0foo@@QAE@PAD@Z"
58 // X64-DAG: @"??0foo@@QEAA@PEAD@Z"
60 static foo
* static_method() { return 0; }
62 }f
,s1(1),s2((char*)0);
82 foo
bar() { return foo(); }
83 // CHECK-DAG: @"?bar@@YA?AVfoo@@XZ"
84 // X64-DAG: @"?bar@@YA?AVfoo@@XZ"
86 int foo::operator+(int a
) {
87 // CHECK-DAG: @"??Hfoo@@QAEHH@Z"
88 // X64-DAG: @"??Hfoo@@QEAAHH@Z"
91 // CHECK-DAG: @"?static_method@foo@@SAPAV1@XZ"
92 // X64-DAG: @"?static_method@foo@@SAPEAV1@XZ"
97 const short foo::d
= 0;
99 const volatile char foo::f
= 'C';
102 // CHECK-DAG: @"?g@bar@@2HA"
104 extern int * const h1
= &a
;
105 // CHECK-DAG: @"?h1@@3QAHA"
106 extern const int * const h2
= &a
;
107 // CHECK-DAG: @"?h2@@3QBHB"
108 extern int * const __restrict h3
= &a
;
109 // CHECK-DAG: @"?h3@@3QIAHIA"
110 // X64-DAG: @"?h3@@3QEIAHEIA"
113 // CHECK-DAG: @"?i@@3PAY0BE@HA"
115 typedef int (*FunT
)(int, int);
117 // CHECK-DAG: @"?FunArr@@3PAY0BE@P6AHHH@ZA"
118 // X64-DAG: @"?FunArr@@3PAY0BE@P6AHHH@ZA"
120 int (__stdcall
*j
)(signed char, unsigned char);
121 // CHECK-DAG: @"?j@@3P6GHCE@ZA"
124 // CHECK-DAG: @"?m@@3PRfoo@@DR1@"
125 // X64-DAG: @"?m@@3PERfoo@@DER1@"
127 const volatile char foo2::*k
;
128 // CHECK-DAG: @"?k@@3PTfoo@@DT1@"
129 // X64-DAG: @"?k@@3PETfoo@@DET1@"
132 // CHECK-DAG: @"?l@@3P8foo@@AEHH@ZQ1@"
134 // Ensure typedef CV qualifiers are mangled correctly
135 typedef const int cInt
;
136 typedef volatile int vInt
;
137 typedef const volatile int cvInt
;
139 extern cInt g_cInt
= 1;
143 // CHECK-DAG: @"?g_cInt@@3HB"
144 // CHECK-DAG: @"?g_vInt@@3HC"
145 // CHECK-DAG: @"?g_cvInt@@3HD"
147 // Static functions are mangled, too.
148 // Also make sure calling conventions, arglists, and throw specs work.
149 static void __stdcall
alpha(float a
, double b
) throw() {}
150 bool __fastcall
beta(long long a
, wchar_t b
) throw(signed char, unsigned char) {
151 // CHECK-DAG: @"?beta@@YI_N_J_W@Z"
152 // X64-DAG: @"?beta@@YA_N_J_W@Z"
157 // CHECK-DAG: @"?alpha@@YGXMN@Z"
158 // X64-DAG: @"?alpha@@YAXMN@Z"
160 // Make sure tag-type mangling works.
161 void gamma(class foo
, struct bar
, union baz
, enum quux
) {}
162 // CHECK-DAG: @"?gamma@@YAXVfoo@@Ubar@@Tbaz@@W4quux@@@Z"
163 // X64-DAG: @"?gamma@@YAXVfoo@@Ubar@@Tbaz@@W4quux@@@Z"
165 // Make sure pointer/reference-type mangling works.
166 void delta(int * const a
, const long &) {}
167 // CHECK-DAG: @"?delta@@YAXQAHABJ@Z"
168 // X64-DAG: @"?delta@@YAXQEAHAEBJ@Z"
171 void epsilon(int a
[][10][20]) {}
172 // CHECK-DAG: @"?epsilon@@YAXQAY19BE@H@Z"
173 // X64-DAG: @"?epsilon@@YAXQEAY19BE@H@Z"
175 void zeta(int (*)(int, int)) {}
176 // CHECK-DAG: @"?zeta@@YAXP6AHHH@Z@Z"
177 // X64-DAG: @"?zeta@@YAXP6AHHH@Z@Z"
179 // Blocks mangling (Clang extension). A block should be mangled slightly
180 // differently from a similar function pointer.
181 void eta(int (^)(int, int)) {}
182 // CHECK-DAG: @"?eta@@YAXP_EAHHH@Z@Z"
184 typedef int theta_arg(int,int);
185 void theta(theta_arg
^ block
) {}
186 // CHECK-DAG: @"?theta@@YAXP_EAHHH@Z@Z"
188 void operator_new_delete() {
189 char *ptr
= new char;
190 // CHECK-DAG: @"??2@YAPAXI@Z"
193 // CHECK-DAG: @"??3@YAXPAX@Z"
195 char *array
= new char[42];
196 // CHECK-DAG: @"??_U@YAPAXI@Z"
199 // CHECK-DAG: @"??_V@YAXPAX@Z"
203 void (redundant_parens
)();
204 void redundant_parens_use() { redundant_parens(); }
205 // CHECK-DAG: @"?redundant_parens@@YAXXZ"
206 // X64-DAG: @"?redundant_parens@@YAXXZ"
209 typedef double RGB
[3];
211 // CHECK-DAG: @"?color1@@3PANA"
212 extern const RGB color2
= {};
213 // CHECK-DAG: @"?color2@@3QBNB"
214 extern RGB
const color3
[5] = {};
215 // CHECK-DAG: @"?color3@@3QAY02$$CBNA"
216 extern RGB
const ((color4
)[5]) = {};
217 // CHECK-DAG: @"?color4@@3QAY02$$CBNA"
220 volatile int B::* volatile memptr1
;
221 // X64-DAG: @"?memptr1@@3RESB@@HES1@"
222 volatile int B::* memptr2
;
223 // X64-DAG: @"?memptr2@@3PESB@@HES1@"
224 int B::* volatile memptr3
;
225 // X64-DAG: @"?memptr3@@3REQB@@HEQ1@"
226 typedef int (*fun
)();
227 volatile fun
B::* volatile funmemptr1
;
228 // X64-DAG: @"?funmemptr1@@3RESB@@R6AHXZES1@"
229 volatile fun
B::* funmemptr2
;
230 // X64-DAG: @"?funmemptr2@@3PESB@@R6AHXZES1@"
231 fun
B::* volatile funmemptr3
;
232 // X64-DAG: @"?funmemptr3@@3REQB@@P6AHXZEQ1@"
233 void (B::* volatile memptrtofun1
)();
234 // X64-DAG: @"?memptrtofun1@@3R8B@@EAAXXZEQ1@"
235 const void (B::* memptrtofun2
)();
236 // X64-DAG: @"?memptrtofun2@@3P8B@@EAAXXZEQ1@"
237 volatile void (B::* memptrtofun3
)();
238 // X64-DAG: @"?memptrtofun3@@3P8B@@EAAXXZEQ1@"
239 int (B::* volatile memptrtofun4
)();
240 // X64-DAG: @"?memptrtofun4@@3R8B@@EAAHXZEQ1@"
241 volatile int (B::* memptrtofun5
)();
242 // X64-DAG: @"?memptrtofun5@@3P8B@@EAA?CHXZEQ1@"
243 const int (B::* memptrtofun6
)();
244 // X64-DAG: @"?memptrtofun6@@3P8B@@EAA?BHXZEQ1@"
245 fun (B::* volatile memptrtofun7
)();
246 // X64-DAG: @"?memptrtofun7@@3R8B@@EAAP6AHXZXZEQ1@"
247 volatile fun (B::* memptrtofun8
)();
248 // X64-DAG: @"?memptrtofun8@@3P8B@@EAAR6AHXZXZEQ1@"
249 const fun (B::* memptrtofun9
)();
250 // X64-DAG: @"?memptrtofun9@@3P8B@@EAAQ6AHXZXZEQ1@"
254 // CHECK-DAG: "?fooE@@YA?AW4E@@XZ"
255 // X64-DAG: "?fooE@@YA?AW4E@@XZ"
256 E
fooE() { return E(); }
259 // CHECK-DAG: "?fooX@@YA?AVX@@XZ"
260 // X64-DAG: "?fooX@@YA?AVX@@XZ"
261 X
fooX() { return X(); }
265 // CHECK-DAG: @"?s0@PR13182@@3PADA"
267 // CHECK-DAG: @"?s1@PR13182@@3PADA"
268 extern const char s2
[];
269 // CHECK-DAG: @"?s2@PR13182@@3QBDB"
270 extern const char s3
[42];
271 // CHECK-DAG: @"?s3@PR13182@@3QBDB"
272 extern volatile char s4
[];
273 // CHECK-DAG: @"?s4@PR13182@@3RCDC"
274 extern const volatile char s5
[];
275 // CHECK-DAG: @"?s5@PR13182@@3SDDD"
276 extern const char* const* s6
;
277 // CHECK-DAG: @"?s6@PR13182@@3PBQBDB"
280 return s0
[0] + s1
[0] + s2
[0] + s3
[0] + s4
[0] + s5
[0] + s6
[0][0];
284 extern "C" inline void extern_c_func() {
286 // CHECK-DAG: @"?local@?1??extern_c_func@@9@4HA"
287 // X64-DAG: @"?local@?1??extern_c_func@@9@4HA"
290 void call_extern_c_func() {
294 int main() { return 0; }
298 int wmain() { return 0; }
302 int WinMain() { return 0; }
303 // CHECK-DAG: @WinMain
306 int wWinMain() { return 0; }
307 // CHECK-DAG: @wWinMain
308 // X64-DAG: @wWinMain
310 int DllMain() { return 0; }
311 // CHECK-DAG: @DllMain
314 inline int inline_function_with_local_type() {
317 } static_variable_in_inline_function
= { 20 }, second_static
= { 40 };
318 // CHECK: @"?static_variable_in_inline_function@?1??inline_function_with_local_type@@YAHXZ@4U<unnamed-type-static_variable_in_inline_function>@?1??1@YAHXZ@A"
320 return static_variable_in_inline_function
.a_field
+ second_static
.a_field
;
323 int call_inline_function_with_local_type() {
324 return inline_function_with_local_type();
327 template <typename T
>
328 inline int templated_inline_function_with_local_type() {
331 } static_variable_in_templated_inline_function
= { 20 },
332 second_static
= { 40 };
333 // CHECK: @"?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"
335 return static_variable_in_templated_inline_function
.a_field
+
336 second_static
.a_field
;
339 int call_templated_inline_function_with_local_type() {
340 return templated_inline_function_with_local_type
<int>();
344 struct OverloadedNewDelete
{
346 void *operator new(__SIZE_TYPE__
);
347 void *operator new[](__SIZE_TYPE__
);
348 void operator delete(void *);
349 void operator delete[](void *);
354 void *OverloadedNewDelete::operator new(__SIZE_TYPE__ s
) { return 0; }
355 void *OverloadedNewDelete::operator new[](__SIZE_TYPE__ s
) { return 0; }
356 void OverloadedNewDelete::operator delete(void *) { }
357 void OverloadedNewDelete::operator delete[](void *) { }
358 int OverloadedNewDelete::operator+(int x
) { return x
; };
360 // CHECK-DAG: ??2OverloadedNewDelete@@SAPAXI@Z
361 // CHECK-DAG: ??_UOverloadedNewDelete@@SAPAXI@Z
362 // CHECK-DAG: ??3OverloadedNewDelete@@SAXPAX@Z
363 // CHECK-DAG: ??_VOverloadedNewDelete@@SAXPAX@Z
364 // CHECK-DAG: ??HOverloadedNewDelete@@QAEHH@Z
366 // X64-DAG: ??2OverloadedNewDelete@@SAPEAX_K@Z
367 // X64-DAG: ??_UOverloadedNewDelete@@SAPEAX_K@Z
368 // X64-DAG: ??3OverloadedNewDelete@@SAXPEAX@Z
369 // X64-DAG: ??_VOverloadedNewDelete@@SAXPEAX@Z
370 // X64-DAG: ??HOverloadedNewDelete@@QEAAHH@Z
372 // Indirecting the function type through a typedef will require a calling
373 // convention adjustment before building the method decl.
375 typedef void *__thiscall
OperatorNewType(__SIZE_TYPE__
);
376 typedef void __thiscall
OperatorDeleteType(void *);
378 struct TypedefNewDelete
{
379 OperatorNewType
operator new;
380 OperatorNewType
operator new[];
381 OperatorDeleteType
operator delete;
382 OperatorDeleteType
operator delete[];
385 void *TypedefNewDelete::operator new(__SIZE_TYPE__ s
) { return 0; }
386 void *TypedefNewDelete::operator new[](__SIZE_TYPE__ s
) { return 0; }
387 void TypedefNewDelete::operator delete(void *) { }
388 void TypedefNewDelete::operator delete[](void *) { }
390 // CHECK-DAG: ??2TypedefNewDelete@@SAPAXI@Z
391 // CHECK-DAG: ??_UTypedefNewDelete@@SAPAXI@Z
392 // CHECK-DAG: ??3TypedefNewDelete@@SAXPAX@Z
393 // CHECK-DAG: ??_VTypedefNewDelete@@SAXPAX@Z
395 void __vectorcall
vector_func() { }
396 // CHECK-DAG: @"?vector_func@@YQXXZ"
398 template <void (*)(void)>
401 template void fn_tmpl
<extern_c_func
>();
402 // CHECK-DAG: @"??$fn_tmpl@$1?extern_c_func@@YAXXZ@@YAXXZ"
404 extern "C" void __attribute__((overloadable
)) overloaded_fn() {}
405 // CHECK-DAG: @"?overloaded_fn@@$$J0YAXXZ"
407 extern "C" void overloaded_fn2() {}
408 // CHECK-DAG: @overloaded_fn2
410 extern "C" void __attribute__((overloadable
)) overloaded_fn3();
411 extern "C" void overloaded_fn3() {}
412 // CHECK-DAG: @overloaded_fn3
414 namespace UnnamedType
{
416 typedef struct {} *T1
[1];
417 typedef struct {} T2
;
418 typedef struct {} *T3
, T4
;
419 using T5
= struct {};
420 using T6
= struct {} *;
428 // CHECK-DAG: @"?f@UnnamedType@@YAXQAPAU<unnamed-type-T1>@S@1@@Z"
429 // CHECK-DAG: @"?f@UnnamedType@@YAXUT2@S@1@@Z"
430 // CHECK-DAG: @"?f@UnnamedType@@YAXPAUT4@S@1@@Z"
431 // CHECK-DAG: @"?f@UnnamedType@@YAXUT4@S@1@@Z"
432 // CHECK-DAG: @"?f@UnnamedType@@YAXUT5@S@1@@Z"
433 // CHECK-DAG: @"?f@UnnamedType@@YAXPAU<unnamed-type-T6>@S@1@@Z"
435 // X64-DAG: @"?f@UnnamedType@@YAXQEAPEAU<unnamed-type-T1>@S@1@@Z"
436 // X64-DAG: @"?f@UnnamedType@@YAXUT2@S@1@@Z"
437 // X64-DAG: @"?f@UnnamedType@@YAXPEAUT4@S@1@@Z"(%"struct.UnnamedType::S::T4"
438 // X64-DAG: @"?f@UnnamedType@@YAXUT4@S@1@@Z"
439 // X64-DAG: @"?f@UnnamedType@@YAXUT5@S@1@@Z"
440 // X64-DAG: @"?f@UnnamedType@@YAXPEAU<unnamed-type-T6>@S@1@@Z"
443 namespace PassObjectSize
{
444 // NOTE: This mangling is subject to change.
445 // Reiterating from the comment in MicrosoftMangle, the scheme is pretend a
446 // parameter of type __clang::__pass_object_sizeN exists after each pass object
447 // size param P, where N is the Type of the pass_object_size attribute on P.
449 // e.g. we want to mangle:
450 // void foo(void *const __attribute__((pass_object_size(0))));
452 // namespace __clang { enum __pass_object_size0 : size_t {}; }
453 // void foo(void *const, __clang::__pass_object_size0);
454 // where __clang is a top-level namespace.
456 // CHECK-DAG: define dso_local noundef i32 @"?foo@PassObjectSize@@YAHQAHW4__pass_object_size0@__clang@@@Z"
457 int foo(int *const i
__attribute__((pass_object_size(0)))) { return 0; }
458 // CHECK-DAG: define dso_local noundef i32 @"?bar@PassObjectSize@@YAHQAHW4__pass_object_size1@__clang@@@Z"
459 int bar(int *const i
__attribute__((pass_object_size(1)))) { return 0; }
460 // CHECK-DAG: define dso_local noundef i32 @"?qux@PassObjectSize@@YAHQAHW4__pass_object_size1@__clang@@0W4__pass_object_size0@3@@Z"
461 int qux(int *const i
__attribute__((pass_object_size(1))), int *const j
__attribute__((pass_object_size(0)))) { return 0; }
462 // CHECK-DAG: define dso_local noundef i32 @"?zot@PassObjectSize@@YAHQAHW4__pass_object_size1@__clang@@01@Z"
463 int zot(int *const i
__attribute__((pass_object_size(1))), int *const j
__attribute__((pass_object_size(1)))) { return 0; }
464 // CHECK-DAG: define dso_local noundef i32 @"?silly_word@PassObjectSize@@YAHQAHW4__pass_dynamic_object_size1@__clang@@@Z"
465 int silly_word(int *const i
__attribute__((pass_dynamic_object_size(1)))) { return 0; }
469 // CHECK-DAG: define dso_local void @"?f@Atomic@@YAXU?$_Atomic@H@__clang@@@Z"(
470 void f(_Atomic(int)) {}
473 // CHECK-DAG: define dso_local void @"?f@Complex@@YAXU?$_Complex@H@__clang@@@Z"(
474 void f(_Complex
int) {}
478 // ARM-DAG: define dso_local void @"?f@Float16@@YAXU_Float16@__clang@@@Z"(
490 struct M
: L
<H
<int *> > {};
501 void runOnFunction() {
505 // CHECK-DAG: call {{.*}} @"??0?$L@V?$H@PAH@PR26029@@@PR26029@@QAE@XZ"