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