1 // RUN: %clang_cc1 -std=c++17 -fms-compatibility-version=19.20 -emit-llvm %s -o - -fms-extensions -fdelayed-template-parsing -triple=x86_64-pc-windows-msvc | FileCheck %s
6 auto AutoT() { return T(); }
9 const auto AutoConstT() { return T(); }
12 volatile auto AutoVolatileT() { return T(); }
15 const volatile auto AutoConstVolatileT() { return T(); }
17 // The qualifiers of the return type should always be emitted even for void types.
18 // Void types usually have their qualifers stripped in the mangled name for MSVC ABI.
19 void test_template_auto_void() {
21 // CHECK: call {{.*}} @"??$AutoT@X@@YA?A_PXZ"
24 // CHECK: call {{.*}} @"??$AutoT@$$CBX@@YA?A_PXZ"
26 AutoT
<volatile void>();
27 // CHECK: call {{.*}} @"??$AutoT@$$CCX@@YA?A_PXZ"
29 AutoT
<const volatile void>();
30 // CHECK: call {{.*}} @"??$AutoT@$$CDX@@YA?A_PXZ"
33 // CHECK: call {{.*}} @"??$AutoConstT@X@@YA?B_PXZ"
35 AutoVolatileT
<void>();
36 // CHECK: call {{.*}} @"??$AutoVolatileT@X@@YA?C_PXZ"
38 AutoConstVolatileT
<void>();
39 // CHECK: call {{.*}} @"??$AutoConstVolatileT@X@@YA?D_PXZ"
42 void test_template_auto_int() {
44 // CHECK: call {{.*}} @"??$AutoT@H@@YA?A_PXZ"
47 // CHECK: call {{.*}} @"??$AutoT@$$CBH@@YA?A_PXZ"
49 AutoT
<volatile int>();
50 // CHECK: call {{.*}} @"??$AutoT@$$CCH@@YA?A_PXZ"
52 AutoT
<const volatile int>();
53 // CHECK: call {{.*}} @"??$AutoT@$$CDH@@YA?A_PXZ"
56 // CHECK: call {{.*}} @"??$AutoConstT@H@@YA?B_PXZ"
59 // CHECK: call {{.*}} @"??$AutoVolatileT@H@@YA?C_PXZ"
61 AutoConstVolatileT
<int>();
62 // CHECK: call {{.*}} @"??$AutoConstVolatileT@H@@YA?D_PXZ"
65 void test_template_auto_struct() {
67 // CHECK: call {{.*}} @"??$AutoT@UStructA@@@@YA?A_PXZ"
69 AutoT
<const StructA
>();
70 // CHECK: call {{.*}} @"??$AutoT@$$CBUStructA@@@@YA?A_PXZ"
72 AutoConstT
<StructA
>();
73 // CHECK: call {{.*}} @"??$AutoConstT@UStructA@@@@YA?B_PXZ"
75 AutoVolatileT
<StructA
>();
76 // CHECK: call {{.*}} @"??$AutoVolatileT@UStructA@@@@YA?C_PXZ"
78 AutoConstVolatileT
<StructA
>();
79 // CHECK: call {{.*}} @"??$AutoConstVolatileT@UStructA@@@@YA?D_PXZ"
82 void test_template_auto_ptr() {
84 // CHECK: call {{.*}} @"??$AutoT@PEAH@@YA?A_PXZ"
87 // CHECK: call {{.*}} @"??$AutoT@PEBH@@YA?A_PXZ"
89 AutoT
<const int* const>();
90 // CHECK: call {{.*}} @"??$AutoT@QEBH@@YA?A_PXZ"
93 // CHECK: call {{.*}} @"??$AutoConstT@PEAH@@YA?B_PXZ"
95 AutoVolatileT
<int*>();
96 // CHECK: call {{.*}} @"??$AutoVolatileT@PEAH@@YA?C_PXZ"
98 AutoConstVolatileT
<int*>();
99 // CHECK: call {{.*}} @"??$AutoConstVolatileT@PEAH@@YA?D_PXZ"
103 auto* PtrAutoT() { return T(); }
106 const auto* PtrAutoConstT() { return T(); }
109 volatile auto* PtrAutoVolatileT() { return T(); }
112 const volatile auto* PtrAutoConstVolatileT() { return T(); }
114 void test_template_ptr_auto() {
116 // CHECK: call {{.*}} @"??$PtrAutoT@PEAH@@YAPEA_PXZ"
118 PtrAutoT
<const int*>();
119 // CHECK: call {{.*}} @"??$PtrAutoT@PEBH@@YAPEA_PXZ"
121 PtrAutoT
<const int* const>();
122 // CHECK: call {{.*}} @"??$PtrAutoT@QEBH@@YAPEA_PXZ"
124 PtrAutoConstT
<int*>();
125 // CHECK: call {{.*}} @"??$PtrAutoConstT@PEAH@@YAPEB_PXZ"
127 PtrAutoVolatileT
<int*>();
128 // CHECK: call {{.*}} @"??$PtrAutoVolatileT@PEAH@@YAPEC_PXZ"
130 PtrAutoConstVolatileT
<int*>();
131 // CHECK: call {{.*}} @"??$PtrAutoConstVolatileT@PEAH@@YAPED_PXZ"
135 const int func_constint();
139 template<class T
, T v
>
140 auto (*FuncPtrAutoT())() { return v
; }
142 void test_template_func_ptr_auto() {
143 FuncPtrAutoT
<int (*)(), &func_int
>();
144 // CHECK: call {{.*}} @"??$FuncPtrAutoT@P6AHXZ$1?func_int@@YAHXZ@@YAP6A?A_PXZXZ"
146 FuncPtrAutoT
<const int (*)(), &func_constint
>();
147 // CHECK: call {{.*}} @"??$FuncPtrAutoT@P6A?BHXZ$1?func_constint@@YA?BHXZ@@YAP6A?A_PXZXZ"
149 FuncPtrAutoT
<void (*)(), &func_void
>();
150 // CHECK: call {{.*}} @"??$FuncPtrAutoT@P6AXXZ$1?func_void@@YAXXZ@@YAP6A?A_PXZXZ"
152 FuncPtrAutoT
<int * (*)(), &func_intptr
>();
153 // CHECK: call {{.*}} @"??$FuncPtrAutoT@P6APEAHXZ$1?func_intptr@@YAPEAHXZ@@YAP6A?A_PXZXZ"
157 auto& RefAutoT(T
& x
) { return x
; }
160 const auto& ConstRefAutoT(T
& x
) { return x
; }
163 auto&& RRefAutoT(T
& x
) { return static_cast<int&&>(x
); }
165 void test_template_ref_auto() {
169 // CHECK: call {{.*}} @"??$RefAutoT@H@@YAAEA_PAEAH@Z"
172 // CHECK: call {{.*}} @"??$ConstRefAutoT@H@@YAAEB_PAEAH@Z"
175 // CHECK: call {{.*}} @"??$RRefAutoT@H@@YA$$QEA_PAEAH@Z"
179 decltype(auto) DecltypeAutoT() { return T(); }
182 decltype(auto) DecltypeAutoT2(T
& x
) { return static_cast<T
&&>(x
); }
184 void test_template_decltypeauto() {
185 DecltypeAutoT
<void>();
186 // CHECK: call {{.*}} @"??$DecltypeAutoT@X@@YA?A_TXZ"
188 DecltypeAutoT
<const void>();
189 // CHECK: call {{.*}} @"??$DecltypeAutoT@$$CBX@@YA?A_TXZ"
191 DecltypeAutoT
<volatile void>();
192 // CHECK: call {{.*}} @"??$DecltypeAutoT@$$CCX@@YA?A_TXZ"
194 DecltypeAutoT
<const volatile void>();
195 // CHECK: call {{.*}} @"??$DecltypeAutoT@$$CDX@@YA?A_TXZ"
197 DecltypeAutoT
<int>();
198 // CHECK: call {{.*}} @"??$DecltypeAutoT@H@@YA?A_TXZ"
200 DecltypeAutoT
<const int>();
201 // CHECK: call {{.*}} @"??$DecltypeAutoT@$$CBH@@YA?A_TXZ"
203 DecltypeAutoT
<volatile int>();
204 // CHECK: call {{.*}} @"??$DecltypeAutoT@$$CCH@@YA?A_TXZ"
206 DecltypeAutoT
<const volatile int>();
207 // CHECK: call {{.*}} @"??$DecltypeAutoT@$$CDH@@YA?A_TXZ"
212 // CHECK: call {{.*}} @"??$DecltypeAutoT2@H@@YA?A_TAEAH@Z"
215 // Still want to use clang's custom mangling for lambdas to keep backwards compatibility until
216 // MSVC lambda name mangling has been deciphered.
220 auto lambdaIntRetAuto
= []() { return 0; };
222 // CHECK: call {{.*}} @"??R<lambda_1>@?0??test_lambda@@YAXXZ@QEBA?A?<auto>@@XZ"
224 auto lambdaIntRet
= []() -> int { return 0; };
226 // CHECK: call {{.*}} @"??R<lambda_2>@?0??test_lambda@@YAXXZ@QEBA@XZ"
228 auto lambdaGenericIntIntRetAuto
= [](auto a
) { return a
; };
229 lambdaGenericIntIntRetAuto(0);
230 // CHECK: call {{.*}} @"??$?RH@<lambda_0>@?0??test_lambda@@YAXXZ@QEBA?A?<auto>@@H@Z"
232 auto lambdaRetTrailingAuto
= []() -> auto { return 0; };
233 lambdaRetTrailingAuto();
234 // CHECK: call {{.*}} @"??R<lambda_3>@?0??test_lambda@@YAXXZ@QEBA?A?<auto>@@XZ"
236 auto lambdaRetTrailingDecltypeAuto
= []() -> decltype(auto) { return 0; };
237 lambdaRetTrailingDecltypeAuto();
238 // CHECK: call {{.*}} @"??R<lambda_4>@?0??test_lambda@@YAXXZ@QEBA?A?<decltype-auto>@@XZ"
240 auto lambdaRetTrailingRefCollapse
= [](int x
) -> auto&& { return x
; };
241 lambdaRetTrailingRefCollapse(i
);
242 // CHECK: call {{.*}} @"??R<lambda_5>@?0??test_lambda@@YAXXZ@QEBA?A?<auto>@@H@Z"
245 auto TestTrailingInt() -> int {
249 auto TestTrailingConstVolatileVoid() -> const volatile void {
252 auto TestTrailingStructA() -> StructA
{
256 void test_trailing_return() {
258 // CHECK: call {{.*}} @"?TestTrailingInt@@YAHXZ"
260 TestTrailingConstVolatileVoid();
261 // CHECK: call {{.*}} @"?TestTrailingConstVolatileVoid@@YAXXZ"
263 TestTrailingStructA();
264 // CHECK: call {{.*}} @"?TestTrailingStructA@@YA?AUStructA@@XZ"
267 auto TestNonTemplateAutoInt() {
271 auto TestNonTemplateAutoVoid() {
275 auto TestNonTemplateAutoStructA() {
279 const auto TestNonTemplateConstAutoInt() {
283 const auto TestNonTemplateConstAutoVoid() {
287 const auto TestNonTemplateConstAutoStructA() {
291 void test_nontemplate_auto() {
292 TestNonTemplateAutoInt();
293 // CHECK: call {{.*}} @"?TestNonTemplateAutoInt@@YA@XZ"
295 TestNonTemplateAutoVoid();
296 // CHECK: call {{.*}} @"?TestNonTemplateAutoVoid@@YA@XZ"
298 TestNonTemplateAutoStructA();
299 // CHECK: call {{.*}} @"?TestNonTemplateAutoStructA@@YA@XZ"
301 TestNonTemplateConstAutoInt();
302 // CHECK: call {{.*}} @"?TestNonTemplateConstAutoInt@@YA@XZ"
304 TestNonTemplateConstAutoVoid();
305 // CHECK: call {{.*}} @"?TestNonTemplateConstAutoVoid@@YA@XZ"
307 TestNonTemplateConstAutoStructA();
308 // CHECK: call {{.*}} @"?TestNonTemplateConstAutoStructA@@YA@XZ"
311 decltype(auto) TestNonTemplateDecltypeAutoInt() {
315 decltype(auto) TestNonTemplateDecltypeAutoVoid() {
319 decltype(auto) TestNonTemplateDecltypeAutoStructA() {
323 void test_nontemplate_decltypeauto() {
324 TestNonTemplateDecltypeAutoInt();
325 // CHECK: call {{.*}} @"?TestNonTemplateDecltypeAutoInt@@YA@XZ"
327 TestNonTemplateDecltypeAutoVoid();
328 // CHECK: call {{.*}} @"?TestNonTemplateDecltypeAutoVoid@@YA@XZ"
330 TestNonTemplateDecltypeAutoStructA();
331 // CHECK: call {{.*}} @"?TestNonTemplateDecltypeAutoStructA@@YA@XZ"
339 auto StructB::* AutoMemberDataPtrT(T x
) { return x
; }
342 const auto StructB::* AutoConstMemberDataPtrT(T x
) { return x
; }
344 void test_template_auto_member_data_ptr() {
345 AutoMemberDataPtrT(&StructB::x
);
346 // CHECK: call {{.*}} @"??$AutoMemberDataPtrT@PEQStructB@@H@@YAPEQStructB@@_PPEQ0@H@Z"
348 AutoConstMemberDataPtrT(&StructB::x
);
349 // CHECK: call {{.*}} @"??$AutoConstMemberDataPtrT@PEQStructB@@H@@YAPERStructB@@_PPEQ0@H@Z"
357 const int test() { return 0; }
361 auto (StructC::*AutoMemberFuncPtrT(T x
))() { return x
; }
364 const auto (StructD::*AutoConstMemberFuncPtrT(T x
))() { return x
; }
366 void test_template_auto_member_func_ptr() {
367 AutoMemberFuncPtrT(&StructC::test
);
368 // CHECK: call {{.*}} @"??$AutoMemberFuncPtrT@P8StructC@@EAAXXZ@@YAP8StructC@@EAA?A_PXZP80@EAAXXZ@Z"
370 AutoConstMemberFuncPtrT(&StructD::test
);
371 // CHECK: call {{.*}} @"??$AutoConstMemberFuncPtrT@P8StructD@@EAA?BHXZ@@YAP8StructD@@EAA?B_PXZP80@EAA?BHXZ@Z"
375 auto * __attribute__((address_space(1))) * AutoPtrAddressSpaceT() {
376 T
* __attribute__((address_space(1))) * p
= nullptr;
380 void test_template_auto_address_space_ptr() {
381 AutoPtrAddressSpaceT
<int>();
382 // CHECK: call {{.*}} @"??$AutoPtrAddressSpaceT@H@@YA?A?<auto>@@XZ"
386 auto&& AutoReferenceCollapseT(T
& x
) { return static_cast<T
&>(x
); }
388 auto&& AutoReferenceCollapse(int& x
) { return static_cast<int&>(x
); }
392 auto&& rref0
= AutoReferenceCollapseT(x
);
393 // CHECK: call {{.*}} @"??$AutoReferenceCollapseT@H@@YA$$QEA_PAEAH@Z"
395 auto&& rref1
= AutoReferenceCollapse(x
);
396 // CHECK: call {{.*}} @"?AutoReferenceCollapse@@YA@AEAH@Z"