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