1// RUN: %clang_cc1 -triple i686-win32 -fsyntax-only -verify -std=c++11 -Wunsupported-dll-base-class-template -DMS %s 2// RUN: %clang_cc1 -triple x86_64-win32 -fsyntax-only -verify -std=c++1y -Wunsupported-dll-base-class-template -DMS %s 3// RUN: %clang_cc1 -triple i686-mingw32 -fsyntax-only -verify -std=c++1y -Wunsupported-dll-base-class-template %s 4// RUN: %clang_cc1 -triple x86_64-mingw32 -fsyntax-only -verify -std=c++11 -Wunsupported-dll-base-class-template %s 5 6// Helper structs to make templates more expressive. 7struct ImplicitInst_Exported {}; 8struct ExplicitDecl_Exported {}; 9struct ExplicitInst_Exported {}; 10struct ExplicitSpec_Exported {}; 11struct ExplicitSpec_Def_Exported {}; 12struct ExplicitSpec_InlineDef_Exported {}; 13struct ExplicitSpec_NotExported {}; 14namespace { struct Internal {}; } 15struct External { int v; }; 16 17 18// Invalid usage. 19__declspec(dllexport) typedef int typedef1; // expected-warning{{'dllexport' attribute only applies to variables, functions and classes}} 20typedef __declspec(dllexport) int typedef2; // expected-warning{{'dllexport' attribute only applies to variables, functions and classes}} 21typedef int __declspec(dllexport) typedef3; // expected-warning{{'dllexport' attribute only applies to variables, functions and classes}} 22typedef __declspec(dllexport) void (*FunTy)(); // expected-warning{{'dllexport' attribute only applies to variables, functions and classes}} 23enum __declspec(dllexport) Enum {}; // expected-warning{{'dllexport' attribute only applies to variables, functions and classes}} 24#if __has_feature(cxx_strong_enums) 25 enum class __declspec(dllexport) EnumClass {}; // expected-warning{{'dllexport' attribute only applies to variables, functions and classes}} 26#endif 27 28 29 30//===----------------------------------------------------------------------===// 31// Globals 32//===----------------------------------------------------------------------===// 33 34// Export declaration. 35__declspec(dllexport) extern int ExternGlobalDecl; 36 37// dllexport implies a definition. 38__declspec(dllexport) int GlobalDef; 39 40// Export definition. 41__declspec(dllexport) int GlobalInit1 = 1; 42int __declspec(dllexport) GlobalInit2 = 1; 43 44// Declare, then export definition. 45__declspec(dllexport) extern int GlobalDeclInit; 46int GlobalDeclInit = 1; 47 48// Redeclarations 49__declspec(dllexport) extern int GlobalRedecl1; 50__declspec(dllexport) int GlobalRedecl1; 51 52__declspec(dllexport) extern int GlobalRedecl2; 53 int GlobalRedecl2; 54 55 extern int GlobalRedecl3; // expected-note{{previous declaration is here}} 56__declspec(dllexport) extern int GlobalRedecl3; // expected-warning{{redeclaration of 'GlobalRedecl3' should not add 'dllexport' attribute}} 57 58extern "C" { 59 extern int GlobalRedecl4; // expected-note{{previous declaration is here}} 60__declspec(dllexport) extern int GlobalRedecl4; // expected-warning{{redeclaration of 'GlobalRedecl4' should not add 'dllexport' attribute}} 61} 62 63// External linkage is required. 64__declspec(dllexport) static int StaticGlobal; // expected-error{{'StaticGlobal' must have external linkage when declared 'dllexport'}} 65__declspec(dllexport) Internal InternalTypeGlobal; // expected-error{{'InternalTypeGlobal' must have external linkage when declared 'dllexport'}} 66namespace { __declspec(dllexport) int InternalGlobal; } // expected-error{{'(anonymous namespace)::InternalGlobal' must have external linkage when declared 'dllexport'}} 67namespace ns { __declspec(dllexport) int ExternalGlobal; } 68 69__declspec(dllexport) auto InternalAutoTypeGlobal = Internal(); // expected-error{{'InternalAutoTypeGlobal' must have external linkage when declared 'dllexport'}} 70__declspec(dllexport) auto ExternalAutoTypeGlobal = External(); 71 72// Thread local variables are invalid. 73__declspec(dllexport) __thread int ThreadLocalGlobal; // expected-error{{'ThreadLocalGlobal' cannot be thread local when declared 'dllexport'}} 74 75// Export in local scope. 76void functionScope() { 77 __declspec(dllexport) int LocalVarDecl; // expected-error{{'LocalVarDecl' must have external linkage when declared 'dllexport'}} 78 __declspec(dllexport) int LocalVarDef = 1; // expected-error{{'LocalVarDef' must have external linkage when declared 'dllexport'}} 79 __declspec(dllexport) extern int ExternLocalVarDecl; 80 __declspec(dllexport) static int StaticLocalVar; // expected-error{{'StaticLocalVar' must have external linkage when declared 'dllexport'}} 81} 82 83 84 85//===----------------------------------------------------------------------===// 86// Variable templates 87//===----------------------------------------------------------------------===// 88#if __has_feature(cxx_variable_templates) 89 90// Export declaration. 91template<typename T> __declspec(dllexport) extern int ExternVarTmplDecl; 92 93// dllexport implies a definition. 94template<typename T> __declspec(dllexport) int VarTmplDef; 95 96// Export definition. 97template<typename T> __declspec(dllexport) int VarTmplInit1 = 1; 98template<typename T> int __declspec(dllexport) VarTmplInit2 = 1; 99 100// Declare, then export definition. 101template<typename T> __declspec(dllexport) extern int VarTmplDeclInit; 102template<typename T> int VarTmplDeclInit = 1; 103 104// Redeclarations 105template<typename T> __declspec(dllexport) extern int VarTmplRedecl1; 106template<typename T> __declspec(dllexport) int VarTmplRedecl1 = 1; 107 108template<typename T> __declspec(dllexport) extern int VarTmplRedecl2; 109template<typename T> int VarTmplRedecl2 = 1; 110 111template<typename T> extern int VarTmplRedecl3; // expected-note{{previous declaration is here}} 112template<typename T> __declspec(dllexport) extern int VarTmplRedecl3; // expected-error{{redeclaration of 'VarTmplRedecl3' cannot add 'dllexport' attribute}} 113 114// External linkage is required. 115template<typename T> __declspec(dllexport) static int StaticVarTmpl; // expected-error{{'StaticVarTmpl' must have external linkage when declared 'dllexport'}} 116template<typename T> __declspec(dllexport) Internal InternalTypeVarTmpl; // expected-error{{'InternalTypeVarTmpl' must have external linkage when declared 'dllexport'}} 117namespace { template<typename T> __declspec(dllexport) int InternalVarTmpl; } // expected-error{{'(anonymous namespace)::InternalVarTmpl' must have external linkage when declared 'dllexport'}} 118namespace ns { template<typename T> __declspec(dllexport) int ExternalVarTmpl = 1; } 119 120template<typename T> __declspec(dllexport) auto InternalAutoTypeVarTmpl = Internal(); // expected-error{{'InternalAutoTypeVarTmpl' must have external linkage when declared 'dllexport'}} 121template<typename T> __declspec(dllexport) auto ExternalAutoTypeVarTmpl = External(); 122template External ExternalAutoTypeVarTmpl<ExplicitInst_Exported>; 123 124 125template<typename T> int VarTmpl = 1; 126template<typename T> __declspec(dllexport) int ExportedVarTmpl = 1; 127 128// Export implicit instantiation of an exported variable template. 129int useVarTmpl() { return ExportedVarTmpl<ImplicitInst_Exported>; } 130 131// Export explicit instantiation declaration of an exported variable template. 132extern template int ExportedVarTmpl<ExplicitDecl_Exported>; 133 template int ExportedVarTmpl<ExplicitDecl_Exported>; 134 135// Export explicit instantiation definition of an exported variable template. 136template __declspec(dllexport) int ExportedVarTmpl<ExplicitInst_Exported>; 137 138// Export specialization of an exported variable template. 139template<> __declspec(dllexport) int ExportedVarTmpl<ExplicitSpec_Exported>; 140template<> __declspec(dllexport) int ExportedVarTmpl<ExplicitSpec_Def_Exported> = 1; 141 142// Not exporting specialization of an exported variable template without 143// explicit dllexport. 144template<> int ExportedVarTmpl<ExplicitSpec_NotExported>; 145 146 147// Export explicit instantiation declaration of a non-exported variable template. 148extern template __declspec(dllexport) int VarTmpl<ExplicitDecl_Exported>; 149 template __declspec(dllexport) int VarTmpl<ExplicitDecl_Exported>; 150 151// Export explicit instantiation definition of a non-exported variable template. 152template __declspec(dllexport) int VarTmpl<ExplicitInst_Exported>; 153 154// Export specialization of a non-exported variable template. 155template<> __declspec(dllexport) int VarTmpl<ExplicitSpec_Exported>; 156template<> __declspec(dllexport) int VarTmpl<ExplicitSpec_Def_Exported> = 1; 157 158#endif // __has_feature(cxx_variable_templates) 159 160 161 162//===----------------------------------------------------------------------===// 163// Functions 164//===----------------------------------------------------------------------===// 165 166// Export function declaration. Check different placements. 167__attribute__((dllexport)) void decl1A(); // Sanity check with __attribute__ 168__declspec(dllexport) void decl1B(); 169 170void __attribute__((dllexport)) decl2A(); 171void __declspec(dllexport) decl2B(); 172 173// Export function definition. 174__declspec(dllexport) void def() {} 175 176// extern "C" 177extern "C" __declspec(dllexport) void externC() {} 178 179// Export inline function. 180__declspec(dllexport) inline void inlineFunc1() {} 181inline void __attribute__((dllexport)) inlineFunc2() {} 182 183__declspec(dllexport) inline void inlineDecl(); 184 void inlineDecl() {} 185 186__declspec(dllexport) void inlineDef(); 187 inline void inlineDef() {} 188 189// Redeclarations 190__declspec(dllexport) void redecl1(); 191__declspec(dllexport) void redecl1() {} 192 193__declspec(dllexport) void redecl2(); 194 void redecl2() {} 195 196 void redecl3(); // expected-note{{previous declaration is here}} 197__declspec(dllexport) void redecl3(); // expected-warning{{redeclaration of 'redecl3' should not add 'dllexport' attribute}} 198 199extern "C" { 200 void redecl4(); // expected-note{{previous declaration is here}} 201__declspec(dllexport) void redecl4(); // expected-warning{{redeclaration of 'redecl4' should not add 'dllexport' attribute}} 202} 203 204 void redecl5(); // expected-note{{previous declaration is here}} 205__declspec(dllexport) inline void redecl5() {} // expected-warning{{redeclaration of 'redecl5' should not add 'dllexport' attribute}} 206 207// Friend functions 208struct FuncFriend { 209 friend __declspec(dllexport) void friend1(); 210 friend __declspec(dllexport) void friend2(); 211 friend void friend3(); // expected-note{{previous declaration is here}} 212 friend void friend4(); // expected-note{{previous declaration is here}} 213}; 214__declspec(dllexport) void friend1() {} 215 void friend2() {} 216__declspec(dllexport) void friend3() {} // expected-warning{{redeclaration of 'friend3' should not add 'dllexport' attribute}} 217__declspec(dllexport) inline void friend4() {} // expected-warning{{redeclaration of 'friend4' should not add 'dllexport' attribute}} 218 219// Implicit declarations can be redeclared with dllexport. 220__declspec(dllexport) void* operator new(__SIZE_TYPE__ n); 221 222// External linkage is required. 223__declspec(dllexport) static int staticFunc(); // expected-error{{'staticFunc' must have external linkage when declared 'dllexport'}} 224__declspec(dllexport) Internal internalRetFunc(); // expected-error{{'internalRetFunc' must have external linkage when declared 'dllexport'}} 225namespace { __declspec(dllexport) void internalFunc() {} } // expected-error{{'(anonymous namespace)::internalFunc' must have external linkage when declared 'dllexport'}} 226namespace ns { __declspec(dllexport) void externalFunc() {} } 227 228// Export deleted function. 229__declspec(dllexport) void deletedFunc() = delete; // expected-error{{attribute 'dllexport' cannot be applied to a deleted function}} 230__declspec(dllexport) inline void deletedInlineFunc() = delete; // expected-error{{attribute 'dllexport' cannot be applied to a deleted function}} 231 232 233 234//===----------------------------------------------------------------------===// 235// Function templates 236//===----------------------------------------------------------------------===// 237 238// Export function template declaration. Check different placements. 239template<typename T> __declspec(dllexport) void funcTmplDecl1(); 240template<typename T> void __declspec(dllexport) funcTmplDecl2(); 241 242// Export function template definition. 243template<typename T> __declspec(dllexport) void funcTmplDef() {} 244 245// Export inline function template. 246template<typename T> __declspec(dllexport) inline void inlineFuncTmpl1() {} 247template<typename T> inline void __attribute__((dllexport)) inlineFuncTmpl2() {} 248 249template<typename T> __declspec(dllexport) inline void inlineFuncTmplDecl(); 250template<typename T> void inlineFuncTmplDecl() {} 251 252template<typename T> __declspec(dllexport) void inlineFuncTmplDef(); 253template<typename T> inline void inlineFuncTmplDef() {} 254 255// Redeclarations 256template<typename T> __declspec(dllexport) void funcTmplRedecl1(); 257template<typename T> __declspec(dllexport) void funcTmplRedecl1() {} 258 259template<typename T> __declspec(dllexport) void funcTmplRedecl2(); 260template<typename T> void funcTmplRedecl2() {} 261 262template<typename T> void funcTmplRedecl3(); // expected-note{{previous declaration is here}} 263template<typename T> __declspec(dllexport) void funcTmplRedecl3(); // expected-error{{redeclaration of 'funcTmplRedecl3' cannot add 'dllexport' attribute}} 264 265template<typename T> void funcTmplRedecl4(); // expected-note{{previous declaration is here}} 266template<typename T> __declspec(dllexport) inline void funcTmplRedecl4() {} // expected-error{{redeclaration of 'funcTmplRedecl4' cannot add 'dllexport' attribute}} 267 268// Function template friends 269struct FuncTmplFriend { 270 template<typename T> friend __declspec(dllexport) void funcTmplFriend1(); 271 template<typename T> friend __declspec(dllexport) void funcTmplFriend2(); 272 template<typename T> friend void funcTmplFriend3(); // expected-note{{previous declaration is here}} 273 template<typename T> friend void funcTmplFriend4(); // expected-note{{previous declaration is here}} 274}; 275template<typename T> __declspec(dllexport) void funcTmplFriend1() {} 276template<typename T> void funcTmplFriend2() {} 277template<typename T> __declspec(dllexport) void funcTmplFriend3() {} // expected-error{{redeclaration of 'funcTmplFriend3' cannot add 'dllexport' attribute}} 278template<typename T> __declspec(dllexport) inline void funcTmplFriend4() {} // expected-error{{redeclaration of 'funcTmplFriend4' cannot add 'dllexport' attribute}} 279 280// External linkage is required. 281template<typename T> __declspec(dllexport) static int staticFuncTmpl(); // expected-error{{'staticFuncTmpl' must have external linkage when declared 'dllexport'}} 282template<typename T> __declspec(dllexport) Internal internalRetFuncTmpl(); // expected-error{{'internalRetFuncTmpl' must have external linkage when declared 'dllexport'}} 283namespace { template<typename T> __declspec(dllexport) void internalFuncTmpl(); } // expected-error{{'(anonymous namespace)::internalFuncTmpl' must have external linkage when declared 'dllexport'}} 284namespace ns { template<typename T> __declspec(dllexport) void externalFuncTmpl(); } 285 286 287template<typename T> void funcTmpl() {} 288template<typename T> __declspec(dllexport) void exportedFuncTmplDecl(); 289template<typename T> __declspec(dllexport) void exportedFuncTmpl() {} 290 291// Export implicit instantiation of an exported function template. 292void useFunTmplDecl() { exportedFuncTmplDecl<ImplicitInst_Exported>(); } 293void useFunTmplDef() { exportedFuncTmpl<ImplicitInst_Exported>(); } 294 295// Export explicit instantiation declaration of an exported function template. 296extern template void exportedFuncTmpl<ExplicitDecl_Exported>(); 297 template void exportedFuncTmpl<ExplicitDecl_Exported>(); 298 299// Export explicit instantiation definition of an exported function template. 300template void exportedFuncTmpl<ExplicitInst_Exported>(); 301 302// Export specialization of an exported function template. 303template<> __declspec(dllexport) void exportedFuncTmpl<ExplicitSpec_Exported>(); 304template<> __declspec(dllexport) void exportedFuncTmpl<ExplicitSpec_Def_Exported>() {} 305template<> __declspec(dllexport) inline void exportedFuncTmpl<ExplicitSpec_InlineDef_Exported>() {} 306 307// Not exporting specialization of an exported function template without 308// explicit dllexport. 309template<> void exportedFuncTmpl<ExplicitSpec_NotExported>() {} 310 311 312// Export explicit instantiation declaration of a non-exported function template. 313extern template __declspec(dllexport) void funcTmpl<ExplicitDecl_Exported>(); 314 template __declspec(dllexport) void funcTmpl<ExplicitDecl_Exported>(); 315 316// Export explicit instantiation definition of a non-exported function template. 317template __declspec(dllexport) void funcTmpl<ExplicitInst_Exported>(); 318 319// Export specialization of a non-exported function template. 320template<> __declspec(dllexport) void funcTmpl<ExplicitSpec_Exported>(); 321template<> __declspec(dllexport) void funcTmpl<ExplicitSpec_Def_Exported>() {} 322template<> __declspec(dllexport) inline void funcTmpl<ExplicitSpec_InlineDef_Exported>() {} 323 324 325 326//===----------------------------------------------------------------------===// 327// Classes 328//===----------------------------------------------------------------------===// 329 330namespace { 331 struct __declspec(dllexport) AnonymousClass {}; // expected-error{{(anonymous namespace)::AnonymousClass' must have external linkage when declared 'dllexport'}} 332} 333 334class __declspec(dllexport) ClassDecl; 335 336class __declspec(dllexport) ClassDef {}; 337 338#ifdef MS 339// expected-warning@+3{{'dllexport' attribute ignored}} 340#endif 341template <typename T> struct PartiallySpecializedClassTemplate {}; 342template <typename T> struct __declspec(dllexport) PartiallySpecializedClassTemplate<T*> { void f() {} }; 343 344template <typename T> struct ExpliciallySpecializedClassTemplate {}; 345template <> struct __declspec(dllexport) ExpliciallySpecializedClassTemplate<int> { void f() {} }; 346 347// Don't instantiate class members of implicitly instantiated templates, even if they are exported. 348struct IncompleteType; 349template <typename T> struct __declspec(dllexport) ImplicitlyInstantiatedExportedTemplate { 350 int f() { return sizeof(T); } // no-error 351}; 352ImplicitlyInstantiatedExportedTemplate<IncompleteType> implicitlyInstantiatedExportedTemplate; 353 354// Don't instantiate class members of templates with explicit instantiation declarations, even if they are exported. 355struct IncompleteType2; 356template <typename T> struct __declspec(dllexport) ExportedTemplateWithExplicitInstantiationDecl { // expected-note{{attribute is here}} 357 int f() { return sizeof(T); } // no-error 358}; 359extern template struct ExportedTemplateWithExplicitInstantiationDecl<IncompleteType2>; // expected-warning{{explicit instantiation declaration should not be 'dllexport'}} 360 361// Instantiate class members for explicitly instantiated exported templates. 362struct IncompleteType3; // expected-note{{forward declaration of 'IncompleteType3'}} 363template <typename T> struct __declspec(dllexport) ExplicitlyInstantiatedExportedTemplate { 364 int f() { return sizeof(T); } // expected-error{{invalid application of 'sizeof' to an incomplete type 'IncompleteType3'}} 365}; 366template struct ExplicitlyInstantiatedExportedTemplate<IncompleteType3>; // expected-note{{in instantiation of member function 'ExplicitlyInstantiatedExportedTemplate<IncompleteType3>::f' requested here}} 367 368// In MS mode, instantiate members of class templates that are base classes of exported classes. 369#ifdef MS 370 // expected-note@+3{{forward declaration of 'IncompleteType4'}} 371 // expected-note@+3{{in instantiation of member function 'BaseClassTemplateOfExportedClass<IncompleteType4>::f' requested here}} 372#endif 373struct IncompleteType4; 374template <typename T> struct BaseClassTemplateOfExportedClass { 375#ifdef MS 376 // expected-error@+2{{invalid application of 'sizeof' to an incomplete type 'IncompleteType4'}} 377#endif 378 int f() { return sizeof(T); }; 379}; 380struct __declspec(dllexport) ExportedBaseClass : public BaseClassTemplateOfExportedClass<IncompleteType4> {}; 381 382// Don't instantiate members of explicitly exported class templates that are base classes of exported classes. 383struct IncompleteType5; 384template <typename T> struct __declspec(dllexport) ExportedBaseClassTemplateOfExportedClass { 385 int f() { return sizeof(T); }; // no-error 386}; 387struct __declspec(dllexport) ExportedBaseClass2 : public ExportedBaseClassTemplateOfExportedClass<IncompleteType5> {}; 388 389// Warn about explicit instantiation declarations of dllexport classes. 390template <typename T> struct ExplicitInstantiationDeclTemplate {}; 391extern template struct __declspec(dllexport) ExplicitInstantiationDeclTemplate<int>; // expected-warning{{explicit instantiation declaration should not be 'dllexport'}} expected-note{{attribute is here}} 392 393template <typename T> struct __declspec(dllexport) ExplicitInstantiationDeclExportedTemplate {}; // expected-note{{attribute is here}} 394extern template struct ExplicitInstantiationDeclExportedTemplate<int>; // expected-warning{{explicit instantiation declaration should not be 'dllexport'}} 395 396//===----------------------------------------------------------------------===// 397// Classes with template base classes 398//===----------------------------------------------------------------------===// 399 400template <typename T> class ClassTemplate {}; 401template <typename T> class __declspec(dllexport) ExportedClassTemplate {}; 402template <typename T> class __declspec(dllimport) ImportedClassTemplate {}; 403 404template <typename T> struct ExplicitlySpecializedTemplate { void func() {} }; 405#ifdef MS 406// expected-note@+2{{class template 'ExplicitlySpecializedTemplate<int>' was explicitly specialized here}} 407#endif 408template <> struct ExplicitlySpecializedTemplate<int> { void func() {} }; 409template <typename T> struct ExplicitlyExportSpecializedTemplate { void func() {} }; 410template <> struct __declspec(dllexport) ExplicitlyExportSpecializedTemplate<int> { void func() {} }; 411template <typename T> struct ExplicitlyImportSpecializedTemplate { void func() {} }; 412template <> struct __declspec(dllimport) ExplicitlyImportSpecializedTemplate<int> { void func() {} }; 413 414template <typename T> struct ExplicitlyInstantiatedTemplate { void func() {} }; 415#ifdef MS 416// expected-note@+2{{class template 'ExplicitlyInstantiatedTemplate<int>' was instantiated here}} 417#endif 418template struct ExplicitlyInstantiatedTemplate<int>; 419template <typename T> struct ExplicitlyExportInstantiatedTemplate { void func() {} }; 420template struct __declspec(dllexport) ExplicitlyExportInstantiatedTemplate<int>; 421template <typename T> struct ExplicitlyImportInstantiatedTemplate { void func() {} }; 422template struct __declspec(dllimport) ExplicitlyImportInstantiatedTemplate<int>; 423 424// ClassTemplate<int> gets exported. 425class __declspec(dllexport) DerivedFromTemplate : public ClassTemplate<int> {}; 426 427// ClassTemplate<int> is already exported. 428class __declspec(dllexport) DerivedFromTemplate2 : public ClassTemplate<int> {}; 429 430// ExportedTemplate is explicitly exported. 431class __declspec(dllexport) DerivedFromExportedTemplate : public ExportedClassTemplate<int> {}; 432 433// ImportedTemplate is explicitly imported. 434class __declspec(dllexport) DerivedFromImportedTemplate : public ImportedClassTemplate<int> {}; 435 436#ifdef MS 437// expected-note@+4{{class template 'ClassTemplate<double>' was instantiated here}} 438// expected-warning@+4{{propagating dll attribute to already instantiated base class template without dll attribute is not supported}} 439// expected-note@+3{{attribute is here}} 440#endif 441class DerivedFromTemplateD : public ClassTemplate<double> {}; 442class __declspec(dllexport) DerivedFromTemplateD2 : public ClassTemplate<double> {}; 443 444#ifdef MS 445// expected-note@+4{{class template 'ClassTemplate<bool>' was instantiated here}} 446// expected-warning@+4{{propagating dll attribute to already instantiated base class template with different dll attribute is not supported}} 447// expected-note@+3{{attribute is here}} 448#endif 449class __declspec(dllimport) DerivedFromTemplateB : public ClassTemplate<bool> {}; 450class __declspec(dllexport) DerivedFromTemplateB2 : public ClassTemplate<bool> {}; 451 452#ifdef MS 453// expected-warning@+3{{propagating dll attribute to explicitly specialized base class template without dll attribute is not supported}} 454// expected-note@+2{{attribute is here}} 455#endif 456struct __declspec(dllexport) DerivedFromExplicitlySpecializedTemplate : public ExplicitlySpecializedTemplate<int> {}; 457 458// Base class alredy specialized with export attribute. 459struct __declspec(dllexport) DerivedFromExplicitlyExportSpecializedTemplate : public ExplicitlyExportSpecializedTemplate<int> {}; 460 461// Base class already specialized with import attribute. 462struct __declspec(dllexport) DerivedFromExplicitlyImportSpecializedTemplate : public ExplicitlyImportSpecializedTemplate<int> {}; 463 464#ifdef MS 465// expected-warning@+3{{propagating dll attribute to already instantiated base class template without dll attribute is not supported}} 466// expected-note@+2{{attribute is here}} 467#endif 468struct __declspec(dllexport) DerivedFromExplicitlyInstantiatedTemplate : public ExplicitlyInstantiatedTemplate<int> {}; 469 470// Base class already instantiated with export attribute. 471struct __declspec(dllexport) DerivedFromExplicitlyExportInstantiatedTemplate : public ExplicitlyExportInstantiatedTemplate<int> {}; 472 473// Base class already instantiated with import attribute. 474struct __declspec(dllexport) DerivedFromExplicitlyImportInstantiatedTemplate : public ExplicitlyImportInstantiatedTemplate<int> {}; 475 476 477//===----------------------------------------------------------------------===// 478// Precedence 479//===----------------------------------------------------------------------===// 480 481// dllexport takes precedence over dllimport if both are specified. 482__attribute__((dllimport, dllexport)) extern int PrecedenceExternGlobal1A; // expected-warning{{'dllimport' attribute ignored}} 483__declspec(dllimport) __declspec(dllexport) extern int PrecedenceExternGlobal1B; // expected-warning{{'dllimport' attribute ignored}} 484 485__attribute__((dllexport, dllimport)) extern int PrecedenceExternGlobal2A; // expected-warning{{'dllimport' attribute ignored}} 486__declspec(dllexport) __declspec(dllimport) extern int PrecedenceExternGlobal2B; // expected-warning{{'dllimport' attribute ignored}} 487 488__attribute__((dllimport, dllexport)) int PrecedenceGlobal1A; // expected-warning{{'dllimport' attribute ignored}} 489__declspec(dllimport) __declspec(dllexport) int PrecedenceGlobal1B; // expected-warning{{'dllimport' attribute ignored}} 490 491__attribute__((dllexport, dllimport)) int PrecedenceGlobal2A; // expected-warning{{'dllimport' attribute ignored}} 492__declspec(dllexport) __declspec(dllimport) int PrecedenceGlobal2B; // expected-warning{{'dllimport' attribute ignored}} 493 494__declspec(dllexport) extern int PrecedenceExternGlobalRedecl1; 495__declspec(dllimport) extern int PrecedenceExternGlobalRedecl1; // expected-warning{{'dllimport' attribute ignored}} 496 497__declspec(dllimport) extern int PrecedenceExternGlobalRedecl2; // expected-warning{{'dllimport' attribute ignored}} 498__declspec(dllexport) extern int PrecedenceExternGlobalRedecl2; 499 500__declspec(dllexport) extern int PrecedenceGlobalRedecl1; 501__declspec(dllimport) int PrecedenceGlobalRedecl1; // expected-warning{{'dllimport' attribute ignored}} 502 503__declspec(dllimport) extern int PrecedenceGlobalRedecl2; // expected-warning{{'dllimport' attribute ignored}} 504__declspec(dllexport) int PrecedenceGlobalRedecl2; 505 506void __attribute__((dllimport, dllexport)) precedence1A() {} // expected-warning{{'dllimport' attribute ignored}} 507void __declspec(dllimport) __declspec(dllexport) precedence1B() {} // expected-warning{{'dllimport' attribute ignored}} 508 509void __attribute__((dllexport, dllimport)) precedence2A() {} // expected-warning{{'dllimport' attribute ignored}} 510void __declspec(dllexport) __declspec(dllimport) precedence2B() {} // expected-warning{{'dllimport' attribute ignored}} 511 512void __declspec(dllimport) precedenceRedecl1(); // expected-warning{{'dllimport' attribute ignored}} 513void __declspec(dllexport) precedenceRedecl1() {} 514 515void __declspec(dllexport) precedenceRedecl2(); 516void __declspec(dllimport) precedenceRedecl2() {} // expected-warning{{'dllimport' attribute ignored}} 517 518 519 520//===----------------------------------------------------------------------===// 521// Class members 522//===----------------------------------------------------------------------===// 523 524// Export individual members of a class. 525struct ExportMembers { 526 struct Nested { 527 __declspec(dllexport) void normalDef(); 528 }; 529 530 __declspec(dllexport) void normalDecl(); 531 __declspec(dllexport) void normalDef(); 532 __declspec(dllexport) void normalInclass() {} 533 __declspec(dllexport) void normalInlineDef(); 534 __declspec(dllexport) inline void normalInlineDecl(); 535 __declspec(dllexport) virtual void virtualDecl(); 536 __declspec(dllexport) virtual void virtualDef(); 537 __declspec(dllexport) virtual void virtualInclass() {} 538 __declspec(dllexport) virtual void virtualInlineDef(); 539 __declspec(dllexport) virtual inline void virtualInlineDecl(); 540 __declspec(dllexport) static void staticDecl(); 541 __declspec(dllexport) static void staticDef(); 542 __declspec(dllexport) static void staticInclass() {} 543 __declspec(dllexport) static void staticInlineDef(); 544 __declspec(dllexport) static inline void staticInlineDecl(); 545 546protected: 547 __declspec(dllexport) void protectedDef(); 548private: 549 __declspec(dllexport) void privateDef(); 550public: 551 552 __declspec(dllexport) int Field; // expected-warning{{'dllexport' attribute only applies to variables, functions and classes}} 553 __declspec(dllexport) static int StaticField; 554 __declspec(dllexport) static int StaticFieldDef; 555 __declspec(dllexport) static const int StaticConstField; 556 __declspec(dllexport) static const int StaticConstFieldDef; 557 __declspec(dllexport) static const int StaticConstFieldEqualInit = 1; 558 __declspec(dllexport) static const int StaticConstFieldBraceInit{1}; 559 __declspec(dllexport) constexpr static int ConstexprField = 1; 560 __declspec(dllexport) constexpr static int ConstexprFieldDef = 1; 561}; 562 563 void ExportMembers::Nested::normalDef() {} 564 void ExportMembers::normalDef() {} 565inline void ExportMembers::normalInlineDef() {} 566 void ExportMembers::normalInlineDecl() {} 567 void ExportMembers::virtualDef() {} 568inline void ExportMembers::virtualInlineDef() {} 569 void ExportMembers::virtualInlineDecl() {} 570 void ExportMembers::staticDef() {} 571inline void ExportMembers::staticInlineDef() {} 572 void ExportMembers::staticInlineDecl() {} 573 void ExportMembers::protectedDef() {} 574 void ExportMembers::privateDef() {} 575 576 int ExportMembers::StaticFieldDef; 577const int ExportMembers::StaticConstFieldDef = 1; 578constexpr int ExportMembers::ConstexprFieldDef; 579 580 581// Export on member definitions. 582struct ExportMemberDefs { 583 __declspec(dllexport) void normalDef(); 584 __declspec(dllexport) void normalInlineDef(); 585 __declspec(dllexport) inline void normalInlineDecl(); 586 __declspec(dllexport) virtual void virtualDef(); 587 __declspec(dllexport) virtual void virtualInlineDef(); 588 __declspec(dllexport) virtual inline void virtualInlineDecl(); 589 __declspec(dllexport) static void staticDef(); 590 __declspec(dllexport) static void staticInlineDef(); 591 __declspec(dllexport) static inline void staticInlineDecl(); 592 593 __declspec(dllexport) static int StaticField; 594 __declspec(dllexport) static const int StaticConstField; 595 __declspec(dllexport) constexpr static int ConstexprField = 1; 596}; 597 598__declspec(dllexport) void ExportMemberDefs::normalDef() {} 599__declspec(dllexport) inline void ExportMemberDefs::normalInlineDef() {} 600__declspec(dllexport) void ExportMemberDefs::normalInlineDecl() {} 601__declspec(dllexport) void ExportMemberDefs::virtualDef() {} 602__declspec(dllexport) inline void ExportMemberDefs::virtualInlineDef() {} 603__declspec(dllexport) void ExportMemberDefs::virtualInlineDecl() {} 604__declspec(dllexport) void ExportMemberDefs::staticDef() {} 605__declspec(dllexport) inline void ExportMemberDefs::staticInlineDef() {} 606__declspec(dllexport) void ExportMemberDefs::staticInlineDecl() {} 607 608__declspec(dllexport) int ExportMemberDefs::StaticField; 609__declspec(dllexport) const int ExportMemberDefs::StaticConstField = 1; 610__declspec(dllexport) constexpr int ExportMemberDefs::ConstexprField; 611 612 613// Export special member functions. 614struct ExportSpecials { 615 __declspec(dllexport) ExportSpecials() {} 616 __declspec(dllexport) ~ExportSpecials(); 617 __declspec(dllexport) inline ExportSpecials(const ExportSpecials&); 618 __declspec(dllexport) ExportSpecials& operator=(const ExportSpecials&); 619 __declspec(dllexport) ExportSpecials(ExportSpecials&&); 620 __declspec(dllexport) ExportSpecials& operator=(ExportSpecials&&); 621}; 622 623ExportSpecials::~ExportSpecials() {} 624ExportSpecials::ExportSpecials(const ExportSpecials&) {} 625inline ExportSpecials& ExportSpecials::operator=(const ExportSpecials&) { return *this; } 626ExportSpecials::ExportSpecials(ExportSpecials&&) {} 627ExportSpecials& ExportSpecials::operator=(ExportSpecials&&) { return *this; } 628 629 630// Export allocation functions. 631extern "C" void* malloc(__SIZE_TYPE__ size); 632extern "C" void free(void* p); 633struct ExportAlloc { 634 __declspec(dllexport) void* operator new(__SIZE_TYPE__); 635 __declspec(dllexport) void* operator new[](__SIZE_TYPE__); 636 __declspec(dllexport) void operator delete(void*); 637 __declspec(dllexport) void operator delete[](void*); 638}; 639void* ExportAlloc::operator new(__SIZE_TYPE__ n) { return malloc(n); } 640void* ExportAlloc::operator new[](__SIZE_TYPE__ n) { return malloc(n); } 641void ExportAlloc::operator delete(void* p) { free(p); } 642void ExportAlloc::operator delete[](void* p) { free(p); } 643 644 645// Export deleted member functions. 646struct ExportDeleted { 647 __declspec(dllexport) ExportDeleted() = delete; // expected-error{{attribute 'dllexport' cannot be applied to a deleted function}} 648 __declspec(dllexport) ~ExportDeleted() = delete; // expected-error{{attribute 'dllexport' cannot be applied to a deleted function}} 649 __declspec(dllexport) ExportDeleted(const ExportDeleted&) = delete; // expected-error{{attribute 'dllexport' cannot be applied to a deleted function}} 650 __declspec(dllexport) ExportDeleted& operator=(const ExportDeleted&) = delete; // expected-error{{attribute 'dllexport' cannot be applied to a deleted function}} 651 __declspec(dllexport) ExportDeleted(ExportDeleted&&) = delete; // expected-error{{attribute 'dllexport' cannot be applied to a deleted function}} 652 __declspec(dllexport) ExportDeleted& operator=(ExportDeleted&&) = delete; // expected-error{{attribute 'dllexport' cannot be applied to a deleted function}} 653 __declspec(dllexport) void deleted() = delete; // expected-error{{attribute 'dllexport' cannot be applied to a deleted function}} 654}; 655 656 657// Export defaulted member functions. 658struct ExportDefaulted { 659 __declspec(dllexport) ExportDefaulted() = default; 660 __declspec(dllexport) ~ExportDefaulted() = default; 661 __declspec(dllexport) ExportDefaulted(const ExportDefaulted&) = default; 662 __declspec(dllexport) ExportDefaulted& operator=(const ExportDefaulted&) = default; 663 __declspec(dllexport) ExportDefaulted(ExportDefaulted&&) = default; 664 __declspec(dllexport) ExportDefaulted& operator=(ExportDefaulted&&) = default; 665}; 666 667 668// Export defaulted member function definitions. 669struct ExportDefaultedDefs { 670 __declspec(dllexport) ExportDefaultedDefs(); 671 __declspec(dllexport) ~ExportDefaultedDefs(); 672 673 __declspec(dllexport) inline ExportDefaultedDefs(const ExportDefaultedDefs&); 674 __declspec(dllexport) ExportDefaultedDefs& operator=(const ExportDefaultedDefs&); 675 676 __declspec(dllexport) ExportDefaultedDefs(ExportDefaultedDefs&&); 677 __declspec(dllexport) ExportDefaultedDefs& operator=(ExportDefaultedDefs&&); 678}; 679 680// Export definitions. 681__declspec(dllexport) ExportDefaultedDefs::ExportDefaultedDefs() = default; 682ExportDefaultedDefs::~ExportDefaultedDefs() = default; 683 684// Export inline declaration and definition. 685__declspec(dllexport) ExportDefaultedDefs::ExportDefaultedDefs(const ExportDefaultedDefs&) = default; 686inline ExportDefaultedDefs& ExportDefaultedDefs::operator=(const ExportDefaultedDefs&) = default; 687 688__declspec(dllexport) ExportDefaultedDefs::ExportDefaultedDefs(ExportDefaultedDefs&&) = default; 689ExportDefaultedDefs& ExportDefaultedDefs::operator=(ExportDefaultedDefs&&) = default; 690 691 692// Redeclarations cannot add dllexport. 693struct MemberRedecl { 694 void normalDef(); // expected-note{{previous declaration is here}} 695 void normalInlineDef(); // expected-note{{previous declaration is here}} 696 inline void normalInlineDecl(); // expected-note{{previous declaration is here}} 697 virtual void virtualDef(); // expected-note{{previous declaration is here}} 698 virtual void virtualInlineDef(); // expected-note{{previous declaration is here}} 699 virtual inline void virtualInlineDecl(); // expected-note{{previous declaration is here}} 700 static void staticDef(); // expected-note{{previous declaration is here}} 701 static void staticInlineDef(); // expected-note{{previous declaration is here}} 702 static inline void staticInlineDecl(); // expected-note{{previous declaration is here}} 703 704 static int StaticField; // expected-note{{previous declaration is here}} 705 static const int StaticConstField; // expected-note{{previous declaration is here}} 706 constexpr static int ConstexprField = 1; // expected-note{{previous declaration is here}} 707}; 708 709__declspec(dllexport) void MemberRedecl::normalDef() {} // expected-error{{redeclaration of 'MemberRedecl::normalDef' cannot add 'dllexport' attribute}} 710__declspec(dllexport) inline void MemberRedecl::normalInlineDef() {} // expected-error{{redeclaration of 'MemberRedecl::normalInlineDef' cannot add 'dllexport' attribute}} 711__declspec(dllexport) void MemberRedecl::normalInlineDecl() {} // expected-error{{redeclaration of 'MemberRedecl::normalInlineDecl' cannot add 'dllexport' attribute}} 712__declspec(dllexport) void MemberRedecl::virtualDef() {} // expected-error{{redeclaration of 'MemberRedecl::virtualDef' cannot add 'dllexport' attribute}} 713__declspec(dllexport) inline void MemberRedecl::virtualInlineDef() {} // expected-error{{redeclaration of 'MemberRedecl::virtualInlineDef' cannot add 'dllexport' attribute}} 714__declspec(dllexport) void MemberRedecl::virtualInlineDecl() {} // expected-error{{redeclaration of 'MemberRedecl::virtualInlineDecl' cannot add 'dllexport' attribute}} 715__declspec(dllexport) void MemberRedecl::staticDef() {} // expected-error{{redeclaration of 'MemberRedecl::staticDef' cannot add 'dllexport' attribute}} 716__declspec(dllexport) inline void MemberRedecl::staticInlineDef() {} // expected-error{{redeclaration of 'MemberRedecl::staticInlineDef' cannot add 'dllexport' attribute}} 717__declspec(dllexport) void MemberRedecl::staticInlineDecl() {} // expected-error{{redeclaration of 'MemberRedecl::staticInlineDecl' cannot add 'dllexport' attribute}} 718 719__declspec(dllexport) int MemberRedecl::StaticField = 1; // expected-error{{redeclaration of 'MemberRedecl::StaticField' cannot add 'dllexport' attribute}} 720__declspec(dllexport) const int MemberRedecl::StaticConstField = 1; // expected-error{{redeclaration of 'MemberRedecl::StaticConstField' cannot add 'dllexport' attribute}} 721__declspec(dllexport) constexpr int MemberRedecl::ConstexprField; // expected-error{{redeclaration of 'MemberRedecl::ConstexprField' cannot add 'dllexport' attribute}} 722 723 724 725//===----------------------------------------------------------------------===// 726// Class member templates 727//===----------------------------------------------------------------------===// 728 729struct ExportMemberTmpl { 730 template<typename T> __declspec(dllexport) void normalDecl(); 731 template<typename T> __declspec(dllexport) void normalDef(); 732 template<typename T> __declspec(dllexport) void normalInclass() {} 733 template<typename T> __declspec(dllexport) void normalInlineDef(); 734 template<typename T> __declspec(dllexport) inline void normalInlineDecl(); 735 template<typename T> __declspec(dllexport) static void staticDecl(); 736 template<typename T> __declspec(dllexport) static void staticDef(); 737 template<typename T> __declspec(dllexport) static void staticInclass() {} 738 template<typename T> __declspec(dllexport) static void staticInlineDef(); 739 template<typename T> __declspec(dllexport) static inline void staticInlineDecl(); 740 741#if __has_feature(cxx_variable_templates) 742 template<typename T> __declspec(dllexport) static int StaticField; 743 template<typename T> __declspec(dllexport) static int StaticFieldDef; 744 template<typename T> __declspec(dllexport) static const int StaticConstField; 745 template<typename T> __declspec(dllexport) static const int StaticConstFieldDef; 746 template<typename T> __declspec(dllexport) static const int StaticConstFieldEqualInit = 1; 747 template<typename T> __declspec(dllexport) static const int StaticConstFieldBraceInit{1}; 748 template<typename T> __declspec(dllexport) constexpr static int ConstexprField = 1; 749 template<typename T> __declspec(dllexport) constexpr static int ConstexprFieldDef = 1; 750#endif // __has_feature(cxx_variable_templates) 751}; 752 753template<typename T> void ExportMemberTmpl::normalDef() {} 754template<typename T> inline void ExportMemberTmpl::normalInlineDef() {} 755template<typename T> void ExportMemberTmpl::normalInlineDecl() {} 756template<typename T> void ExportMemberTmpl::staticDef() {} 757template<typename T> inline void ExportMemberTmpl::staticInlineDef() {} 758template<typename T> void ExportMemberTmpl::staticInlineDecl() {} 759 760#if __has_feature(cxx_variable_templates) 761template<typename T> int ExportMemberTmpl::StaticFieldDef; 762template<typename T> const int ExportMemberTmpl::StaticConstFieldDef = 1; 763template<typename T> constexpr int ExportMemberTmpl::ConstexprFieldDef; 764#endif // __has_feature(cxx_variable_templates) 765 766 767// Redeclarations cannot add dllexport. 768struct MemTmplRedecl { 769 template<typename T> void normalDef(); // expected-note{{previous declaration is here}} 770 template<typename T> void normalInlineDef(); // expected-note{{previous declaration is here}} 771 template<typename T> inline void normalInlineDecl(); // expected-note{{previous declaration is here}} 772 template<typename T> static void staticDef(); // expected-note{{previous declaration is here}} 773 template<typename T> static void staticInlineDef(); // expected-note{{previous declaration is here}} 774 template<typename T> static inline void staticInlineDecl(); // expected-note{{previous declaration is here}} 775 776#if __has_feature(cxx_variable_templates) 777 template<typename T> static int StaticField; // expected-note{{previous declaration is here}} 778 template<typename T> static const int StaticConstField; // expected-note{{previous declaration is here}} 779 template<typename T> constexpr static int ConstexprField = 1; // expected-note{{previous declaration is here}} 780#endif // __has_feature(cxx_variable_templates) 781}; 782 783template<typename T> __declspec(dllexport) void MemTmplRedecl::normalDef() {} // expected-error{{redeclaration of 'MemTmplRedecl::normalDef' cannot add 'dllexport' attribute}} 784template<typename T> __declspec(dllexport) inline void MemTmplRedecl::normalInlineDef() {} // expected-error{{redeclaration of 'MemTmplRedecl::normalInlineDef' cannot add 'dllexport' attribute}} 785template<typename T> __declspec(dllexport) void MemTmplRedecl::normalInlineDecl() {} // expected-error{{redeclaration of 'MemTmplRedecl::normalInlineDecl' cannot add 'dllexport' attribute}} 786template<typename T> __declspec(dllexport) void MemTmplRedecl::staticDef() {} // expected-error{{redeclaration of 'MemTmplRedecl::staticDef' cannot add 'dllexport' attribute}} 787template<typename T> __declspec(dllexport) inline void MemTmplRedecl::staticInlineDef() {} // expected-error{{redeclaration of 'MemTmplRedecl::staticInlineDef' cannot add 'dllexport' attribute}} 788template<typename T> __declspec(dllexport) void MemTmplRedecl::staticInlineDecl() {} // expected-error{{redeclaration of 'MemTmplRedecl::staticInlineDecl' cannot add 'dllexport' attribute}} 789 790#if __has_feature(cxx_variable_templates) 791template<typename T> __declspec(dllexport) int MemTmplRedecl::StaticField = 1; // expected-error{{redeclaration of 'MemTmplRedecl::StaticField' cannot add 'dllexport' attribute}} 792template<typename T> __declspec(dllexport) const int MemTmplRedecl::StaticConstField = 1; // expected-error{{redeclaration of 'MemTmplRedecl::StaticConstField' cannot add 'dllexport' attribute}} 793template<typename T> __declspec(dllexport) constexpr int MemTmplRedecl::ConstexprField; // expected-error{{redeclaration of 'MemTmplRedecl::ConstexprField' cannot add 'dllexport' attribute}} 794#endif // __has_feature(cxx_variable_templates) 795 796 797 798struct MemFunTmpl { 799 template<typename T> void normalDef() {} 800 template<typename T> __declspec(dllexport) void exportedNormal() {} 801 template<typename T> static void staticDef() {} 802 template<typename T> __declspec(dllexport) static void exportedStatic() {} 803}; 804 805// Export implicit instantiation of an exported member function template. 806void useMemFunTmpl() { 807 MemFunTmpl().exportedNormal<ImplicitInst_Exported>(); 808 MemFunTmpl().exportedStatic<ImplicitInst_Exported>(); 809} 810 811// Export explicit instantiation declaration of an exported member function 812// template. 813extern template void MemFunTmpl::exportedNormal<ExplicitDecl_Exported>(); 814 template void MemFunTmpl::exportedNormal<ExplicitDecl_Exported>(); 815 816extern template void MemFunTmpl::exportedStatic<ExplicitDecl_Exported>(); 817 template void MemFunTmpl::exportedStatic<ExplicitDecl_Exported>(); 818 819// Export explicit instantiation definition of an exported member function 820// template. 821template void MemFunTmpl::exportedNormal<ExplicitInst_Exported>(); 822template void MemFunTmpl::exportedStatic<ExplicitInst_Exported>(); 823 824// Export specialization of an exported member function template. 825template<> __declspec(dllexport) void MemFunTmpl::exportedNormal<ExplicitSpec_Exported>(); 826template<> __declspec(dllexport) void MemFunTmpl::exportedNormal<ExplicitSpec_Def_Exported>() {} 827template<> __declspec(dllexport) inline void MemFunTmpl::exportedNormal<ExplicitSpec_InlineDef_Exported>() {} 828 829template<> __declspec(dllexport) void MemFunTmpl::exportedStatic<ExplicitSpec_Exported>(); 830template<> __declspec(dllexport) void MemFunTmpl::exportedStatic<ExplicitSpec_Def_Exported>() {} 831template<> __declspec(dllexport) inline void MemFunTmpl::exportedStatic<ExplicitSpec_InlineDef_Exported>() {} 832 833// Not exporting specialization of an exported member function template without 834// explicit dllexport. 835template<> void MemFunTmpl::exportedNormal<ExplicitSpec_NotExported>() {} 836template<> void MemFunTmpl::exportedStatic<ExplicitSpec_NotExported>() {} 837 838 839// Export explicit instantiation declaration of a non-exported member function 840// template. 841extern template __declspec(dllexport) void MemFunTmpl::normalDef<ExplicitDecl_Exported>(); 842 template __declspec(dllexport) void MemFunTmpl::normalDef<ExplicitDecl_Exported>(); 843 844extern template __declspec(dllexport) void MemFunTmpl::staticDef<ExplicitDecl_Exported>(); 845 template __declspec(dllexport) void MemFunTmpl::staticDef<ExplicitDecl_Exported>(); 846 847// Export explicit instantiation definition of a non-exported member function 848// template. 849template __declspec(dllexport) void MemFunTmpl::normalDef<ExplicitInst_Exported>(); 850template __declspec(dllexport) void MemFunTmpl::staticDef<ExplicitInst_Exported>(); 851 852// Export specialization of a non-exported member function template. 853template<> __declspec(dllexport) void MemFunTmpl::normalDef<ExplicitSpec_Exported>(); 854template<> __declspec(dllexport) void MemFunTmpl::normalDef<ExplicitSpec_Def_Exported>() {} 855template<> __declspec(dllexport) inline void MemFunTmpl::normalDef<ExplicitSpec_InlineDef_Exported>() {} 856 857template<> __declspec(dllexport) void MemFunTmpl::staticDef<ExplicitSpec_Exported>(); 858template<> __declspec(dllexport) void MemFunTmpl::staticDef<ExplicitSpec_Def_Exported>() {} 859template<> __declspec(dllexport) inline void MemFunTmpl::staticDef<ExplicitSpec_InlineDef_Exported>() {} 860 861 862 863#if __has_feature(cxx_variable_templates) 864struct MemVarTmpl { 865 template<typename T> static const int StaticVar = 1; 866 template<typename T> __declspec(dllexport) static const int ExportedStaticVar = 1; 867}; 868template<typename T> const int MemVarTmpl::StaticVar; 869template<typename T> const int MemVarTmpl::ExportedStaticVar; 870 871// Export implicit instantiation of an exported member variable template. 872int useMemVarTmpl() { return MemVarTmpl::ExportedStaticVar<ImplicitInst_Exported>; } 873 874// Export explicit instantiation declaration of an exported member variable 875// template. 876extern template const int MemVarTmpl::ExportedStaticVar<ExplicitDecl_Exported>; 877 template const int MemVarTmpl::ExportedStaticVar<ExplicitDecl_Exported>; 878 879// Export explicit instantiation definition of an exported member variable 880// template. 881template const int MemVarTmpl::ExportedStaticVar<ExplicitInst_Exported>; 882 883// Export specialization of an exported member variable template. 884template<> __declspec(dllexport) const int MemVarTmpl::ExportedStaticVar<ExplicitSpec_Exported>; 885template<> __declspec(dllexport) const int MemVarTmpl::ExportedStaticVar<ExplicitSpec_Def_Exported> = 1; 886 887// Not exporting specialization of an exported member variable template without 888// explicit dllexport. 889template<> const int MemVarTmpl::ExportedStaticVar<ExplicitSpec_NotExported>; 890 891 892// Export explicit instantiation declaration of a non-exported member variable 893// template. 894extern template __declspec(dllexport) const int MemVarTmpl::StaticVar<ExplicitDecl_Exported>; 895 template __declspec(dllexport) const int MemVarTmpl::StaticVar<ExplicitDecl_Exported>; 896 897// Export explicit instantiation definition of a non-exported member variable 898// template. 899template __declspec(dllexport) const int MemVarTmpl::StaticVar<ExplicitInst_Exported>; 900 901// Export specialization of a non-exported member variable template. 902template<> __declspec(dllexport) const int MemVarTmpl::StaticVar<ExplicitSpec_Exported>; 903template<> __declspec(dllexport) const int MemVarTmpl::StaticVar<ExplicitSpec_Def_Exported> = 1; 904 905#endif // __has_feature(cxx_variable_templates) 906 907 908 909//===----------------------------------------------------------------------===// 910// Class template members 911//===----------------------------------------------------------------------===// 912 913// Export individual members of a class template. 914template<typename T> 915struct ExportClassTmplMembers { 916 __declspec(dllexport) void normalDecl(); 917 __declspec(dllexport) void normalDef(); 918 __declspec(dllexport) void normalInclass() {} 919 __declspec(dllexport) void normalInlineDef(); 920 __declspec(dllexport) inline void normalInlineDecl(); 921 __declspec(dllexport) virtual void virtualDecl(); 922 __declspec(dllexport) virtual void virtualDef(); 923 __declspec(dllexport) virtual void virtualInclass() {} 924 __declspec(dllexport) virtual void virtualInlineDef(); 925 __declspec(dllexport) virtual inline void virtualInlineDecl(); 926 __declspec(dllexport) static void staticDecl(); 927 __declspec(dllexport) static void staticDef(); 928 __declspec(dllexport) static void staticInclass() {} 929 __declspec(dllexport) static void staticInlineDef(); 930 __declspec(dllexport) static inline void staticInlineDecl(); 931 932protected: 933 __declspec(dllexport) void protectedDef(); 934private: 935 __declspec(dllexport) void privateDef(); 936public: 937 938 __declspec(dllexport) int Field; // expected-warning{{'dllexport' attribute only applies to variables, functions and classes}} 939 __declspec(dllexport) static int StaticField; 940 __declspec(dllexport) static int StaticFieldDef; 941 __declspec(dllexport) static const int StaticConstField; 942 __declspec(dllexport) static const int StaticConstFieldDef; 943 __declspec(dllexport) static const int StaticConstFieldEqualInit = 1; 944 __declspec(dllexport) static const int StaticConstFieldBraceInit{1}; 945 __declspec(dllexport) constexpr static int ConstexprField = 1; 946 __declspec(dllexport) constexpr static int ConstexprFieldDef = 1; 947}; 948 949template<typename T> void ExportClassTmplMembers<T>::normalDef() {} 950template<typename T> inline void ExportClassTmplMembers<T>::normalInlineDef() {} 951template<typename T> void ExportClassTmplMembers<T>::normalInlineDecl() {} 952template<typename T> void ExportClassTmplMembers<T>::virtualDef() {} 953template<typename T> inline void ExportClassTmplMembers<T>::virtualInlineDef() {} 954template<typename T> void ExportClassTmplMembers<T>::virtualInlineDecl() {} 955template<typename T> void ExportClassTmplMembers<T>::staticDef() {} 956template<typename T> inline void ExportClassTmplMembers<T>::staticInlineDef() {} 957template<typename T> void ExportClassTmplMembers<T>::staticInlineDecl() {} 958template<typename T> void ExportClassTmplMembers<T>::protectedDef() {} 959template<typename T> void ExportClassTmplMembers<T>::privateDef() {} 960 961template<typename T> int ExportClassTmplMembers<T>::StaticFieldDef; 962template<typename T> const int ExportClassTmplMembers<T>::StaticConstFieldDef = 1; 963template<typename T> constexpr int ExportClassTmplMembers<T>::ConstexprFieldDef; 964 965template struct ExportClassTmplMembers<ImplicitInst_Exported>; 966 967 968// Redeclarations cannot add dllexport. 969template<typename T> 970struct CTMR /*ClassTmplMemberRedecl*/ { 971 void normalDef(); // expected-note{{previous declaration is here}} 972 void normalInlineDef(); // expected-note{{previous declaration is here}} 973 inline void normalInlineDecl(); // expected-note{{previous declaration is here}} 974 virtual void virtualDef(); // expected-note{{previous declaration is here}} 975 virtual void virtualInlineDef(); // expected-note{{previous declaration is here}} 976 virtual inline void virtualInlineDecl(); // expected-note{{previous declaration is here}} 977 static void staticDef(); // expected-note{{previous declaration is here}} 978 static void staticInlineDef(); // expected-note{{previous declaration is here}} 979 static inline void staticInlineDecl(); // expected-note{{previous declaration is here}} 980 981 static int StaticField; // expected-note{{previous declaration is here}} 982 static const int StaticConstField; // expected-note{{previous declaration is here}} 983 constexpr static int ConstexprField = 1; // expected-note{{previous declaration is here}} 984}; 985 986template<typename T> __declspec(dllexport) void CTMR<T>::normalDef() {} // expected-error{{redeclaration of 'CTMR::normalDef' cannot add 'dllexport' attribute}} 987template<typename T> __declspec(dllexport) inline void CTMR<T>::normalInlineDef() {} // expected-error{{redeclaration of 'CTMR::normalInlineDef' cannot add 'dllexport' attribute}} 988template<typename T> __declspec(dllexport) void CTMR<T>::normalInlineDecl() {} // expected-error{{redeclaration of 'CTMR::normalInlineDecl' cannot add 'dllexport' attribute}} 989template<typename T> __declspec(dllexport) void CTMR<T>::virtualDef() {} // expected-error{{redeclaration of 'CTMR::virtualDef' cannot add 'dllexport' attribute}} 990template<typename T> __declspec(dllexport) inline void CTMR<T>::virtualInlineDef() {} // expected-error{{redeclaration of 'CTMR::virtualInlineDef' cannot add 'dllexport' attribute}} 991template<typename T> __declspec(dllexport) void CTMR<T>::virtualInlineDecl() {} // expected-error{{redeclaration of 'CTMR::virtualInlineDecl' cannot add 'dllexport' attribute}} 992template<typename T> __declspec(dllexport) void CTMR<T>::staticDef() {} // expected-error{{redeclaration of 'CTMR::staticDef' cannot add 'dllexport' attribute}} 993template<typename T> __declspec(dllexport) inline void CTMR<T>::staticInlineDef() {} // expected-error{{redeclaration of 'CTMR::staticInlineDef' cannot add 'dllexport' attribute}} 994template<typename T> __declspec(dllexport) void CTMR<T>::staticInlineDecl() {} // expected-error{{redeclaration of 'CTMR::staticInlineDecl' cannot add 'dllexport' attribute}} 995 996template<typename T> __declspec(dllexport) int CTMR<T>::StaticField = 1; // expected-error{{redeclaration of 'CTMR::StaticField' cannot add 'dllexport' attribute}} 997template<typename T> __declspec(dllexport) const int CTMR<T>::StaticConstField = 1; // expected-error{{redeclaration of 'CTMR::StaticConstField' cannot add 'dllexport' attribute}} 998template<typename T> __declspec(dllexport) constexpr int CTMR<T>::ConstexprField; // expected-error{{redeclaration of 'CTMR::ConstexprField' cannot add 'dllexport' attribute}} 999 1000 1001 1002//===----------------------------------------------------------------------===// 1003// Class template member templates 1004//===----------------------------------------------------------------------===// 1005 1006template<typename T> 1007struct ExportClsTmplMemTmpl { 1008 template<typename U> __declspec(dllexport) void normalDecl(); 1009 template<typename U> __declspec(dllexport) void normalDef(); 1010 template<typename U> __declspec(dllexport) void normalInclass() {} 1011 template<typename U> __declspec(dllexport) void normalInlineDef(); 1012 template<typename U> __declspec(dllexport) inline void normalInlineDecl(); 1013 template<typename U> __declspec(dllexport) static void staticDecl(); 1014 template<typename U> __declspec(dllexport) static void staticDef(); 1015 template<typename U> __declspec(dllexport) static void staticInclass() {} 1016 template<typename U> __declspec(dllexport) static void staticInlineDef(); 1017 template<typename U> __declspec(dllexport) static inline void staticInlineDecl(); 1018 1019#if __has_feature(cxx_variable_templates) 1020 template<typename U> __declspec(dllexport) static int StaticField; 1021 template<typename U> __declspec(dllexport) static int StaticFieldDef; 1022 template<typename U> __declspec(dllexport) static const int StaticConstField; 1023 template<typename U> __declspec(dllexport) static const int StaticConstFieldDef; 1024 template<typename U> __declspec(dllexport) static const int StaticConstFieldEqualInit = 1; 1025 template<typename U> __declspec(dllexport) static const int StaticConstFieldBraceInit{1}; 1026 template<typename U> __declspec(dllexport) constexpr static int ConstexprField = 1; 1027 template<typename U> __declspec(dllexport) constexpr static int ConstexprFieldDef = 1; 1028#endif // __has_feature(cxx_variable_templates) 1029}; 1030 1031template<typename T> template<typename U> void ExportClsTmplMemTmpl<T>::normalDef() {} 1032template<typename T> template<typename U> inline void ExportClsTmplMemTmpl<T>::normalInlineDef() {} 1033template<typename T> template<typename U> void ExportClsTmplMemTmpl<T>::normalInlineDecl() {} 1034template<typename T> template<typename U> void ExportClsTmplMemTmpl<T>::staticDef() {} 1035template<typename T> template<typename U> inline void ExportClsTmplMemTmpl<T>::staticInlineDef() {} 1036template<typename T> template<typename U> void ExportClsTmplMemTmpl<T>::staticInlineDecl() {} 1037 1038#if __has_feature(cxx_variable_templates) 1039template<typename T> template<typename U> int ExportClsTmplMemTmpl<T>::StaticFieldDef; 1040template<typename T> template<typename U> const int ExportClsTmplMemTmpl<T>::StaticConstFieldDef = 1; 1041template<typename T> template<typename U> constexpr int ExportClsTmplMemTmpl<T>::ConstexprFieldDef; 1042#endif // __has_feature(cxx_variable_templates) 1043 1044 1045// Redeclarations cannot add dllexport. 1046template<typename T> 1047struct CTMTR /*ClassTmplMemberTmplRedecl*/ { 1048 template<typename U> void normalDef(); // expected-note{{previous declaration is here}} 1049 template<typename U> void normalInlineDef(); // expected-note{{previous declaration is here}} 1050 template<typename U> inline void normalInlineDecl(); // expected-note{{previous declaration is here}} 1051 template<typename U> static void staticDef(); // expected-note{{previous declaration is here}} 1052 template<typename U> static void staticInlineDef(); // expected-note{{previous declaration is here}} 1053 template<typename U> static inline void staticInlineDecl(); // expected-note{{previous declaration is here}} 1054 1055#if __has_feature(cxx_variable_templates) 1056 template<typename U> static int StaticField; // expected-note{{previous declaration is here}} 1057 template<typename U> static const int StaticConstField; // expected-note{{previous declaration is here}} 1058 template<typename U> constexpr static int ConstexprField = 1; // expected-note{{previous declaration is here}} 1059#endif // __has_feature(cxx_variable_templates) 1060}; 1061 1062template<typename T> template<typename U> __declspec(dllexport) void CTMTR<T>::normalDef() {} // expected-error{{redeclaration of 'CTMTR::normalDef' cannot add 'dllexport' attribute}} 1063template<typename T> template<typename U> __declspec(dllexport) inline void CTMTR<T>::normalInlineDef() {} // expected-error{{redeclaration of 'CTMTR::normalInlineDef' cannot add 'dllexport' attribute}} 1064template<typename T> template<typename U> __declspec(dllexport) void CTMTR<T>::normalInlineDecl() {} // expected-error{{redeclaration of 'CTMTR::normalInlineDecl' cannot add 'dllexport' attribute}} 1065template<typename T> template<typename U> __declspec(dllexport) void CTMTR<T>::staticDef() {} // expected-error{{redeclaration of 'CTMTR::staticDef' cannot add 'dllexport' attribute}} 1066template<typename T> template<typename U> __declspec(dllexport) inline void CTMTR<T>::staticInlineDef() {} // expected-error{{redeclaration of 'CTMTR::staticInlineDef' cannot add 'dllexport' attribute}} 1067template<typename T> template<typename U> __declspec(dllexport) void CTMTR<T>::staticInlineDecl() {} // expected-error{{redeclaration of 'CTMTR::staticInlineDecl' cannot add 'dllexport' attribute}} 1068 1069#if __has_feature(cxx_variable_templates) 1070template<typename T> template<typename U> __declspec(dllexport) int CTMTR<T>::StaticField = 1; // expected-error{{redeclaration of 'CTMTR::StaticField' cannot add 'dllexport' attribute}} 1071template<typename T> template<typename U> __declspec(dllexport) const int CTMTR<T>::StaticConstField = 1; // expected-error{{redeclaration of 'CTMTR::StaticConstField' cannot add 'dllexport' attribute}} 1072template<typename T> template<typename U> __declspec(dllexport) constexpr int CTMTR<T>::ConstexprField; // expected-error{{redeclaration of 'CTMTR::ConstexprField' cannot add 'dllexport' attribute}} 1073#endif // __has_feature(cxx_variable_templates) 1074 1075// FIXME: Precedence rules seem to be different for classes. 1076