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