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