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