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. 7struct ImplicitInst_Imported {}; 8struct ExplicitDecl_Imported {}; 9struct ExplicitInst_Imported {}; 10struct ExplicitSpec_Imported {}; 11struct ExplicitSpec_Def_Imported {}; 12struct ExplicitSpec_InlineDef_Imported {}; 13struct ExplicitSpec_NotImported {}; 14namespace { struct Internal {}; } 15 16 17// Invalid usage. 18__declspec(dllimport) typedef int typedef1; // expected-warning{{'dllimport' attribute only applies to variables, functions and classes}} 19typedef __declspec(dllimport) int typedef2; // expected-warning{{'dllimport' attribute only applies to variables, functions and classes}} 20typedef int __declspec(dllimport) typedef3; // expected-warning{{'dllimport' attribute only applies to variables, functions and classes}} 21typedef __declspec(dllimport) void (*FunTy)(); // expected-warning{{'dllimport' attribute only applies to variables, functions and classes}} 22enum __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; 38int **__attribute__((dllimport))* GlobalDeclChunkAttr; 39int 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}} 44int __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 56int 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 67int GlobalDeclInit = 1; 68 69#ifdef GNU 70// expected-note@+2{{previous attribute is here}} 71#endif 72int *__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 78int *GlobalDeclChunkAttrInit = 0; 79 80#ifdef GNU 81// expected-note@+2{{previous attribute is here}} 82#endif 83int 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 89int 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 98int *__attribute__((dllimport)) GlobalRedecl2b; 99int *__attribute__((dllimport)) GlobalRedecl2b; 100 101int GlobalRedecl2c __attribute__((dllimport)); 102int 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 110extern "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'}} 118namespace { __declspec(dllimport) int InternalGlobal; } // expected-error{{'(anonymous namespace)::InternalGlobal' must have external linkage when declared 'dllimport'}} 119namespace 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 128inline 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}} 137void 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. 157template<typename T> __declspec(dllimport) extern int ExternVarTmplDecl; 158 159// dllimport implies a declaration. 160template<typename T> __declspec(dllimport) int VarTmplDecl; 161 162// Not allowed on definitions. 163template<typename T> __declspec(dllimport) extern int ExternVarTmplInit = 1; // expected-error{{definition of dllimport data}} 164template<typename T> __declspec(dllimport) int VarTmplInit1 = 1; // expected-error{{definition of dllimport data}} 165template<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 171template <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 178template <typename T> 179int ExternVarTmplDeclInit = 1; 180 181#ifdef GNU 182// expected-note@+3{{previous attribute is here}} 183#endif 184template <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 191template <typename T> 192int VarTmplDeclInit = 1; 193 194// Redeclarations 195template<typename T> __declspec(dllimport) extern int VarTmplRedecl1; 196template<typename T> __declspec(dllimport) extern int VarTmplRedecl1; 197 198template<typename T> __declspec(dllimport) int VarTmplRedecl2; 199template<typename T> __declspec(dllimport) int VarTmplRedecl2; 200 201template<typename T> __declspec(dllimport) extern int VarTmplRedecl3; // expected-note{{previous declaration is here}} expected-note{{previous attribute is here}} 202template<typename T> extern int VarTmplRedecl3; // expected-warning{{'VarTmplRedecl3' redeclared without 'dllimport' attribute: previous 'dllimport' ignored}} 203 204template<typename T> extern int VarTmplRedecl4; // expected-note{{previous declaration is here}} 205template<typename T> __declspec(dllimport) extern int VarTmplRedecl4; // expected-error{{redeclaration of 'VarTmplRedecl4' cannot add 'dllimport' attribute}} 206 207// External linkage is required. 208template<typename T> __declspec(dllimport) static int StaticVarTmpl; // expected-error{{'StaticVarTmpl' must have external linkage when declared 'dllimport'}} 209template<typename T> __declspec(dllimport) Internal InternalTypeVarTmpl; // expected-error{{'InternalTypeVarTmpl' must have external linkage when declared 'dllimport'}} 210namespace { template<typename T> __declspec(dllimport) int InternalVarTmpl; } // expected-error{{'(anonymous namespace)::InternalVarTmpl' must have external linkage when declared 'dllimport'}} 211namespace ns { template<typename T> __declspec(dllimport) int ExternalVarTmpl; } 212 213template<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 216template<typename T> int VarTmpl; 217template<typename T> __declspec(dllimport) int ImportedVarTmpl; 218 219// Import implicit instantiation of an imported variable template. 220int useVarTmpl() { return ImportedVarTmpl<ImplicitInst_Imported>; } 221 222// Import explicit instantiation declaration of an imported variable template. 223extern 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. 229template<> __declspec(dllimport) int ImportedVarTmpl<ExplicitSpec_Imported>; 230template<> __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. 234template<> int ImportedVarTmpl<ExplicitSpec_NotImported>; 235 236 237// Import explicit instantiation declaration of a non-imported variable template. 238extern template __declspec(dllimport) int VarTmpl<ExplicitDecl_Imported>; 239 240// Import explicit instantiation definition of a non-imported variable template. 241template __declspec(dllimport) int VarTmpl<ExplicitInst_Imported>; 242 243// Import specialization of a non-imported variable template. 244template<> __declspec(dllimport) int VarTmpl<ExplicitSpec_Imported>; 245template<> __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 258void __attribute__((dllimport)) decl2A(); 259void __declspec(dllimport) decl2B(); 260 261// Not allowed on function definitions. 262__declspec(dllimport) void def() {} // expected-error{{dllimport cannot be applied to non-inline function definition}} 263 264// extern "C" 265extern "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 272__declspec(dllimport) inline void inlineFunc1() {} 273inline 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(); 279 void inlineDecl() {} 280 281__declspec(dllimport) void inlineDef(); 282#ifdef GNU 283// expected-warning@+2{{'inlineDef' redeclared inline; 'dllimport' attribute ignored}} 284#endif 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 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 309extern "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}} 316__declspec(dllimport) inline void redecl6() {} // expected-warning{{redeclaration of 'redecl6' should not add 'dllimport' attribute}} 317#else 318 void redecl6(); 319__declspec(dllimport) inline void redecl6() {} // expected-warning{{'dllimport' attribute ignored on inline function}} 320#endif 321 322// Friend functions 323struct 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 343 void friend3() {} 344__declspec(dllimport) void friend4(); // expected-warning{{redeclaration of 'friend4' should not add 'dllimport' attribute}} 345#ifdef MS 346__declspec(dllimport) inline void friend5() {} // expected-warning{{redeclaration of 'friend5' should not add 'dllimport' attribute}} 347#else 348__declspec(dllimport) inline void friend5() {} // expected-warning{{'dllimport' attribute ignored on inline function}} 349#endif 350 351 352void __declspec(dllimport) friend6(); // expected-note{{previous declaration is here}} expected-note{{previous attribute is here}} 353void __declspec(dllimport) friend7(); 354struct 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'}} 365namespace { __declspec(dllimport) void internalFunc(); } // expected-error{{'(anonymous namespace)::internalFunc' must have external linkage when declared 'dllimport'}} 366namespace 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. 386template<typename T> __declspec(dllimport) void funcTmplDecl1(); 387template<typename T> void __declspec(dllimport) funcTmplDecl2(); 388 389// Import function template definition. 390template<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 399template<typename T> __declspec(dllimport) inline void inlineFuncTmpl1() {} 400template<typename T> inline void __attribute__((dllimport)) inlineFuncTmpl2() {} 401 402template<typename T> __declspec(dllimport) inline void inlineFuncTmplDecl(); 403template<typename T> void inlineFuncTmplDecl() {} 404 405template<typename T> __declspec(dllimport) void inlineFuncTmplDef(); 406template<typename T> inline void inlineFuncTmplDef() {} 407 408// Redeclarations 409template<typename T> __declspec(dllimport) void funcTmplRedecl1(); 410template<typename T> __declspec(dllimport) void funcTmplRedecl1(); 411 412template<typename T> __declspec(dllimport) void funcTmplRedecl2(); // expected-note{{previous declaration is here}} expected-note{{previous attribute is here}} 413template<typename T> void funcTmplRedecl2(); // expected-warning{{'funcTmplRedecl2' redeclared without 'dllimport' attribute: previous 'dllimport' ignored}} 414 415template<typename T> __declspec(dllimport) void funcTmplRedecl3(); // expected-note{{previous declaration is here}} expected-note{{previous attribute is here}} 416template<typename T> void funcTmplRedecl3() {} // expected-warning{{'funcTmplRedecl3' redeclared without 'dllimport' attribute: previous 'dllimport' ignored}} 417 418template<typename T> void funcTmplRedecl4(); // expected-note{{previous declaration is here}} 419template<typename T> __declspec(dllimport) void funcTmplRedecl4(); // expected-error{{redeclaration of 'funcTmplRedecl4' cannot add 'dllimport' attribute}} 420 421#ifdef MS 422template<typename T> void funcTmplRedecl5(); // expected-note{{previous declaration is here}} 423template<typename T> __declspec(dllimport) inline void funcTmplRedecl5() {} // expected-error{{redeclaration of 'funcTmplRedecl5' cannot add 'dllimport' attribute}} 424#endif 425 426// Function template friends 427struct 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}; 437template<typename T> __declspec(dllimport) void funcTmplFriend1(); 438template<typename T> void funcTmplFriend2(); // expected-warning{{'funcTmplFriend2' redeclared without 'dllimport' attribute: previous 'dllimport' ignored}} 439template<typename T> void funcTmplFriend3() {} // expected-warning{{'funcTmplFriend3' redeclared without 'dllimport' attribute: previous 'dllimport' ignored}} 440template<typename T> __declspec(dllimport) void funcTmplFriend4(); // expected-error{{redeclaration of 'funcTmplFriend4' cannot add 'dllimport' attribute}} 441template<typename T> inline void funcTmplFriend5() {} 442 443// External linkage is required. 444template<typename T> __declspec(dllimport) static int staticFuncTmpl(); // expected-error{{'staticFuncTmpl' must have external linkage when declared 'dllimport'}} 445template<typename T> __declspec(dllimport) Internal internalRetFuncTmpl(); // expected-error{{'internalRetFuncTmpl' must have external linkage when declared 'dllimport'}} 446namespace { template<typename T> __declspec(dllimport) void internalFuncTmpl(); } // expected-error{{'(anonymous namespace)::internalFuncTmpl' must have external linkage when declared 'dllimport'}} 447namespace ns { template<typename T> __declspec(dllimport) void externalFuncTmpl(); } 448 449 450template<typename T> void funcTmpl() {} 451template<typename T> inline void inlineFuncTmpl() {} 452template<typename T> __declspec(dllimport) void importedFuncTmplDecl(); 453#ifdef GNU 454// expected-warning@+2{{'dllimport' attribute ignored on inline function}} 455#endif 456template<typename T> __declspec(dllimport) inline void importedFuncTmpl() {} 457 458// Import implicit instantiation of an imported function template. 459void useFunTmplDecl() { importedFuncTmplDecl<ImplicitInst_Imported>(); } 460void useFunTmplDef() { importedFuncTmpl<ImplicitInst_Imported>(); } 461 462// Import explicit instantiation declaration of an imported function template. 463extern 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. 468template void importedFuncTmpl<ExplicitInst_Imported>(); 469 470// Import specialization of an imported function template. A definition must be 471// declared inline. 472template<> __declspec(dllimport) void importedFuncTmpl<ExplicitSpec_Imported>(); 473template<> __declspec(dllimport) void importedFuncTmpl<ExplicitSpec_Def_Imported>() {} // expected-error{{dllimport cannot be applied to non-inline function definition}} 474#ifdef MS 475template<> __declspec(dllimport) inline void importedFuncTmpl<ExplicitSpec_InlineDef_Imported>() {} 476#endif 477 478// Not importing specialization of an imported function template without 479// explicit dllimport. 480template<> void importedFuncTmpl<ExplicitSpec_NotImported>() {} 481 482 483// Import explicit instantiation declaration of a non-imported function template. 484extern template __declspec(dllimport) void funcTmpl<ExplicitDecl_Imported>(); 485#ifdef GNU 486// expected-warning@+2{{'dllimport' attribute ignored on inline function}} 487#endif 488extern template __declspec(dllimport) void inlineFuncTmpl<ExplicitDecl_Imported>(); 489 490// Import explicit instantiation definition of a non-imported function template. 491template __declspec(dllimport) void funcTmpl<ExplicitInst_Imported>(); 492#ifdef GNU 493// expected-warning@+2{{'dllimport' attribute ignored on inline function}} 494#endif 495template __declspec(dllimport) void inlineFuncTmpl<ExplicitInst_Imported>(); 496 497// Import specialization of a non-imported function template. A definition must 498// be declared inline. 499template<> __declspec(dllimport) void funcTmpl<ExplicitSpec_Imported>(); 500template<> __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 504template<> __declspec(dllimport) inline void funcTmpl<ExplicitSpec_InlineDef_Imported>() {} 505 506 507//===----------------------------------------------------------------------===// 508// Class members 509//===----------------------------------------------------------------------===// 510 511// Import individual members of a class. 512struct 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}} 528 __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}} 538 __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}} 548 __declspec(dllimport) static void staticInclass() {} 549 __declspec(dllimport) static void staticInlineDef(); 550 __declspec(dllimport) static inline void staticInlineDecl(); 551 552protected: 553 __declspec(dllimport) void protectedDecl(); 554private: 555 __declspec(dllimport) void privateDecl(); 556public: 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 574void 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 580void ImportMembers::normalDef() {} 581#ifdef GNU 582// expected-warning@+2{{'ImportMembers::normalInlineDef' redeclared inline; 'dllimport' attribute ignored}} 583#endif 584inline void ImportMembers::normalInlineDef() {} 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 591 void ImportMembers::virtualDef() {} 592#ifdef GNU 593// expected-warning@+2{{'ImportMembers::virtualInlineDef' redeclared inline; 'dllimport' attribute ignored}} 594#endif 595inline void ImportMembers::virtualInlineDef() {} 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 602 void ImportMembers::staticDef() {} 603#ifdef GNU 604// expected-warning@+2{{'ImportMembers::staticInlineDef' redeclared inline; 'dllimport' attribute ignored}} 605#endif 606inline void ImportMembers::staticInlineDef() {} 607 void ImportMembers::staticInlineDecl() {} 608 609 int ImportMembers::StaticFieldDef; // expected-error{{definition of dllimport static field not allowed}} 610const int ImportMembers::StaticConstFieldDef = 1; // expected-error{{definition of dllimport static field not allowed}} 611constexpr int ImportMembers::ConstexprFieldDef; // expected-error{{definition of dllimport static field not allowed}} 612 613 614// Import on member definitions. 615struct 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 633__declspec(dllimport) void ImportMemberDefs::normalDef() {} // expected-error{{dllimport cannot be applied to non-inline function definition}} 634__declspec(dllimport) void ImportMemberDefs::virtualDef() {} // expected-error{{dllimport cannot be applied to non-inline function definition}} 635__declspec(dllimport) void ImportMemberDefs::staticDef() {} // expected-error{{dllimport cannot be applied to non-inline function definition}} 636#ifdef MS 637__declspec(dllimport) inline void ImportMemberDefs::normalInlineDef() {} 638__declspec(dllimport) void ImportMemberDefs::normalInlineDecl() {} 639__declspec(dllimport) inline void ImportMemberDefs::virtualInlineDef() {} 640__declspec(dllimport) void ImportMemberDefs::virtualInlineDecl() {} 641__declspec(dllimport) inline void ImportMemberDefs::staticInlineDef() {} 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. 651struct 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. 662struct 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. 684struct 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. 693struct 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. 712struct 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. 742ImportDefaultedDefs::~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; 750inline 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 758ImportDefaultedDefs &ImportDefaultedDefs::operator=(ImportDefaultedDefs &&) = default; 759 760// Redeclarations cannot add dllimport. 761struct 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 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}} 785__declspec(dllimport) void MemberRedecl::normalInlineDecl() {} // expected-error{{redeclaration of 'MemberRedecl::normalInlineDecl' cannot add 'dllimport' attribute}} 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}} 788__declspec(dllimport) void MemberRedecl::virtualInlineDecl() {} // expected-error{{redeclaration of 'MemberRedecl::virtualInlineDecl' cannot add 'dllimport' attribute}} 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}} 791__declspec(dllimport) void MemberRedecl::staticInlineDecl() {} // expected-error{{redeclaration of 'MemberRedecl::staticInlineDecl' cannot add 'dllimport' attribute}} 792 793#ifdef MS 794__declspec(dllimport) inline void MemberRedecl::normalInlineDef() {} // expected-error{{redeclaration of 'MemberRedecl::normalInlineDef' cannot add 'dllimport' attribute}} 795__declspec(dllimport) inline void MemberRedecl::virtualInlineDef() {} // expected-error{{redeclaration of 'MemberRedecl::virtualInlineDef' cannot add 'dllimport' attribute}} 796__declspec(dllimport) inline void MemberRedecl::staticInlineDef() {} // expected-error{{redeclaration of 'MemberRedecl::staticInlineDef' cannot add 'dllimport' attribute}} 797#else 798__declspec(dllimport) inline void MemberRedecl::normalInlineDef() {} // expected-warning{{'dllimport' attribute ignored on inline function}} 799__declspec(dllimport) inline void MemberRedecl::virtualInlineDef() {} // expected-warning{{'dllimport' attribute ignored on inline function}} 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 821struct 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 835 template<typename T> __declspec(dllimport) void normalInclass() {} 836 template<typename T> __declspec(dllimport) inline void normalInlineDecl(); 837 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 852template<typename T> void ImportMemberTmpl::normalDef() {} // expected-warning{{'ImportMemberTmpl::normalDef' redeclared without 'dllimport' attribute: previous 'dllimport' ignored}} 853template<typename T> void ImportMemberTmpl::normalInlineDecl() {} 854template<typename T> void ImportMemberTmpl::staticDef() {} // expected-warning{{'ImportMemberTmpl::staticDef' redeclared without 'dllimport' attribute: previous 'dllimport' ignored}} 855template<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 861template<typename T> inline void ImportMemberTmpl::normalInlineDef() {} 862template<typename T> inline void ImportMemberTmpl::staticInlineDef() {} 863 864#if __has_feature(cxx_variable_templates) 865template<typename T> int ImportMemberTmpl::StaticFieldDef; // expected-error{{definition of dllimport static field not allowed}} 866template<typename T> const int ImportMemberTmpl::StaticConstFieldDef = 1; // expected-error{{definition of dllimport static field not allowed}} 867template<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. 872struct 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 892template<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 895template<typename T> __declspec(dllimport) inline void MemTmplRedecl::normalInlineDef() {} // expected-error{{redeclaration of 'MemTmplRedecl::normalInlineDef' cannot add 'dllimport' attribute}} 896#else 897template<typename T> __declspec(dllimport) inline void MemTmplRedecl::normalInlineDef() {} // expected-warning{{'dllimport' attribute ignored on inline function}} 898#endif 899template<typename T> __declspec(dllimport) void MemTmplRedecl::normalInlineDecl() {} // expected-error{{redeclaration of 'MemTmplRedecl::normalInlineDecl' cannot add 'dllimport' attribute}} 900template<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 903template<typename T> __declspec(dllimport) inline void MemTmplRedecl::staticInlineDef() {} // expected-error{{redeclaration of 'MemTmplRedecl::staticInlineDef' cannot add 'dllimport' attribute}} 904#else 905template<typename T> __declspec(dllimport) inline void MemTmplRedecl::staticInlineDef() {} // expected-warning{{'dllimport' attribute ignored on inline function}} 906#endif 907template<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) 910template<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}} 913template<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}} 916template<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 923struct MemFunTmpl { 924 template<typename T> void normalDef() {} 925#ifdef GNU 926 // expected-warning@+2{{'dllimport' attribute ignored on inline function}} 927#endif 928 template<typename T> __declspec(dllimport) void importedNormal() {} 929 template<typename T> static void staticDef() {} 930#ifdef GNU 931 // expected-warning@+2{{'dllimport' attribute ignored on inline function}} 932#endif 933 template<typename T> __declspec(dllimport) static void importedStatic() {} 934}; 935 936// Import implicit instantiation of an imported member function template. 937void 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. 944extern template void MemFunTmpl::importedNormal<ExplicitDecl_Imported>(); 945extern 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. 950template void MemFunTmpl::importedNormal<ExplicitInst_Imported>(); 951template void MemFunTmpl::importedStatic<ExplicitInst_Imported>(); 952 953// Import specialization of an imported member function template. 954template<> __declspec(dllimport) void MemFunTmpl::importedNormal<ExplicitSpec_Imported>(); 955template<> __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 959template<> __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 965template<> __declspec(dllimport) void MemFunTmpl::importedStatic<ExplicitSpec_Imported>(); 966template<> __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 970template<> __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. 978template<> void MemFunTmpl::importedNormal<ExplicitSpec_NotImported>() {} 979template<> 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 988extern template __declspec(dllimport) void MemFunTmpl::normalDef<ExplicitDecl_Imported>(); 989extern 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 997template __declspec(dllimport) void MemFunTmpl::normalDef<ExplicitInst_Imported>(); 998template __declspec(dllimport) void MemFunTmpl::staticDef<ExplicitInst_Imported>(); 999 1000// Import specialization of a non-imported member function template. 1001template<> __declspec(dllimport) void MemFunTmpl::normalDef<ExplicitSpec_Imported>(); 1002template<> __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 1006template<> __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 1012template<> __declspec(dllimport) void MemFunTmpl::staticDef<ExplicitSpec_Imported>(); 1013template<> __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 1017template<> __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) 1026struct 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. 1032int useMemVarTmpl() { return MemVarTmpl::ImportedStaticVar<ImplicitInst_Imported>; } 1033 1034// Import explicit instantiation declaration of an imported member variable 1035// template. 1036extern 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. 1043template<> __declspec(dllimport) const int MemVarTmpl::ImportedStaticVar<ExplicitSpec_Imported>; 1044template<> __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. 1050template<> const int MemVarTmpl::ImportedStaticVar<ExplicitSpec_NotImported>; 1051 1052 1053// Import explicit instantiation declaration of a non-imported member variable 1054// template. 1055extern 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. 1062template<> __declspec(dllimport) const int MemVarTmpl::StaticVar<ExplicitSpec_Imported>; 1063template<> __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. 1076template<typename T> 1077struct 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 1105 __declspec(dllimport) void normalInclass() {} 1106 __declspec(dllimport) inline void normalInlineDecl(); 1107 __declspec(dllimport) virtual void virtualInclass() {} 1108 __declspec(dllimport) virtual inline void virtualInlineDecl(); 1109 __declspec(dllimport) static void staticInclass() {} 1110 __declspec(dllimport) static inline void staticInlineDecl(); 1111 1112protected: 1113 __declspec(dllimport) void protectedDecl(); 1114private: 1115 __declspec(dllimport) void privateDecl(); 1116public: 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 1136template <typename T> 1137void ImportClassTmplMembers<T>::normalDef() {} 1138#ifdef GNU 1139// expected-warning@+2{{'ImportClassTmplMembers::normalInlineDef' redeclared inline; 'dllimport' attribute ignored}} 1140#endif 1141template<typename T> inline void ImportClassTmplMembers<T>::normalInlineDef() {} 1142template<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 1148template <typename T> 1149void ImportClassTmplMembers<T>::virtualDef() {} 1150#ifdef GNU 1151// expected-warning@+2{{'ImportClassTmplMembers::virtualInlineDef' redeclared inline; 'dllimport' attribute ignored}} 1152#endif 1153template<typename T> inline void ImportClassTmplMembers<T>::virtualInlineDef() {} 1154template<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 1160template <typename T> 1161void ImportClassTmplMembers<T>::staticDef() {} 1162#ifdef GNU 1163// expected-warning@+2{{'ImportClassTmplMembers::staticInlineDef' redeclared inline; 'dllimport' attribute ignored}} 1164#endif 1165template<typename T> inline void ImportClassTmplMembers<T>::staticInlineDef() {} 1166template<typename T> void ImportClassTmplMembers<T>::staticInlineDecl() {} 1167 1168template<typename T> int ImportClassTmplMembers<T>::StaticFieldDef; // expected-warning{{definition of dllimport static field}} 1169template<typename T> const int ImportClassTmplMembers<T>::StaticConstFieldDef = 1; // expected-warning{{definition of dllimport static field}} 1170template<typename T> constexpr int ImportClassTmplMembers<T>::ConstexprFieldDef; // expected-warning{{definition of dllimport static field}} 1171 1172 1173// Redeclarations cannot add dllimport. 1174template<typename T> 1175struct 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 1197template<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}} 1199template<typename T> __declspec(dllimport) void CTMR<T>::normalInlineDecl() {} // expected-error{{redeclaration of 'CTMR::normalInlineDecl' cannot add 'dllimport' attribute}} 1200template<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}} 1202template<typename T> __declspec(dllimport) void CTMR<T>::virtualInlineDecl() {} // expected-error{{redeclaration of 'CTMR::virtualInlineDecl' cannot add 'dllimport' attribute}} 1203template<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}} 1205template<typename T> __declspec(dllimport) void CTMR<T>::staticInlineDecl() {} // expected-error{{redeclaration of 'CTMR::staticInlineDecl' cannot add 'dllimport' attribute}} 1206 1207#ifdef MS 1208template<typename T> __declspec(dllimport) inline void CTMR<T>::normalInlineDef() {} // expected-error{{redeclaration of 'CTMR::normalInlineDef' cannot add 'dllimport' attribute}} 1209template<typename T> __declspec(dllimport) inline void CTMR<T>::virtualInlineDef() {} // expected-error{{redeclaration of 'CTMR::virtualInlineDef' cannot add 'dllimport' attribute}} 1210template<typename T> __declspec(dllimport) inline void CTMR<T>::staticInlineDef() {} // expected-error{{redeclaration of 'CTMR::staticInlineDef' cannot add 'dllimport' attribute}} 1211#else 1212template<typename T> __declspec(dllimport) inline void CTMR<T>::normalInlineDef() {} // expected-warning{{'dllimport' attribute ignored on inline function}} 1213template<typename T> __declspec(dllimport) inline void CTMR<T>::virtualInlineDef() {} // expected-warning{{'dllimport' attribute ignored on inline function}} 1214template<typename T> __declspec(dllimport) inline void CTMR<T>::staticInlineDef() {} // expected-warning{{'dllimport' attribute ignored on inline function}} 1215#endif 1216 1217template<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}} 1220template<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}} 1223template<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 1233template<typename T> 1234struct 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 1248 template<typename U> __declspec(dllimport) void normalInclass() {} 1249 template<typename U> __declspec(dllimport) inline void normalInlineDecl(); 1250 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 1265template<typename T> template<typename U> void ImportClsTmplMemTmpl<T>::normalDef() {} // expected-warning{{'ImportClsTmplMemTmpl::normalDef' redeclared without 'dllimport' attribute: previous 'dllimport' ignored}} 1266template<typename T> template<typename U> void ImportClsTmplMemTmpl<T>::normalInlineDecl() {} 1267template<typename T> template<typename U> void ImportClsTmplMemTmpl<T>::staticDef() {} // expected-warning{{'ImportClsTmplMemTmpl::staticDef' redeclared without 'dllimport' attribute: previous 'dllimport' ignored}} 1268template<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 1274template<typename T> template<typename U> inline void ImportClsTmplMemTmpl<T>::normalInlineDef() {} 1275template<typename T> template<typename U> inline void ImportClsTmplMemTmpl<T>::staticInlineDef() {} 1276 1277#if __has_feature(cxx_variable_templates) 1278template<typename T> template<typename U> int ImportClsTmplMemTmpl<T>::StaticFieldDef; // expected-warning{{definition of dllimport static field}} 1279template<typename T> template<typename U> const int ImportClsTmplMemTmpl<T>::StaticConstFieldDef = 1; // expected-warning{{definition of dllimport static field}} 1280template<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. 1285template<typename T> 1286struct 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 1306template<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}} 1308template<typename T> template<typename U> __declspec(dllimport) void CTMTR<T>::normalInlineDecl() {} // expected-error{{redeclaration of 'CTMTR::normalInlineDecl' cannot add 'dllimport' attribute}} 1309template<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}} 1311template<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 1314template<typename T> template<typename U> __declspec(dllimport) inline void CTMTR<T>::normalInlineDef() {} // expected-error{{redeclaration of 'CTMTR::normalInlineDef' cannot add 'dllimport' attribute}} 1315template<typename T> template<typename U> __declspec(dllimport) inline void CTMTR<T>::staticInlineDef() {} // expected-error{{redeclaration of 'CTMTR::staticInlineDef' cannot add 'dllimport' attribute}} 1316#else 1317template<typename T> template<typename U> __declspec(dllimport) inline void CTMTR<T>::normalInlineDef() {} // expected-warning{{'dllimport' attribute ignored on inline function}} 1318template<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) 1322template<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}} 1325template<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}} 1328template<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 1339namespace { 1340 struct __declspec(dllimport) AnonymousClass {}; // expected-error{{(anonymous namespace)::AnonymousClass' must have external linkage when declared 'dllimport'}} 1341} 1342 1343class __declspec(dllimport) ClassDecl; 1344 1345class __declspec(dllimport) ClassDef { }; 1346 1347template <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 1355class __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 1366template <typename T> class __declspec(dllexport) ExportClassWithDllMember { 1367 void __declspec(dllimport) foo(); 1368 void __declspec(dllexport) bar(); 1369}; 1370 1371namespace ImportedExplicitSpecialization { 1372template <typename T> struct S { static int x; }; 1373template <typename T> int S<T>::x = sizeof(T); 1374template <> struct __declspec(dllimport) S<int> { static int x; }; // expected-note{{attribute is here}} 1375int S<int>::x = -1; // expected-error{{definition of dllimport static field not allowed}} 1376} 1377 1378namespace PR19988 { 1379// Don't error about applying delete to dllimport member function when instantiating. 1380template <typename> struct __declspec(dllimport) S { 1381 void foo() = delete; 1382}; 1383S<int> s; 1384} 1385 1386#ifdef MS 1387// expected-warning@+3{{'dllimport' attribute ignored}} 1388#endif 1389template <typename T> struct PartiallySpecializedClassTemplate {}; 1390template <typename T> struct __declspec(dllimport) PartiallySpecializedClassTemplate<T*> { void f() {} }; 1391 1392template <typename T> struct ExpliciallySpecializedClassTemplate {}; 1393template <> struct __declspec(dllimport) ExpliciallySpecializedClassTemplate<int> { void f() {} }; 1394 1395 1396//===----------------------------------------------------------------------===// 1397// Classes with template base classes 1398//===----------------------------------------------------------------------===// 1399 1400template <typename T> class __declspec(dllexport) ExportedClassTemplate {}; 1401 1402template <typename T> class __declspec(dllimport) ImportedClassTemplate {}; 1403 1404// ClassTemplate<int> gets imported. 1405class __declspec(dllimport) DerivedFromTemplate : public ClassTemplate<int> {}; 1406 1407// ClassTemplate<int> is already imported. 1408class __declspec(dllimport) DerivedFromTemplate2 : public ClassTemplate<int> {}; 1409 1410// ImportedClassTemplate is expliitly imported. 1411class __declspec(dllimport) DerivedFromImportedTemplate : public ImportedClassTemplate<int> {}; 1412 1413// ExportedClassTemplate is explicitly exported. 1414class __declspec(dllimport) DerivedFromExportedTemplate : public ExportedClassTemplate<int> {}; 1415 1416class DerivedFromTemplateD : public ClassTemplate<double> {}; 1417// Base class previously implicitly instantiated without attribute; it will get propagated. 1418class __declspec(dllimport) DerivedFromTemplateD2 : public ClassTemplate<double> {}; 1419 1420// Base class has explicit instantiation declaration; the attribute will get propagated. 1421extern template class ClassTemplate<float>; 1422class __declspec(dllimport) DerivedFromTemplateF : public ClassTemplate<float> {}; 1423 1424class __declspec(dllimport) DerivedFromTemplateB : public ClassTemplate<bool> {}; 1425// The second derived class doesn't change anything, the attribute that was propagated first wins. 1426class __declspec(dllexport) DerivedFromTemplateB2 : public ClassTemplate<bool> {}; 1427 1428template <typename T> struct ExplicitlySpecializedTemplate { void func() {} }; 1429#ifdef MS 1430// expected-note@+2{{class template 'ExplicitlySpecializedTemplate<int>' was explicitly specialized here}} 1431#endif 1432template <> struct ExplicitlySpecializedTemplate<int> { void func() {} }; 1433template <typename T> struct ExplicitlyExportSpecializedTemplate { void func() {} }; 1434template <> struct __declspec(dllexport) ExplicitlyExportSpecializedTemplate<int> { void func() {} }; 1435template <typename T> struct ExplicitlyImportSpecializedTemplate { void func() {} }; 1436template <> struct __declspec(dllimport) ExplicitlyImportSpecializedTemplate<int> { void func() {} }; 1437 1438template <typename T> struct ExplicitlyInstantiatedTemplate { void func() {} }; 1439#ifdef MS 1440// expected-note@+2{{class template 'ExplicitlyInstantiatedTemplate<int>' was instantiated here}} 1441#endif 1442template struct ExplicitlyInstantiatedTemplate<int>; 1443template <typename T> struct ExplicitlyExportInstantiatedTemplate { void func() {} }; 1444template struct __declspec(dllexport) ExplicitlyExportInstantiatedTemplate<int>; 1445template <typename T> struct ExplicitlyImportInstantiatedTemplate { void func() {} }; 1446template 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 1452struct __declspec(dllimport) DerivedFromExplicitlySpecializedTemplate : public ExplicitlySpecializedTemplate<int> {}; 1453 1454// Base class already specialized with export attribute. 1455struct __declspec(dllimport) DerivedFromExplicitlyExportSpecializedTemplate : public ExplicitlyExportSpecializedTemplate<int> {}; 1456 1457// Base class already specialized with import attribute. 1458struct __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 1464struct __declspec(dllimport) DerivedFromExplicitlyInstantiatedTemplate : public ExplicitlyInstantiatedTemplate<int> {}; 1465 1466// Base class already instantiated with export attribute. 1467struct __declspec(dllimport) DerivedFromExplicitlyExportInstantiatedTemplate : public ExplicitlyExportInstantiatedTemplate<int> {}; 1468 1469// Base class already instantiated with import attribute. 1470struct __declspec(dllimport) DerivedFromExplicitlyImportInstantiatedTemplate : public ExplicitlyImportInstantiatedTemplate<int> {}; 1471 1472template <typename T> struct ExplicitInstantiationDeclTemplateBase { void func() {} }; 1473extern template struct ExplicitInstantiationDeclTemplateBase<int>; 1474struct __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 1485auto Lambda = []() __declspec(dllimport) -> bool { return true; }; 1486