398 lines · cpp
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 %s2 3struct StructA {};4 5template<class T>6auto AutoT() { return T(); }7 8template<class T>9const auto AutoConstT() { return T(); }10 11template<class T>12volatile auto AutoVolatileT() { return T(); }13 14template<class T>15const volatile auto AutoConstVolatileT() { return T(); }16 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.19void test_template_auto_void() {20 AutoT<void>();21 // CHECK: call {{.*}} @"??$AutoT@X@@YA?A_PXZ"22 23 AutoT<const void>();24 // CHECK: call {{.*}} @"??$AutoT@$$CBX@@YA?A_PXZ"25 26 AutoT<volatile void>();27 // CHECK: call {{.*}} @"??$AutoT@$$CCX@@YA?A_PXZ"28 29 AutoT<const volatile void>();30 // CHECK: call {{.*}} @"??$AutoT@$$CDX@@YA?A_PXZ"31 32 AutoConstT<void>();33 // CHECK: call {{.*}} @"??$AutoConstT@X@@YA?B_PXZ"34 35 AutoVolatileT<void>();36 // CHECK: call {{.*}} @"??$AutoVolatileT@X@@YA?C_PXZ"37 38 AutoConstVolatileT<void>();39 // CHECK: call {{.*}} @"??$AutoConstVolatileT@X@@YA?D_PXZ"40}41 42void test_template_auto_int() {43 AutoT<int>();44 // CHECK: call {{.*}} @"??$AutoT@H@@YA?A_PXZ"45 46 AutoT<const int>();47 // CHECK: call {{.*}} @"??$AutoT@$$CBH@@YA?A_PXZ"48 49 AutoT<volatile int>();50 // CHECK: call {{.*}} @"??$AutoT@$$CCH@@YA?A_PXZ"51 52 AutoT<const volatile int>();53 // CHECK: call {{.*}} @"??$AutoT@$$CDH@@YA?A_PXZ"54 55 AutoConstT<int>();56 // CHECK: call {{.*}} @"??$AutoConstT@H@@YA?B_PXZ"57 58 AutoVolatileT<int>();59 // CHECK: call {{.*}} @"??$AutoVolatileT@H@@YA?C_PXZ"60 61 AutoConstVolatileT<int>();62 // CHECK: call {{.*}} @"??$AutoConstVolatileT@H@@YA?D_PXZ"63}64 65void test_template_auto_struct() {66 AutoT<StructA>();67 // CHECK: call {{.*}} @"??$AutoT@UStructA@@@@YA?A_PXZ"68 69 AutoT<const StructA>();70 // CHECK: call {{.*}} @"??$AutoT@$$CBUStructA@@@@YA?A_PXZ"71 72 AutoConstT<StructA>();73 // CHECK: call {{.*}} @"??$AutoConstT@UStructA@@@@YA?B_PXZ"74 75 AutoVolatileT<StructA>();76 // CHECK: call {{.*}} @"??$AutoVolatileT@UStructA@@@@YA?C_PXZ"77 78 AutoConstVolatileT<StructA>();79 // CHECK: call {{.*}} @"??$AutoConstVolatileT@UStructA@@@@YA?D_PXZ"80}81 82void test_template_auto_ptr() {83 AutoT<int*>();84 // CHECK: call {{.*}} @"??$AutoT@PEAH@@YA?A_PXZ"85 86 AutoT<const int*>();87 // CHECK: call {{.*}} @"??$AutoT@PEBH@@YA?A_PXZ"88 89 AutoT<const int* const>();90 // CHECK: call {{.*}} @"??$AutoT@QEBH@@YA?A_PXZ"91 92 AutoConstT<int*>();93 // CHECK: call {{.*}} @"??$AutoConstT@PEAH@@YA?B_PXZ"94 95 AutoVolatileT<int*>();96 // CHECK: call {{.*}} @"??$AutoVolatileT@PEAH@@YA?C_PXZ"97 98 AutoConstVolatileT<int*>();99 // CHECK: call {{.*}} @"??$AutoConstVolatileT@PEAH@@YA?D_PXZ"100}101 102template<class T>103auto* PtrAutoT() { return T(); }104 105template<class T>106const auto* PtrAutoConstT() { return T(); }107 108template<class T>109volatile auto* PtrAutoVolatileT() { return T(); }110 111template<class T>112const volatile auto* PtrAutoConstVolatileT() { return T(); }113 114void test_template_ptr_auto() {115 PtrAutoT<int*>();116 // CHECK: call {{.*}} @"??$PtrAutoT@PEAH@@YAPEA_PXZ"117 118 PtrAutoT<const int*>();119 // CHECK: call {{.*}} @"??$PtrAutoT@PEBH@@YAPEA_PXZ"120 121 PtrAutoT<const int* const>();122 // CHECK: call {{.*}} @"??$PtrAutoT@QEBH@@YAPEA_PXZ"123 124 PtrAutoConstT<int*>();125 // CHECK: call {{.*}} @"??$PtrAutoConstT@PEAH@@YAPEB_PXZ"126 127 PtrAutoVolatileT<int*>();128 // CHECK: call {{.*}} @"??$PtrAutoVolatileT@PEAH@@YAPEC_PXZ"129 130 PtrAutoConstVolatileT<int*>();131 // CHECK: call {{.*}} @"??$PtrAutoConstVolatileT@PEAH@@YAPED_PXZ"132}133 134int func_int();135const int func_constint();136void func_void();137int* func_intptr();138 139template<class T, T v>140auto (*FuncPtrAutoT())() { return v; }141 142void test_template_func_ptr_auto() {143 FuncPtrAutoT<int (*)(), &func_int>();144 // CHECK: call {{.*}} @"??$FuncPtrAutoT@P6AHXZ$1?func_int@@YAHXZ@@YAP6A?A_PXZXZ"145 146 FuncPtrAutoT<const int (*)(), &func_constint>();147 // CHECK: call {{.*}} @"??$FuncPtrAutoT@P6A?BHXZ$1?func_constint@@YA?BHXZ@@YAP6A?A_PXZXZ"148 149 FuncPtrAutoT<void (*)(), &func_void>();150 // CHECK: call {{.*}} @"??$FuncPtrAutoT@P6AXXZ$1?func_void@@YAXXZ@@YAP6A?A_PXZXZ"151 152 FuncPtrAutoT<int * (*)(), &func_intptr>();153 // CHECK: call {{.*}} @"??$FuncPtrAutoT@P6APEAHXZ$1?func_intptr@@YAPEAHXZ@@YAP6A?A_PXZXZ"154}155 156template<class T>157auto& RefAutoT(T& x) { return x; }158 159template<class T>160const auto& ConstRefAutoT(T& x) { return x; }161 162template<class T>163auto&& RRefAutoT(T& x) { return static_cast<int&&>(x); }164 165void test_template_ref_auto() {166 int x;167 168 RefAutoT(x);169 // CHECK: call {{.*}} @"??$RefAutoT@H@@YAAEA_PAEAH@Z"170 171 ConstRefAutoT(x);172 // CHECK: call {{.*}} @"??$ConstRefAutoT@H@@YAAEB_PAEAH@Z"173 174 RRefAutoT(x);175 // CHECK: call {{.*}} @"??$RRefAutoT@H@@YA$$QEA_PAEAH@Z"176}177 178template<class T>179decltype(auto) DecltypeAutoT() { return T(); }180 181template<class T>182decltype(auto) DecltypeAutoT2(T& x) { return static_cast<T&&>(x); }183 184void test_template_decltypeauto() {185 DecltypeAutoT<void>();186 // CHECK: call {{.*}} @"??$DecltypeAutoT@X@@YA?A_TXZ"187 188 DecltypeAutoT<const void>();189 // CHECK: call {{.*}} @"??$DecltypeAutoT@$$CBX@@YA?A_TXZ"190 191 DecltypeAutoT<volatile void>();192 // CHECK: call {{.*}} @"??$DecltypeAutoT@$$CCX@@YA?A_TXZ"193 194 DecltypeAutoT<const volatile void>();195 // CHECK: call {{.*}} @"??$DecltypeAutoT@$$CDX@@YA?A_TXZ"196 197 DecltypeAutoT<int>();198 // CHECK: call {{.*}} @"??$DecltypeAutoT@H@@YA?A_TXZ"199 200 DecltypeAutoT<const int>();201 // CHECK: call {{.*}} @"??$DecltypeAutoT@$$CBH@@YA?A_TXZ"202 203 DecltypeAutoT<volatile int>();204 // CHECK: call {{.*}} @"??$DecltypeAutoT@$$CCH@@YA?A_TXZ"205 206 DecltypeAutoT<const volatile int>();207 // CHECK: call {{.*}} @"??$DecltypeAutoT@$$CDH@@YA?A_TXZ"208 209 int x;210 211 DecltypeAutoT2(x);212 // CHECK: call {{.*}} @"??$DecltypeAutoT2@H@@YA?A_TAEAH@Z"213}214 215// Still want to use clang's custom mangling for lambdas to keep backwards compatibility until216// MSVC lambda name mangling has been deciphered.217void test_lambda() {218 int i = 0;219 220 auto lambdaIntRetAuto = []() { return 0; };221 lambdaIntRetAuto();222 // CHECK: call {{.*}} @"??R<lambda_1>@?0??test_lambda@@YAXXZ@QEBA?A?<auto>@@XZ"223 224 auto lambdaIntRet = []() -> int { return 0; };225 lambdaIntRet();226 // CHECK: call {{.*}} @"??R<lambda_2>@?0??test_lambda@@YAXXZ@QEBA@XZ"227 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"231 232 auto lambdaRetTrailingAuto = []() -> auto { return 0; };233 lambdaRetTrailingAuto();234 // CHECK: call {{.*}} @"??R<lambda_3>@?0??test_lambda@@YAXXZ@QEBA?A?<auto>@@XZ"235 236 auto lambdaRetTrailingDecltypeAuto = []() -> decltype(auto) { return 0; };237 lambdaRetTrailingDecltypeAuto();238 // CHECK: call {{.*}} @"??R<lambda_4>@?0??test_lambda@@YAXXZ@QEBA?A?<decltype-auto>@@XZ"239 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"243}244 245auto TestTrailingInt() -> int {246 return 0;247}248 249auto TestTrailingConstVolatileVoid() -> const volatile void {250}251 252auto TestTrailingStructA() -> StructA {253 return StructA{};254}255 256void test_trailing_return() {257 TestTrailingInt();258 // CHECK: call {{.*}} @"?TestTrailingInt@@YAHXZ"259 260 TestTrailingConstVolatileVoid();261 // CHECK: call {{.*}} @"?TestTrailingConstVolatileVoid@@YAXXZ"262 263 TestTrailingStructA();264 // CHECK: call {{.*}} @"?TestTrailingStructA@@YA?AUStructA@@XZ"265}266 267auto TestNonTemplateAutoInt() {268 return 0;269}270 271auto TestNonTemplateAutoVoid() {272 return;273}274 275auto TestNonTemplateAutoStructA() {276 return StructA{};277}278 279const auto TestNonTemplateConstAutoInt() {280 return 0;281}282 283const auto TestNonTemplateConstAutoVoid() {284 return;285}286 287const auto TestNonTemplateConstAutoStructA() {288 return StructA{};289}290 291void test_nontemplate_auto() {292 TestNonTemplateAutoInt();293 // CHECK: call {{.*}} @"?TestNonTemplateAutoInt@@YA@XZ"294 295 TestNonTemplateAutoVoid();296 // CHECK: call {{.*}} @"?TestNonTemplateAutoVoid@@YA@XZ"297 298 TestNonTemplateAutoStructA();299 // CHECK: call {{.*}} @"?TestNonTemplateAutoStructA@@YA@XZ"300 301 TestNonTemplateConstAutoInt();302 // CHECK: call {{.*}} @"?TestNonTemplateConstAutoInt@@YA@XZ"303 304 TestNonTemplateConstAutoVoid();305 // CHECK: call {{.*}} @"?TestNonTemplateConstAutoVoid@@YA@XZ"306 307 TestNonTemplateConstAutoStructA();308 // CHECK: call {{.*}} @"?TestNonTemplateConstAutoStructA@@YA@XZ"309}310 311decltype(auto) TestNonTemplateDecltypeAutoInt() {312 return 0;313}314 315decltype(auto) TestNonTemplateDecltypeAutoVoid() {316 return;317}318 319decltype(auto) TestNonTemplateDecltypeAutoStructA() {320 return StructA{};321}322 323void test_nontemplate_decltypeauto() {324 TestNonTemplateDecltypeAutoInt();325 // CHECK: call {{.*}} @"?TestNonTemplateDecltypeAutoInt@@YA@XZ"326 327 TestNonTemplateDecltypeAutoVoid();328 // CHECK: call {{.*}} @"?TestNonTemplateDecltypeAutoVoid@@YA@XZ"329 330 TestNonTemplateDecltypeAutoStructA();331 // CHECK: call {{.*}} @"?TestNonTemplateDecltypeAutoStructA@@YA@XZ"332}333 334struct StructB {335 int x;336};337 338template<class T>339auto StructB::* AutoMemberDataPtrT(T x) { return x; }340 341template<class T>342const auto StructB::* AutoConstMemberDataPtrT(T x) { return x; }343 344void test_template_auto_member_data_ptr() {345 AutoMemberDataPtrT(&StructB::x);346 // CHECK: call {{.*}} @"??$AutoMemberDataPtrT@PEQStructB@@H@@YAPEQStructB@@_PPEQ0@H@Z"347 348 AutoConstMemberDataPtrT(&StructB::x);349 // CHECK: call {{.*}} @"??$AutoConstMemberDataPtrT@PEQStructB@@H@@YAPERStructB@@_PPEQ0@H@Z"350}351 352struct StructC {353 void test() {}354};355 356struct StructD {357 const int test() { return 0; }358};359 360template<class T>361auto (StructC::*AutoMemberFuncPtrT(T x))() { return x; }362 363template<class T>364const auto (StructD::*AutoConstMemberFuncPtrT(T x))() { return x; }365 366void test_template_auto_member_func_ptr() {367 AutoMemberFuncPtrT(&StructC::test);368 // CHECK: call {{.*}} @"??$AutoMemberFuncPtrT@P8StructC@@EAAXXZ@@YAP8StructC@@EAA?A_PXZP80@EAAXXZ@Z"369 370 AutoConstMemberFuncPtrT(&StructD::test);371 // CHECK: call {{.*}} @"??$AutoConstMemberFuncPtrT@P8StructD@@EAA?BHXZ@@YAP8StructD@@EAA?B_PXZP80@EAA?BHXZ@Z"372}373 374template<class T>375auto * __attribute__((address_space(1))) * AutoPtrAddressSpaceT() {376 T * __attribute__((address_space(1))) * p = nullptr;377 return p;378}379 380void test_template_auto_address_space_ptr() {381 AutoPtrAddressSpaceT<int>();382 // CHECK: call {{.*}} @"??$AutoPtrAddressSpaceT@H@@YA?A?<auto>@@XZ"383}384 385template<class T>386auto&& AutoReferenceCollapseT(T& x) { return static_cast<T&>(x); }387 388auto&& AutoReferenceCollapse(int& x) { return static_cast<int&>(x); }389 390void test2() {391 int x = 1;392 auto&& rref0 = AutoReferenceCollapseT(x);393 // CHECK: call {{.*}} @"??$AutoReferenceCollapseT@H@@YA$$QEA_PAEAH@Z"394 395 auto&& rref1 = AutoReferenceCollapse(x);396 // CHECK: call {{.*}} @"?AutoReferenceCollapse@@YA@AEAH@Z"397}398