brintos

brintos / llvm-project-archived public Read only

0
0
Text · 67.9 KiB · 169af5c Raw
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