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