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