// RUN: %clang_cc1 -triple i686-win32 -fsyntax-only -verify -std=c++11 -Wunsupported-dll-base-class-template -DMS %s // RUN: %clang_cc1 -triple x86_64-win32 -fsyntax-only -verify -std=c++1y -Wunsupported-dll-base-class-template -DMS %s // RUN: %clang_cc1 -triple i686-mingw32 -fsyntax-only -verify -std=c++1y -Wunsupported-dll-base-class-template %s // RUN: %clang_cc1 -triple x86_64-mingw32 -fsyntax-only -verify -std=c++11 -Wunsupported-dll-base-class-template %s // Helper structs to make templates more expressive. struct ImplicitInst_Exported {}; struct ExplicitDecl_Exported {}; struct ExplicitInst_Exported {}; struct ExplicitSpec_Exported {}; struct ExplicitSpec_Def_Exported {}; struct ExplicitSpec_InlineDef_Exported {}; struct ExplicitSpec_NotExported {}; namespace { struct Internal {}; } struct External { int v; }; // Invalid usage. __declspec(dllexport) typedef int typedef1; // expected-warning{{'dllexport' attribute only applies to variables, functions and classes}} typedef __declspec(dllexport) int typedef2; // expected-warning{{'dllexport' attribute only applies to variables, functions and classes}} typedef int __declspec(dllexport) typedef3; // expected-warning{{'dllexport' attribute only applies to variables, functions and classes}} typedef __declspec(dllexport) void (*FunTy)(); // expected-warning{{'dllexport' attribute only applies to variables, functions and classes}} enum __declspec(dllexport) Enum {}; // expected-warning{{'dllexport' attribute only applies to variables, functions and classes}} #if __has_feature(cxx_strong_enums) enum class __declspec(dllexport) EnumClass {}; // expected-warning{{'dllexport' attribute only applies to variables, functions and classes}} #endif //===----------------------------------------------------------------------===// // Globals //===----------------------------------------------------------------------===// // Export declaration. __declspec(dllexport) extern int ExternGlobalDecl; // dllexport implies a definition. __declspec(dllexport) int GlobalDef; // Export definition. __declspec(dllexport) int GlobalInit1 = 1; int __declspec(dllexport) GlobalInit2 = 1; // Declare, then export definition. __declspec(dllexport) extern int GlobalDeclInit; int GlobalDeclInit = 1; // Redeclarations __declspec(dllexport) extern int GlobalRedecl1; __declspec(dllexport) int GlobalRedecl1; __declspec(dllexport) extern int GlobalRedecl2; int GlobalRedecl2; extern int GlobalRedecl3; // expected-note{{previous declaration is here}} __declspec(dllexport) extern int GlobalRedecl3; // expected-warning{{redeclaration of 'GlobalRedecl3' should not add 'dllexport' attribute}} extern "C" { extern int GlobalRedecl4; // expected-note{{previous declaration is here}} __declspec(dllexport) extern int GlobalRedecl4; // expected-warning{{redeclaration of 'GlobalRedecl4' should not add 'dllexport' attribute}} } // External linkage is required. __declspec(dllexport) static int StaticGlobal; // expected-error{{'StaticGlobal' must have external linkage when declared 'dllexport'}} __declspec(dllexport) Internal InternalTypeGlobal; // expected-error{{'InternalTypeGlobal' must have external linkage when declared 'dllexport'}} namespace { __declspec(dllexport) int InternalGlobal; } // expected-error{{'(anonymous namespace)::InternalGlobal' must have external linkage when declared 'dllexport'}} namespace ns { __declspec(dllexport) int ExternalGlobal; } __declspec(dllexport) auto InternalAutoTypeGlobal = Internal(); // expected-error{{'InternalAutoTypeGlobal' must have external linkage when declared 'dllexport'}} __declspec(dllexport) auto ExternalAutoTypeGlobal = External(); // Thread local variables are invalid. __declspec(dllexport) __thread int ThreadLocalGlobal; // expected-error{{'ThreadLocalGlobal' cannot be thread local when declared 'dllexport'}} // Export in local scope. void functionScope() { __declspec(dllexport) int LocalVarDecl; // expected-error{{'LocalVarDecl' must have external linkage when declared 'dllexport'}} __declspec(dllexport) int LocalVarDef = 1; // expected-error{{'LocalVarDef' must have external linkage when declared 'dllexport'}} __declspec(dllexport) extern int ExternLocalVarDecl; __declspec(dllexport) static int StaticLocalVar; // expected-error{{'StaticLocalVar' must have external linkage when declared 'dllexport'}} } //===----------------------------------------------------------------------===// // Variable templates //===----------------------------------------------------------------------===// #if __has_feature(cxx_variable_templates) // Export declaration. template __declspec(dllexport) extern int ExternVarTmplDecl; // dllexport implies a definition. template __declspec(dllexport) int VarTmplDef; // Export definition. template __declspec(dllexport) int VarTmplInit1 = 1; template int __declspec(dllexport) VarTmplInit2 = 1; // Declare, then export definition. template __declspec(dllexport) extern int VarTmplDeclInit; template int VarTmplDeclInit = 1; // Redeclarations template __declspec(dllexport) extern int VarTmplRedecl1; template __declspec(dllexport) int VarTmplRedecl1 = 1; template __declspec(dllexport) extern int VarTmplRedecl2; template int VarTmplRedecl2 = 1; template extern int VarTmplRedecl3; // expected-note{{previous declaration is here}} template __declspec(dllexport) extern int VarTmplRedecl3; // expected-error{{redeclaration of 'VarTmplRedecl3' cannot add 'dllexport' attribute}} // External linkage is required. template __declspec(dllexport) static int StaticVarTmpl; // expected-error{{'StaticVarTmpl' must have external linkage when declared 'dllexport'}} template __declspec(dllexport) Internal InternalTypeVarTmpl; // expected-error{{'InternalTypeVarTmpl' must have external linkage when declared 'dllexport'}} namespace { template __declspec(dllexport) int InternalVarTmpl; } // expected-error{{'(anonymous namespace)::InternalVarTmpl' must have external linkage when declared 'dllexport'}} namespace ns { template __declspec(dllexport) int ExternalVarTmpl = 1; } template __declspec(dllexport) auto InternalAutoTypeVarTmpl = Internal(); // expected-error{{'InternalAutoTypeVarTmpl' must have external linkage when declared 'dllexport'}} template __declspec(dllexport) auto ExternalAutoTypeVarTmpl = External(); template External ExternalAutoTypeVarTmpl; template int VarTmpl = 1; template __declspec(dllexport) int ExportedVarTmpl = 1; // Export implicit instantiation of an exported variable template. int useVarTmpl() { return ExportedVarTmpl; } // Export explicit instantiation declaration of an exported variable template. extern template int ExportedVarTmpl; template int ExportedVarTmpl; // Export explicit instantiation definition of an exported variable template. template __declspec(dllexport) int ExportedVarTmpl; // Export specialization of an exported variable template. template<> __declspec(dllexport) int ExportedVarTmpl; template<> __declspec(dllexport) int ExportedVarTmpl = 1; // Not exporting specialization of an exported variable template without // explicit dllexport. template<> int ExportedVarTmpl; // Export explicit instantiation declaration of a non-exported variable template. extern template __declspec(dllexport) int VarTmpl; template __declspec(dllexport) int VarTmpl; // Export explicit instantiation definition of a non-exported variable template. template __declspec(dllexport) int VarTmpl; // Export specialization of a non-exported variable template. template<> __declspec(dllexport) int VarTmpl; template<> __declspec(dllexport) int VarTmpl = 1; #endif // __has_feature(cxx_variable_templates) //===----------------------------------------------------------------------===// // Functions //===----------------------------------------------------------------------===// // Export function declaration. Check different placements. __attribute__((dllexport)) void decl1A(); // Sanity check with __attribute__ __declspec(dllexport) void decl1B(); void __attribute__((dllexport)) decl2A(); void __declspec(dllexport) decl2B(); // Export function definition. __declspec(dllexport) void def() {} // extern "C" extern "C" __declspec(dllexport) void externC() {} // Export inline function. __declspec(dllexport) inline void inlineFunc1() {} inline void __attribute__((dllexport)) inlineFunc2() {} __declspec(dllexport) inline void inlineDecl(); void inlineDecl() {} __declspec(dllexport) void inlineDef(); inline void inlineDef() {} // Redeclarations __declspec(dllexport) void redecl1(); __declspec(dllexport) void redecl1() {} __declspec(dllexport) void redecl2(); void redecl2() {} void redecl3(); // expected-note{{previous declaration is here}} __declspec(dllexport) void redecl3(); // expected-warning{{redeclaration of 'redecl3' should not add 'dllexport' attribute}} extern "C" { void redecl4(); // expected-note{{previous declaration is here}} __declspec(dllexport) void redecl4(); // expected-warning{{redeclaration of 'redecl4' should not add 'dllexport' attribute}} } void redecl5(); // expected-note{{previous declaration is here}} __declspec(dllexport) inline void redecl5() {} // expected-warning{{redeclaration of 'redecl5' should not add 'dllexport' attribute}} // Friend functions struct FuncFriend { friend __declspec(dllexport) void friend1(); friend __declspec(dllexport) void friend2(); friend void friend3(); // expected-note{{previous declaration is here}} friend void friend4(); // expected-note{{previous declaration is here}} }; __declspec(dllexport) void friend1() {} void friend2() {} __declspec(dllexport) void friend3() {} // expected-warning{{redeclaration of 'friend3' should not add 'dllexport' attribute}} __declspec(dllexport) inline void friend4() {} // expected-warning{{redeclaration of 'friend4' should not add 'dllexport' attribute}} // Implicit declarations can be redeclared with dllexport. __declspec(dllexport) void* operator new(__SIZE_TYPE__ n); // External linkage is required. __declspec(dllexport) static int staticFunc(); // expected-error{{'staticFunc' must have external linkage when declared 'dllexport'}} __declspec(dllexport) Internal internalRetFunc(); // expected-error{{'internalRetFunc' must have external linkage when declared 'dllexport'}} namespace { __declspec(dllexport) void internalFunc() {} } // expected-error{{'(anonymous namespace)::internalFunc' must have external linkage when declared 'dllexport'}} namespace ns { __declspec(dllexport) void externalFunc() {} } // Export deleted function. __declspec(dllexport) void deletedFunc() = delete; // expected-error{{attribute 'dllexport' cannot be applied to a deleted function}} __declspec(dllexport) inline void deletedInlineFunc() = delete; // expected-error{{attribute 'dllexport' cannot be applied to a deleted function}} //===----------------------------------------------------------------------===// // Function templates //===----------------------------------------------------------------------===// // Export function template declaration. Check different placements. template __declspec(dllexport) void funcTmplDecl1(); template void __declspec(dllexport) funcTmplDecl2(); // Export function template definition. template __declspec(dllexport) void funcTmplDef() {} // Export inline function template. template __declspec(dllexport) inline void inlineFuncTmpl1() {} template inline void __attribute__((dllexport)) inlineFuncTmpl2() {} template __declspec(dllexport) inline void inlineFuncTmplDecl(); template void inlineFuncTmplDecl() {} template __declspec(dllexport) void inlineFuncTmplDef(); template inline void inlineFuncTmplDef() {} // Redeclarations template __declspec(dllexport) void funcTmplRedecl1(); template __declspec(dllexport) void funcTmplRedecl1() {} template __declspec(dllexport) void funcTmplRedecl2(); template void funcTmplRedecl2() {} template void funcTmplRedecl3(); // expected-note{{previous declaration is here}} template __declspec(dllexport) void funcTmplRedecl3(); // expected-error{{redeclaration of 'funcTmplRedecl3' cannot add 'dllexport' attribute}} template void funcTmplRedecl4(); // expected-note{{previous declaration is here}} template __declspec(dllexport) inline void funcTmplRedecl4() {} // expected-error{{redeclaration of 'funcTmplRedecl4' cannot add 'dllexport' attribute}} // Function template friends struct FuncTmplFriend { template friend __declspec(dllexport) void funcTmplFriend1(); template friend __declspec(dllexport) void funcTmplFriend2(); template friend void funcTmplFriend3(); // expected-note{{previous declaration is here}} template friend void funcTmplFriend4(); // expected-note{{previous declaration is here}} }; template __declspec(dllexport) void funcTmplFriend1() {} template void funcTmplFriend2() {} template __declspec(dllexport) void funcTmplFriend3() {} // expected-error{{redeclaration of 'funcTmplFriend3' cannot add 'dllexport' attribute}} template __declspec(dllexport) inline void funcTmplFriend4() {} // expected-error{{redeclaration of 'funcTmplFriend4' cannot add 'dllexport' attribute}} // External linkage is required. template __declspec(dllexport) static int staticFuncTmpl(); // expected-error{{'staticFuncTmpl' must have external linkage when declared 'dllexport'}} template __declspec(dllexport) Internal internalRetFuncTmpl(); // expected-error{{'internalRetFuncTmpl' must have external linkage when declared 'dllexport'}} namespace { template __declspec(dllexport) void internalFuncTmpl(); } // expected-error{{'(anonymous namespace)::internalFuncTmpl' must have external linkage when declared 'dllexport'}} namespace ns { template __declspec(dllexport) void externalFuncTmpl(); } template void funcTmpl() {} template __declspec(dllexport) void exportedFuncTmplDecl(); template __declspec(dllexport) void exportedFuncTmpl() {} // Export implicit instantiation of an exported function template. void useFunTmplDecl() { exportedFuncTmplDecl(); } void useFunTmplDef() { exportedFuncTmpl(); } // Export explicit instantiation declaration of an exported function template. extern template void exportedFuncTmpl(); template void exportedFuncTmpl(); // Export explicit instantiation definition of an exported function template. template void exportedFuncTmpl(); // Export specialization of an exported function template. template<> __declspec(dllexport) void exportedFuncTmpl(); template<> __declspec(dllexport) void exportedFuncTmpl() {} template<> __declspec(dllexport) inline void exportedFuncTmpl() {} // Not exporting specialization of an exported function template without // explicit dllexport. template<> void exportedFuncTmpl() {} // Export explicit instantiation declaration of a non-exported function template. extern template __declspec(dllexport) void funcTmpl(); template __declspec(dllexport) void funcTmpl(); // Export explicit instantiation definition of a non-exported function template. template __declspec(dllexport) void funcTmpl(); // Export specialization of a non-exported function template. template<> __declspec(dllexport) void funcTmpl(); template<> __declspec(dllexport) void funcTmpl() {} template<> __declspec(dllexport) inline void funcTmpl() {} //===----------------------------------------------------------------------===// // Classes //===----------------------------------------------------------------------===// namespace { struct __declspec(dllexport) AnonymousClass {}; // expected-error{{(anonymous namespace)::AnonymousClass' must have external linkage when declared 'dllexport'}} } class __declspec(dllexport) ClassDecl; class __declspec(dllexport) ClassDef {}; #ifdef MS // expected-warning@+3{{'dllexport' attribute ignored}} #endif template struct PartiallySpecializedClassTemplate {}; template struct __declspec(dllexport) PartiallySpecializedClassTemplate { void f() {} }; template struct ExpliciallySpecializedClassTemplate {}; template <> struct __declspec(dllexport) ExpliciallySpecializedClassTemplate { void f() {} }; // Don't instantiate class members of implicitly instantiated templates, even if they are exported. struct IncompleteType; template struct __declspec(dllexport) ImplicitlyInstantiatedExportedTemplate { int f() { return sizeof(T); } // no-error }; ImplicitlyInstantiatedExportedTemplate implicitlyInstantiatedExportedTemplate; // Don't instantiate class members of templates with explicit instantiation declarations, even if they are exported. struct IncompleteType2; template struct __declspec(dllexport) ExportedTemplateWithExplicitInstantiationDecl { // expected-note{{attribute is here}} int f() { return sizeof(T); } // no-error }; extern template struct ExportedTemplateWithExplicitInstantiationDecl; // expected-warning{{explicit instantiation declaration should not be 'dllexport'}} // Instantiate class members for explicitly instantiated exported templates. struct IncompleteType3; // expected-note{{forward declaration of 'IncompleteType3'}} template struct __declspec(dllexport) ExplicitlyInstantiatedExportedTemplate { int f() { return sizeof(T); } // expected-error{{invalid application of 'sizeof' to an incomplete type 'IncompleteType3'}} }; template struct ExplicitlyInstantiatedExportedTemplate; // expected-note{{in instantiation of member function 'ExplicitlyInstantiatedExportedTemplate::f' requested here}} // In MS mode, instantiate members of class templates that are base classes of exported classes. #ifdef MS // expected-note@+3{{forward declaration of 'IncompleteType4'}} // expected-note@+3{{in instantiation of member function 'BaseClassTemplateOfExportedClass::f' requested here}} #endif struct IncompleteType4; template struct BaseClassTemplateOfExportedClass { #ifdef MS // expected-error@+2{{invalid application of 'sizeof' to an incomplete type 'IncompleteType4'}} #endif int f() { return sizeof(T); }; }; struct __declspec(dllexport) ExportedBaseClass : public BaseClassTemplateOfExportedClass {}; // Don't instantiate members of explicitly exported class templates that are base classes of exported classes. struct IncompleteType5; template struct __declspec(dllexport) ExportedBaseClassTemplateOfExportedClass { int f() { return sizeof(T); }; // no-error }; struct __declspec(dllexport) ExportedBaseClass2 : public ExportedBaseClassTemplateOfExportedClass {}; // Warn about explicit instantiation declarations of dllexport classes. template struct ExplicitInstantiationDeclTemplate {}; extern template struct __declspec(dllexport) ExplicitInstantiationDeclTemplate; // expected-warning{{explicit instantiation declaration should not be 'dllexport'}} expected-note{{attribute is here}} template struct __declspec(dllexport) ExplicitInstantiationDeclExportedTemplate {}; // expected-note{{attribute is here}} extern template struct ExplicitInstantiationDeclExportedTemplate; // expected-warning{{explicit instantiation declaration should not be 'dllexport'}} //===----------------------------------------------------------------------===// // Classes with template base classes //===----------------------------------------------------------------------===// template class ClassTemplate {}; template class __declspec(dllexport) ExportedClassTemplate {}; template class __declspec(dllimport) ImportedClassTemplate {}; template struct ExplicitlySpecializedTemplate { void func() {} }; #ifdef MS // expected-note@+2{{class template 'ExplicitlySpecializedTemplate' was explicitly specialized here}} #endif template <> struct ExplicitlySpecializedTemplate { void func() {} }; template struct ExplicitlyExportSpecializedTemplate { void func() {} }; template <> struct __declspec(dllexport) ExplicitlyExportSpecializedTemplate { void func() {} }; template struct ExplicitlyImportSpecializedTemplate { void func() {} }; template <> struct __declspec(dllimport) ExplicitlyImportSpecializedTemplate { void func() {} }; template struct ExplicitlyInstantiatedTemplate { void func() {} }; #ifdef MS // expected-note@+2{{class template 'ExplicitlyInstantiatedTemplate' was instantiated here}} #endif template struct ExplicitlyInstantiatedTemplate; template struct ExplicitlyExportInstantiatedTemplate { void func() {} }; template struct __declspec(dllexport) ExplicitlyExportInstantiatedTemplate; template struct ExplicitlyImportInstantiatedTemplate { void func() {} }; template struct __declspec(dllimport) ExplicitlyImportInstantiatedTemplate; // ClassTemplate gets exported. class __declspec(dllexport) DerivedFromTemplate : public ClassTemplate {}; // ClassTemplate is already exported. class __declspec(dllexport) DerivedFromTemplate2 : public ClassTemplate {}; // ExportedTemplate is explicitly exported. class __declspec(dllexport) DerivedFromExportedTemplate : public ExportedClassTemplate {}; // ImportedTemplate is explicitly imported. class __declspec(dllexport) DerivedFromImportedTemplate : public ImportedClassTemplate {}; #ifdef MS // expected-note@+4{{class template 'ClassTemplate' was instantiated here}} // expected-warning@+4{{propagating dll attribute to already instantiated base class template without dll attribute is not supported}} // expected-note@+3{{attribute is here}} #endif class DerivedFromTemplateD : public ClassTemplate {}; class __declspec(dllexport) DerivedFromTemplateD2 : public ClassTemplate {}; #ifdef MS // expected-note@+4{{class template 'ClassTemplate' was instantiated here}} // expected-warning@+4{{propagating dll attribute to already instantiated base class template with different dll attribute is not supported}} // expected-note@+3{{attribute is here}} #endif class __declspec(dllimport) DerivedFromTemplateB : public ClassTemplate {}; class __declspec(dllexport) DerivedFromTemplateB2 : public ClassTemplate {}; #ifdef MS // expected-warning@+3{{propagating dll attribute to explicitly specialized base class template without dll attribute is not supported}} // expected-note@+2{{attribute is here}} #endif struct __declspec(dllexport) DerivedFromExplicitlySpecializedTemplate : public ExplicitlySpecializedTemplate {}; // Base class alredy specialized with export attribute. struct __declspec(dllexport) DerivedFromExplicitlyExportSpecializedTemplate : public ExplicitlyExportSpecializedTemplate {}; // Base class already specialized with import attribute. struct __declspec(dllexport) DerivedFromExplicitlyImportSpecializedTemplate : public ExplicitlyImportSpecializedTemplate {}; #ifdef MS // expected-warning@+3{{propagating dll attribute to already instantiated base class template without dll attribute is not supported}} // expected-note@+2{{attribute is here}} #endif struct __declspec(dllexport) DerivedFromExplicitlyInstantiatedTemplate : public ExplicitlyInstantiatedTemplate {}; // Base class already instantiated with export attribute. struct __declspec(dllexport) DerivedFromExplicitlyExportInstantiatedTemplate : public ExplicitlyExportInstantiatedTemplate {}; // Base class already instantiated with import attribute. struct __declspec(dllexport) DerivedFromExplicitlyImportInstantiatedTemplate : public ExplicitlyImportInstantiatedTemplate {}; //===----------------------------------------------------------------------===// // Precedence //===----------------------------------------------------------------------===// // dllexport takes precedence over dllimport if both are specified. __attribute__((dllimport, dllexport)) extern int PrecedenceExternGlobal1A; // expected-warning{{'dllimport' attribute ignored}} __declspec(dllimport) __declspec(dllexport) extern int PrecedenceExternGlobal1B; // expected-warning{{'dllimport' attribute ignored}} __attribute__((dllexport, dllimport)) extern int PrecedenceExternGlobal2A; // expected-warning{{'dllimport' attribute ignored}} __declspec(dllexport) __declspec(dllimport) extern int PrecedenceExternGlobal2B; // expected-warning{{'dllimport' attribute ignored}} __attribute__((dllimport, dllexport)) int PrecedenceGlobal1A; // expected-warning{{'dllimport' attribute ignored}} __declspec(dllimport) __declspec(dllexport) int PrecedenceGlobal1B; // expected-warning{{'dllimport' attribute ignored}} __attribute__((dllexport, dllimport)) int PrecedenceGlobal2A; // expected-warning{{'dllimport' attribute ignored}} __declspec(dllexport) __declspec(dllimport) int PrecedenceGlobal2B; // expected-warning{{'dllimport' attribute ignored}} __declspec(dllexport) extern int PrecedenceExternGlobalRedecl1; __declspec(dllimport) extern int PrecedenceExternGlobalRedecl1; // expected-warning{{'dllimport' attribute ignored}} __declspec(dllimport) extern int PrecedenceExternGlobalRedecl2; // expected-warning{{'dllimport' attribute ignored}} __declspec(dllexport) extern int PrecedenceExternGlobalRedecl2; __declspec(dllexport) extern int PrecedenceGlobalRedecl1; __declspec(dllimport) int PrecedenceGlobalRedecl1; // expected-warning{{'dllimport' attribute ignored}} __declspec(dllimport) extern int PrecedenceGlobalRedecl2; // expected-warning{{'dllimport' attribute ignored}} __declspec(dllexport) int PrecedenceGlobalRedecl2; void __attribute__((dllimport, dllexport)) precedence1A() {} // expected-warning{{'dllimport' attribute ignored}} void __declspec(dllimport) __declspec(dllexport) precedence1B() {} // expected-warning{{'dllimport' attribute ignored}} void __attribute__((dllexport, dllimport)) precedence2A() {} // expected-warning{{'dllimport' attribute ignored}} void __declspec(dllexport) __declspec(dllimport) precedence2B() {} // expected-warning{{'dllimport' attribute ignored}} void __declspec(dllimport) precedenceRedecl1(); // expected-warning{{'dllimport' attribute ignored}} void __declspec(dllexport) precedenceRedecl1() {} void __declspec(dllexport) precedenceRedecl2(); void __declspec(dllimport) precedenceRedecl2() {} // expected-warning{{'dllimport' attribute ignored}} //===----------------------------------------------------------------------===// // Class members //===----------------------------------------------------------------------===// // Export individual members of a class. struct ExportMembers { struct Nested { __declspec(dllexport) void normalDef(); }; __declspec(dllexport) void normalDecl(); __declspec(dllexport) void normalDef(); __declspec(dllexport) void normalInclass() {} __declspec(dllexport) void normalInlineDef(); __declspec(dllexport) inline void normalInlineDecl(); __declspec(dllexport) virtual void virtualDecl(); __declspec(dllexport) virtual void virtualDef(); __declspec(dllexport) virtual void virtualInclass() {} __declspec(dllexport) virtual void virtualInlineDef(); __declspec(dllexport) virtual inline void virtualInlineDecl(); __declspec(dllexport) static void staticDecl(); __declspec(dllexport) static void staticDef(); __declspec(dllexport) static void staticInclass() {} __declspec(dllexport) static void staticInlineDef(); __declspec(dllexport) static inline void staticInlineDecl(); protected: __declspec(dllexport) void protectedDef(); private: __declspec(dllexport) void privateDef(); public: __declspec(dllexport) int Field; // expected-warning{{'dllexport' attribute only applies to variables, functions and classes}} __declspec(dllexport) static int StaticField; __declspec(dllexport) static int StaticFieldDef; __declspec(dllexport) static const int StaticConstField; __declspec(dllexport) static const int StaticConstFieldDef; __declspec(dllexport) static const int StaticConstFieldEqualInit = 1; __declspec(dllexport) static const int StaticConstFieldBraceInit{1}; __declspec(dllexport) constexpr static int ConstexprField = 1; __declspec(dllexport) constexpr static int ConstexprFieldDef = 1; }; void ExportMembers::Nested::normalDef() {} void ExportMembers::normalDef() {} inline void ExportMembers::normalInlineDef() {} void ExportMembers::normalInlineDecl() {} void ExportMembers::virtualDef() {} inline void ExportMembers::virtualInlineDef() {} void ExportMembers::virtualInlineDecl() {} void ExportMembers::staticDef() {} inline void ExportMembers::staticInlineDef() {} void ExportMembers::staticInlineDecl() {} void ExportMembers::protectedDef() {} void ExportMembers::privateDef() {} int ExportMembers::StaticFieldDef; const int ExportMembers::StaticConstFieldDef = 1; constexpr int ExportMembers::ConstexprFieldDef; // Export on member definitions. struct ExportMemberDefs { __declspec(dllexport) void normalDef(); __declspec(dllexport) void normalInlineDef(); __declspec(dllexport) inline void normalInlineDecl(); __declspec(dllexport) virtual void virtualDef(); __declspec(dllexport) virtual void virtualInlineDef(); __declspec(dllexport) virtual inline void virtualInlineDecl(); __declspec(dllexport) static void staticDef(); __declspec(dllexport) static void staticInlineDef(); __declspec(dllexport) static inline void staticInlineDecl(); __declspec(dllexport) static int StaticField; __declspec(dllexport) static const int StaticConstField; __declspec(dllexport) constexpr static int ConstexprField = 1; }; __declspec(dllexport) void ExportMemberDefs::normalDef() {} __declspec(dllexport) inline void ExportMemberDefs::normalInlineDef() {} __declspec(dllexport) void ExportMemberDefs::normalInlineDecl() {} __declspec(dllexport) void ExportMemberDefs::virtualDef() {} __declspec(dllexport) inline void ExportMemberDefs::virtualInlineDef() {} __declspec(dllexport) void ExportMemberDefs::virtualInlineDecl() {} __declspec(dllexport) void ExportMemberDefs::staticDef() {} __declspec(dllexport) inline void ExportMemberDefs::staticInlineDef() {} __declspec(dllexport) void ExportMemberDefs::staticInlineDecl() {} __declspec(dllexport) int ExportMemberDefs::StaticField; __declspec(dllexport) const int ExportMemberDefs::StaticConstField = 1; __declspec(dllexport) constexpr int ExportMemberDefs::ConstexprField; // Export special member functions. struct ExportSpecials { __declspec(dllexport) ExportSpecials() {} __declspec(dllexport) ~ExportSpecials(); __declspec(dllexport) inline ExportSpecials(const ExportSpecials&); __declspec(dllexport) ExportSpecials& operator=(const ExportSpecials&); __declspec(dllexport) ExportSpecials(ExportSpecials&&); __declspec(dllexport) ExportSpecials& operator=(ExportSpecials&&); }; ExportSpecials::~ExportSpecials() {} ExportSpecials::ExportSpecials(const ExportSpecials&) {} inline ExportSpecials& ExportSpecials::operator=(const ExportSpecials&) { return *this; } ExportSpecials::ExportSpecials(ExportSpecials&&) {} ExportSpecials& ExportSpecials::operator=(ExportSpecials&&) { return *this; } // Export allocation functions. extern "C" void* malloc(__SIZE_TYPE__ size); extern "C" void free(void* p); struct ExportAlloc { __declspec(dllexport) void* operator new(__SIZE_TYPE__); __declspec(dllexport) void* operator new[](__SIZE_TYPE__); __declspec(dllexport) void operator delete(void*); __declspec(dllexport) void operator delete[](void*); }; void* ExportAlloc::operator new(__SIZE_TYPE__ n) { return malloc(n); } void* ExportAlloc::operator new[](__SIZE_TYPE__ n) { return malloc(n); } void ExportAlloc::operator delete(void* p) { free(p); } void ExportAlloc::operator delete[](void* p) { free(p); } // Export deleted member functions. struct ExportDeleted { __declspec(dllexport) ExportDeleted() = delete; // expected-error{{attribute 'dllexport' cannot be applied to a deleted function}} __declspec(dllexport) ~ExportDeleted() = delete; // expected-error{{attribute 'dllexport' cannot be applied to a deleted function}} __declspec(dllexport) ExportDeleted(const ExportDeleted&) = delete; // expected-error{{attribute 'dllexport' cannot be applied to a deleted function}} __declspec(dllexport) ExportDeleted& operator=(const ExportDeleted&) = delete; // expected-error{{attribute 'dllexport' cannot be applied to a deleted function}} __declspec(dllexport) ExportDeleted(ExportDeleted&&) = delete; // expected-error{{attribute 'dllexport' cannot be applied to a deleted function}} __declspec(dllexport) ExportDeleted& operator=(ExportDeleted&&) = delete; // expected-error{{attribute 'dllexport' cannot be applied to a deleted function}} __declspec(dllexport) void deleted() = delete; // expected-error{{attribute 'dllexport' cannot be applied to a deleted function}} }; // Export defaulted member functions. struct ExportDefaulted { __declspec(dllexport) ExportDefaulted() = default; __declspec(dllexport) ~ExportDefaulted() = default; __declspec(dllexport) ExportDefaulted(const ExportDefaulted&) = default; __declspec(dllexport) ExportDefaulted& operator=(const ExportDefaulted&) = default; __declspec(dllexport) ExportDefaulted(ExportDefaulted&&) = default; __declspec(dllexport) ExportDefaulted& operator=(ExportDefaulted&&) = default; }; // Export defaulted member function definitions. struct ExportDefaultedDefs { __declspec(dllexport) ExportDefaultedDefs(); __declspec(dllexport) ~ExportDefaultedDefs(); __declspec(dllexport) inline ExportDefaultedDefs(const ExportDefaultedDefs&); __declspec(dllexport) ExportDefaultedDefs& operator=(const ExportDefaultedDefs&); __declspec(dllexport) ExportDefaultedDefs(ExportDefaultedDefs&&); __declspec(dllexport) ExportDefaultedDefs& operator=(ExportDefaultedDefs&&); }; // Export definitions. __declspec(dllexport) ExportDefaultedDefs::ExportDefaultedDefs() = default; ExportDefaultedDefs::~ExportDefaultedDefs() = default; // Export inline declaration and definition. __declspec(dllexport) ExportDefaultedDefs::ExportDefaultedDefs(const ExportDefaultedDefs&) = default; inline ExportDefaultedDefs& ExportDefaultedDefs::operator=(const ExportDefaultedDefs&) = default; __declspec(dllexport) ExportDefaultedDefs::ExportDefaultedDefs(ExportDefaultedDefs&&) = default; ExportDefaultedDefs& ExportDefaultedDefs::operator=(ExportDefaultedDefs&&) = default; // Redeclarations cannot add dllexport. struct MemberRedecl { void normalDef(); // expected-note{{previous declaration is here}} void normalInlineDef(); // expected-note{{previous declaration is here}} inline void normalInlineDecl(); // expected-note{{previous declaration is here}} virtual void virtualDef(); // expected-note{{previous declaration is here}} virtual void virtualInlineDef(); // expected-note{{previous declaration is here}} virtual inline void virtualInlineDecl(); // expected-note{{previous declaration is here}} static void staticDef(); // expected-note{{previous declaration is here}} static void staticInlineDef(); // expected-note{{previous declaration is here}} static inline void staticInlineDecl(); // expected-note{{previous declaration is here}} static int StaticField; // expected-note{{previous declaration is here}} static const int StaticConstField; // expected-note{{previous declaration is here}} constexpr static int ConstexprField = 1; // expected-note{{previous declaration is here}} }; __declspec(dllexport) void MemberRedecl::normalDef() {} // expected-error{{redeclaration of 'MemberRedecl::normalDef' cannot add 'dllexport' attribute}} __declspec(dllexport) inline void MemberRedecl::normalInlineDef() {} // expected-error{{redeclaration of 'MemberRedecl::normalInlineDef' cannot add 'dllexport' attribute}} __declspec(dllexport) void MemberRedecl::normalInlineDecl() {} // expected-error{{redeclaration of 'MemberRedecl::normalInlineDecl' cannot add 'dllexport' attribute}} __declspec(dllexport) void MemberRedecl::virtualDef() {} // expected-error{{redeclaration of 'MemberRedecl::virtualDef' cannot add 'dllexport' attribute}} __declspec(dllexport) inline void MemberRedecl::virtualInlineDef() {} // expected-error{{redeclaration of 'MemberRedecl::virtualInlineDef' cannot add 'dllexport' attribute}} __declspec(dllexport) void MemberRedecl::virtualInlineDecl() {} // expected-error{{redeclaration of 'MemberRedecl::virtualInlineDecl' cannot add 'dllexport' attribute}} __declspec(dllexport) void MemberRedecl::staticDef() {} // expected-error{{redeclaration of 'MemberRedecl::staticDef' cannot add 'dllexport' attribute}} __declspec(dllexport) inline void MemberRedecl::staticInlineDef() {} // expected-error{{redeclaration of 'MemberRedecl::staticInlineDef' cannot add 'dllexport' attribute}} __declspec(dllexport) void MemberRedecl::staticInlineDecl() {} // expected-error{{redeclaration of 'MemberRedecl::staticInlineDecl' cannot add 'dllexport' attribute}} __declspec(dllexport) int MemberRedecl::StaticField = 1; // expected-error{{redeclaration of 'MemberRedecl::StaticField' cannot add 'dllexport' attribute}} __declspec(dllexport) const int MemberRedecl::StaticConstField = 1; // expected-error{{redeclaration of 'MemberRedecl::StaticConstField' cannot add 'dllexport' attribute}} __declspec(dllexport) constexpr int MemberRedecl::ConstexprField; // expected-error{{redeclaration of 'MemberRedecl::ConstexprField' cannot add 'dllexport' attribute}} //===----------------------------------------------------------------------===// // Class member templates //===----------------------------------------------------------------------===// struct ExportMemberTmpl { template __declspec(dllexport) void normalDecl(); template __declspec(dllexport) void normalDef(); template __declspec(dllexport) void normalInclass() {} template __declspec(dllexport) void normalInlineDef(); template __declspec(dllexport) inline void normalInlineDecl(); template __declspec(dllexport) static void staticDecl(); template __declspec(dllexport) static void staticDef(); template __declspec(dllexport) static void staticInclass() {} template __declspec(dllexport) static void staticInlineDef(); template __declspec(dllexport) static inline void staticInlineDecl(); #if __has_feature(cxx_variable_templates) template __declspec(dllexport) static int StaticField; template __declspec(dllexport) static int StaticFieldDef; template __declspec(dllexport) static const int StaticConstField; template __declspec(dllexport) static const int StaticConstFieldDef; template __declspec(dllexport) static const int StaticConstFieldEqualInit = 1; template __declspec(dllexport) static const int StaticConstFieldBraceInit{1}; template __declspec(dllexport) constexpr static int ConstexprField = 1; template __declspec(dllexport) constexpr static int ConstexprFieldDef = 1; #endif // __has_feature(cxx_variable_templates) }; template void ExportMemberTmpl::normalDef() {} template inline void ExportMemberTmpl::normalInlineDef() {} template void ExportMemberTmpl::normalInlineDecl() {} template void ExportMemberTmpl::staticDef() {} template inline void ExportMemberTmpl::staticInlineDef() {} template void ExportMemberTmpl::staticInlineDecl() {} #if __has_feature(cxx_variable_templates) template int ExportMemberTmpl::StaticFieldDef; template const int ExportMemberTmpl::StaticConstFieldDef = 1; template constexpr int ExportMemberTmpl::ConstexprFieldDef; #endif // __has_feature(cxx_variable_templates) // Redeclarations cannot add dllexport. struct MemTmplRedecl { template void normalDef(); // expected-note{{previous declaration is here}} template void normalInlineDef(); // expected-note{{previous declaration is here}} template inline void normalInlineDecl(); // expected-note{{previous declaration is here}} template static void staticDef(); // expected-note{{previous declaration is here}} template static void staticInlineDef(); // expected-note{{previous declaration is here}} template static inline void staticInlineDecl(); // expected-note{{previous declaration is here}} #if __has_feature(cxx_variable_templates) template static int StaticField; // expected-note{{previous declaration is here}} template static const int StaticConstField; // expected-note{{previous declaration is here}} template constexpr static int ConstexprField = 1; // expected-note{{previous declaration is here}} #endif // __has_feature(cxx_variable_templates) }; template __declspec(dllexport) void MemTmplRedecl::normalDef() {} // expected-error{{redeclaration of 'MemTmplRedecl::normalDef' cannot add 'dllexport' attribute}} template __declspec(dllexport) inline void MemTmplRedecl::normalInlineDef() {} // expected-error{{redeclaration of 'MemTmplRedecl::normalInlineDef' cannot add 'dllexport' attribute}} template __declspec(dllexport) void MemTmplRedecl::normalInlineDecl() {} // expected-error{{redeclaration of 'MemTmplRedecl::normalInlineDecl' cannot add 'dllexport' attribute}} template __declspec(dllexport) void MemTmplRedecl::staticDef() {} // expected-error{{redeclaration of 'MemTmplRedecl::staticDef' cannot add 'dllexport' attribute}} template __declspec(dllexport) inline void MemTmplRedecl::staticInlineDef() {} // expected-error{{redeclaration of 'MemTmplRedecl::staticInlineDef' cannot add 'dllexport' attribute}} template __declspec(dllexport) void MemTmplRedecl::staticInlineDecl() {} // expected-error{{redeclaration of 'MemTmplRedecl::staticInlineDecl' cannot add 'dllexport' attribute}} #if __has_feature(cxx_variable_templates) template __declspec(dllexport) int MemTmplRedecl::StaticField = 1; // expected-error{{redeclaration of 'MemTmplRedecl::StaticField' cannot add 'dllexport' attribute}} template __declspec(dllexport) const int MemTmplRedecl::StaticConstField = 1; // expected-error{{redeclaration of 'MemTmplRedecl::StaticConstField' cannot add 'dllexport' attribute}} template __declspec(dllexport) constexpr int MemTmplRedecl::ConstexprField; // expected-error{{redeclaration of 'MemTmplRedecl::ConstexprField' cannot add 'dllexport' attribute}} #endif // __has_feature(cxx_variable_templates) struct MemFunTmpl { template void normalDef() {} template __declspec(dllexport) void exportedNormal() {} template static void staticDef() {} template __declspec(dllexport) static void exportedStatic() {} }; // Export implicit instantiation of an exported member function template. void useMemFunTmpl() { MemFunTmpl().exportedNormal(); MemFunTmpl().exportedStatic(); } // Export explicit instantiation declaration of an exported member function // template. extern template void MemFunTmpl::exportedNormal(); template void MemFunTmpl::exportedNormal(); extern template void MemFunTmpl::exportedStatic(); template void MemFunTmpl::exportedStatic(); // Export explicit instantiation definition of an exported member function // template. template void MemFunTmpl::exportedNormal(); template void MemFunTmpl::exportedStatic(); // Export specialization of an exported member function template. template<> __declspec(dllexport) void MemFunTmpl::exportedNormal(); template<> __declspec(dllexport) void MemFunTmpl::exportedNormal() {} template<> __declspec(dllexport) inline void MemFunTmpl::exportedNormal() {} template<> __declspec(dllexport) void MemFunTmpl::exportedStatic(); template<> __declspec(dllexport) void MemFunTmpl::exportedStatic() {} template<> __declspec(dllexport) inline void MemFunTmpl::exportedStatic() {} // Not exporting specialization of an exported member function template without // explicit dllexport. template<> void MemFunTmpl::exportedNormal() {} template<> void MemFunTmpl::exportedStatic() {} // Export explicit instantiation declaration of a non-exported member function // template. extern template __declspec(dllexport) void MemFunTmpl::normalDef(); template __declspec(dllexport) void MemFunTmpl::normalDef(); extern template __declspec(dllexport) void MemFunTmpl::staticDef(); template __declspec(dllexport) void MemFunTmpl::staticDef(); // Export explicit instantiation definition of a non-exported member function // template. template __declspec(dllexport) void MemFunTmpl::normalDef(); template __declspec(dllexport) void MemFunTmpl::staticDef(); // Export specialization of a non-exported member function template. template<> __declspec(dllexport) void MemFunTmpl::normalDef(); template<> __declspec(dllexport) void MemFunTmpl::normalDef() {} template<> __declspec(dllexport) inline void MemFunTmpl::normalDef() {} template<> __declspec(dllexport) void MemFunTmpl::staticDef(); template<> __declspec(dllexport) void MemFunTmpl::staticDef() {} template<> __declspec(dllexport) inline void MemFunTmpl::staticDef() {} #if __has_feature(cxx_variable_templates) struct MemVarTmpl { template static const int StaticVar = 1; template __declspec(dllexport) static const int ExportedStaticVar = 1; }; template const int MemVarTmpl::StaticVar; template const int MemVarTmpl::ExportedStaticVar; // Export implicit instantiation of an exported member variable template. int useMemVarTmpl() { return MemVarTmpl::ExportedStaticVar; } // Export explicit instantiation declaration of an exported member variable // template. extern template const int MemVarTmpl::ExportedStaticVar; template const int MemVarTmpl::ExportedStaticVar; // Export explicit instantiation definition of an exported member variable // template. template const int MemVarTmpl::ExportedStaticVar; // Export specialization of an exported member variable template. template<> __declspec(dllexport) const int MemVarTmpl::ExportedStaticVar; template<> __declspec(dllexport) const int MemVarTmpl::ExportedStaticVar = 1; // Not exporting specialization of an exported member variable template without // explicit dllexport. template<> const int MemVarTmpl::ExportedStaticVar; // Export explicit instantiation declaration of a non-exported member variable // template. extern template __declspec(dllexport) const int MemVarTmpl::StaticVar; template __declspec(dllexport) const int MemVarTmpl::StaticVar; // Export explicit instantiation definition of a non-exported member variable // template. template __declspec(dllexport) const int MemVarTmpl::StaticVar; // Export specialization of a non-exported member variable template. template<> __declspec(dllexport) const int MemVarTmpl::StaticVar; template<> __declspec(dllexport) const int MemVarTmpl::StaticVar = 1; #endif // __has_feature(cxx_variable_templates) //===----------------------------------------------------------------------===// // Class template members //===----------------------------------------------------------------------===// // Export individual members of a class template. template struct ExportClassTmplMembers { __declspec(dllexport) void normalDecl(); __declspec(dllexport) void normalDef(); __declspec(dllexport) void normalInclass() {} __declspec(dllexport) void normalInlineDef(); __declspec(dllexport) inline void normalInlineDecl(); __declspec(dllexport) virtual void virtualDecl(); __declspec(dllexport) virtual void virtualDef(); __declspec(dllexport) virtual void virtualInclass() {} __declspec(dllexport) virtual void virtualInlineDef(); __declspec(dllexport) virtual inline void virtualInlineDecl(); __declspec(dllexport) static void staticDecl(); __declspec(dllexport) static void staticDef(); __declspec(dllexport) static void staticInclass() {} __declspec(dllexport) static void staticInlineDef(); __declspec(dllexport) static inline void staticInlineDecl(); protected: __declspec(dllexport) void protectedDef(); private: __declspec(dllexport) void privateDef(); public: __declspec(dllexport) int Field; // expected-warning{{'dllexport' attribute only applies to variables, functions and classes}} __declspec(dllexport) static int StaticField; __declspec(dllexport) static int StaticFieldDef; __declspec(dllexport) static const int StaticConstField; __declspec(dllexport) static const int StaticConstFieldDef; __declspec(dllexport) static const int StaticConstFieldEqualInit = 1; __declspec(dllexport) static const int StaticConstFieldBraceInit{1}; __declspec(dllexport) constexpr static int ConstexprField = 1; __declspec(dllexport) constexpr static int ConstexprFieldDef = 1; }; template void ExportClassTmplMembers::normalDef() {} template inline void ExportClassTmplMembers::normalInlineDef() {} template void ExportClassTmplMembers::normalInlineDecl() {} template void ExportClassTmplMembers::virtualDef() {} template inline void ExportClassTmplMembers::virtualInlineDef() {} template void ExportClassTmplMembers::virtualInlineDecl() {} template void ExportClassTmplMembers::staticDef() {} template inline void ExportClassTmplMembers::staticInlineDef() {} template void ExportClassTmplMembers::staticInlineDecl() {} template void ExportClassTmplMembers::protectedDef() {} template void ExportClassTmplMembers::privateDef() {} template int ExportClassTmplMembers::StaticFieldDef; template const int ExportClassTmplMembers::StaticConstFieldDef = 1; template constexpr int ExportClassTmplMembers::ConstexprFieldDef; template struct ExportClassTmplMembers; // Redeclarations cannot add dllexport. template struct CTMR /*ClassTmplMemberRedecl*/ { void normalDef(); // expected-note{{previous declaration is here}} void normalInlineDef(); // expected-note{{previous declaration is here}} inline void normalInlineDecl(); // expected-note{{previous declaration is here}} virtual void virtualDef(); // expected-note{{previous declaration is here}} virtual void virtualInlineDef(); // expected-note{{previous declaration is here}} virtual inline void virtualInlineDecl(); // expected-note{{previous declaration is here}} static void staticDef(); // expected-note{{previous declaration is here}} static void staticInlineDef(); // expected-note{{previous declaration is here}} static inline void staticInlineDecl(); // expected-note{{previous declaration is here}} static int StaticField; // expected-note{{previous declaration is here}} static const int StaticConstField; // expected-note{{previous declaration is here}} constexpr static int ConstexprField = 1; // expected-note{{previous declaration is here}} }; template __declspec(dllexport) void CTMR::normalDef() {} // expected-error{{redeclaration of 'CTMR::normalDef' cannot add 'dllexport' attribute}} template __declspec(dllexport) inline void CTMR::normalInlineDef() {} // expected-error{{redeclaration of 'CTMR::normalInlineDef' cannot add 'dllexport' attribute}} template __declspec(dllexport) void CTMR::normalInlineDecl() {} // expected-error{{redeclaration of 'CTMR::normalInlineDecl' cannot add 'dllexport' attribute}} template __declspec(dllexport) void CTMR::virtualDef() {} // expected-error{{redeclaration of 'CTMR::virtualDef' cannot add 'dllexport' attribute}} template __declspec(dllexport) inline void CTMR::virtualInlineDef() {} // expected-error{{redeclaration of 'CTMR::virtualInlineDef' cannot add 'dllexport' attribute}} template __declspec(dllexport) void CTMR::virtualInlineDecl() {} // expected-error{{redeclaration of 'CTMR::virtualInlineDecl' cannot add 'dllexport' attribute}} template __declspec(dllexport) void CTMR::staticDef() {} // expected-error{{redeclaration of 'CTMR::staticDef' cannot add 'dllexport' attribute}} template __declspec(dllexport) inline void CTMR::staticInlineDef() {} // expected-error{{redeclaration of 'CTMR::staticInlineDef' cannot add 'dllexport' attribute}} template __declspec(dllexport) void CTMR::staticInlineDecl() {} // expected-error{{redeclaration of 'CTMR::staticInlineDecl' cannot add 'dllexport' attribute}} template __declspec(dllexport) int CTMR::StaticField = 1; // expected-error{{redeclaration of 'CTMR::StaticField' cannot add 'dllexport' attribute}} template __declspec(dllexport) const int CTMR::StaticConstField = 1; // expected-error{{redeclaration of 'CTMR::StaticConstField' cannot add 'dllexport' attribute}} template __declspec(dllexport) constexpr int CTMR::ConstexprField; // expected-error{{redeclaration of 'CTMR::ConstexprField' cannot add 'dllexport' attribute}} //===----------------------------------------------------------------------===// // Class template member templates //===----------------------------------------------------------------------===// template struct ExportClsTmplMemTmpl { template __declspec(dllexport) void normalDecl(); template __declspec(dllexport) void normalDef(); template __declspec(dllexport) void normalInclass() {} template __declspec(dllexport) void normalInlineDef(); template __declspec(dllexport) inline void normalInlineDecl(); template __declspec(dllexport) static void staticDecl(); template __declspec(dllexport) static void staticDef(); template __declspec(dllexport) static void staticInclass() {} template __declspec(dllexport) static void staticInlineDef(); template __declspec(dllexport) static inline void staticInlineDecl(); #if __has_feature(cxx_variable_templates) template __declspec(dllexport) static int StaticField; template __declspec(dllexport) static int StaticFieldDef; template __declspec(dllexport) static const int StaticConstField; template __declspec(dllexport) static const int StaticConstFieldDef; template __declspec(dllexport) static const int StaticConstFieldEqualInit = 1; template __declspec(dllexport) static const int StaticConstFieldBraceInit{1}; template __declspec(dllexport) constexpr static int ConstexprField = 1; template __declspec(dllexport) constexpr static int ConstexprFieldDef = 1; #endif // __has_feature(cxx_variable_templates) }; template template void ExportClsTmplMemTmpl::normalDef() {} template template inline void ExportClsTmplMemTmpl::normalInlineDef() {} template template void ExportClsTmplMemTmpl::normalInlineDecl() {} template template void ExportClsTmplMemTmpl::staticDef() {} template template inline void ExportClsTmplMemTmpl::staticInlineDef() {} template template void ExportClsTmplMemTmpl::staticInlineDecl() {} #if __has_feature(cxx_variable_templates) template template int ExportClsTmplMemTmpl::StaticFieldDef; template template const int ExportClsTmplMemTmpl::StaticConstFieldDef = 1; template template constexpr int ExportClsTmplMemTmpl::ConstexprFieldDef; #endif // __has_feature(cxx_variable_templates) // Redeclarations cannot add dllexport. template struct CTMTR /*ClassTmplMemberTmplRedecl*/ { template void normalDef(); // expected-note{{previous declaration is here}} template void normalInlineDef(); // expected-note{{previous declaration is here}} template inline void normalInlineDecl(); // expected-note{{previous declaration is here}} template static void staticDef(); // expected-note{{previous declaration is here}} template static void staticInlineDef(); // expected-note{{previous declaration is here}} template static inline void staticInlineDecl(); // expected-note{{previous declaration is here}} #if __has_feature(cxx_variable_templates) template static int StaticField; // expected-note{{previous declaration is here}} template static const int StaticConstField; // expected-note{{previous declaration is here}} template constexpr static int ConstexprField = 1; // expected-note{{previous declaration is here}} #endif // __has_feature(cxx_variable_templates) }; template template __declspec(dllexport) void CTMTR::normalDef() {} // expected-error{{redeclaration of 'CTMTR::normalDef' cannot add 'dllexport' attribute}} template template __declspec(dllexport) inline void CTMTR::normalInlineDef() {} // expected-error{{redeclaration of 'CTMTR::normalInlineDef' cannot add 'dllexport' attribute}} template template __declspec(dllexport) void CTMTR::normalInlineDecl() {} // expected-error{{redeclaration of 'CTMTR::normalInlineDecl' cannot add 'dllexport' attribute}} template template __declspec(dllexport) void CTMTR::staticDef() {} // expected-error{{redeclaration of 'CTMTR::staticDef' cannot add 'dllexport' attribute}} template template __declspec(dllexport) inline void CTMTR::staticInlineDef() {} // expected-error{{redeclaration of 'CTMTR::staticInlineDef' cannot add 'dllexport' attribute}} template template __declspec(dllexport) void CTMTR::staticInlineDecl() {} // expected-error{{redeclaration of 'CTMTR::staticInlineDecl' cannot add 'dllexport' attribute}} #if __has_feature(cxx_variable_templates) template template __declspec(dllexport) int CTMTR::StaticField = 1; // expected-error{{redeclaration of 'CTMTR::StaticField' cannot add 'dllexport' attribute}} template template __declspec(dllexport) const int CTMTR::StaticConstField = 1; // expected-error{{redeclaration of 'CTMTR::StaticConstField' cannot add 'dllexport' attribute}} template template __declspec(dllexport) constexpr int CTMTR::ConstexprField; // expected-error{{redeclaration of 'CTMTR::ConstexprField' cannot add 'dllexport' attribute}} #endif // __has_feature(cxx_variable_templates) // FIXME: Precedence rules seem to be different for classes.