1 // RUN: %clang_cc1 -triple i686-win32 -fsyntax-only -fms-extensions -verify -std=c++11 -Wunsupported-dll-base-class-template -DMS %s 2 // RUN: %clang_cc1 -triple x86_64-win32 -fsyntax-only -fms-extensions -verify -std=c++1y -Wunsupported-dll-base-class-template -DMS %s 3 // RUN: %clang_cc1 -triple i686-mingw32 -fsyntax-only -fms-extensions -verify -std=c++1y -Wunsupported-dll-base-class-template -DGNU %s 4 // RUN: %clang_cc1 -triple x86_64-mingw32 -fsyntax-only -fms-extensions -verify -std=c++11 -Wunsupported-dll-base-class-template -DGNU %s 5 // RUN: %clang_cc1 -triple x86_64-mingw32 -fsyntax-only -fms-extensions -verify -std=c++17 -Wunsupported-dll-base-class-template -DGNU %s 6 // RUN: %clang_cc1 -triple i686-windows-itanium -fsyntax-only -fms-extensions -verify -std=c++11 -Wunsupported-dll-base-class-template -DWI %s 7 // RUN: %clang_cc1 -triple x86_64-windows-itanium -fsyntax-only -fms-extensions -verify -std=c++17 -Wunsupported-dll-base-class-template -DWI %s 8 // RUN: %clang_cc1 -triple x86_64-scei-ps4 -fsyntax-only -fdeclspec -verify -std=c++11 -Wunsupported-dll-base-class-template -DWI %s 9 // RUN: %clang_cc1 -triple x86_64-scei-ps4 -fsyntax-only -fdeclspec -verify -std=c++17 -Wunsupported-dll-base-class-template -DWI %s 10 11 // Helper structs to make templates more expressive. 12 struct ImplicitInst_Imported {}; 13 struct ExplicitDecl_Imported {}; 14 struct ExplicitInst_Imported {}; 15 struct ExplicitSpec_Imported {}; 16 struct ExplicitSpec_Def_Imported {}; 17 struct ExplicitSpec_InlineDef_Imported {}; 18 struct ExplicitSpec_NotImported {}; 19 namespace { struct Internal {}; } 20 21 22 // Invalid usage. 23 __declspec(dllimport) typedef int typedef1; 24 // expected-warning@-1{{'dllimport' attribute only applies to functions, variables, classes, and Objective-C interfaces}} 25 typedef __declspec(dllimport) int typedef2; 26 // expected-warning@-1{{'dllimport' attribute only applies to}} 27 typedef int __declspec(dllimport) typedef3; 28 // expected-warning@-1{{'dllimport' attribute only applies to}} 29 typedef __declspec(dllimport) void (*FunTy)(); 30 // expected-warning@-1{{'dllimport' attribute only applies to}} 31 enum __declspec(dllimport) Enum {}; 32 // expected-warning@-1{{'dllimport' attribute only applies to}} 33 #if __has_feature(cxx_strong_enums) 34 enum class __declspec(dllimport) EnumClass {}; 35 // expected-warning@-1{{'dllimport' attribute only applies to}} 36 #endif 37 38 39 40 //===----------------------------------------------------------------------===// 41 // Globals 42 //===----------------------------------------------------------------------===// 43 44 // Import declaration. 45 __declspec(dllimport) extern int ExternGlobalDecl; 46 47 // dllimport implies a declaration. 48 __declspec(dllimport) int GlobalDecl; 49 int **__attribute__((dllimport))* GlobalDeclChunkAttr; 50 int GlobalDeclAttr __attribute__((dllimport)); 51 52 // Not allowed on definitions. 53 __declspec(dllimport) extern int ExternGlobalInit = 1; // expected-error{{definition of dllimport data}} 54 __declspec(dllimport) int GlobalInit1 = 1; // expected-error{{definition of dllimport data}} 55 int __declspec(dllimport) GlobalInit2 = 1; // expected-error{{definition of dllimport data}} 56 57 // Declare, then reject definition. 58 #ifdef GNU 59 // expected-note@+2{{previous attribute is here}} 60 #endif 61 __declspec(dllimport) extern int ExternGlobalDeclInit; // expected-note{{previous declaration is here}} 62 #if defined(MS) || defined(WI) 63 // expected-warning@+4{{'ExternGlobalDeclInit' redeclared without 'dllimport' attribute: 'dllexport' attribute added}} 64 #else 65 // expected-warning@+2{{'ExternGlobalDeclInit' redeclared without 'dllimport' attribute: previous 'dllimport' ignored}} 66 #endif 67 int ExternGlobalDeclInit = 1; 68 69 #ifdef GNU 70 // expected-note@+2{{previous attribute is here}} 71 #endif 72 __declspec(dllimport) int GlobalDeclInit; // expected-note{{previous declaration is here}} 73 #if defined(MS) || defined(WI) 74 // expected-warning@+4{{'GlobalDeclInit' redeclared without 'dllimport' attribute: 'dllexport' attribute added}} 75 #else 76 // expected-warning@+2{{'GlobalDeclInit' redeclared without 'dllimport' attribute: previous 'dllimport' ignored}} 77 #endif 78 int GlobalDeclInit = 1; 79 80 #ifdef GNU 81 // expected-note@+2{{previous attribute is here}} 82 #endif 83 int *__attribute__((dllimport)) GlobalDeclChunkAttrInit; // expected-note{{previous declaration is here}} 84 #if defined(MS) || defined(WI) 85 // expected-warning@+4{{'GlobalDeclChunkAttrInit' redeclared without 'dllimport' attribute: 'dllexport' attribute added}} 86 #else 87 // expected-warning@+2{{'GlobalDeclChunkAttrInit' redeclared without 'dllimport' attribute: previous 'dllimport' ignored}} 88 #endif 89 int *GlobalDeclChunkAttrInit = 0; 90 91 #ifdef GNU 92 // expected-note@+2{{previous attribute is here}} 93 #endif 94 int GlobalDeclAttrInit __attribute__((dllimport)); // expected-note{{previous declaration is here}} 95 #if defined(MS) || defined(WI) 96 // expected-warning@+4{{'GlobalDeclAttrInit' redeclared without 'dllimport' attribute: 'dllexport' attribute added}} 97 #else 98 // expected-warning@+2{{'GlobalDeclAttrInit' redeclared without 'dllimport' attribute: previous 'dllimport' ignored}} 99 #endif 100 int GlobalDeclAttrInit = 1; 101 102 // Redeclarations 103 __declspec(dllimport) extern int GlobalRedecl1; 104 __declspec(dllimport) extern int GlobalRedecl1; 105 106 __declspec(dllimport) int GlobalRedecl2a; 107 __declspec(dllimport) int GlobalRedecl2a; 108 109 int *__attribute__((dllimport)) GlobalRedecl2b; 110 int *__attribute__((dllimport)) GlobalRedecl2b; 111 112 int GlobalRedecl2c __attribute__((dllimport)); 113 int GlobalRedecl2c __attribute__((dllimport)); 114 115 __declspec(dllimport) extern int GlobalRedecl3; // expected-note{{previous declaration is here}} expected-note{{previous attribute is here}} 116 extern int GlobalRedecl3; // expected-warning{{'GlobalRedecl3' redeclared without 'dllimport' attribute: previous 'dllimport' ignored}} 117 118 extern int GlobalRedecl4; // expected-note{{previous declaration is here}} 119 __declspec(dllimport) extern int GlobalRedecl4; // expected-warning{{redeclaration of 'GlobalRedecl4' should not add 'dllimport' attribute}} 120 121 extern "C" { 122 extern int GlobalRedecl5; // expected-note{{previous declaration is here}} 123 __declspec(dllimport) extern int GlobalRedecl5; // expected-warning{{redeclaration of 'GlobalRedecl5' should not add 'dllimport' attribute}} 124 } 125 126 // External linkage is required. 127 __declspec(dllimport) static int StaticGlobal; // expected-error{{'StaticGlobal' must have external linkage when declared 'dllimport'}} 128 __declspec(dllimport) Internal InternalTypeGlobal; // expected-error{{'InternalTypeGlobal' must have external linkage when declared 'dllimport'}} 129 #ifndef MS 130 namespace { __declspec(dllimport) int InternalGlobal; } // expected-error{{'(anonymous namespace)::InternalGlobal' must have external linkage when declared 'dllimport'}} 131 #endif 132 namespace ns { __declspec(dllimport) int ExternalGlobal; } 133 134 __declspec(dllimport) auto InternalAutoTypeGlobal = Internal(); // expected-error{{'InternalAutoTypeGlobal' must have external linkage when declared 'dllimport'}} 135 // expected-error@-1{{definition of dllimport data}} 136 137 // Thread local variables are invalid. 138 __declspec(dllimport) __thread int ThreadLocalGlobal; // expected-error{{'ThreadLocalGlobal' cannot be thread local when declared 'dllimport'}} 139 // This doesn't work on MinGW, because there, dllimport on the inline function is ignored. 140 #ifndef GNU 141 inline void __declspec(dllimport) ImportedInlineWithThreadLocal() { 142 static __thread int OK; // no-error 143 } 144 #endif 145 146 // Import in local scope. 147 __declspec(dllimport) float LocalRedecl1; // expected-note{{previous declaration is here}} 148 __declspec(dllimport) float LocalRedecl2; // expected-note{{previous declaration is here}} 149 __declspec(dllimport) float LocalRedecl3; // expected-note{{previous declaration is here}} 150 void functionScope() { 151 __declspec(dllimport) int LocalRedecl1; // expected-error{{redeclaration of 'LocalRedecl1' with a different type: 'int' vs 'float'}} 152 int *__attribute__((dllimport)) LocalRedecl2; // expected-error{{redeclaration of 'LocalRedecl2' with a different type: 'int *' vs 'float'}} 153 int LocalRedecl3 __attribute__((dllimport)); // expected-error{{redeclaration of 'LocalRedecl3' with a different type: 'int' vs 'float'}} 154 155 __declspec(dllimport) int LocalVarDecl; 156 __declspec(dllimport) int LocalVarDef = 1; // expected-error{{definition of dllimport data}} 157 __declspec(dllimport) extern int ExternLocalVarDecl; 158 __declspec(dllimport) extern int ExternLocalVarDef = 1; // expected-error{{definition of dllimport data}} 159 __declspec(dllimport) static int StaticLocalVar; // expected-error{{'StaticLocalVar' must have external linkage when declared 'dllimport'}} 160 } 161 162 163 164 //===----------------------------------------------------------------------===// 165 // Variable templates 166 //===----------------------------------------------------------------------===// 167 #if __has_feature(cxx_variable_templates) 168 169 // Import declaration. 170 template<typename T> __declspec(dllimport) extern int ExternVarTmplDecl; 171 172 // dllimport implies a declaration. 173 template<typename T> __declspec(dllimport) int VarTmplDecl; 174 175 // Not allowed on definitions. 176 template<typename T> __declspec(dllimport) extern int ExternVarTmplInit = 1; // expected-error{{definition of dllimport data}} 177 template<typename T> __declspec(dllimport) int VarTmplInit1 = 1; // expected-error{{definition of dllimport data}} 178 template<typename T> int __declspec(dllimport) VarTmplInit2 = 1; // expected-error{{definition of dllimport data}} 179 180 // Declare, then reject definition. 181 #ifdef GNU 182 // expected-note@+3{{previous attribute is here}} 183 #endif 184 template <typename T> 185 __declspec(dllimport) extern int ExternVarTmplDeclInit; // expected-note{{previous declaration is here}} 186 #if defined(MS) || defined(WI) 187 // expected-warning@+5{{'ExternVarTmplDeclInit' redeclared without 'dllimport' attribute: 'dllexport' attribute added}} 188 #else 189 // expected-warning@+3{{'ExternVarTmplDeclInit' redeclared without 'dllimport' attribute: previous 'dllimport' ignored}} 190 #endif 191 template <typename T> 192 int ExternVarTmplDeclInit = 1; 193 194 #ifdef GNU 195 // expected-note@+3{{previous attribute is here}} 196 #endif 197 template <typename T> 198 __declspec(dllimport) int VarTmplDeclInit; // expected-note{{previous declaration is here}} 199 #if defined(MS) || defined(WI) 200 // expected-warning@+5{{'VarTmplDeclInit' redeclared without 'dllimport' attribute: 'dllexport' attribute added}} 201 #else 202 // expected-warning@+3{{'VarTmplDeclInit' redeclared without 'dllimport' attribute: previous 'dllimport' ignored}} 203 #endif 204 template <typename T> 205 int VarTmplDeclInit = 1; 206 207 // Redeclarations 208 template<typename T> __declspec(dllimport) extern int VarTmplRedecl1; 209 template<typename T> __declspec(dllimport) extern int VarTmplRedecl1; 210 211 template<typename T> __declspec(dllimport) int VarTmplRedecl2; 212 template<typename T> __declspec(dllimport) int VarTmplRedecl2; 213 214 template<typename T> __declspec(dllimport) extern int VarTmplRedecl3; // expected-note{{previous declaration is here}} expected-note{{previous attribute is here}} 215 template<typename T> extern int VarTmplRedecl3; // expected-warning{{'VarTmplRedecl3' redeclared without 'dllimport' attribute: previous 'dllimport' ignored}} 216 217 template<typename T> extern int VarTmplRedecl4; // expected-note{{previous declaration is here}} 218 template<typename T> __declspec(dllimport) extern int VarTmplRedecl4; // expected-error{{redeclaration of 'VarTmplRedecl4' cannot add 'dllimport' attribute}} 219 220 // External linkage is required. 221 template<typename T> __declspec(dllimport) static int StaticVarTmpl; // expected-error{{'StaticVarTmpl' must have external linkage when declared 'dllimport'}} 222 template<typename T> __declspec(dllimport) Internal InternalTypeVarTmpl; // expected-error{{'InternalTypeVarTmpl' must have external linkage when declared 'dllimport'}} 223 #ifndef MS 224 namespace { template<typename T> __declspec(dllimport) int InternalVarTmpl; } // expected-error{{'(anonymous namespace)::InternalVarTmpl' must have external linkage when declared 'dllimport'}} 225 #endif 226 namespace ns { template<typename T> __declspec(dllimport) int ExternalVarTmpl; } 227 228 template<typename T> __declspec(dllimport) auto InternalAutoTypeVarTmpl = Internal(); // expected-error{{definition of dllimport data}} // expected-error{{'InternalAutoTypeVarTmpl' must have external linkage when declared 'dllimport'}} 229 230 231 template<typename T> int VarTmpl; 232 template<typename T> __declspec(dllimport) int ImportedVarTmpl; 233 234 // Import implicit instantiation of an imported variable template. 235 int useVarTmpl() { return ImportedVarTmpl<ImplicitInst_Imported>; } 236 237 // Import explicit instantiation declaration of an imported variable template. 238 extern template int ImportedVarTmpl<ExplicitDecl_Imported>; 239 240 // An explicit instantiation definition of an imported variable template cannot 241 // be imported because the template must be defined which is illegal. 242 243 // Import specialization of an imported variable template. 244 template<> __declspec(dllimport) int ImportedVarTmpl<ExplicitSpec_Imported>; 245 template<> __declspec(dllimport) int ImportedVarTmpl<ExplicitSpec_Def_Imported> = 1; // expected-error{{definition of dllimport data}} 246 247 // Not importing specialization of an imported variable template without 248 // explicit dllimport. 249 template<> int ImportedVarTmpl<ExplicitSpec_NotImported>; 250 251 252 // Import explicit instantiation declaration of a non-imported variable template. 253 extern template __declspec(dllimport) int VarTmpl<ExplicitDecl_Imported>; 254 255 // Import explicit instantiation definition of a non-imported variable template. 256 template __declspec(dllimport) int VarTmpl<ExplicitInst_Imported>; 257 258 // Import specialization of a non-imported variable template. 259 template<> __declspec(dllimport) int VarTmpl<ExplicitSpec_Imported>; 260 template<> __declspec(dllimport) int VarTmpl<ExplicitSpec_Def_Imported> = 1; // expected-error{{definition of dllimport data}} 261 262 #endif // __has_feature(cxx_variable_templates) 263 264 265 //===----------------------------------------------------------------------===// 266 // Functions 267 //===----------------------------------------------------------------------===// 268 269 // Import function declaration. Check different placements. 270 __attribute__((dllimport)) void decl1A(); // Sanity check with __attribute__ 271 __declspec(dllimport) void decl1B(); 272 273 void __attribute__((dllimport)) decl2A(); 274 void __declspec(dllimport) decl2B(); 275 276 // Not allowed on function definitions. 277 __declspec(dllimport) void def() {} // expected-error{{dllimport cannot be applied to non-inline function definition}} 278 279 // extern "C" 280 extern "C" __declspec(dllimport) void externC(); 281 282 // Import inline function. 283 #ifdef GNU 284 // expected-warning@+3{{'dllimport' attribute ignored on inline function}} 285 // expected-warning@+3{{'dllimport' attribute ignored on inline function}} 286 #endif 287 __declspec(dllimport) inline void inlineFunc1() {} 288 inline void __attribute__((dllimport)) inlineFunc2() {} 289 290 #ifdef GNU 291 // expected-warning@+2{{'dllimport' attribute ignored on inline function}} 292 #endif 293 __declspec(dllimport) inline void inlineDecl(); 294 void inlineDecl() {} 295 296 __declspec(dllimport) void inlineDef(); 297 #ifdef GNU 298 // expected-warning@+2{{'inlineDef' redeclared inline; 'dllimport' attribute ignored}} 299 #endif 300 inline void inlineDef() {} 301 302 // Redeclarations 303 __declspec(dllimport) void redecl1(); 304 __declspec(dllimport) void redecl1(); 305 306 __declspec(dllimport) void redecl2(); // expected-note{{previous declaration is here}} expected-note{{previous attribute is here}} 307 void redecl2(); // expected-warning{{'redecl2' redeclared without 'dllimport' attribute: previous 'dllimport' ignored}} 308 309 #ifdef GNU 310 // expected-note@+2{{previous attribute is here}} 311 #endif 312 __declspec(dllimport) void redecl3(); // expected-note{{previous declaration is here}} 313 // NB: Both MSVC and Clang issue a warning and make redecl3 dllexport. 314 #if defined(MS) || defined(WI) 315 // expected-warning@+4{{'redecl3' redeclared without 'dllimport' attribute: 'dllexport' attribute added}} 316 #else 317 // expected-warning@+2{{'redecl3' redeclared without 'dllimport' attribute: previous 'dllimport' ignored}} 318 #endif 319 void redecl3() {} 320 321 void redecl4(); // expected-note{{previous declaration is here}} 322 __declspec(dllimport) void redecl4(); // expected-warning{{redeclaration of 'redecl4' should not add 'dllimport' attribute}} 323 324 extern "C" { 325 void redecl5(); // expected-note{{previous declaration is here}} 326 __declspec(dllimport) void redecl5(); // expected-warning{{redeclaration of 'redecl5' should not add 'dllimport' attribute}} 327 } 328 329 #if defined(MS) || defined(WI) 330 void redecl6(); // expected-note{{previous declaration is here}} 331 __declspec(dllimport) inline void redecl6() {} // expected-warning{{redeclaration of 'redecl6' should not add 'dllimport' attribute}} 332 #else 333 void redecl6(); 334 __declspec(dllimport) inline void redecl6() {} // expected-warning{{'dllimport' attribute ignored on inline function}} 335 #endif 336 337 // Friend functions 338 struct FuncFriend { 339 friend __declspec(dllimport) void friend1(); 340 friend __declspec(dllimport) void friend2(); // expected-note{{previous declaration is here}} expected-note{{previous attribute is here}} 341 #ifdef GNU 342 // expected-note@+2{{previous attribute is here}} 343 #endif 344 friend __declspec(dllimport) void friend3(); // expected-note{{previous declaration is here}} 345 friend void friend4(); // expected-note{{previous declaration is here}} 346 #if defined(MS) || defined(WI) 347 // expected-note@+2{{previous declaration is here}} 348 #endif 349 friend void friend5(); 350 }; 351 __declspec(dllimport) void friend1(); 352 void friend2(); // expected-warning{{'friend2' redeclared without 'dllimport' attribute: previous 'dllimport' ignored}} 353 #if defined(MS) || defined(WI) 354 // expected-warning@+4{{'friend3' redeclared without 'dllimport' attribute: 'dllexport' attribute added}} 355 #else 356 // expected-warning@+2{{'friend3' redeclared without 'dllimport' attribute: previous 'dllimport' ignored}} 357 #endif 358 void friend3() {} 359 __declspec(dllimport) void friend4(); // expected-warning{{redeclaration of 'friend4' should not add 'dllimport' attribute}} 360 #if defined(MS) || defined(WI) 361 __declspec(dllimport) inline void friend5() {} // expected-warning{{redeclaration of 'friend5' should not add 'dllimport' attribute}} 362 #else 363 __declspec(dllimport) inline void friend5() {} // expected-warning{{'dllimport' attribute ignored on inline function}} 364 #endif 365 366 367 void __declspec(dllimport) friend6(); // expected-note{{previous declaration is here}} expected-note{{previous attribute is here}} 368 void __declspec(dllimport) friend7(); 369 struct FuncFriend2 { 370 friend void friend6(); // expected-warning{{'friend6' redeclared without 'dllimport' attribute: previous 'dllimport' ignored}} 371 friend void ::friend7(); 372 }; 373 374 // Implicit declarations can be redeclared with dllimport. 375 __declspec(dllimport) void* operator new(__SIZE_TYPE__ n); 376 377 // External linkage is required. 378 __declspec(dllimport) static int staticFunc(); // expected-error{{'staticFunc' must have external linkage when declared 'dllimport'}} 379 __declspec(dllimport) Internal internalRetFunc(); // expected-error{{'internalRetFunc' must have external linkage when declared 'dllimport'}} 380 namespace { __declspec(dllimport) void internalFunc(); } // expected-error{{'(anonymous namespace)::internalFunc' must have external linkage when declared 'dllimport'}} 381 namespace ns { __declspec(dllimport) void externalFunc(); } 382 383 // Import deleted functions. 384 // FIXME: Deleted functions are definitions so a missing inline is diagnosed 385 // here which is irrelevant. But because the delete keyword is parsed later 386 // there is currently no straight-forward way to avoid this diagnostic. 387 __declspec(dllimport) void deletedFunc() = delete; // expected-error{{attribute 'dllimport' cannot be applied to a deleted function}} expected-error{{dllimport cannot be applied to non-inline function definition}} 388 #if defined(MS) || defined(WI) 389 __declspec(dllimport) inline void deletedInlineFunc() = delete; // expected-error{{attribute 'dllimport' cannot be applied to a deleted function}} 390 #else 391 __declspec(dllimport) inline void deletedInlineFunc() = delete; // expected-warning{{'dllimport' attribute ignored on inline function}} 392 #endif 393 394 395 396 //===----------------------------------------------------------------------===// 397 // Function templates 398 //===----------------------------------------------------------------------===// 399 400 // Import function template declaration. Check different placements. 401 template<typename T> __declspec(dllimport) void funcTmplDecl1(); 402 template<typename T> void __declspec(dllimport) funcTmplDecl2(); 403 404 // Import function template definition. 405 template<typename T> __declspec(dllimport) void funcTmplDef() {} // expected-error{{dllimport cannot be applied to non-inline function definition}} 406 407 // Import inline function template. 408 #ifdef GNU // MinGW always ignores dllimport on inline functions. 409 410 template<typename T> __declspec(dllimport) inline void inlineFuncTmpl1() {} // expected-warning{{'dllimport' attribute ignored on inline function}} 411 template<typename T> inline void __attribute__((dllimport)) inlineFuncTmpl2() {} // expected-warning{{'dllimport' attribute ignored on inline function}} 412 413 template<typename T> __declspec(dllimport) inline void inlineFuncTmplDecl(); // expected-warning{{'dllimport' attribute ignored on inline function}} 414 template<typename T> void inlineFuncTmplDecl() {} 415 416 template<typename T> __declspec(dllimport) void inlineFuncTmplDef(); 417 template<typename T> inline void inlineFuncTmplDef() {} // expected-warning{{'inlineFuncTmplDef' redeclared inline; 'dllimport' attribute ignored}} 418 419 #else // MSVC drops dllimport when the function template is redeclared without it. (It doesn't warn, but we do.) 420 421 template<typename T> __declspec(dllimport) inline void inlineFuncTmpl1() {} 422 template<typename T> inline void __attribute__((dllimport)) inlineFuncTmpl2() {} 423 424 template<typename T> __declspec(dllimport) inline void inlineFuncTmplDecl(); // expected-note{{previous declaration is here}} expected-note{{previous attribute is here}} 425 template<typename T> void inlineFuncTmplDecl() {} // expected-warning{{'inlineFuncTmplDecl' redeclared without 'dllimport' attribute: previous 'dllimport' ignored}} 426 427 template<typename T> __declspec(dllimport) void inlineFuncTmplDef(); // expected-note{{previous declaration is here}} expected-note{{previous attribute is here}} 428 template<typename T> inline void inlineFuncTmplDef() {} // expected-warning{{'inlineFuncTmplDef' redeclared without 'dllimport' attribute: previous 'dllimport' ignored}} 429 #endif 430 431 // Redeclarations 432 template<typename T> __declspec(dllimport) void funcTmplRedecl1(); 433 template<typename T> __declspec(dllimport) void funcTmplRedecl1(); 434 435 template<typename T> __declspec(dllimport) void funcTmplRedecl2(); // expected-note{{previous declaration is here}} expected-note{{previous attribute is here}} 436 template<typename T> void funcTmplRedecl2(); // expected-warning{{'funcTmplRedecl2' redeclared without 'dllimport' attribute: previous 'dllimport' ignored}} 437 438 template<typename T> __declspec(dllimport) void funcTmplRedecl3(); // expected-note{{previous declaration is here}} expected-note{{previous attribute is here}} 439 template<typename T> void funcTmplRedecl3() {} // expected-warning{{'funcTmplRedecl3' redeclared without 'dllimport' attribute: previous 'dllimport' ignored}} 440 441 template<typename T> void funcTmplRedecl4(); // expected-note{{previous declaration is here}} 442 template<typename T> __declspec(dllimport) void funcTmplRedecl4(); // expected-error{{redeclaration of 'funcTmplRedecl4' cannot add 'dllimport' attribute}} 443 444 #ifdef MS 445 template<typename T> void funcTmplRedecl5(); // expected-note{{previous declaration is here}} 446 template<typename T> __declspec(dllimport) inline void funcTmplRedecl5() {} // expected-error{{redeclaration of 'funcTmplRedecl5' cannot add 'dllimport' attribute}} 447 #endif 448 449 // Function template friends 450 struct FuncTmplFriend { 451 template<typename T> friend __declspec(dllimport) void funcTmplFriend1(); 452 template<typename T> friend __declspec(dllimport) void funcTmplFriend2(); // expected-note{{previous declaration is here}} expected-note{{previous attribute is here}} 453 template<typename T> friend __declspec(dllimport) void funcTmplFriend3(); // expected-note{{previous declaration is here}} expected-note{{previous attribute is here}} 454 template<typename T> friend void funcTmplFriend4(); // expected-note{{previous declaration is here}} 455 #ifdef GNU 456 // expected-warning@+4{{'dllimport' attribute ignored on inline function}} 457 #else 458 // expected-note@+2{{previous declaration is here}} expected-note@+2{{previous attribute is here}} 459 #endif 460 template<typename T> friend __declspec(dllimport) inline void funcTmplFriend5(); 461 }; 462 template<typename T> __declspec(dllimport) void funcTmplFriend1(); 463 template<typename T> void funcTmplFriend2(); // expected-warning{{'funcTmplFriend2' redeclared without 'dllimport' attribute: previous 'dllimport' ignored}} 464 template<typename T> void funcTmplFriend3() {} // expected-warning{{'funcTmplFriend3' redeclared without 'dllimport' attribute: previous 'dllimport' ignored}} 465 template<typename T> __declspec(dllimport) void funcTmplFriend4(); // expected-error{{redeclaration of 'funcTmplFriend4' cannot add 'dllimport' attribute}} 466 #if defined(MS) || defined(WI) 467 // expected-warning@+2{{'funcTmplFriend5' redeclared without 'dllimport' attribute: previous 'dllimport' ignored}} 468 #endif 469 template<typename T> inline void funcTmplFriend5() {} 470 471 // External linkage is required. 472 template<typename T> __declspec(dllimport) static int staticFuncTmpl(); // expected-error{{'staticFuncTmpl' must have external linkage when declared 'dllimport'}} 473 template<typename T> __declspec(dllimport) Internal internalRetFuncTmpl(); // expected-error{{'internalRetFuncTmpl' must have external linkage when declared 'dllimport'}} 474 namespace { template<typename T> __declspec(dllimport) void internalFuncTmpl(); } // expected-error{{'(anonymous namespace)::internalFuncTmpl' must have external linkage when declared 'dllimport'}} 475 namespace ns { template<typename T> __declspec(dllimport) void externalFuncTmpl(); } 476 477 478 template<typename T> void funcTmpl() {} 479 template<typename T> inline void inlineFuncTmpl() {} 480 template<typename T> __declspec(dllimport) void importedFuncTmplDecl(); 481 #ifdef GNU 482 // expected-warning@+2{{'dllimport' attribute ignored on inline function}} 483 #endif 484 template<typename T> __declspec(dllimport) inline void importedFuncTmpl() {} 485 486 // Import implicit instantiation of an imported function template. 487 void useFunTmplDecl() { importedFuncTmplDecl<ImplicitInst_Imported>(); } 488 void useFunTmplDef() { importedFuncTmpl<ImplicitInst_Imported>(); } 489 490 // Import explicit instantiation declaration of an imported function template. 491 extern template void importedFuncTmpl<ExplicitDecl_Imported>(); 492 493 // Import explicit instantiation definition of an imported function template. 494 // NB: MSVC fails this instantiation without explicit dllimport which is most 495 // likely a bug because an implicit instantiation is accepted. 496 template void importedFuncTmpl<ExplicitInst_Imported>(); 497 498 // Import specialization of an imported function template. A definition must be 499 // declared inline. 500 template<> __declspec(dllimport) void importedFuncTmpl<ExplicitSpec_Imported>(); 501 template<> __declspec(dllimport) void importedFuncTmpl<ExplicitSpec_Def_Imported>() {} // expected-error{{dllimport cannot be applied to non-inline function definition}} 502 #ifdef MS 503 template<> __declspec(dllimport) inline void importedFuncTmpl<ExplicitSpec_InlineDef_Imported>() {} 504 #endif 505 506 // Not importing specialization of an imported function template without 507 // explicit dllimport. 508 template<> void importedFuncTmpl<ExplicitSpec_NotImported>() {} 509 510 511 // Import explicit instantiation declaration of a non-imported function template. 512 extern template __declspec(dllimport) void funcTmpl<ExplicitDecl_Imported>(); 513 #ifdef GNU 514 // expected-warning@+2{{'dllimport' attribute ignored on inline function}} 515 #endif 516 extern template __declspec(dllimport) void inlineFuncTmpl<ExplicitDecl_Imported>(); 517 518 // Import explicit instantiation definition of a non-imported function template. 519 template __declspec(dllimport) void funcTmpl<ExplicitInst_Imported>(); 520 #ifdef GNU 521 // expected-warning@+2{{'dllimport' attribute ignored on inline function}} 522 #endif 523 template __declspec(dllimport) void inlineFuncTmpl<ExplicitInst_Imported>(); 524 525 // Import specialization of a non-imported function template. A definition must 526 // be declared inline. 527 template<> __declspec(dllimport) void funcTmpl<ExplicitSpec_Imported>(); 528 template<> __declspec(dllimport) void funcTmpl<ExplicitSpec_Def_Imported>() {} // expected-error{{dllimport cannot be applied to non-inline function definition}} 529 #ifdef GNU 530 // expected-warning@+2{{'dllimport' attribute ignored on inline function}} 531 #endif 532 template<> __declspec(dllimport) inline void funcTmpl<ExplicitSpec_InlineDef_Imported>() {} 533 534 535 //===----------------------------------------------------------------------===// 536 // Class members 537 //===----------------------------------------------------------------------===// 538 539 // Import individual members of a class. 540 struct ImportMembers { 541 struct Nested { 542 __declspec(dllimport) void normalDecl(); 543 #ifdef GNU 544 // expected-note@+2{{previous attribute is here}} 545 #endif 546 __declspec(dllimport) void normalDef(); // expected-note{{previous declaration is here}} 547 }; 548 549 #ifdef GNU 550 // expected-note@+5{{previous attribute is here}} 551 // expected-warning@+5{{'dllimport' attribute ignored on inline function}} 552 // expected-warning@+6{{'dllimport' attribute ignored on inline function}} 553 #endif 554 __declspec(dllimport) void normalDecl(); 555 __declspec(dllimport) void normalDef(); // expected-note{{previous declaration is here}} 556 __declspec(dllimport) void normalInclass() {} 557 __declspec(dllimport) void normalInlineDef(); 558 __declspec(dllimport) inline void normalInlineDecl(); 559 #ifdef GNU 560 // expected-note@+5{{previous attribute is here}} 561 // expected-warning@+5{{'dllimport' attribute ignored on inline function}} 562 // expected-warning@+6{{'dllimport' attribute ignored on inline function}} 563 #endif 564 __declspec(dllimport) virtual void virtualDecl(); 565 __declspec(dllimport) virtual void virtualDef(); // expected-note{{previous declaration is here}} 566 __declspec(dllimport) virtual void virtualInclass() {} 567 __declspec(dllimport) virtual void virtualInlineDef(); 568 __declspec(dllimport) virtual inline void virtualInlineDecl(); 569 #ifdef GNU 570 // expected-note@+5{{previous attribute is here}} 571 // expected-warning@+5{{'dllimport' attribute ignored on inline function}} 572 // expected-warning@+6{{'dllimport' attribute ignored on inline function}} 573 #endif 574 __declspec(dllimport) static void staticDecl(); 575 __declspec(dllimport) static void staticDef(); // expected-note{{previous declaration is here}} 576 __declspec(dllimport) static void staticInclass() {} 577 __declspec(dllimport) static void staticInlineDef(); 578 __declspec(dllimport) static inline void staticInlineDecl(); 579 580 protected: 581 __declspec(dllimport) void protectedDecl(); 582 private: 583 __declspec(dllimport) void privateDecl(); 584 public: 585 586 __declspec(dllimport) int Field; // expected-warning{{'dllimport' attribute only applies to}} 587 __declspec(dllimport) static int StaticField; 588 __declspec(dllimport) static int StaticFieldDef; // expected-note{{attribute is here}} 589 __declspec(dllimport) static const int StaticConstField; 590 __declspec(dllimport) static const int StaticConstFieldDef; // expected-note{{attribute is here}} 591 __declspec(dllimport) static const int StaticConstFieldEqualInit = 1; 592 __declspec(dllimport) static const int StaticConstFieldBraceInit{1}; 593 __declspec(dllimport) constexpr static int ConstexprField = 1; 594 #if __cplusplus < 201703L && !defined(MS) 595 // expected-note@+2{{attribute is here}} 596 #endif 597 __declspec(dllimport) constexpr static int ConstexprFieldDef = 1; 598 }; 599 600 #if defined(MS) || defined(WI) 601 // expected-warning@+4{{'ImportMembers::Nested::normalDef' redeclared without 'dllimport' attribute: 'dllexport' attribute added}} 602 #else 603 // expected-warning@+2{{'ImportMembers::Nested::normalDef' redeclared without 'dllimport' attribute: previous 'dllimport' ignored}} 604 #endif 605 void ImportMembers::Nested::normalDef() {} 606 #if defined(MS) || defined(WI) 607 // expected-warning@+4{{'ImportMembers::normalDef' redeclared without 'dllimport' attribute: 'dllexport' attribute added}} 608 #else 609 // expected-warning@+2{{'ImportMembers::normalDef' redeclared without 'dllimport' attribute: previous 'dllimport' ignored}} 610 #endif 611 void ImportMembers::normalDef() {} 612 #ifdef GNU 613 // expected-warning@+2{{'ImportMembers::normalInlineDef' redeclared inline; 'dllimport' attribute ignored}} 614 #endif 615 inline void ImportMembers::normalInlineDef() {} 616 void ImportMembers::normalInlineDecl() {} 617 #if defined(MS) || defined(WI) 618 // expected-warning@+4{{'ImportMembers::virtualDef' redeclared without 'dllimport' attribute: 'dllexport' attribute added}} 619 #else 620 // expected-warning@+2{{'ImportMembers::virtualDef' redeclared without 'dllimport' attribute: previous 'dllimport' ignored}} 621 #endif 622 void ImportMembers::virtualDef() {} 623 #ifdef GNU 624 // expected-warning@+2{{'ImportMembers::virtualInlineDef' redeclared inline; 'dllimport' attribute ignored}} 625 #endif 626 inline void ImportMembers::virtualInlineDef() {} 627 void ImportMembers::virtualInlineDecl() {} 628 #if defined(MS) || defined(WI) 629 // expected-warning@+4{{'ImportMembers::staticDef' redeclared without 'dllimport' attribute: 'dllexport' attribute added}} 630 #else 631 // expected-warning@+2{{'ImportMembers::staticDef' redeclared without 'dllimport' attribute: previous 'dllimport' ignored}} 632 #endif 633 void ImportMembers::staticDef() {} 634 #ifdef GNU 635 // expected-warning@+2{{'ImportMembers::staticInlineDef' redeclared inline; 'dllimport' attribute ignored}} 636 #endif 637 inline void ImportMembers::staticInlineDef() {} 638 void ImportMembers::staticInlineDecl() {} 639 640 int ImportMembers::StaticFieldDef; // expected-error{{definition of dllimport static field not allowed}} 641 const int ImportMembers::StaticConstFieldDef = 1; // expected-error{{definition of dllimport static field not allowed}} 642 #if __cplusplus < 201703L && !defined(MS) 643 // expected-error@+2{{definition of dllimport static field not allowed}} 644 #endif 645 constexpr int ImportMembers::ConstexprFieldDef; 646 647 648 // Import on member definitions. 649 struct ImportMemberDefs { 650 __declspec(dllimport) void normalDef(); 651 __declspec(dllimport) void normalInlineDef(); 652 __declspec(dllimport) virtual void virtualDef(); 653 __declspec(dllimport) virtual void virtualInlineDef(); 654 __declspec(dllimport) static void staticDef(); 655 __declspec(dllimport) static void staticInlineDef(); 656 #ifdef MS 657 __declspec(dllimport) inline void normalInlineDecl(); 658 __declspec(dllimport) virtual inline void virtualInlineDecl(); 659 __declspec(dllimport) static inline void staticInlineDecl(); 660 #endif 661 662 __declspec(dllimport) static int StaticField; 663 __declspec(dllimport) static const int StaticConstField; 664 __declspec(dllimport) constexpr static int ConstexprField = 1; 665 }; 666 667 __declspec(dllimport) void ImportMemberDefs::normalDef() {} // expected-error{{dllimport cannot be applied to non-inline function definition}} 668 __declspec(dllimport) void ImportMemberDefs::virtualDef() {} // expected-error{{dllimport cannot be applied to non-inline function definition}} 669 __declspec(dllimport) void ImportMemberDefs::staticDef() {} // expected-error{{dllimport cannot be applied to non-inline function definition}} 670 #ifdef MS 671 __declspec(dllimport) inline void ImportMemberDefs::normalInlineDef() {} 672 __declspec(dllimport) void ImportMemberDefs::normalInlineDecl() {} 673 __declspec(dllimport) inline void ImportMemberDefs::virtualInlineDef() {} 674 __declspec(dllimport) void ImportMemberDefs::virtualInlineDecl() {} 675 __declspec(dllimport) inline void ImportMemberDefs::staticInlineDef() {} 676 __declspec(dllimport) void ImportMemberDefs::staticInlineDecl() {} 677 #endif 678 679 __declspec(dllimport) int ImportMemberDefs::StaticField; // expected-error{{definition of dllimport static field not allowed}} expected-note{{attribute is here}} 680 __declspec(dllimport) const int ImportMemberDefs::StaticConstField = 1; // expected-error{{definition of dllimport static field not allowed}} expected-note{{attribute is here}} 681 #if __cplusplus < 201703L && !defined(MS) 682 // expected-error@+3{{definition of dllimport static field not allowed}} 683 // expected-note@+2{{attribute is here}} 684 #endif 685 __declspec(dllimport) constexpr int ImportMemberDefs::ConstexprField; 686 687 688 // Import special member functions. 689 struct ImportSpecials { 690 __declspec(dllimport) ImportSpecials(); 691 __declspec(dllimport) ~ImportSpecials(); 692 __declspec(dllimport) ImportSpecials(const ImportSpecials&); 693 __declspec(dllimport) ImportSpecials& operator=(const ImportSpecials&); 694 __declspec(dllimport) ImportSpecials(ImportSpecials&&); 695 __declspec(dllimport) ImportSpecials& operator=(ImportSpecials&&); 696 }; 697 698 699 // Import deleted member functions. 700 struct ImportDeleted { 701 #if defined(MS) || defined(WI) 702 __declspec(dllimport) ImportDeleted() = delete; // expected-error{{attribute 'dllimport' cannot be applied to a deleted function}} 703 __declspec(dllimport) ~ImportDeleted() = delete; // expected-error{{attribute 'dllimport' cannot be applied to a deleted function}} 704 __declspec(dllimport) ImportDeleted(const ImportDeleted&) = delete; // expected-error{{attribute 'dllimport' cannot be applied to a deleted function}} 705 __declspec(dllimport) ImportDeleted& operator=(const ImportDeleted&) = delete; // expected-error{{attribute 'dllimport' cannot be applied to a deleted function}} 706 __declspec(dllimport) ImportDeleted(ImportDeleted&&) = delete; // expected-error{{attribute 'dllimport' cannot be applied to a deleted function}} 707 __declspec(dllimport) ImportDeleted& operator=(ImportDeleted&&) = delete; // expected-error{{attribute 'dllimport' cannot be applied to a deleted function}} 708 __declspec(dllimport) void deleted() = delete; // expected-error{{attribute 'dllimport' cannot be applied to a deleted function}} 709 #else 710 __declspec(dllimport) ImportDeleted() = delete; // expected-warning{{'dllimport' attribute ignored on inline function}} 711 __declspec(dllimport) ~ImportDeleted() = delete; // expected-warning{{'dllimport' attribute ignored on inline function}} 712 __declspec(dllimport) ImportDeleted(const ImportDeleted&) = delete; // expected-warning{{'dllimport' attribute ignored on inline function}} 713 __declspec(dllimport) ImportDeleted& operator=(const ImportDeleted&) = delete; // expected-warning{{'dllimport' attribute ignored on inline function}} 714 __declspec(dllimport) ImportDeleted(ImportDeleted&&) = delete; // expected-warning{{'dllimport' attribute ignored on inline function}} 715 __declspec(dllimport) ImportDeleted& operator=(ImportDeleted&&) = delete; // expected-warning{{'dllimport' attribute ignored on inline function}} 716 __declspec(dllimport) void deleted() = delete; // expected-warning{{'dllimport' attribute ignored on inline function}} 717 #endif 718 }; 719 720 721 // Import allocation functions. 722 struct ImportAlloc { 723 __declspec(dllimport) void* operator new(__SIZE_TYPE__); 724 __declspec(dllimport) void* operator new[](__SIZE_TYPE__); 725 __declspec(dllimport) void operator delete(void*); 726 __declspec(dllimport) void operator delete[](void*); 727 }; 728 729 730 // Import defaulted member functions. 731 struct ImportDefaulted { 732 #ifdef GNU 733 // expected-warning@+7{{'dllimport' attribute ignored on inline function}} 734 // expected-warning@+7{{'dllimport' attribute ignored on inline function}} 735 // expected-warning@+7{{'dllimport' attribute ignored on inline function}} 736 // expected-warning@+7{{'dllimport' attribute ignored on inline function}} 737 // expected-warning@+7{{'dllimport' attribute ignored on inline function}} 738 // expected-warning@+7{{'dllimport' attribute ignored on inline function}} 739 #endif 740 __declspec(dllimport) ImportDefaulted() = default; 741 __declspec(dllimport) ~ImportDefaulted() = default; 742 __declspec(dllimport) ImportDefaulted(const ImportDefaulted&) = default; 743 __declspec(dllimport) ImportDefaulted& operator=(const ImportDefaulted&) = default; 744 __declspec(dllimport) ImportDefaulted(ImportDefaulted&&) = default; 745 __declspec(dllimport) ImportDefaulted& operator=(ImportDefaulted&&) = default; 746 }; 747 748 749 // Import defaulted member function definitions. 750 struct ImportDefaultedDefs { 751 __declspec(dllimport) ImportDefaultedDefs(); 752 #ifdef GNU 753 // expected-note@+2{{previous attribute is here}} 754 #endif 755 __declspec(dllimport) ~ImportDefaultedDefs(); // expected-note{{previous declaration is here}} 756 757 #ifdef GNU 758 // expected-warning@+3{{'dllimport' attribute ignored on inline function}} 759 // expected-note@+2{{previous declaration is here}} 760 #endif 761 __declspec(dllimport) inline ImportDefaultedDefs(const ImportDefaultedDefs&); 762 __declspec(dllimport) ImportDefaultedDefs& operator=(const ImportDefaultedDefs&); 763 764 __declspec(dllimport) ImportDefaultedDefs(ImportDefaultedDefs&&); 765 #ifdef GNU 766 // expected-note@+2{{previous attribute is here}} 767 #endif 768 __declspec(dllimport) ImportDefaultedDefs &operator=(ImportDefaultedDefs &&); // expected-note{{previous declaration is here}} 769 }; 770 771 // Not allowed on definitions. 772 __declspec(dllimport) ImportDefaultedDefs::ImportDefaultedDefs() = default; // expected-error{{dllimport cannot be applied to non-inline function definition}} 773 774 #if defined(MS) || defined(WI) 775 // expected-warning@+5{{'ImportDefaultedDefs::~ImportDefaultedDefs' redeclared without 'dllimport' attribute: 'dllexport' attribute added}} 776 #else 777 // expected-warning@+3{{'ImportDefaultedDefs::~ImportDefaultedDefs' redeclared without 'dllimport' attribute: previous 'dllimport' ignored}} 778 #endif 779 // dllimport cannot be dropped. 780 ImportDefaultedDefs::~ImportDefaultedDefs() = default; 781 782 // Import inline declaration and definition. 783 #ifdef GNU 784 // expected-error@+3{{redeclaration of 'ImportDefaultedDefs::ImportDefaultedDefs' cannot add 'dllimport' attribute}} 785 // expected-warning@+3{{'ImportDefaultedDefs::operator=' redeclared inline; 'dllimport' attribute ignored}} 786 #endif 787 __declspec(dllimport) ImportDefaultedDefs::ImportDefaultedDefs(const ImportDefaultedDefs&) = default; 788 inline ImportDefaultedDefs& ImportDefaultedDefs::operator=(const ImportDefaultedDefs&) = default; 789 790 __declspec(dllimport) ImportDefaultedDefs::ImportDefaultedDefs(ImportDefaultedDefs&&) = default; // expected-error{{dllimport cannot be applied to non-inline function definition}} 791 #if defined(MS) || defined(WI) 792 // expected-warning@+4{{'ImportDefaultedDefs::operator=' redeclared without 'dllimport' attribute: 'dllexport' attribute added}} 793 #else 794 // expected-warning@+2{{'ImportDefaultedDefs::operator=' redeclared without 'dllimport' attribute: previous 'dllimport' ignored}} 795 #endif 796 ImportDefaultedDefs &ImportDefaultedDefs::operator=(ImportDefaultedDefs &&) = default; 797 798 // Redeclarations cannot add dllimport. 799 struct MemberRedecl { 800 void normalDef(); // expected-note{{previous declaration is here}} 801 inline void normalInlineDecl(); // expected-note{{previous declaration is here}} 802 virtual void virtualDef(); // expected-note{{previous declaration is here}} 803 virtual inline void virtualInlineDecl(); // expected-note{{previous declaration is here}} 804 static void staticDef(); // expected-note{{previous declaration is here}} 805 static inline void staticInlineDecl(); // expected-note{{previous declaration is here}} 806 807 #if defined(MS) || defined(WI) 808 // expected-note@+4{{previous declaration is here}} 809 // expected-note@+4{{previous declaration is here}} 810 // expected-note@+4{{previous declaration is here}} 811 #endif 812 void normalInlineDef(); 813 virtual void virtualInlineDef(); 814 static void staticInlineDef(); 815 816 static int StaticField; // expected-note{{previous declaration is here}} 817 static const int StaticConstField; // expected-note{{previous declaration is here}} 818 constexpr static int ConstexprField = 1; // expected-note-re{{previous {{(declaration|definition)}} is here}} 819 }; 820 821 __declspec(dllimport) void MemberRedecl::normalDef() {} // expected-error{{redeclaration of 'MemberRedecl::normalDef' cannot add 'dllimport' attribute}} 822 // expected-error@-1{{dllimport cannot be applied to non-inline function definition}} 823 __declspec(dllimport) void MemberRedecl::normalInlineDecl() {} // expected-error{{redeclaration of 'MemberRedecl::normalInlineDecl' cannot add 'dllimport' attribute}} 824 __declspec(dllimport) void MemberRedecl::virtualDef() {} // expected-error{{redeclaration of 'MemberRedecl::virtualDef' cannot add 'dllimport' attribute}} 825 // expected-error@-1{{dllimport cannot be applied to non-inline function definition}} 826 __declspec(dllimport) void MemberRedecl::virtualInlineDecl() {} // expected-error{{redeclaration of 'MemberRedecl::virtualInlineDecl' cannot add 'dllimport' attribute}} 827 __declspec(dllimport) void MemberRedecl::staticDef() {} // expected-error{{redeclaration of 'MemberRedecl::staticDef' cannot add 'dllimport' attribute}} 828 // expected-error@-1{{dllimport cannot be applied to non-inline function definition}} 829 __declspec(dllimport) void MemberRedecl::staticInlineDecl() {} // expected-error{{redeclaration of 'MemberRedecl::staticInlineDecl' cannot add 'dllimport' attribute}} 830 831 #if defined(MS) || defined(WI) 832 __declspec(dllimport) inline void MemberRedecl::normalInlineDef() {} // expected-error{{redeclaration of 'MemberRedecl::normalInlineDef' cannot add 'dllimport' attribute}} 833 __declspec(dllimport) inline void MemberRedecl::virtualInlineDef() {} // expected-error{{redeclaration of 'MemberRedecl::virtualInlineDef' cannot add 'dllimport' attribute}} 834 __declspec(dllimport) inline void MemberRedecl::staticInlineDef() {} // expected-error{{redeclaration of 'MemberRedecl::staticInlineDef' cannot add 'dllimport' attribute}} 835 #else 836 __declspec(dllimport) inline void MemberRedecl::normalInlineDef() {} // expected-warning{{'dllimport' attribute ignored on inline function}} 837 __declspec(dllimport) inline void MemberRedecl::virtualInlineDef() {} // expected-warning{{'dllimport' attribute ignored on inline function}} 838 __declspec(dllimport) inline void MemberRedecl::staticInlineDef() {} // expected-warning{{'dllimport' attribute ignored on inline function}} 839 #endif 840 841 842 843 __declspec(dllimport) int MemberRedecl::StaticField = 1; // expected-error{{redeclaration of 'MemberRedecl::StaticField' cannot add 'dllimport' attribute}} 844 // expected-error@-1{{definition of dllimport static field not allowed}} 845 // expected-note@-2{{attribute is here}} 846 __declspec(dllimport) const int MemberRedecl::StaticConstField = 1; // expected-error{{redeclaration of 'MemberRedecl::StaticConstField' cannot add 'dllimport' attribute}} 847 // expected-error@-1{{definition of dllimport static field not allowed}} 848 // expected-note@-2{{attribute is here}} 849 850 #if __cplusplus < 201703L && !defined(MS) 851 // expected-error@+6{{redeclaration of 'MemberRedecl::ConstexprField' cannot add 'dllimport' attribute}} 852 // expected-error@+5{{definition of dllimport static field not allowed}} 853 // expected-note@+4{{attribute is here}} 854 #else 855 // expected-warning@+2{{attribute declaration must precede definition}} 856 #endif 857 __declspec(dllimport) constexpr int MemberRedecl::ConstexprField; 858 859 860 861 //===----------------------------------------------------------------------===// 862 // Class member templates 863 //===----------------------------------------------------------------------===// 864 865 struct ImportMemberTmpl { 866 template<typename T> __declspec(dllimport) void normalDecl(); 867 template<typename T> __declspec(dllimport) void normalDef(); // expected-note{{previous declaration is here}} expected-note{{previous attribute is here}} 868 #if defined(MS) || defined(WI) 869 // expected-note@+2{{previous declaration is here}} expected-note@+2{{previous attribute is here}} 870 #endif 871 template<typename T> __declspec(dllimport) void normalInlineDef(); 872 template<typename T> __declspec(dllimport) static void staticDecl(); 873 template<typename T> __declspec(dllimport) static void staticDef(); // expected-note{{previous declaration is here}} expected-note{{previous attribute is here}} 874 #if defined(MS) || defined(WI) 875 // expected-note@+2{{previous declaration is here}} expected-note@+2{{previous attribute is here}} 876 #endif 877 template<typename T> __declspec(dllimport) static void staticInlineDef(); 878 879 #ifdef GNU 880 template<typename T> __declspec(dllimport) void normalInclass() {} // expected-warning{{'dllimport' attribute ignored on inline function}} 881 template<typename T> __declspec(dllimport) inline void normalInlineDecl(); // expected-warning{{'dllimport' attribute ignored on inline function}} 882 template<typename T> __declspec(dllimport) static void staticInclass() {} // expected-warning{{'dllimport' attribute ignored on inline function}} 883 template<typename T> __declspec(dllimport) static inline void staticInlineDecl(); // expected-warning{{'dllimport' attribute ignored on inline function}} 884 #else 885 template<typename T> __declspec(dllimport) void normalInclass() {} 886 template<typename T> __declspec(dllimport) inline void normalInlineDecl(); // expected-note{{previous declaration is here}} expected-note{{previous attribute is here}} 887 template<typename T> __declspec(dllimport) static void staticInclass() {} 888 template<typename T> __declspec(dllimport) static inline void staticInlineDecl(); // expected-note{{previous declaration is here}} expected-note{{previous attribute is here}} 889 #endif 890 891 #if __has_feature(cxx_variable_templates) 892 template<typename T> __declspec(dllimport) static int StaticField; 893 template<typename T> __declspec(dllimport) static int StaticFieldDef; // expected-note{{attribute is here}} 894 template<typename T> __declspec(dllimport) static const int StaticConstField; 895 template<typename T> __declspec(dllimport) static const int StaticConstFieldDef; // expected-note{{attribute is here}} 896 template<typename T> __declspec(dllimport) static const int StaticConstFieldEqualInit = 1; 897 template<typename T> __declspec(dllimport) static const int StaticConstFieldBraceInit{1}; 898 template<typename T> __declspec(dllimport) constexpr static int ConstexprField = 1; 899 template<typename T> __declspec(dllimport) constexpr static int ConstexprFieldDef = 1; 900 #endif // __has_feature(cxx_variable_templates) 901 }; 902 903 template<typename T> void ImportMemberTmpl::normalDef() {} // expected-warning{{'ImportMemberTmpl::normalDef' redeclared without 'dllimport' attribute: previous 'dllimport' ignored}} 904 template<typename T> void ImportMemberTmpl::staticDef() {} // expected-warning{{'ImportMemberTmpl::staticDef' redeclared without 'dllimport' attribute: previous 'dllimport' ignored}} 905 #ifdef GNU // dllimport was ignored above 906 template<typename T> void ImportMemberTmpl::normalInlineDecl() {} 907 template<typename T> void ImportMemberTmpl::staticInlineDecl() {} 908 #else // dllimport dropped here 909 template<typename T> void ImportMemberTmpl::normalInlineDecl() {} // expected-warning{{'ImportMemberTmpl::normalInlineDecl' redeclared without 'dllimport' attribute: previous 'dllimport' ignored}} 910 template<typename T> void ImportMemberTmpl::staticInlineDecl() {} // expected-warning{{'ImportMemberTmpl::staticInlineDecl' redeclared without 'dllimport' attribute: previous 'dllimport' ignored}} 911 #endif 912 913 #ifdef GNU 914 template<typename T> inline void ImportMemberTmpl::normalInlineDef() {} // expected-warning{{ImportMemberTmpl::normalInlineDef' redeclared inline; 'dllimport' attribute ignored}} 915 template<typename T> inline void ImportMemberTmpl::staticInlineDef() {} // expected-warning{{ImportMemberTmpl::staticInlineDef' redeclared inline; 'dllimport' attribute ignored}} 916 #else 917 template<typename T> inline void ImportMemberTmpl::normalInlineDef() {} // expected-warning{{ImportMemberTmpl::normalInlineDef' redeclared without 'dllimport' attribute: previous 'dllimport' ignored}} 918 template<typename T> inline void ImportMemberTmpl::staticInlineDef() {} // expected-warning{{ImportMemberTmpl::staticInlineDef' redeclared without 'dllimport' attribute: previous 'dllimport' ignored}} 919 #endif 920 921 #if __has_feature(cxx_variable_templates) 922 template<typename T> int ImportMemberTmpl::StaticFieldDef; // expected-error{{definition of dllimport static field not allowed}} 923 template<typename T> const int ImportMemberTmpl::StaticConstFieldDef = 1; // expected-error{{definition of dllimport static field not allowed}} 924 #ifdef MS 925 template<typename T> constexpr int ImportMemberTmpl::ConstexprFieldDef; 926 #endif 927 #endif // __has_feature(cxx_variable_templates) 928 929 930 // Redeclarations cannot add dllimport. 931 struct MemTmplRedecl { 932 template<typename T> void normalDef(); // expected-note{{previous declaration is here}} 933 template<typename T> inline void normalInlineDecl(); // expected-note{{previous declaration is here}} 934 template<typename T> static void staticDef(); // expected-note{{previous declaration is here}} 935 template<typename T> static inline void staticInlineDecl(); // expected-note{{previous declaration is here}} 936 937 #if defined(MS) || defined(WI) 938 // expected-note@+3{{previous declaration is here}} 939 // expected-note@+3{{previous declaration is here}} 940 #endif 941 template<typename T> void normalInlineDef(); 942 template<typename T> static void staticInlineDef(); 943 944 #if __has_feature(cxx_variable_templates) 945 template<typename T> static int StaticField; // expected-note{{previous declaration is here}} 946 template<typename T> static const int StaticConstField; // expected-note{{previous declaration is here}} 947 #ifdef MS 948 template<typename T> constexpr static int ConstexprField = 1; // expected-note{{previous definition is here}} 949 #endif 950 #endif // __has_feature(cxx_variable_templates) 951 }; 952 953 template<typename T> __declspec(dllimport) void MemTmplRedecl::normalDef() {} // expected-error{{redeclaration of 'MemTmplRedecl::normalDef' cannot add 'dllimport' attribute}} 954 // expected-error@-1{{dllimport cannot be applied to non-inline function definition}} 955 #if defined(MS) || defined(WI) 956 template<typename T> __declspec(dllimport) inline void MemTmplRedecl::normalInlineDef() {} // expected-error{{redeclaration of 'MemTmplRedecl::normalInlineDef' cannot add 'dllimport' attribute}} 957 #else 958 template<typename T> __declspec(dllimport) inline void MemTmplRedecl::normalInlineDef() {} // expected-warning{{'dllimport' attribute ignored on inline function}} 959 #endif 960 template<typename T> __declspec(dllimport) void MemTmplRedecl::normalInlineDecl() {} // expected-error{{redeclaration of 'MemTmplRedecl::normalInlineDecl' cannot add 'dllimport' attribute}} 961 template<typename T> __declspec(dllimport) void MemTmplRedecl::staticDef() {} // expected-error{{redeclaration of 'MemTmplRedecl::staticDef' cannot add 'dllimport' attribute}} 962 // expected-error@-1{{dllimport cannot be applied to non-inline function definition}} 963 #if defined(MS) || defined(WI) 964 template<typename T> __declspec(dllimport) inline void MemTmplRedecl::staticInlineDef() {} // expected-error{{redeclaration of 'MemTmplRedecl::staticInlineDef' cannot add 'dllimport' attribute}} 965 #else 966 template<typename T> __declspec(dllimport) inline void MemTmplRedecl::staticInlineDef() {} // expected-warning{{'dllimport' attribute ignored on inline function}} 967 #endif 968 template<typename T> __declspec(dllimport) void MemTmplRedecl::staticInlineDecl() {} // expected-error{{redeclaration of 'MemTmplRedecl::staticInlineDecl' cannot add 'dllimport' attribute}} 969 970 #if __has_feature(cxx_variable_templates) 971 template<typename T> __declspec(dllimport) int MemTmplRedecl::StaticField = 1; // expected-error{{redeclaration of 'MemTmplRedecl::StaticField' cannot add 'dllimport' attribute}} 972 // expected-error@-1{{definition of dllimport static field not allowed}} 973 // expected-note@-2{{attribute is here}} 974 template<typename T> __declspec(dllimport) const int MemTmplRedecl::StaticConstField = 1; // expected-error{{redeclaration of 'MemTmplRedecl::StaticConstField' cannot add 'dllimport' attribute}} 975 // expected-error@-1{{definition of dllimport static field not allowed}} 976 // expected-note@-2{{attribute is here}} 977 #ifdef MS 978 // expected-warning@+1{{attribute declaration must precede definition}} 979 template<typename T> __declspec(dllimport) constexpr int MemTmplRedecl::ConstexprField; 980 #endif 981 #endif // __has_feature(cxx_variable_templates) 982 983 984 985 struct MemFunTmpl { 986 template<typename T> void normalDef() {} 987 #ifdef GNU 988 // expected-warning@+2{{'dllimport' attribute ignored on inline function}} 989 #endif 990 template<typename T> __declspec(dllimport) void importedNormal() {} 991 template<typename T> static void staticDef() {} 992 #ifdef GNU 993 // expected-warning@+2{{'dllimport' attribute ignored on inline function}} 994 #endif 995 template<typename T> __declspec(dllimport) static void importedStatic() {} 996 }; 997 998 // Import implicit instantiation of an imported member function template. 999 void useMemFunTmpl() { 1000 MemFunTmpl().importedNormal<ImplicitInst_Imported>(); 1001 MemFunTmpl().importedStatic<ImplicitInst_Imported>(); 1002 } 1003 1004 // Import explicit instantiation declaration of an imported member function 1005 // template. 1006 extern template void MemFunTmpl::importedNormal<ExplicitDecl_Imported>(); 1007 extern template void MemFunTmpl::importedStatic<ExplicitDecl_Imported>(); 1008 1009 // Import explicit instantiation definition of an imported member function 1010 // template. 1011 // NB: MSVC fails this instantiation without explicit dllimport. 1012 template void MemFunTmpl::importedNormal<ExplicitInst_Imported>(); 1013 template void MemFunTmpl::importedStatic<ExplicitInst_Imported>(); 1014 1015 // Import specialization of an imported member function template. 1016 template<> __declspec(dllimport) void MemFunTmpl::importedNormal<ExplicitSpec_Imported>(); 1017 template<> __declspec(dllimport) void MemFunTmpl::importedNormal<ExplicitSpec_Def_Imported>() {} // error on mingw 1018 #ifdef GNU 1019 // expected-warning@+2{{'dllimport' attribute ignored on inline function}} 1020 #endif 1021 template<> __declspec(dllimport) inline void MemFunTmpl::importedNormal<ExplicitSpec_InlineDef_Imported>() {} 1022 #if 1 1023 // FIXME: This should not be an error when targeting MSVC. (PR21406) 1024 // expected-error@-7{{dllimport cannot be applied to non-inline function definition}} 1025 #endif 1026 1027 template<> __declspec(dllimport) void MemFunTmpl::importedStatic<ExplicitSpec_Imported>(); 1028 template<> __declspec(dllimport) void MemFunTmpl::importedStatic<ExplicitSpec_Def_Imported>() {} // error on mingw 1029 #ifdef GNU 1030 // expected-warning@+2{{'dllimport' attribute ignored on inline function}} 1031 #endif 1032 template<> __declspec(dllimport) inline void MemFunTmpl::importedStatic<ExplicitSpec_InlineDef_Imported>() {} 1033 #if 1 1034 // FIXME: This should not be an error when targeting MSVC. (PR21406) 1035 // expected-error@-7{{dllimport cannot be applied to non-inline function definition}} 1036 #endif 1037 1038 // Not importing specialization of an imported member function template without 1039 // explicit dllimport. 1040 template<> void MemFunTmpl::importedNormal<ExplicitSpec_NotImported>() {} 1041 template<> void MemFunTmpl::importedStatic<ExplicitSpec_NotImported>() {} 1042 1043 1044 // Import explicit instantiation declaration of a non-imported member function 1045 // template. 1046 #ifdef GNU 1047 // expected-warning@+3{{'dllimport' attribute ignored on inline function}} 1048 // expected-warning@+3{{'dllimport' attribute ignored on inline function}} 1049 #endif 1050 extern template __declspec(dllimport) void MemFunTmpl::normalDef<ExplicitDecl_Imported>(); 1051 extern template __declspec(dllimport) void MemFunTmpl::staticDef<ExplicitDecl_Imported>(); 1052 1053 // Import explicit instantiation definition of a non-imported member function 1054 // template. 1055 #ifdef GNU 1056 // expected-warning@+3{{'dllimport' attribute ignored on inline function}} 1057 // expected-warning@+3{{'dllimport' attribute ignored on inline function}} 1058 #endif 1059 template __declspec(dllimport) void MemFunTmpl::normalDef<ExplicitInst_Imported>(); 1060 template __declspec(dllimport) void MemFunTmpl::staticDef<ExplicitInst_Imported>(); 1061 1062 // Import specialization of a non-imported member function template. 1063 template<> __declspec(dllimport) void MemFunTmpl::normalDef<ExplicitSpec_Imported>(); 1064 template<> __declspec(dllimport) void MemFunTmpl::normalDef<ExplicitSpec_Def_Imported>() {} // error on mingw 1065 #ifdef GNU 1066 // expected-warning@+2{{'dllimport' attribute ignored on inline function}} 1067 #endif 1068 template<> __declspec(dllimport) inline void MemFunTmpl::normalDef<ExplicitSpec_InlineDef_Imported>() {} 1069 #if 1 1070 // FIXME: This should not be an error when targeting MSVC. (PR21406) 1071 // expected-error@-7{{dllimport cannot be applied to non-inline function definition}} 1072 #endif 1073 1074 template<> __declspec(dllimport) void MemFunTmpl::staticDef<ExplicitSpec_Imported>(); 1075 template<> __declspec(dllimport) void MemFunTmpl::staticDef<ExplicitSpec_Def_Imported>() {} // error on mingw 1076 #ifdef GNU 1077 // expected-warning@+2{{'dllimport' attribute ignored on inline function}} 1078 #endif 1079 template<> __declspec(dllimport) inline void MemFunTmpl::staticDef<ExplicitSpec_InlineDef_Imported>() {} 1080 #if 1 1081 // FIXME: This should not be an error when targeting MSVC. (PR21406) 1082 // expected-error@-7{{dllimport cannot be applied to non-inline function definition}} 1083 #endif 1084 1085 1086 1087 #if __has_feature(cxx_variable_templates) 1088 struct MemVarTmpl { 1089 template<typename T> static const int StaticVar = 1; 1090 template<typename T> __declspec(dllimport) static const int ImportedStaticVar = 1; 1091 }; 1092 1093 // Import implicit instantiation of an imported member variable template. 1094 int useMemVarTmpl() { return MemVarTmpl::ImportedStaticVar<ImplicitInst_Imported>; } 1095 1096 // Import explicit instantiation declaration of an imported member variable 1097 // template. 1098 extern template const int MemVarTmpl::ImportedStaticVar<ExplicitDecl_Imported>; 1099 1100 // An explicit instantiation definition of an imported member variable template 1101 // cannot be imported because the template must be defined which is illegal. The 1102 // in-class initializer does not count. 1103 1104 // Import specialization of an imported member variable template. 1105 template<> __declspec(dllimport) const int MemVarTmpl::ImportedStaticVar<ExplicitSpec_Imported>; 1106 template<> __declspec(dllimport) const int MemVarTmpl::ImportedStaticVar<ExplicitSpec_Def_Imported> = 1; 1107 // expected-error@-1{{definition of dllimport static field not allowed}} 1108 // expected-note@-2{{attribute is here}} 1109 1110 // Not importing specialization of a member variable template without explicit 1111 // dllimport. 1112 template<> const int MemVarTmpl::ImportedStaticVar<ExplicitSpec_NotImported>; 1113 1114 1115 // Import explicit instantiation declaration of a non-imported member variable 1116 // template. 1117 extern template __declspec(dllimport) const int MemVarTmpl::StaticVar<ExplicitDecl_Imported>; 1118 1119 // An explicit instantiation definition of a non-imported member variable template 1120 // cannot be imported because the template must be defined which is illegal. The 1121 // in-class initializer does not count. 1122 1123 // Import specialization of a non-imported member variable template. 1124 template<> __declspec(dllimport) const int MemVarTmpl::StaticVar<ExplicitSpec_Imported>; 1125 template<> __declspec(dllimport) const int MemVarTmpl::StaticVar<ExplicitSpec_Def_Imported> = 1; 1126 // expected-error@-1{{definition of dllimport static field not allowed}} 1127 // expected-note@-2{{attribute is here}} 1128 1129 #endif // __has_feature(cxx_variable_templates) 1130 1131 1132 1133 //===----------------------------------------------------------------------===// 1134 // Class template members 1135 //===----------------------------------------------------------------------===// 1136 1137 // Import individual members of a class template. 1138 template<typename T> 1139 struct ImportClassTmplMembers { 1140 __declspec(dllimport) void normalDecl(); 1141 #ifdef GNU 1142 // expected-note@+2{{previous attribute is here}} 1143 #endif 1144 __declspec(dllimport) void normalDef(); // expected-note{{previous declaration is here}} 1145 __declspec(dllimport) void normalInlineDef(); 1146 __declspec(dllimport) virtual void virtualDecl(); 1147 #ifdef GNU 1148 // expected-note@+2{{previous attribute is here}} 1149 #endif 1150 __declspec(dllimport) virtual void virtualDef(); // expected-note{{previous declaration is here}} 1151 __declspec(dllimport) virtual void virtualInlineDef(); 1152 __declspec(dllimport) static void staticDecl(); 1153 #ifdef GNU 1154 // expected-note@+2{{previous attribute is here}} 1155 #endif 1156 __declspec(dllimport) static void staticDef(); // expected-note{{previous declaration is here}} 1157 __declspec(dllimport) static void staticInlineDef(); 1158 1159 #ifdef GNU 1160 // expected-warning@+7{{'dllimport' attribute ignored on inline function}} 1161 // expected-warning@+7{{'dllimport' attribute ignored on inline function}} 1162 // expected-warning@+7{{'dllimport' attribute ignored on inline function}} 1163 // expected-warning@+7{{'dllimport' attribute ignored on inline function}} 1164 // expected-warning@+7{{'dllimport' attribute ignored on inline function}} 1165 // expected-warning@+7{{'dllimport' attribute ignored on inline function}} 1166 #endif 1167 __declspec(dllimport) void normalInclass() {} 1168 __declspec(dllimport) inline void normalInlineDecl(); 1169 __declspec(dllimport) virtual void virtualInclass() {} 1170 __declspec(dllimport) virtual inline void virtualInlineDecl(); 1171 __declspec(dllimport) static void staticInclass() {} 1172 __declspec(dllimport) static inline void staticInlineDecl(); 1173 1174 protected: 1175 __declspec(dllimport) void protectedDecl(); 1176 private: 1177 __declspec(dllimport) void privateDecl(); 1178 public: 1179 1180 __declspec(dllimport) int Field; // expected-warning{{'dllimport' attribute only applies to}} 1181 __declspec(dllimport) static int StaticField; 1182 __declspec(dllimport) static int StaticFieldDef; // expected-note{{attribute is here}} 1183 __declspec(dllimport) static const int StaticConstField; 1184 __declspec(dllimport) static const int StaticConstFieldDef; // expected-note{{attribute is here}} 1185 __declspec(dllimport) static const int StaticConstFieldEqualInit = 1; 1186 __declspec(dllimport) static const int StaticConstFieldBraceInit{1}; 1187 __declspec(dllimport) constexpr static int ConstexprField = 1; 1188 #if __cplusplus < 201703L && !defined(MS) 1189 // expected-note@+2{{attribute is here}} 1190 #endif 1191 __declspec(dllimport) constexpr static int ConstexprFieldDef = 1; 1192 }; 1193 1194 // NB: MSVC is inconsistent here and disallows *InlineDef on class templates, 1195 // but allows it on classes. We allow both. 1196 #if defined(MS) || defined(WI) 1197 // expected-warning@+5{{'ImportClassTmplMembers::normalDef' redeclared without 'dllimport' attribute: 'dllexport' attribute added}} 1198 #else 1199 // expected-warning@+3{{'ImportClassTmplMembers::normalDef' redeclared without 'dllimport' attribute: previous 'dllimport' ignored}} 1200 #endif 1201 template <typename T> 1202 void ImportClassTmplMembers<T>::normalDef() {} 1203 #ifdef GNU 1204 // expected-warning@+2{{'ImportClassTmplMembers::normalInlineDef' redeclared inline; 'dllimport' attribute ignored}} 1205 #endif 1206 template<typename T> inline void ImportClassTmplMembers<T>::normalInlineDef() {} 1207 template<typename T> void ImportClassTmplMembers<T>::normalInlineDecl() {} 1208 #if defined(MS) || defined(WI) 1209 // expected-warning@+5{{'ImportClassTmplMembers::virtualDef' redeclared without 'dllimport' attribute: 'dllexport' attribute added}} 1210 #else 1211 // expected-warning@+3{{'ImportClassTmplMembers::virtualDef' redeclared without 'dllimport' attribute: previous 'dllimport' ignored}} 1212 #endif 1213 template <typename T> 1214 void ImportClassTmplMembers<T>::virtualDef() {} 1215 #ifdef GNU 1216 // expected-warning@+2{{'ImportClassTmplMembers::virtualInlineDef' redeclared inline; 'dllimport' attribute ignored}} 1217 #endif 1218 template<typename T> inline void ImportClassTmplMembers<T>::virtualInlineDef() {} 1219 template<typename T> void ImportClassTmplMembers<T>::virtualInlineDecl() {} 1220 #if defined(MS) || defined(WI) 1221 // expected-warning@+5{{'ImportClassTmplMembers::staticDef' redeclared without 'dllimport' attribute: 'dllexport' attribute added}} 1222 #else 1223 // expected-warning@+3{{'ImportClassTmplMembers::staticDef' redeclared without 'dllimport' attribute: previous 'dllimport' ignored}} 1224 #endif 1225 template <typename T> 1226 void ImportClassTmplMembers<T>::staticDef() {} 1227 #ifdef GNU 1228 // expected-warning@+2{{'ImportClassTmplMembers::staticInlineDef' redeclared inline; 'dllimport' attribute ignored}} 1229 #endif 1230 template<typename T> inline void ImportClassTmplMembers<T>::staticInlineDef() {} 1231 template<typename T> void ImportClassTmplMembers<T>::staticInlineDecl() {} 1232 1233 template<typename T> int ImportClassTmplMembers<T>::StaticFieldDef; // expected-warning{{definition of dllimport static field}} 1234 template<typename T> const int ImportClassTmplMembers<T>::StaticConstFieldDef = 1; // expected-warning{{definition of dllimport static field}} 1235 #if __cplusplus < 201703L && !defined(MS) 1236 // expected-warning@+2{{definition of dllimport static field}} 1237 #endif 1238 template<typename T> constexpr int ImportClassTmplMembers<T>::ConstexprFieldDef; 1239 1240 1241 // Redeclarations cannot add dllimport. 1242 template<typename T> 1243 struct CTMR /*ClassTmplMemberRedecl*/ { 1244 void normalDef(); // expected-note{{previous declaration is here}} 1245 inline void normalInlineDecl(); // expected-note{{previous declaration is here}} 1246 virtual void virtualDef(); // expected-note{{previous declaration is here}} 1247 virtual inline void virtualInlineDecl(); // expected-note{{previous declaration is here}} 1248 static void staticDef(); // expected-note{{previous declaration is here}} 1249 static inline void staticInlineDecl(); // expected-note{{previous declaration is here}} 1250 1251 #if defined(MS) || defined(WI) 1252 // expected-note@+4{{previous declaration is here}} 1253 // expected-note@+4{{previous declaration is here}} 1254 // expected-note@+4{{previous declaration is here}} 1255 #endif 1256 void normalInlineDef(); 1257 virtual void virtualInlineDef(); 1258 static void staticInlineDef(); 1259 1260 static int StaticField; // expected-note{{previous declaration is here}} 1261 static const int StaticConstField; // expected-note{{previous declaration is here}} 1262 constexpr static int ConstexprField = 1; // expected-note-re{{previous {{(declaration|definition)}} is here}} 1263 }; 1264 1265 template<typename T> __declspec(dllimport) void CTMR<T>::normalDef() {} // expected-error{{redeclaration of 'CTMR::normalDef' cannot add 'dllimport' attribute}} 1266 // expected-error@-1{{dllimport cannot be applied to non-inline function definition}} 1267 template<typename T> __declspec(dllimport) void CTMR<T>::normalInlineDecl() {} // expected-error{{redeclaration of 'CTMR::normalInlineDecl' cannot add 'dllimport' attribute}} 1268 template<typename T> __declspec(dllimport) void CTMR<T>::virtualDef() {} // expected-error{{redeclaration of 'CTMR::virtualDef' cannot add 'dllimport' attribute}} 1269 // expected-error@-1{{dllimport cannot be applied to non-inline function definition}} 1270 template<typename T> __declspec(dllimport) void CTMR<T>::virtualInlineDecl() {} // expected-error{{redeclaration of 'CTMR::virtualInlineDecl' cannot add 'dllimport' attribute}} 1271 template<typename T> __declspec(dllimport) void CTMR<T>::staticDef() {} // expected-error{{redeclaration of 'CTMR::staticDef' cannot add 'dllimport' attribute}} 1272 // expected-error@-1{{dllimport cannot be applied to non-inline function definition}} 1273 template<typename T> __declspec(dllimport) void CTMR<T>::staticInlineDecl() {} // expected-error{{redeclaration of 'CTMR::staticInlineDecl' cannot add 'dllimport' attribute}} 1274 1275 #if defined(MS) || defined(WI) 1276 template<typename T> __declspec(dllimport) inline void CTMR<T>::normalInlineDef() {} // expected-error{{redeclaration of 'CTMR::normalInlineDef' cannot add 'dllimport' attribute}} 1277 template<typename T> __declspec(dllimport) inline void CTMR<T>::virtualInlineDef() {} // expected-error{{redeclaration of 'CTMR::virtualInlineDef' cannot add 'dllimport' attribute}} 1278 template<typename T> __declspec(dllimport) inline void CTMR<T>::staticInlineDef() {} // expected-error{{redeclaration of 'CTMR::staticInlineDef' cannot add 'dllimport' attribute}} 1279 #else 1280 template<typename T> __declspec(dllimport) inline void CTMR<T>::normalInlineDef() {} // expected-warning{{'dllimport' attribute ignored on inline function}} 1281 template<typename T> __declspec(dllimport) inline void CTMR<T>::virtualInlineDef() {} // expected-warning{{'dllimport' attribute ignored on inline function}} 1282 template<typename T> __declspec(dllimport) inline void CTMR<T>::staticInlineDef() {} // expected-warning{{'dllimport' attribute ignored on inline function}} 1283 #endif 1284 1285 template<typename T> __declspec(dllimport) int CTMR<T>::StaticField = 1; // expected-error{{redeclaration of 'CTMR::StaticField' cannot add 'dllimport' attribute}} 1286 // expected-warning@-1{{definition of dllimport static field}} 1287 // expected-note@-2{{attribute is here}} 1288 template<typename T> __declspec(dllimport) const int CTMR<T>::StaticConstField = 1; // expected-error{{redeclaration of 'CTMR::StaticConstField' cannot add 'dllimport' attribute}} 1289 // expected-warning@-1{{definition of dllimport static field}} 1290 // expected-note@-2{{attribute is here}} 1291 1292 #if __cplusplus < 201703L && !defined(MS) 1293 // expected-error@+6{{redeclaration of 'CTMR::ConstexprField' cannot add 'dllimport' attribute}} 1294 // expected-warning@+5{{definition of dllimport static field}} 1295 // expected-note@+4{{attribute is here}} 1296 #else 1297 // expected-warning@+2{{attribute declaration must precede definition}} 1298 #endif 1299 template<typename T> __declspec(dllimport) constexpr int CTMR<T>::ConstexprField; 1300 1301 1302 1303 //===----------------------------------------------------------------------===// 1304 // Class template member templates 1305 //===----------------------------------------------------------------------===// 1306 1307 template<typename T> 1308 struct ImportClsTmplMemTmpl { 1309 template<typename U> __declspec(dllimport) void normalDecl(); 1310 template<typename U> __declspec(dllimport) void normalDef(); // expected-note{{previous declaration is here}} expected-note{{previous attribute is here}} 1311 #if defined(MS) || defined(WI) 1312 // expected-note@+2{{previous declaration is here}} expected-note@+2{{previous attribute is here}} 1313 #endif 1314 template<typename U> __declspec(dllimport) void normalInlineDef(); 1315 template<typename U> __declspec(dllimport) static void staticDecl(); 1316 template<typename U> __declspec(dllimport) static void staticDef(); // expected-note{{previous declaration is here}} expected-note{{previous attribute is here}} 1317 #if defined(MS) || defined(WI) 1318 // expected-note@+2{{previous declaration is here}} expected-note@+2{{previous attribute is here}} 1319 #endif 1320 template<typename U> __declspec(dllimport) static void staticInlineDef(); 1321 1322 #ifdef GNU 1323 // expected-warning@+5{{'dllimport' attribute ignored on inline function}} 1324 // expected-warning@+8{{'dllimport' attribute ignored on inline function}} 1325 // expected-warning@+8{{'dllimport' attribute ignored on inline function}} 1326 // expected-warning@+11{{'dllimport' attribute ignored on inline function}} 1327 #endif 1328 template<typename U> __declspec(dllimport) void normalInclass() {} 1329 #if defined(MS) || defined(WI) 1330 // expected-note@+2{{previous declaration is here}} expected-note@+2{{previous attribute is here}} 1331 #endif 1332 template<typename U> __declspec(dllimport) inline void normalInlineDecl(); 1333 template<typename U> __declspec(dllimport) static void staticInclass() {} 1334 #if defined(MS) || defined(WI) 1335 // expected-note@+2{{previous declaration is here}} expected-note@+2{{previous attribute is here}} 1336 #endif 1337 template<typename U> __declspec(dllimport) static inline void staticInlineDecl(); 1338 1339 #if __has_feature(cxx_variable_templates) 1340 template<typename U> __declspec(dllimport) static int StaticField; 1341 template<typename U> __declspec(dllimport) static int StaticFieldDef; // expected-note{{attribute is here}} 1342 template<typename U> __declspec(dllimport) static const int StaticConstField; 1343 template<typename U> __declspec(dllimport) static const int StaticConstFieldDef; // expected-note{{attribute is here}} 1344 template<typename U> __declspec(dllimport) static const int StaticConstFieldEqualInit = 1; 1345 template<typename U> __declspec(dllimport) static const int StaticConstFieldBraceInit{1}; 1346 template<typename U> __declspec(dllimport) constexpr static int ConstexprField = 1; 1347 #ifdef MS 1348 template<typename U> __declspec(dllimport) constexpr static int ConstexprFieldDef = 1; 1349 #endif 1350 #endif // __has_feature(cxx_variable_templates) 1351 }; 1352 1353 template<typename T> template<typename U> void ImportClsTmplMemTmpl<T>::normalDef() {} // expected-warning{{'ImportClsTmplMemTmpl::normalDef' redeclared without 'dllimport' attribute: previous 'dllimport' ignored}} 1354 template<typename T> template<typename U> void ImportClsTmplMemTmpl<T>::staticDef() {} // expected-warning{{'ImportClsTmplMemTmpl::staticDef' redeclared without 'dllimport' attribute: previous 'dllimport' ignored}} 1355 #ifdef GNU 1356 template<typename T> template<typename U> void ImportClsTmplMemTmpl<T>::normalInlineDecl() {} 1357 template<typename T> template<typename U> void ImportClsTmplMemTmpl<T>::staticInlineDecl() {} 1358 #else 1359 template<typename T> template<typename U> void ImportClsTmplMemTmpl<T>::normalInlineDecl() {} // expected-warning{{'ImportClsTmplMemTmpl::normalInlineDecl' redeclared without 'dllimport' attribute: previous 'dllimport' ignored}} 1360 template<typename T> template<typename U> void ImportClsTmplMemTmpl<T>::staticInlineDecl() {} // expected-warning{{'ImportClsTmplMemTmpl::staticInlineDecl' redeclared without 'dllimport' attribute: previous 'dllimport' ignored}} 1361 #endif 1362 1363 #ifdef GNU 1364 template<typename T> template<typename U> inline void ImportClsTmplMemTmpl<T>::normalInlineDef() {} // expected-warning{{'ImportClsTmplMemTmpl::normalInlineDef' redeclared inline; 'dllimport' attribute ignored}} 1365 template<typename T> template<typename U> inline void ImportClsTmplMemTmpl<T>::staticInlineDef() {} // expected-warning{{'ImportClsTmplMemTmpl::staticInlineDef' redeclared inline; 'dllimport' attribute ignored}} 1366 #else 1367 template<typename T> template<typename U> inline void ImportClsTmplMemTmpl<T>::normalInlineDef() {} // expected-warning{{'ImportClsTmplMemTmpl::normalInlineDef' redeclared without 'dllimport' attribute: previous 'dllimport' ignored}} 1368 template<typename T> template<typename U> inline void ImportClsTmplMemTmpl<T>::staticInlineDef() {} // expected-warning{{'ImportClsTmplMemTmpl::staticInlineDef' redeclared without 'dllimport' attribute: previous 'dllimport' ignored}} 1369 #endif 1370 1371 #if __has_feature(cxx_variable_templates) 1372 template<typename T> template<typename U> int ImportClsTmplMemTmpl<T>::StaticFieldDef; // expected-warning{{definition of dllimport static field}} 1373 template<typename T> template<typename U> const int ImportClsTmplMemTmpl<T>::StaticConstFieldDef = 1; // expected-warning{{definition of dllimport static field}} 1374 #ifdef MS 1375 template<typename T> template<typename U> constexpr int ImportClsTmplMemTmpl<T>::ConstexprFieldDef; 1376 #endif 1377 #endif // __has_feature(cxx_variable_templates) 1378 1379 1380 // Redeclarations cannot add dllimport. 1381 template<typename T> 1382 struct CTMTR /*ClassTmplMemberTmplRedecl*/ { 1383 template<typename U> void normalDef(); // expected-note{{previous declaration is here}} 1384 template<typename U> inline void normalInlineDecl(); // expected-note{{previous declaration is here}} 1385 template<typename U> static void staticDef(); // expected-note{{previous declaration is here}} 1386 template<typename U> static inline void staticInlineDecl(); // expected-note{{previous declaration is here}} 1387 1388 #if defined(MS) || defined(WI) 1389 // expected-note@+3{{previous declaration is here}} 1390 // expected-note@+3{{previous declaration is here}} 1391 #endif 1392 template<typename U> void normalInlineDef(); 1393 template<typename U> static void staticInlineDef(); 1394 1395 #if __has_feature(cxx_variable_templates) 1396 template<typename U> static int StaticField; // expected-note{{previous declaration is here}} 1397 template<typename U> static const int StaticConstField; // expected-note{{previous declaration is here}} 1398 #ifdef MS 1399 template<typename U> constexpr static int ConstexprField = 1; // expected-note{{previous definition is here}} 1400 #endif 1401 #endif // __has_feature(cxx_variable_templates) 1402 }; 1403 1404 template<typename T> template<typename U> __declspec(dllimport) void CTMTR<T>::normalDef() {} // expected-error{{redeclaration of 'CTMTR::normalDef' cannot add 'dllimport' attribute}} 1405 // expected-error@-1{{dllimport cannot be applied to non-inline function definition}} 1406 template<typename T> template<typename U> __declspec(dllimport) void CTMTR<T>::normalInlineDecl() {} // expected-error{{redeclaration of 'CTMTR::normalInlineDecl' cannot add 'dllimport' attribute}} 1407 template<typename T> template<typename U> __declspec(dllimport) void CTMTR<T>::staticDef() {} // expected-error{{redeclaration of 'CTMTR::staticDef' cannot add 'dllimport' attribute}} 1408 // expected-error@-1{{dllimport cannot be applied to non-inline function definition}} 1409 template<typename T> template<typename U> __declspec(dllimport) void CTMTR<T>::staticInlineDecl() {} // expected-error{{redeclaration of 'CTMTR::staticInlineDecl' cannot add 'dllimport' attribute}} 1410 1411 #if defined(MS) || defined(WI) 1412 template<typename T> template<typename U> __declspec(dllimport) inline void CTMTR<T>::normalInlineDef() {} // expected-error{{redeclaration of 'CTMTR::normalInlineDef' cannot add 'dllimport' attribute}} 1413 template<typename T> template<typename U> __declspec(dllimport) inline void CTMTR<T>::staticInlineDef() {} // expected-error{{redeclaration of 'CTMTR::staticInlineDef' cannot add 'dllimport' attribute}} 1414 #else 1415 template<typename T> template<typename U> __declspec(dllimport) inline void CTMTR<T>::normalInlineDef() {} // expected-warning{{'dllimport' attribute ignored on inline function}} 1416 template<typename T> template<typename U> __declspec(dllimport) inline void CTMTR<T>::staticInlineDef() {} // expected-warning{{'dllimport' attribute ignored on inline function}} 1417 #endif 1418 1419 #if __has_feature(cxx_variable_templates) 1420 template<typename T> template<typename U> __declspec(dllimport) int CTMTR<T>::StaticField = 1; // expected-error{{redeclaration of 'CTMTR::StaticField' cannot add 'dllimport' attribute}} 1421 // expected-warning@-1{{definition of dllimport static field}} 1422 // expected-note@-2{{attribute is here}} 1423 template<typename T> template<typename U> __declspec(dllimport) const int CTMTR<T>::StaticConstField = 1; // expected-error{{redeclaration of 'CTMTR::StaticConstField' cannot add 'dllimport' attribute}} 1424 // expected-warning@-1{{definition of dllimport static field}} 1425 // expected-note@-2{{attribute is here}} 1426 #ifdef MS 1427 // expected-warning@+1{{attribute declaration must precede definition}} 1428 template<typename T> template<typename U> __declspec(dllimport) constexpr int CTMTR<T>::ConstexprField; 1429 #endif 1430 #endif // __has_feature(cxx_variable_templates) 1431 1432 1433 1434 //===----------------------------------------------------------------------===// 1435 // Classes 1436 //===----------------------------------------------------------------------===// 1437 1438 namespace { 1439 struct __declspec(dllimport) AnonymousClass {}; // expected-error{{(anonymous namespace)::AnonymousClass' must have external linkage when declared 'dllimport'}} 1440 } 1441 1442 class __declspec(dllimport) ClassDecl; 1443 1444 class __declspec(dllimport) ClassDef { }; 1445 1446 template <typename T> class ClassTemplate {}; 1447 1448 #if defined(MS) || defined(WI) 1449 // expected-note@+5{{previous attribute is here}} 1450 // expected-note@+4{{previous attribute is here}} 1451 // expected-error@+4{{attribute 'dllexport' cannot be applied to member of 'dllimport' class}} 1452 // expected-error@+4{{attribute 'dllimport' cannot be applied to member of 'dllimport' class}} 1453 #endif 1454 class __declspec(dllimport) ImportClassWithDllMember { 1455 void __declspec(dllexport) foo(); 1456 void __declspec(dllimport) bar(); 1457 }; 1458 1459 #if defined(MS) || defined(WI) 1460 // expected-note@+5{{previous attribute is here}} 1461 // expected-note@+4{{previous attribute is here}} 1462 // expected-error@+4{{attribute 'dllimport' cannot be applied to member of 'dllexport' class}} 1463 // expected-error@+4{{attribute 'dllexport' cannot be applied to member of 'dllexport' class}} 1464 #endif 1465 template <typename T> class __declspec(dllexport) ExportClassWithDllMember { 1466 void __declspec(dllimport) foo(); 1467 void __declspec(dllexport) bar(); 1468 }; 1469 1470 namespace ImportedExplicitSpecialization { 1471 template <typename T> struct S { static int x; }; 1472 template <typename T> int S<T>::x = sizeof(T); 1473 template <> struct __declspec(dllimport) S<int> { static int x; }; // expected-note{{attribute is here}} 1474 int S<int>::x = -1; // expected-error{{definition of dllimport static field not allowed}} 1475 } 1476 1477 namespace PR19988 { 1478 // Don't error about applying delete to dllimport member function when instantiating. 1479 template <typename> struct __declspec(dllimport) S { 1480 void foo() = delete; 1481 }; 1482 S<int> s; 1483 } 1484 1485 #if defined(MS) || defined(WI) 1486 // expected-warning@+3{{'dllimport' attribute ignored}} 1487 #endif 1488 template <typename T> struct PartiallySpecializedClassTemplate {}; 1489 template <typename T> struct __declspec(dllimport) PartiallySpecializedClassTemplate<T*> { void f() {} }; 1490 1491 template <typename T> struct ExpliciallySpecializedClassTemplate {}; 1492 template <> struct __declspec(dllimport) ExpliciallySpecializedClassTemplate<int> { void f() {} }; 1493 1494 1495 //===----------------------------------------------------------------------===// 1496 // Classes with template base classes 1497 //===----------------------------------------------------------------------===// 1498 1499 template <typename T> class __declspec(dllexport) ExportedClassTemplate {}; 1500 1501 template <typename T> class __declspec(dllimport) ImportedClassTemplate {}; 1502 1503 // ClassTemplate<int> gets imported. 1504 class __declspec(dllimport) DerivedFromTemplate : public ClassTemplate<int> {}; 1505 1506 // ClassTemplate<int> is already imported. 1507 class __declspec(dllimport) DerivedFromTemplate2 : public ClassTemplate<int> {}; 1508 1509 // ImportedClassTemplate is expliitly imported. 1510 class __declspec(dllimport) DerivedFromImportedTemplate : public ImportedClassTemplate<int> {}; 1511 1512 // ExportedClassTemplate is explicitly exported. 1513 class __declspec(dllimport) DerivedFromExportedTemplate : public ExportedClassTemplate<int> {}; 1514 1515 class DerivedFromTemplateD : public ClassTemplate<double> {}; 1516 // Base class previously implicitly instantiated without attribute; it will get propagated. 1517 class __declspec(dllimport) DerivedFromTemplateD2 : public ClassTemplate<double> {}; 1518 1519 // Base class has explicit instantiation declaration; the attribute will get propagated. 1520 extern template class ClassTemplate<float>; 1521 class __declspec(dllimport) DerivedFromTemplateF : public ClassTemplate<float> {}; 1522 1523 class __declspec(dllimport) DerivedFromTemplateB : public ClassTemplate<bool> {}; 1524 // The second derived class doesn't change anything, the attribute that was propagated first wins. 1525 class __declspec(dllexport) DerivedFromTemplateB2 : public ClassTemplate<bool> {}; 1526 1527 template <typename T> struct ExplicitlySpecializedTemplate { void func() {} }; 1528 #ifdef MS 1529 // expected-note@+2{{class template 'ExplicitlySpecializedTemplate<int>' was explicitly specialized here}} 1530 #endif 1531 template <> struct ExplicitlySpecializedTemplate<int> { void func() {} }; 1532 template <typename T> struct ExplicitlyExportSpecializedTemplate { void func() {} }; 1533 template <> struct __declspec(dllexport) ExplicitlyExportSpecializedTemplate<int> { void func() {} }; 1534 template <typename T> struct ExplicitlyImportSpecializedTemplate { void func() {} }; 1535 template <> struct __declspec(dllimport) ExplicitlyImportSpecializedTemplate<int> { void func() {} }; 1536 1537 template <typename T> struct ExplicitlyInstantiatedTemplate { void func() {} }; 1538 #ifdef MS 1539 // expected-note@+2{{class template 'ExplicitlyInstantiatedTemplate<int>' was instantiated here}} 1540 #endif 1541 template struct ExplicitlyInstantiatedTemplate<int>; 1542 template <typename T> struct ExplicitlyExportInstantiatedTemplate { void func() {} }; 1543 template struct __declspec(dllexport) ExplicitlyExportInstantiatedTemplate<int>; 1544 template <typename T> struct ExplicitlyImportInstantiatedTemplate { void func() {} }; 1545 template struct __declspec(dllimport) ExplicitlyImportInstantiatedTemplate<int>; 1546 1547 #ifdef MS 1548 // expected-warning@+3{{propagating dll attribute to explicitly specialized base class template without dll attribute is not supported}} 1549 // expected-note@+2{{attribute is here}} 1550 #endif 1551 struct __declspec(dllimport) DerivedFromExplicitlySpecializedTemplate : public ExplicitlySpecializedTemplate<int> {}; 1552 1553 // Base class already specialized with export attribute. 1554 struct __declspec(dllimport) DerivedFromExplicitlyExportSpecializedTemplate : public ExplicitlyExportSpecializedTemplate<int> {}; 1555 1556 // Base class already specialized with import attribute. 1557 struct __declspec(dllimport) DerivedFromExplicitlyImportSpecializedTemplate : public ExplicitlyImportSpecializedTemplate<int> {}; 1558 1559 #ifdef MS 1560 // expected-warning@+3{{propagating dll attribute to already instantiated base class template without dll attribute is not supported}} 1561 // expected-note@+2{{attribute is here}} 1562 #endif 1563 struct __declspec(dllimport) DerivedFromExplicitlyInstantiatedTemplate : public ExplicitlyInstantiatedTemplate<int> {}; 1564 1565 // Base class already instantiated with export attribute. 1566 struct __declspec(dllimport) DerivedFromExplicitlyExportInstantiatedTemplate : public ExplicitlyExportInstantiatedTemplate<int> {}; 1567 1568 // Base class already instantiated with import attribute. 1569 struct __declspec(dllimport) DerivedFromExplicitlyImportInstantiatedTemplate : public ExplicitlyImportInstantiatedTemplate<int> {}; 1570 1571 template <typename T> struct ExplicitInstantiationDeclTemplateBase { void func() {} }; 1572 extern template struct ExplicitInstantiationDeclTemplateBase<int>; 1573 struct __declspec(dllimport) DerivedFromExplicitInstantiationDeclTemplateBase : public ExplicitInstantiationDeclTemplateBase<int> {}; 1574 1575 //===----------------------------------------------------------------------===// 1576 // Lambdas 1577 //===----------------------------------------------------------------------===// 1578 // The MS ABI doesn't provide a stable mangling for lambdas, so they can't be imported or exported. 1579 #if defined(MS) || defined(WI) 1580 // expected-error@+4{{lambda cannot be declared 'dllimport'}} 1581 #else 1582 // expected-warning@+2{{'dllimport' attribute ignored on inline function}} 1583 #endif 1584 auto Lambda = []() __declspec(dllimport) -> bool { return true; }; 1585