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 -DGNU %s
      4 // RUN: %clang_cc1 -triple x86_64-mingw32 -fsyntax-only -fms-extensions -verify -std=c++11 -Wunsupported-dll-base-class-template -DGNU %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 #ifdef GNU
     48 // expected-note@+2{{previous attribute is here}}
     49 #endif
     50 __declspec(dllimport) extern int ExternGlobalDeclInit; // expected-note{{previous declaration is here}}
     51 #ifdef MS
     52 // expected-warning@+4{{'ExternGlobalDeclInit' redeclared without 'dllimport' attribute: 'dllexport' attribute added}}
     53 #else
     54 // expected-warning@+2{{'ExternGlobalDeclInit' redeclared without 'dllimport' attribute: previous 'dllimport' ignored}}
     55 #endif
     56 int ExternGlobalDeclInit = 1;
     57 
     58 #ifdef GNU
     59 // expected-note@+2{{previous attribute is here}}
     60 #endif
     61 __declspec(dllimport) int GlobalDeclInit; // expected-note{{previous declaration is here}}
     62 #ifdef MS
     63 // expected-warning@+4{{'GlobalDeclInit' redeclared without 'dllimport' attribute: 'dllexport' attribute added}}
     64 #else
     65 // expected-warning@+2{{'GlobalDeclInit' redeclared without 'dllimport' attribute: previous 'dllimport' ignored}}
     66 #endif
     67 int GlobalDeclInit = 1;
     68 
     69 #ifdef GNU
     70 // expected-note@+2{{previous attribute is here}}
     71 #endif
     72 int *__attribute__((dllimport)) GlobalDeclChunkAttrInit; // expected-note{{previous declaration is here}}
     73 #ifdef MS
     74 // expected-warning@+4{{'GlobalDeclChunkAttrInit' redeclared without 'dllimport' attribute: 'dllexport' attribute added}}
     75 #else
     76 // expected-warning@+2{{'GlobalDeclChunkAttrInit' redeclared without 'dllimport' attribute: previous 'dllimport' ignored}}
     77 #endif
     78 int *GlobalDeclChunkAttrInit = 0;
     79 
     80 #ifdef GNU
     81 // expected-note@+2{{previous attribute is here}}
     82 #endif
     83 int GlobalDeclAttrInit __attribute__((dllimport)); // expected-note{{previous declaration is here}}
     84 #ifdef MS
     85 // expected-warning@+4{{'GlobalDeclAttrInit' redeclared without 'dllimport' attribute: 'dllexport' attribute added}}
     86 #else
     87 // expected-warning@+2{{'GlobalDeclAttrInit' redeclared without 'dllimport' attribute: previous 'dllimport' ignored}}
     88 #endif
     89 int GlobalDeclAttrInit = 1;
     90 
     91 // Redeclarations
     92 __declspec(dllimport) extern int GlobalRedecl1;
     93 __declspec(dllimport) extern int GlobalRedecl1;
     94 
     95 __declspec(dllimport) int GlobalRedecl2a;
     96 __declspec(dllimport) int GlobalRedecl2a;
     97 
     98 int *__attribute__((dllimport)) GlobalRedecl2b;
     99 int *__attribute__((dllimport)) GlobalRedecl2b;
    100 
    101 int GlobalRedecl2c __attribute__((dllimport));
    102 int GlobalRedecl2c __attribute__((dllimport));
    103 
    104 __declspec(dllimport) extern int GlobalRedecl3; // expected-note{{previous declaration is here}} expected-note{{previous attribute is here}}
    105                       extern int GlobalRedecl3; // expected-warning{{'GlobalRedecl3' redeclared without 'dllimport' attribute: previous 'dllimport' ignored}}
    106 
    107                       extern int GlobalRedecl4; // expected-note{{previous declaration is here}}
    108 __declspec(dllimport) extern int GlobalRedecl4; // expected-warning{{redeclaration of 'GlobalRedecl4' should not add 'dllimport' attribute}}
    109 
    110 extern "C" {
    111                       extern int GlobalRedecl5; // expected-note{{previous declaration is here}}
    112 __declspec(dllimport) extern int GlobalRedecl5; // expected-warning{{redeclaration of 'GlobalRedecl5' should not add 'dllimport' attribute}}
    113 }
    114 
    115 // External linkage is required.
    116 __declspec(dllimport) static int StaticGlobal; // expected-error{{'StaticGlobal' must have external linkage when declared 'dllimport'}}
    117 __declspec(dllimport) Internal InternalTypeGlobal; // expected-error{{'InternalTypeGlobal' must have external linkage when declared 'dllimport'}}
    118 namespace    { __declspec(dllimport) int InternalGlobal; } // expected-error{{'(anonymous namespace)::InternalGlobal' must have external linkage when declared 'dllimport'}}
    119 namespace ns { __declspec(dllimport) int ExternalGlobal; }
    120 
    121 __declspec(dllimport) auto InternalAutoTypeGlobal = Internal(); // expected-error{{'InternalAutoTypeGlobal' must have external linkage when declared 'dllimport'}}
    122                                                                 // expected-error@-1{{definition of dllimport data}}
    123 
    124 // Thread local variables are invalid.
    125 __declspec(dllimport) __thread int ThreadLocalGlobal; // expected-error{{'ThreadLocalGlobal' cannot be thread local when declared 'dllimport'}}
    126 // This doesn't work on MinGW, because there, dllimport on the inline function is ignored.
    127 #ifndef GNU
    128 inline void __declspec(dllimport) ImportedInlineWithThreadLocal() {
    129   static __thread int OK; // no-error
    130 }
    131 #endif
    132 
    133 // Import in local scope.
    134 __declspec(dllimport) float LocalRedecl1; // expected-note{{previous declaration is here}}
    135 __declspec(dllimport) float LocalRedecl2; // expected-note{{previous declaration is here}}
    136 __declspec(dllimport) float LocalRedecl3; // expected-note{{previous declaration is here}}
    137 void functionScope() {
    138   __declspec(dllimport) int LocalRedecl1; // expected-error{{redeclaration of 'LocalRedecl1' with a different type: 'int' vs 'float'}}
    139   int *__attribute__((dllimport)) LocalRedecl2; // expected-error{{redeclaration of 'LocalRedecl2' with a different type: 'int *' vs 'float'}}
    140   int LocalRedecl3 __attribute__((dllimport)); // expected-error{{redeclaration of 'LocalRedecl3' with a different type: 'int' vs 'float'}}
    141 
    142   __declspec(dllimport)        int LocalVarDecl;
    143   __declspec(dllimport)        int LocalVarDef = 1; // expected-error{{definition of dllimport data}}
    144   __declspec(dllimport) extern int ExternLocalVarDecl;
    145   __declspec(dllimport) extern int ExternLocalVarDef = 1; // expected-error{{definition of dllimport data}}
    146   __declspec(dllimport) static int StaticLocalVar; // expected-error{{'StaticLocalVar' must have external linkage when declared 'dllimport'}}
    147 }
    148 
    149 
    150 
    151 //===----------------------------------------------------------------------===//
    152 // Variable templates
    153 //===----------------------------------------------------------------------===//
    154 #if __has_feature(cxx_variable_templates)
    155 
    156 // Import declaration.
    157 template<typename T> __declspec(dllimport) extern int ExternVarTmplDecl;
    158 
    159 // dllimport implies a declaration.
    160 template<typename T> __declspec(dllimport) int VarTmplDecl;
    161 
    162 // Not allowed on definitions.
    163 template<typename T> __declspec(dllimport) extern int ExternVarTmplInit = 1; // expected-error{{definition of dllimport data}}
    164 template<typename T> __declspec(dllimport) int VarTmplInit1 = 1; // expected-error{{definition of dllimport data}}
    165 template<typename T> int __declspec(dllimport) VarTmplInit2 = 1; // expected-error{{definition of dllimport data}}
    166 
    167 // Declare, then reject definition.
    168 #ifdef GNU
    169 // expected-note@+3{{previous attribute is here}}
    170 #endif
    171 template <typename T>
    172 __declspec(dllimport) extern int ExternVarTmplDeclInit; // expected-note{{previous declaration is here}}
    173 #ifdef MS
    174 // expected-warning@+5{{'ExternVarTmplDeclInit' redeclared without 'dllimport' attribute: 'dllexport' attribute added}}
    175 #else
    176 // expected-warning@+3{{'ExternVarTmplDeclInit' redeclared without 'dllimport' attribute: previous 'dllimport' ignored}}
    177 #endif
    178 template <typename T>
    179 int ExternVarTmplDeclInit = 1;
    180 
    181 #ifdef GNU
    182 // expected-note@+3{{previous attribute is here}}
    183 #endif
    184 template <typename T>
    185 __declspec(dllimport) int VarTmplDeclInit; // expected-note{{previous declaration is here}}
    186 #ifdef MS
    187 // expected-warning@+5{{'VarTmplDeclInit' redeclared without 'dllimport' attribute: 'dllexport' attribute added}}
    188 #else
    189 // expected-warning@+3{{'VarTmplDeclInit' redeclared without 'dllimport' attribute: previous 'dllimport' ignored}}
    190 #endif
    191 template <typename T>
    192 int VarTmplDeclInit = 1;
    193 
    194 // Redeclarations
    195 template<typename T> __declspec(dllimport) extern int VarTmplRedecl1;
    196 template<typename T> __declspec(dllimport) extern int VarTmplRedecl1;
    197 
    198 template<typename T> __declspec(dllimport) int VarTmplRedecl2;
    199 template<typename T> __declspec(dllimport) int VarTmplRedecl2;
    200 
    201 template<typename T> __declspec(dllimport) extern int VarTmplRedecl3; // expected-note{{previous declaration is here}} expected-note{{previous attribute is here}}
    202 template<typename T>                       extern int VarTmplRedecl3; // expected-warning{{'VarTmplRedecl3' redeclared without 'dllimport' attribute: previous 'dllimport' ignored}}
    203 
    204 template<typename T>                       extern int VarTmplRedecl4; // expected-note{{previous declaration is here}}
    205 template<typename T> __declspec(dllimport) extern int VarTmplRedecl4; // expected-error{{redeclaration of 'VarTmplRedecl4' cannot add 'dllimport' attribute}}
    206 
    207 // External linkage is required.
    208 template<typename T> __declspec(dllimport) static int StaticVarTmpl; // expected-error{{'StaticVarTmpl' must have external linkage when declared 'dllimport'}}
    209 template<typename T> __declspec(dllimport) Internal InternalTypeVarTmpl; // expected-error{{'InternalTypeVarTmpl' must have external linkage when declared 'dllimport'}}
    210 namespace    { template<typename T> __declspec(dllimport) int InternalVarTmpl; } // expected-error{{'(anonymous namespace)::InternalVarTmpl' must have external linkage when declared 'dllimport'}}
    211 namespace ns { template<typename T> __declspec(dllimport) int ExternalVarTmpl; }
    212 
    213 template<typename T> __declspec(dllimport) auto InternalAutoTypeVarTmpl = Internal(); // expected-error{{definition of dllimport data}} // expected-error{{'InternalAutoTypeVarTmpl' must have external linkage when declared 'dllimport'}}
    214 
    215 
    216 template<typename T> int VarTmpl;
    217 template<typename T> __declspec(dllimport) int ImportedVarTmpl;
    218 
    219 // Import implicit instantiation of an imported variable template.
    220 int useVarTmpl() { return ImportedVarTmpl<ImplicitInst_Imported>; }
    221 
    222 // Import explicit instantiation declaration of an imported variable template.
    223 extern template int ImportedVarTmpl<ExplicitDecl_Imported>;
    224 
    225 // An explicit instantiation definition of an imported variable template cannot
    226 // be imported because the template must be defined which is illegal.
    227 
    228 // Import specialization of an imported variable template.
    229 template<> __declspec(dllimport) int ImportedVarTmpl<ExplicitSpec_Imported>;
    230 template<> __declspec(dllimport) int ImportedVarTmpl<ExplicitSpec_Def_Imported> = 1; // expected-error{{definition of dllimport data}}
    231 
    232 // Not importing specialization of an imported variable template without
    233 // explicit dllimport.
    234 template<> int ImportedVarTmpl<ExplicitSpec_NotImported>;
    235 
    236 
    237 // Import explicit instantiation declaration of a non-imported variable template.
    238 extern template __declspec(dllimport) int VarTmpl<ExplicitDecl_Imported>;
    239 
    240 // Import explicit instantiation definition of a non-imported variable template.
    241 template __declspec(dllimport) int VarTmpl<ExplicitInst_Imported>;
    242 
    243 // Import specialization of a non-imported variable template.
    244 template<> __declspec(dllimport) int VarTmpl<ExplicitSpec_Imported>;
    245 template<> __declspec(dllimport) int VarTmpl<ExplicitSpec_Def_Imported> = 1; // expected-error{{definition of dllimport data}}
    246 
    247 #endif // __has_feature(cxx_variable_templates)
    248 
    249 
    250 //===----------------------------------------------------------------------===//
    251 // Functions
    252 //===----------------------------------------------------------------------===//
    253 
    254 // Import function declaration. Check different placements.
    255 __attribute__((dllimport)) void decl1A(); // Sanity check with __attribute__
    256 __declspec(dllimport)      void decl1B();
    257 
    258 void __attribute__((dllimport)) decl2A();
    259 void __declspec(dllimport)      decl2B();
    260 
    261 // Not allowed on function definitions.
    262 __declspec(dllimport) void def() {} // expected-error{{dllimport cannot be applied to non-inline function definition}}
    263 
    264 // extern  "C"
    265 extern "C" __declspec(dllimport) void externC();
    266 
    267 // Import inline function.
    268 #ifdef GNU
    269 // expected-warning@+3{{'dllimport' attribute ignored on inline function}}
    270 // expected-warning@+3{{'dllimport' attribute ignored on inline function}}
    271 #endif
    272 __declspec(dllimport) inline void inlineFunc1() {}
    273 inline void __attribute__((dllimport)) inlineFunc2() {}
    274 
    275 #ifdef GNU
    276 // expected-warning@+2{{'dllimport' attribute ignored on inline function}}
    277 #endif
    278 __declspec(dllimport) inline void inlineDecl();
    279                              void inlineDecl() {}
    280 
    281 __declspec(dllimport) void inlineDef();
    282 #ifdef GNU
    283 // expected-warning@+2{{'inlineDef' redeclared inline; 'dllimport' attribute ignored}}
    284 #endif
    285                inline void inlineDef() {}
    286 
    287 // Redeclarations
    288 __declspec(dllimport) void redecl1();
    289 __declspec(dllimport) void redecl1();
    290 
    291 __declspec(dllimport) void redecl2(); // expected-note{{previous declaration is here}} expected-note{{previous attribute is here}}
    292                       void redecl2(); // expected-warning{{'redecl2' redeclared without 'dllimport' attribute: previous 'dllimport' ignored}}
    293 
    294 #ifdef GNU
    295                       // expected-note@+2{{previous attribute is here}}
    296 #endif
    297                       __declspec(dllimport) void redecl3(); // expected-note{{previous declaration is here}}
    298                       // NB: Both MSVC and Clang issue a warning and make redecl3 dllexport.
    299 #ifdef MS
    300                       // expected-warning@+4{{'redecl3' redeclared without 'dllimport' attribute: 'dllexport' attribute added}}
    301 #else
    302                       // expected-warning@+2{{'redecl3' redeclared without 'dllimport' attribute: previous 'dllimport' ignored}}
    303 #endif
    304                       void redecl3() {}
    305 
    306                       void redecl4(); // expected-note{{previous declaration is here}}
    307 __declspec(dllimport) void redecl4(); // expected-warning{{redeclaration of 'redecl4' should not add 'dllimport' attribute}}
    308 
    309 extern "C" {
    310                       void redecl5(); // expected-note{{previous declaration is here}}
    311 __declspec(dllimport) void redecl5(); // expected-warning{{redeclaration of 'redecl5' should not add 'dllimport' attribute}}
    312 }
    313 
    314 #ifdef MS
    315                       void redecl6(); // expected-note{{previous declaration is here}}
    316 __declspec(dllimport) inline void redecl6() {} // expected-warning{{redeclaration of 'redecl6' should not add 'dllimport' attribute}}
    317 #else
    318                       void redecl6();
    319 __declspec(dllimport) inline void redecl6() {} // expected-warning{{'dllimport' attribute ignored on inline function}}
    320 #endif
    321 
    322 // Friend functions
    323 struct FuncFriend {
    324   friend __declspec(dllimport) void friend1();
    325   friend __declspec(dllimport) void friend2(); // expected-note{{previous declaration is here}} expected-note{{previous attribute is here}}
    326 #ifdef GNU
    327 // expected-note@+2{{previous attribute is here}}
    328 #endif
    329   friend __declspec(dllimport) void friend3(); // expected-note{{previous declaration is here}}
    330   friend                       void friend4(); // expected-note{{previous declaration is here}}
    331 #ifdef MS
    332 // expected-note@+2{{previous declaration is here}}
    333 #endif
    334   friend                       void friend5();
    335 };
    336 __declspec(dllimport) void friend1();
    337                       void friend2(); // expected-warning{{'friend2' redeclared without 'dllimport' attribute: previous 'dllimport' ignored}}
    338 #ifdef MS
    339                       // expected-warning@+4{{'friend3' redeclared without 'dllimport' attribute: 'dllexport' attribute added}}
    340 #else
    341                       // expected-warning@+2{{'friend3' redeclared without 'dllimport' attribute: previous 'dllimport' ignored}}
    342 #endif
    343                       void friend3() {}
    344 __declspec(dllimport) void friend4(); // expected-warning{{redeclaration of 'friend4' should not add 'dllimport' attribute}}
    345 #ifdef MS
    346 __declspec(dllimport) inline void friend5() {} // expected-warning{{redeclaration of 'friend5' should not add 'dllimport' attribute}}
    347 #else
    348 __declspec(dllimport) inline void friend5() {} // expected-warning{{'dllimport' attribute ignored on inline function}}
    349 #endif
    350 
    351 
    352 void __declspec(dllimport) friend6(); // expected-note{{previous declaration is here}} expected-note{{previous attribute is here}}
    353 void __declspec(dllimport) friend7();
    354 struct FuncFriend2 {
    355   friend void friend6(); // expected-warning{{'friend6' redeclared without 'dllimport' attribute: previous 'dllimport' ignored}}
    356   friend void ::friend7();
    357 };
    358 
    359 // Implicit declarations can be redeclared with dllimport.
    360 __declspec(dllimport) void* operator new(__SIZE_TYPE__ n);
    361 
    362 // External linkage is required.
    363 __declspec(dllimport) static int staticFunc(); // expected-error{{'staticFunc' must have external linkage when declared 'dllimport'}}
    364 __declspec(dllimport) Internal internalRetFunc(); // expected-error{{'internalRetFunc' must have external linkage when declared 'dllimport'}}
    365 namespace    { __declspec(dllimport) void internalFunc(); } // expected-error{{'(anonymous namespace)::internalFunc' must have external linkage when declared 'dllimport'}}
    366 namespace ns { __declspec(dllimport) void externalFunc(); }
    367 
    368 // Import deleted functions.
    369 // FIXME: Deleted functions are definitions so a missing inline is diagnosed
    370 // here which is irrelevant. But because the delete keyword is parsed later
    371 // there is currently no straight-forward way to avoid this diagnostic.
    372 __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}}
    373 #ifdef MS
    374 __declspec(dllimport) inline void deletedInlineFunc() = delete; // expected-error{{attribute 'dllimport' cannot be applied to a deleted function}}
    375 #else
    376 __declspec(dllimport) inline void deletedInlineFunc() = delete; // expected-warning{{'dllimport' attribute ignored on inline function}}
    377 #endif
    378 
    379 
    380 
    381 //===----------------------------------------------------------------------===//
    382 // Function templates
    383 //===----------------------------------------------------------------------===//
    384 
    385 // Import function template declaration. Check different placements.
    386 template<typename T> __declspec(dllimport) void funcTmplDecl1();
    387 template<typename T> void __declspec(dllimport) funcTmplDecl2();
    388 
    389 // Import function template definition.
    390 template<typename T> __declspec(dllimport) void funcTmplDef() {} // expected-error{{dllimport cannot be applied to non-inline function definition}}
    391 
    392 // Import inline function template.
    393 #ifdef GNU
    394 // expected-warning@+5{{'dllimport' attribute ignored on inline function}}
    395 // expected-warning@+5{{'dllimport' attribute ignored on inline function}}
    396 // expected-warning@+6{{'dllimport' attribute ignored on inline function}}
    397 // expected-warning@+9{{'inlineFuncTmplDef' redeclared inline; 'dllimport' attribute ignored}}
    398 #endif
    399 template<typename T> __declspec(dllimport) inline void inlineFuncTmpl1() {}
    400 template<typename T> inline void __attribute__((dllimport)) inlineFuncTmpl2() {}
    401 
    402 template<typename T> __declspec(dllimport) inline void inlineFuncTmplDecl();
    403 template<typename T>                              void inlineFuncTmplDecl() {}
    404 
    405 template<typename T> __declspec(dllimport) void inlineFuncTmplDef();
    406 template<typename T>                inline void inlineFuncTmplDef() {}
    407 
    408 // Redeclarations
    409 template<typename T> __declspec(dllimport) void funcTmplRedecl1();
    410 template<typename T> __declspec(dllimport) void funcTmplRedecl1();
    411 
    412 template<typename T> __declspec(dllimport) void funcTmplRedecl2(); // expected-note{{previous declaration is here}} expected-note{{previous attribute is here}}
    413 template<typename T>                       void funcTmplRedecl2(); // expected-warning{{'funcTmplRedecl2' redeclared without 'dllimport' attribute: previous 'dllimport' ignored}}
    414 
    415 template<typename T> __declspec(dllimport) void funcTmplRedecl3(); // expected-note{{previous declaration is here}} expected-note{{previous attribute is here}}
    416 template<typename T>                       void funcTmplRedecl3() {} // expected-warning{{'funcTmplRedecl3' redeclared without 'dllimport' attribute: previous 'dllimport' ignored}}
    417 
    418 template<typename T>                       void funcTmplRedecl4(); // expected-note{{previous declaration is here}}
    419 template<typename T> __declspec(dllimport) void funcTmplRedecl4(); // expected-error{{redeclaration of 'funcTmplRedecl4' cannot add 'dllimport' attribute}}
    420 
    421 #ifdef MS
    422 template<typename T>                       void funcTmplRedecl5(); // expected-note{{previous declaration is here}}
    423 template<typename T> __declspec(dllimport) inline void funcTmplRedecl5() {} // expected-error{{redeclaration of 'funcTmplRedecl5' cannot add 'dllimport' attribute}}
    424 #endif
    425 
    426 // Function template friends
    427 struct FuncTmplFriend {
    428   template<typename T> friend __declspec(dllimport) void funcTmplFriend1();
    429   template<typename T> friend __declspec(dllimport) void funcTmplFriend2(); // expected-note{{previous declaration is here}} expected-note{{previous attribute is here}}
    430   template<typename T> friend __declspec(dllimport) void funcTmplFriend3(); // expected-note{{previous declaration is here}} expected-note{{previous attribute is here}}
    431   template<typename T> friend                       void funcTmplFriend4(); // expected-note{{previous declaration is here}}
    432 #ifdef GNU
    433 // expected-warning@+2{{'dllimport' attribute ignored on inline function}}
    434 #endif
    435   template<typename T> friend __declspec(dllimport) inline void funcTmplFriend5();
    436 };
    437 template<typename T> __declspec(dllimport) void funcTmplFriend1();
    438 template<typename T>                       void funcTmplFriend2(); // expected-warning{{'funcTmplFriend2' redeclared without 'dllimport' attribute: previous 'dllimport' ignored}}
    439 template<typename T>                       void funcTmplFriend3() {} // expected-warning{{'funcTmplFriend3' redeclared without 'dllimport' attribute: previous 'dllimport' ignored}}
    440 template<typename T> __declspec(dllimport) void funcTmplFriend4(); // expected-error{{redeclaration of 'funcTmplFriend4' cannot add 'dllimport' attribute}}
    441 template<typename T>                       inline void funcTmplFriend5() {}
    442 
    443 // External linkage is required.
    444 template<typename T> __declspec(dllimport) static int staticFuncTmpl(); // expected-error{{'staticFuncTmpl' must have external linkage when declared 'dllimport'}}
    445 template<typename T> __declspec(dllimport) Internal internalRetFuncTmpl(); // expected-error{{'internalRetFuncTmpl' must have external linkage when declared 'dllimport'}}
    446 namespace    { template<typename T> __declspec(dllimport) void internalFuncTmpl(); } // expected-error{{'(anonymous namespace)::internalFuncTmpl' must have external linkage when declared 'dllimport'}}
    447 namespace ns { template<typename T> __declspec(dllimport) void externalFuncTmpl(); }
    448 
    449 
    450 template<typename T> void funcTmpl() {}
    451 template<typename T> inline void inlineFuncTmpl() {}
    452 template<typename T> __declspec(dllimport) void importedFuncTmplDecl();
    453 #ifdef GNU
    454 // expected-warning@+2{{'dllimport' attribute ignored on inline function}}
    455 #endif
    456 template<typename T> __declspec(dllimport) inline void importedFuncTmpl() {}
    457 
    458 // Import implicit instantiation of an imported function template.
    459 void useFunTmplDecl() { importedFuncTmplDecl<ImplicitInst_Imported>(); }
    460 void useFunTmplDef() { importedFuncTmpl<ImplicitInst_Imported>(); }
    461 
    462 // Import explicit instantiation declaration of an imported function template.
    463 extern template void importedFuncTmpl<ExplicitDecl_Imported>();
    464 
    465 // Import explicit instantiation definition of an imported function template.
    466 // NB: MSVC fails this instantiation without explicit dllimport which is most
    467 // likely a bug because an implicit instantiation is accepted.
    468 template void importedFuncTmpl<ExplicitInst_Imported>();
    469 
    470 // Import specialization of an imported function template. A definition must be
    471 // declared inline.
    472 template<> __declspec(dllimport) void importedFuncTmpl<ExplicitSpec_Imported>();
    473 template<> __declspec(dllimport) void importedFuncTmpl<ExplicitSpec_Def_Imported>() {} // expected-error{{dllimport cannot be applied to non-inline function definition}}
    474 #ifdef MS
    475 template<> __declspec(dllimport) inline void importedFuncTmpl<ExplicitSpec_InlineDef_Imported>() {}
    476 #endif
    477 
    478 // Not importing specialization of an imported function template without
    479 // explicit dllimport.
    480 template<> void importedFuncTmpl<ExplicitSpec_NotImported>() {}
    481 
    482 
    483 // Import explicit instantiation declaration of a non-imported function template.
    484 extern template __declspec(dllimport) void funcTmpl<ExplicitDecl_Imported>();
    485 #ifdef GNU
    486 // expected-warning@+2{{'dllimport' attribute ignored on inline function}}
    487 #endif
    488 extern template __declspec(dllimport) void inlineFuncTmpl<ExplicitDecl_Imported>();
    489 
    490 // Import explicit instantiation definition of a non-imported function template.
    491 template __declspec(dllimport) void funcTmpl<ExplicitInst_Imported>();
    492 #ifdef GNU
    493 // expected-warning@+2{{'dllimport' attribute ignored on inline function}}
    494 #endif
    495 template __declspec(dllimport) void inlineFuncTmpl<ExplicitInst_Imported>();
    496 
    497 // Import specialization of a non-imported function template. A definition must
    498 // be declared inline.
    499 template<> __declspec(dllimport) void funcTmpl<ExplicitSpec_Imported>();
    500 template<> __declspec(dllimport) void funcTmpl<ExplicitSpec_Def_Imported>() {} // expected-error{{dllimport cannot be applied to non-inline function definition}}
    501 #ifdef GNU
    502 // expected-warning@+2{{'dllimport' attribute ignored on inline function}}
    503 #endif
    504 template<> __declspec(dllimport) inline void funcTmpl<ExplicitSpec_InlineDef_Imported>() {}
    505 
    506 
    507 //===----------------------------------------------------------------------===//
    508 // Class members
    509 //===----------------------------------------------------------------------===//
    510 
    511 // Import individual members of a class.
    512 struct ImportMembers {
    513   struct Nested {
    514     __declspec(dllimport) void normalDecl();
    515 #ifdef GNU
    516 // expected-note@+2{{previous attribute is here}}
    517 #endif
    518     __declspec(dllimport) void normalDef(); // expected-note{{previous declaration is here}}
    519   };
    520 
    521 #ifdef GNU
    522 // expected-note@+5{{previous attribute is here}}
    523 // expected-warning@+5{{'dllimport' attribute ignored on inline function}}
    524 // expected-warning@+6{{'dllimport' attribute ignored on inline function}}
    525 #endif
    526   __declspec(dllimport)                void normalDecl();
    527   __declspec(dllimport) void normalDef(); // expected-note{{previous declaration is here}}
    528   __declspec(dllimport)                void normalInclass() {}
    529   __declspec(dllimport)                void normalInlineDef();
    530   __declspec(dllimport)         inline void normalInlineDecl();
    531 #ifdef GNU
    532 // expected-note@+5{{previous attribute is here}}
    533 // expected-warning@+5{{'dllimport' attribute ignored on inline function}}
    534 // expected-warning@+6{{'dllimport' attribute ignored on inline function}}
    535 #endif
    536   __declspec(dllimport) virtual        void virtualDecl();
    537   __declspec(dllimport) virtual void virtualDef(); // expected-note{{previous declaration is here}}
    538   __declspec(dllimport) virtual        void virtualInclass() {}
    539   __declspec(dllimport) virtual        void virtualInlineDef();
    540   __declspec(dllimport) virtual inline void virtualInlineDecl();
    541 #ifdef GNU
    542 // expected-note@+5{{previous attribute is here}}
    543 // expected-warning@+5{{'dllimport' attribute ignored on inline function}}
    544 // expected-warning@+6{{'dllimport' attribute ignored on inline function}}
    545 #endif
    546   __declspec(dllimport) static         void staticDecl();
    547   __declspec(dllimport) static void staticDef(); // expected-note{{previous declaration is here}}
    548   __declspec(dllimport) static         void staticInclass() {}
    549   __declspec(dllimport) static         void staticInlineDef();
    550   __declspec(dllimport) static  inline void staticInlineDecl();
    551 
    552 protected:
    553   __declspec(dllimport)                void protectedDecl();
    554 private:
    555   __declspec(dllimport)                void privateDecl();
    556 public:
    557 
    558   __declspec(dllimport)                int  Field; // expected-warning{{'dllimport' attribute only applies to variables, functions and classes}}
    559   __declspec(dllimport) static         int  StaticField;
    560   __declspec(dllimport) static         int  StaticFieldDef; // expected-note{{attribute is here}}
    561   __declspec(dllimport) static  const  int  StaticConstField;
    562   __declspec(dllimport) static  const  int  StaticConstFieldDef; // expected-note{{attribute is here}}
    563   __declspec(dllimport) static  const  int  StaticConstFieldEqualInit = 1;
    564   __declspec(dllimport) static  const  int  StaticConstFieldBraceInit{1};
    565   __declspec(dllimport) constexpr static int ConstexprField = 1;
    566   __declspec(dllimport) constexpr static int ConstexprFieldDef = 1; // expected-note{{attribute is here}}
    567 };
    568 
    569 #ifdef MS
    570 // expected-warning@+4{{'ImportMembers::Nested::normalDef' redeclared without 'dllimport' attribute: 'dllexport' attribute added}}
    571 #else
    572                                                                                  // expected-warning@+2{{'ImportMembers::Nested::normalDef' redeclared without 'dllimport' attribute: previous 'dllimport' ignored}}
    573 #endif
    574 void ImportMembers::Nested::normalDef() {}
    575 #ifdef MS
    576 // expected-warning@+4{{'ImportMembers::normalDef' redeclared without 'dllimport' attribute: 'dllexport' attribute added}}
    577 #else
    578                                                                                  // expected-warning@+2{{'ImportMembers::normalDef' redeclared without 'dllimport' attribute: previous 'dllimport' ignored}}
    579 #endif
    580 void ImportMembers::normalDef() {}
    581 #ifdef GNU
    582 // expected-warning@+2{{'ImportMembers::normalInlineDef' redeclared inline; 'dllimport' attribute ignored}}
    583 #endif
    584 inline void ImportMembers::normalInlineDef() {}
    585        void ImportMembers::normalInlineDecl() {}
    586 #ifdef MS
    587        // expected-warning@+4{{'ImportMembers::virtualDef' redeclared without 'dllimport' attribute: 'dllexport' attribute added}}
    588 #else
    589                                                                                  // expected-warning@+2{{'ImportMembers::virtualDef' redeclared without 'dllimport' attribute: previous 'dllimport' ignored}}
    590 #endif
    591        void ImportMembers::virtualDef() {}
    592 #ifdef GNU
    593 // expected-warning@+2{{'ImportMembers::virtualInlineDef' redeclared inline; 'dllimport' attribute ignored}}
    594 #endif
    595 inline void ImportMembers::virtualInlineDef() {}
    596        void ImportMembers::virtualInlineDecl() {}
    597 #ifdef MS
    598        // expected-warning@+4{{'ImportMembers::staticDef' redeclared without 'dllimport' attribute: 'dllexport' attribute added}}
    599 #else
    600                                                                                  // expected-warning@+2{{'ImportMembers::staticDef' redeclared without 'dllimport' attribute: previous 'dllimport' ignored}}
    601 #endif
    602        void ImportMembers::staticDef() {}
    603 #ifdef GNU
    604 // expected-warning@+2{{'ImportMembers::staticInlineDef' redeclared inline; 'dllimport' attribute ignored}}
    605 #endif
    606 inline void ImportMembers::staticInlineDef() {}
    607        void ImportMembers::staticInlineDecl() {}
    608 
    609        int  ImportMembers::StaticFieldDef; // expected-error{{definition of dllimport static field not allowed}}
    610 const  int  ImportMembers::StaticConstFieldDef = 1; // expected-error{{definition of dllimport static field not allowed}}
    611 constexpr int ImportMembers::ConstexprFieldDef; // expected-error{{definition of dllimport static field not allowed}}
    612 
    613 
    614 // Import on member definitions.
    615 struct ImportMemberDefs {
    616   __declspec(dllimport)                void normalDef();
    617   __declspec(dllimport)                void normalInlineDef();
    618   __declspec(dllimport) virtual        void virtualDef();
    619   __declspec(dllimport) virtual        void virtualInlineDef();
    620   __declspec(dllimport) static         void staticDef();
    621   __declspec(dllimport) static         void staticInlineDef();
    622 #ifdef MS
    623   __declspec(dllimport)         inline void normalInlineDecl();
    624   __declspec(dllimport) virtual inline void virtualInlineDecl();
    625   __declspec(dllimport) static  inline void staticInlineDecl();
    626 #endif
    627 
    628   __declspec(dllimport) static         int  StaticField;
    629   __declspec(dllimport) static  const  int  StaticConstField;
    630   __declspec(dllimport) constexpr static int ConstexprField = 1;
    631 };
    632 
    633 __declspec(dllimport)        void ImportMemberDefs::normalDef() {} // expected-error{{dllimport cannot be applied to non-inline function definition}}
    634 __declspec(dllimport)        void ImportMemberDefs::virtualDef() {} // expected-error{{dllimport cannot be applied to non-inline function definition}}
    635 __declspec(dllimport)        void ImportMemberDefs::staticDef() {} // expected-error{{dllimport cannot be applied to non-inline function definition}}
    636 #ifdef MS
    637 __declspec(dllimport) inline void ImportMemberDefs::normalInlineDef() {}
    638 __declspec(dllimport)        void ImportMemberDefs::normalInlineDecl() {}
    639 __declspec(dllimport) inline void ImportMemberDefs::virtualInlineDef() {}
    640 __declspec(dllimport)        void ImportMemberDefs::virtualInlineDecl() {}
    641 __declspec(dllimport) inline void ImportMemberDefs::staticInlineDef() {}
    642 __declspec(dllimport)        void ImportMemberDefs::staticInlineDecl() {}
    643 #endif
    644 
    645 __declspec(dllimport)        int  ImportMemberDefs::StaticField; // expected-error{{definition of dllimport static field not allowed}} expected-note{{attribute is here}}
    646 __declspec(dllimport) const  int  ImportMemberDefs::StaticConstField = 1; // expected-error{{definition of dllimport static field not allowed}} expected-note{{attribute is here}}
    647 __declspec(dllimport) constexpr int ImportMemberDefs::ConstexprField; // expected-error{{definition of dllimport static field not allowed}} expected-note{{attribute is here}}
    648 
    649 
    650 // Import special member functions.
    651 struct ImportSpecials {
    652   __declspec(dllimport) ImportSpecials();
    653   __declspec(dllimport) ~ImportSpecials();
    654   __declspec(dllimport) ImportSpecials(const ImportSpecials&);
    655   __declspec(dllimport) ImportSpecials& operator=(const ImportSpecials&);
    656   __declspec(dllimport) ImportSpecials(ImportSpecials&&);
    657   __declspec(dllimport) ImportSpecials& operator=(ImportSpecials&&);
    658 };
    659 
    660 
    661 // Import deleted member functions.
    662 struct ImportDeleted {
    663 #ifdef MS
    664   __declspec(dllimport) ImportDeleted() = delete; // expected-error{{attribute 'dllimport' cannot be applied to a deleted function}}
    665   __declspec(dllimport) ~ImportDeleted() = delete; // expected-error{{attribute 'dllimport' cannot be applied to a deleted function}}
    666   __declspec(dllimport) ImportDeleted(const ImportDeleted&) = delete; // expected-error{{attribute 'dllimport' cannot be applied to a deleted function}}
    667   __declspec(dllimport) ImportDeleted& operator=(const ImportDeleted&) = delete; // expected-error{{attribute 'dllimport' cannot be applied to a deleted function}}
    668   __declspec(dllimport) ImportDeleted(ImportDeleted&&) = delete; // expected-error{{attribute 'dllimport' cannot be applied to a deleted function}}
    669   __declspec(dllimport) ImportDeleted& operator=(ImportDeleted&&) = delete; // expected-error{{attribute 'dllimport' cannot be applied to a deleted function}}
    670   __declspec(dllimport) void deleted() = delete; // expected-error{{attribute 'dllimport' cannot be applied to a deleted function}}
    671 #else
    672   __declspec(dllimport) ImportDeleted() = delete; // expected-warning{{'dllimport' attribute ignored on inline function}}
    673   __declspec(dllimport) ~ImportDeleted() = delete; // expected-warning{{'dllimport' attribute ignored on inline function}}
    674   __declspec(dllimport) ImportDeleted(const ImportDeleted&) = delete; // expected-warning{{'dllimport' attribute ignored on inline function}}
    675   __declspec(dllimport) ImportDeleted& operator=(const ImportDeleted&) = delete; // expected-warning{{'dllimport' attribute ignored on inline function}}
    676   __declspec(dllimport) ImportDeleted(ImportDeleted&&) = delete; // expected-warning{{'dllimport' attribute ignored on inline function}}
    677   __declspec(dllimport) ImportDeleted& operator=(ImportDeleted&&) = delete; // expected-warning{{'dllimport' attribute ignored on inline function}}
    678   __declspec(dllimport) void deleted() = delete; // expected-warning{{'dllimport' attribute ignored on inline function}}
    679 #endif
    680 };
    681 
    682 
    683 // Import allocation functions.
    684 struct ImportAlloc {
    685   __declspec(dllimport) void* operator new(__SIZE_TYPE__);
    686   __declspec(dllimport) void* operator new[](__SIZE_TYPE__);
    687   __declspec(dllimport) void operator delete(void*);
    688   __declspec(dllimport) void operator delete[](void*);
    689 };
    690 
    691 
    692 // Import defaulted member functions.
    693 struct ImportDefaulted {
    694 #ifdef GNU
    695   // expected-warning@+7{{'dllimport' attribute ignored on inline function}}
    696   // expected-warning@+7{{'dllimport' attribute ignored on inline function}}
    697   // expected-warning@+7{{'dllimport' attribute ignored on inline function}}
    698   // expected-warning@+7{{'dllimport' attribute ignored on inline function}}
    699   // expected-warning@+7{{'dllimport' attribute ignored on inline function}}
    700   // expected-warning@+7{{'dllimport' attribute ignored on inline function}}
    701 #endif
    702   __declspec(dllimport) ImportDefaulted() = default;
    703   __declspec(dllimport) ~ImportDefaulted() = default;
    704   __declspec(dllimport) ImportDefaulted(const ImportDefaulted&) = default;
    705   __declspec(dllimport) ImportDefaulted& operator=(const ImportDefaulted&) = default;
    706   __declspec(dllimport) ImportDefaulted(ImportDefaulted&&) = default;
    707   __declspec(dllimport) ImportDefaulted& operator=(ImportDefaulted&&) = default;
    708 };
    709 
    710 
    711 // Import defaulted member function definitions.
    712 struct ImportDefaultedDefs {
    713   __declspec(dllimport) ImportDefaultedDefs();
    714 #ifdef GNU
    715 // expected-note@+2{{previous attribute is here}}
    716 #endif
    717   __declspec(dllimport) ~ImportDefaultedDefs(); // expected-note{{previous declaration is here}}
    718 
    719 #ifdef GNU
    720 // expected-warning@+3{{'dllimport' attribute ignored on inline function}}
    721 // expected-note@+2{{previous declaration is here}}
    722 #endif
    723   __declspec(dllimport) inline ImportDefaultedDefs(const ImportDefaultedDefs&);
    724   __declspec(dllimport) ImportDefaultedDefs& operator=(const ImportDefaultedDefs&);
    725 
    726   __declspec(dllimport) ImportDefaultedDefs(ImportDefaultedDefs&&);
    727 #ifdef GNU
    728 // expected-note@+2{{previous attribute is here}}
    729 #endif
    730   __declspec(dllimport) ImportDefaultedDefs &operator=(ImportDefaultedDefs &&); // expected-note{{previous declaration is here}}
    731 };
    732 
    733 // Not allowed on definitions.
    734 __declspec(dllimport) ImportDefaultedDefs::ImportDefaultedDefs() = default; // expected-error{{dllimport cannot be applied to non-inline function definition}}
    735 
    736 #ifdef MS
    737 // expected-warning@+5{{'ImportDefaultedDefs::~ImportDefaultedDefs' redeclared without 'dllimport' attribute: 'dllexport' attribute added}}
    738 #else
    739 // expected-warning@+3{{'ImportDefaultedDefs::~ImportDefaultedDefs' redeclared without 'dllimport' attribute: previous 'dllimport' ignored}}
    740 #endif
    741 // dllimport cannot be dropped.
    742 ImportDefaultedDefs::~ImportDefaultedDefs() = default;
    743 
    744 // Import inline declaration and definition.
    745 #ifdef GNU
    746 // expected-error@+3{{redeclaration of 'ImportDefaultedDefs::ImportDefaultedDefs' cannot add 'dllimport' attribute}}
    747 // expected-warning@+3{{'ImportDefaultedDefs::operator=' redeclared inline; 'dllimport' attribute ignored}}
    748 #endif
    749 __declspec(dllimport) ImportDefaultedDefs::ImportDefaultedDefs(const ImportDefaultedDefs&) = default;
    750 inline ImportDefaultedDefs& ImportDefaultedDefs::operator=(const ImportDefaultedDefs&) = default;
    751 
    752 __declspec(dllimport) ImportDefaultedDefs::ImportDefaultedDefs(ImportDefaultedDefs&&) = default; // expected-error{{dllimport cannot be applied to non-inline function definition}}
    753 #ifdef MS
    754 // expected-warning@+4{{'ImportDefaultedDefs::operator=' redeclared without 'dllimport' attribute: 'dllexport' attribute added}}
    755 #else
    756 // expected-warning@+2{{'ImportDefaultedDefs::operator=' redeclared without 'dllimport' attribute: previous 'dllimport' ignored}}
    757 #endif
    758 ImportDefaultedDefs &ImportDefaultedDefs::operator=(ImportDefaultedDefs &&) = default;
    759 
    760 // Redeclarations cannot add dllimport.
    761 struct MemberRedecl {
    762                  void normalDef();         // expected-note{{previous declaration is here}}
    763           inline void normalInlineDecl();  // expected-note{{previous declaration is here}}
    764   virtual        void virtualDef();        // expected-note{{previous declaration is here}}
    765   virtual inline void virtualInlineDecl(); // expected-note{{previous declaration is here}}
    766   static         void staticDef();         // expected-note{{previous declaration is here}}
    767   static  inline void staticInlineDecl();  // expected-note{{previous declaration is here}}
    768 
    769 #ifdef MS
    770   // expected-note@+4{{previous declaration is here}}
    771   // expected-note@+4{{previous declaration is here}}
    772   // expected-note@+4{{previous declaration is here}}
    773 #endif
    774                  void normalInlineDef();
    775   virtual        void virtualInlineDef();
    776   static         void staticInlineDef();
    777 
    778   static         int  StaticField;         // expected-note{{previous declaration is here}}
    779   static  const  int  StaticConstField;    // expected-note{{previous declaration is here}}
    780   constexpr static int ConstexprField = 1; // expected-note{{previous declaration is here}}
    781 };
    782 
    783 __declspec(dllimport)        void MemberRedecl::normalDef() {}         // expected-error{{redeclaration of 'MemberRedecl::normalDef' cannot add 'dllimport' attribute}}
    784                                                                        // expected-error@-1{{dllimport cannot be applied to non-inline function definition}}
    785 __declspec(dllimport)        void MemberRedecl::normalInlineDecl() {}  // expected-error{{redeclaration of 'MemberRedecl::normalInlineDecl' cannot add 'dllimport' attribute}}
    786 __declspec(dllimport)        void MemberRedecl::virtualDef() {}        // expected-error{{redeclaration of 'MemberRedecl::virtualDef' cannot add 'dllimport' attribute}}
    787                                                                        // expected-error@-1{{dllimport cannot be applied to non-inline function definition}}
    788 __declspec(dllimport)        void MemberRedecl::virtualInlineDecl() {} // expected-error{{redeclaration of 'MemberRedecl::virtualInlineDecl' cannot add 'dllimport' attribute}}
    789 __declspec(dllimport)        void MemberRedecl::staticDef() {}         // expected-error{{redeclaration of 'MemberRedecl::staticDef' cannot add 'dllimport' attribute}}
    790                                                                        // expected-error@-1{{dllimport cannot be applied to non-inline function definition}}
    791 __declspec(dllimport)        void MemberRedecl::staticInlineDecl() {}  // expected-error{{redeclaration of 'MemberRedecl::staticInlineDecl' cannot add 'dllimport' attribute}}
    792 
    793 #ifdef MS
    794 __declspec(dllimport) inline void MemberRedecl::normalInlineDef() {}   // expected-error{{redeclaration of 'MemberRedecl::normalInlineDef' cannot add 'dllimport' attribute}}
    795 __declspec(dllimport) inline void MemberRedecl::virtualInlineDef() {}  // expected-error{{redeclaration of 'MemberRedecl::virtualInlineDef' cannot add 'dllimport' attribute}}
    796 __declspec(dllimport) inline void MemberRedecl::staticInlineDef() {}   // expected-error{{redeclaration of 'MemberRedecl::staticInlineDef' cannot add 'dllimport' attribute}}
    797 #else
    798 __declspec(dllimport) inline void MemberRedecl::normalInlineDef() {}   // expected-warning{{'dllimport' attribute ignored on inline function}}
    799 __declspec(dllimport) inline void MemberRedecl::virtualInlineDef() {}  // expected-warning{{'dllimport' attribute ignored on inline function}}
    800 __declspec(dllimport) inline void MemberRedecl::staticInlineDef() {}   // expected-warning{{'dllimport' attribute ignored on inline function}}
    801 #endif
    802 
    803 
    804 
    805 __declspec(dllimport)        int  MemberRedecl::StaticField = 1;       // expected-error{{redeclaration of 'MemberRedecl::StaticField' cannot add 'dllimport' attribute}}
    806                                                                        // expected-error@-1{{definition of dllimport static field not allowed}}
    807                                                                        // expected-note@-2{{attribute is here}}
    808 __declspec(dllimport) const  int  MemberRedecl::StaticConstField = 1;  // expected-error{{redeclaration of 'MemberRedecl::StaticConstField' cannot add 'dllimport' attribute}}
    809                                                                        // expected-error@-1{{definition of dllimport static field not allowed}}
    810                                                                        // expected-note@-2{{attribute is here}}
    811 __declspec(dllimport) constexpr int MemberRedecl::ConstexprField;      // expected-error{{redeclaration of 'MemberRedecl::ConstexprField' cannot add 'dllimport' attribute}}
    812                                                                        // expected-error@-1{{definition of dllimport static field not allowed}}
    813                                                                        // expected-note@-2{{attribute is here}}
    814 
    815 
    816 
    817 //===----------------------------------------------------------------------===//
    818 // Class member templates
    819 //===----------------------------------------------------------------------===//
    820 
    821 struct ImportMemberTmpl {
    822   template<typename T> __declspec(dllimport)               void normalDecl();
    823   template<typename T> __declspec(dllimport)               void normalDef(); // expected-note{{previous declaration is here}} expected-note{{previous attribute is here}}
    824   template<typename T> __declspec(dllimport)               void normalInlineDef();
    825   template<typename T> __declspec(dllimport) static        void staticDecl();
    826   template<typename T> __declspec(dllimport) static        void staticDef(); // expected-note{{previous declaration is here}} expected-note{{previous attribute is here}}
    827   template<typename T> __declspec(dllimport) static        void staticInlineDef();
    828 
    829 #ifdef GNU
    830   // expected-warning@+5{{'dllimport' attribute ignored on inline function}}
    831   // expected-warning@+5{{'dllimport' attribute ignored on inline function}}
    832   // expected-warning@+5{{'dllimport' attribute ignored on inline function}}
    833   // expected-warning@+5{{'dllimport' attribute ignored on inline function}}
    834 #endif
    835   template<typename T> __declspec(dllimport)               void normalInclass() {}
    836   template<typename T> __declspec(dllimport)        inline void normalInlineDecl();
    837   template<typename T> __declspec(dllimport) static        void staticInclass() {}
    838   template<typename T> __declspec(dllimport) static inline void staticInlineDecl();
    839 
    840 #if __has_feature(cxx_variable_templates)
    841   template<typename T> __declspec(dllimport) static        int  StaticField;
    842   template<typename T> __declspec(dllimport) static        int  StaticFieldDef; // expected-note{{attribute is here}}
    843   template<typename T> __declspec(dllimport) static const  int  StaticConstField;
    844   template<typename T> __declspec(dllimport) static const  int  StaticConstFieldDef; // expected-note{{attribute is here}}
    845   template<typename T> __declspec(dllimport) static const  int  StaticConstFieldEqualInit = 1;
    846   template<typename T> __declspec(dllimport) static const  int  StaticConstFieldBraceInit{1};
    847   template<typename T> __declspec(dllimport) constexpr static int ConstexprField = 1;
    848   template<typename T> __declspec(dllimport) constexpr static int ConstexprFieldDef = 1; // expected-note{{attribute is here}}
    849 #endif // __has_feature(cxx_variable_templates)
    850 };
    851 
    852 template<typename T>        void ImportMemberTmpl::normalDef() {} // expected-warning{{'ImportMemberTmpl::normalDef' redeclared without 'dllimport' attribute: previous 'dllimport' ignored}}
    853 template<typename T>        void ImportMemberTmpl::normalInlineDecl() {}
    854 template<typename T>        void ImportMemberTmpl::staticDef() {} // expected-warning{{'ImportMemberTmpl::staticDef' redeclared without 'dllimport' attribute: previous 'dllimport' ignored}}
    855 template<typename T>        void ImportMemberTmpl::staticInlineDecl() {}
    856 
    857 #ifdef GNU
    858 // expected-warning@+3{{ImportMemberTmpl::normalInlineDef' redeclared inline; 'dllimport' attribute ignored}}
    859 // expected-warning@+3{{ImportMemberTmpl::staticInlineDef' redeclared inline; 'dllimport' attribute ignored}}
    860 #endif
    861 template<typename T> inline void ImportMemberTmpl::normalInlineDef() {}
    862 template<typename T> inline void ImportMemberTmpl::staticInlineDef() {}
    863 
    864 #if __has_feature(cxx_variable_templates)
    865 template<typename T>        int  ImportMemberTmpl::StaticFieldDef; // expected-error{{definition of dllimport static field not allowed}}
    866 template<typename T> const  int  ImportMemberTmpl::StaticConstFieldDef = 1; // expected-error{{definition of dllimport static field not allowed}}
    867 template<typename T> constexpr int ImportMemberTmpl::ConstexprFieldDef; // expected-error{{definition of dllimport static field not allowed}}
    868 #endif // __has_feature(cxx_variable_templates)
    869 
    870 
    871 // Redeclarations cannot add dllimport.
    872 struct MemTmplRedecl {
    873   template<typename T>               void normalDef();         // expected-note{{previous declaration is here}}
    874   template<typename T>        inline void normalInlineDecl();  // expected-note{{previous declaration is here}}
    875   template<typename T> static        void staticDef();         // expected-note{{previous declaration is here}}
    876   template<typename T> static inline void staticInlineDecl();  // expected-note{{previous declaration is here}}
    877 
    878 #ifdef MS
    879 // expected-note@+3{{previous declaration is here}}
    880 // expected-note@+3{{previous declaration is here}}
    881 #endif
    882   template<typename T>               void normalInlineDef();
    883   template<typename T> static        void staticInlineDef();
    884 
    885 #if __has_feature(cxx_variable_templates)
    886   template<typename T> static        int  StaticField;         // expected-note{{previous declaration is here}}
    887   template<typename T> static const  int  StaticConstField;    // expected-note{{previous declaration is here}}
    888   template<typename T> constexpr static int ConstexprField = 1; // expected-note{{previous declaration is here}}
    889 #endif // __has_feature(cxx_variable_templates)
    890 };
    891 
    892 template<typename T> __declspec(dllimport)        void MemTmplRedecl::normalDef() {}        // expected-error{{redeclaration of 'MemTmplRedecl::normalDef' cannot add 'dllimport' attribute}}
    893                                                                                             // expected-error@-1{{dllimport cannot be applied to non-inline function definition}}
    894 #ifdef MS
    895 template<typename T> __declspec(dllimport) inline void MemTmplRedecl::normalInlineDef() {}  // expected-error{{redeclaration of 'MemTmplRedecl::normalInlineDef' cannot add 'dllimport' attribute}}
    896 #else
    897 template<typename T> __declspec(dllimport) inline void MemTmplRedecl::normalInlineDef() {}  // expected-warning{{'dllimport' attribute ignored on inline function}}
    898 #endif
    899 template<typename T> __declspec(dllimport)        void MemTmplRedecl::normalInlineDecl() {} // expected-error{{redeclaration of 'MemTmplRedecl::normalInlineDecl' cannot add 'dllimport' attribute}}
    900 template<typename T> __declspec(dllimport)        void MemTmplRedecl::staticDef() {}        // expected-error{{redeclaration of 'MemTmplRedecl::staticDef' cannot add 'dllimport' attribute}}
    901                                                                                             // expected-error@-1{{dllimport cannot be applied to non-inline function definition}}
    902 #ifdef MS
    903 template<typename T> __declspec(dllimport) inline void MemTmplRedecl::staticInlineDef() {}  // expected-error{{redeclaration of 'MemTmplRedecl::staticInlineDef' cannot add 'dllimport' attribute}}
    904 #else
    905 template<typename T> __declspec(dllimport) inline void MemTmplRedecl::staticInlineDef() {}  // expected-warning{{'dllimport' attribute ignored on inline function}}
    906 #endif
    907 template<typename T> __declspec(dllimport)        void MemTmplRedecl::staticInlineDecl() {} // expected-error{{redeclaration of 'MemTmplRedecl::staticInlineDecl' cannot add 'dllimport' attribute}}
    908 
    909 #if __has_feature(cxx_variable_templates)
    910 template<typename T> __declspec(dllimport)        int  MemTmplRedecl::StaticField = 1;      // expected-error{{redeclaration of 'MemTmplRedecl::StaticField' cannot add 'dllimport' attribute}}
    911                                                                                             // expected-error@-1{{definition of dllimport static field not allowed}}
    912                                                                                             // expected-note@-2{{attribute is here}}
    913 template<typename T> __declspec(dllimport) const  int  MemTmplRedecl::StaticConstField = 1; // expected-error{{redeclaration of 'MemTmplRedecl::StaticConstField' cannot add 'dllimport' attribute}}
    914                                                                                             // expected-error@-1{{definition of dllimport static field not allowed}}
    915                                                                                             // expected-note@-2{{attribute is here}}
    916 template<typename T> __declspec(dllimport) constexpr int MemTmplRedecl::ConstexprField;     // expected-error{{redeclaration of 'MemTmplRedecl::ConstexprField' cannot add 'dllimport' attribute}}
    917                                                                                             // expected-error@-1{{definition of dllimport static field not allowed}}
    918                                                                                             // expected-note@-2{{attribute is here}}
    919 #endif // __has_feature(cxx_variable_templates)
    920 
    921 
    922 
    923 struct MemFunTmpl {
    924   template<typename T>                              void normalDef() {}
    925 #ifdef GNU
    926   // expected-warning@+2{{'dllimport' attribute ignored on inline function}}
    927 #endif
    928   template<typename T> __declspec(dllimport)        void importedNormal() {}
    929   template<typename T>                       static void staticDef() {}
    930 #ifdef GNU
    931   // expected-warning@+2{{'dllimport' attribute ignored on inline function}}
    932 #endif
    933   template<typename T> __declspec(dllimport) static void importedStatic() {}
    934 };
    935 
    936 // Import implicit instantiation of an imported member function template.
    937 void useMemFunTmpl() {
    938   MemFunTmpl().importedNormal<ImplicitInst_Imported>();
    939   MemFunTmpl().importedStatic<ImplicitInst_Imported>();
    940 }
    941 
    942 // Import explicit instantiation declaration of an imported member function
    943 // template.
    944 extern template void MemFunTmpl::importedNormal<ExplicitDecl_Imported>();
    945 extern template void MemFunTmpl::importedStatic<ExplicitDecl_Imported>();
    946 
    947 // Import explicit instantiation definition of an imported member function
    948 // template.
    949 // NB: MSVC fails this instantiation without explicit dllimport.
    950 template void MemFunTmpl::importedNormal<ExplicitInst_Imported>();
    951 template void MemFunTmpl::importedStatic<ExplicitInst_Imported>();
    952 
    953 // Import specialization of an imported member function template.
    954 template<> __declspec(dllimport) void MemFunTmpl::importedNormal<ExplicitSpec_Imported>();
    955 template<> __declspec(dllimport) void MemFunTmpl::importedNormal<ExplicitSpec_Def_Imported>() {} // error on mingw
    956 #ifdef GNU
    957   // expected-warning@+2{{'dllimport' attribute ignored on inline function}}
    958 #endif
    959 template<> __declspec(dllimport) inline void MemFunTmpl::importedNormal<ExplicitSpec_InlineDef_Imported>() {}
    960 #if 1
    961 // FIXME: This should not be an error when targeting MSVC. (PR21406)
    962 // expected-error@-7{{dllimport cannot be applied to non-inline function definition}}
    963 #endif
    964 
    965 template<> __declspec(dllimport) void MemFunTmpl::importedStatic<ExplicitSpec_Imported>();
    966 template<> __declspec(dllimport) void MemFunTmpl::importedStatic<ExplicitSpec_Def_Imported>() {} // error on mingw
    967 #ifdef GNU
    968   // expected-warning@+2{{'dllimport' attribute ignored on inline function}}
    969 #endif
    970 template<> __declspec(dllimport) inline void MemFunTmpl::importedStatic<ExplicitSpec_InlineDef_Imported>() {}
    971 #if 1
    972 // FIXME: This should not be an error when targeting MSVC. (PR21406)
    973 // expected-error@-7{{dllimport cannot be applied to non-inline function definition}}
    974 #endif
    975 
    976 // Not importing specialization of an imported member function template without
    977 // explicit dllimport.
    978 template<> void MemFunTmpl::importedNormal<ExplicitSpec_NotImported>() {}
    979 template<> void MemFunTmpl::importedStatic<ExplicitSpec_NotImported>() {}
    980 
    981 
    982 // Import explicit instantiation declaration of a non-imported member function
    983 // template.
    984 #ifdef GNU
    985 // expected-warning@+3{{'dllimport' attribute ignored on inline function}}
    986 // expected-warning@+3{{'dllimport' attribute ignored on inline function}}
    987 #endif
    988 extern template __declspec(dllimport) void MemFunTmpl::normalDef<ExplicitDecl_Imported>();
    989 extern template __declspec(dllimport) void MemFunTmpl::staticDef<ExplicitDecl_Imported>();
    990 
    991 // Import explicit instantiation definition of a non-imported member function
    992 // template.
    993 #ifdef GNU
    994 // expected-warning@+3{{'dllimport' attribute ignored on inline function}}
    995 // expected-warning@+3{{'dllimport' attribute ignored on inline function}}
    996 #endif
    997 template __declspec(dllimport) void MemFunTmpl::normalDef<ExplicitInst_Imported>();
    998 template __declspec(dllimport) void MemFunTmpl::staticDef<ExplicitInst_Imported>();
    999 
   1000 // Import specialization of a non-imported member function template.
   1001 template<> __declspec(dllimport) void MemFunTmpl::normalDef<ExplicitSpec_Imported>();
   1002 template<> __declspec(dllimport) void MemFunTmpl::normalDef<ExplicitSpec_Def_Imported>() {} // error on mingw
   1003 #ifdef GNU
   1004   // expected-warning@+2{{'dllimport' attribute ignored on inline function}}
   1005 #endif
   1006 template<> __declspec(dllimport) inline void MemFunTmpl::normalDef<ExplicitSpec_InlineDef_Imported>() {}
   1007 #if 1
   1008 // FIXME: This should not be an error when targeting MSVC. (PR21406)
   1009 // expected-error@-7{{dllimport cannot be applied to non-inline function definition}}
   1010 #endif
   1011 
   1012 template<> __declspec(dllimport) void MemFunTmpl::staticDef<ExplicitSpec_Imported>();
   1013 template<> __declspec(dllimport) void MemFunTmpl::staticDef<ExplicitSpec_Def_Imported>() {} // error on mingw
   1014 #ifdef GNU
   1015   // expected-warning@+2{{'dllimport' attribute ignored on inline function}}
   1016 #endif
   1017 template<> __declspec(dllimport) inline void MemFunTmpl::staticDef<ExplicitSpec_InlineDef_Imported>() {}
   1018 #if 1
   1019 // FIXME: This should not be an error when targeting MSVC. (PR21406)
   1020 // expected-error@-7{{dllimport cannot be applied to non-inline function definition}}
   1021 #endif
   1022 
   1023 
   1024 
   1025 #if __has_feature(cxx_variable_templates)
   1026 struct MemVarTmpl {
   1027   template<typename T>                       static const int StaticVar = 1;
   1028   template<typename T> __declspec(dllimport) static const int ImportedStaticVar = 1;
   1029 };
   1030 
   1031 // Import implicit instantiation of an imported member variable template.
   1032 int useMemVarTmpl() { return MemVarTmpl::ImportedStaticVar<ImplicitInst_Imported>; }
   1033 
   1034 // Import explicit instantiation declaration of an imported member variable
   1035 // template.
   1036 extern template const int MemVarTmpl::ImportedStaticVar<ExplicitDecl_Imported>;
   1037 
   1038 // An explicit instantiation definition of an imported member variable template
   1039 // cannot be imported because the template must be defined which is illegal. The
   1040 // in-class initializer does not count.
   1041 
   1042 // Import specialization of an imported member variable template.
   1043 template<> __declspec(dllimport) const int MemVarTmpl::ImportedStaticVar<ExplicitSpec_Imported>;
   1044 template<> __declspec(dllimport) const int MemVarTmpl::ImportedStaticVar<ExplicitSpec_Def_Imported> = 1;
   1045                                                                                 // expected-error@-1{{definition of dllimport static field not allowed}}
   1046                                                                                 // expected-note@-2{{attribute is here}}
   1047 
   1048 // Not importing specialization of a member variable template without explicit
   1049 // dllimport.
   1050 template<> const int MemVarTmpl::ImportedStaticVar<ExplicitSpec_NotImported>;
   1051 
   1052 
   1053 // Import explicit instantiation declaration of a non-imported member variable
   1054 // template.
   1055 extern template __declspec(dllimport) const int MemVarTmpl::StaticVar<ExplicitDecl_Imported>;
   1056 
   1057 // An explicit instantiation definition of a non-imported member variable template
   1058 // cannot be imported because the template must be defined which is illegal. The
   1059 // in-class initializer does not count.
   1060 
   1061 // Import specialization of a non-imported member variable template.
   1062 template<> __declspec(dllimport) const int MemVarTmpl::StaticVar<ExplicitSpec_Imported>;
   1063 template<> __declspec(dllimport) const int MemVarTmpl::StaticVar<ExplicitSpec_Def_Imported> = 1;
   1064                                                                                 // expected-error@-1{{definition of dllimport static field not allowed}}
   1065                                                                                 // expected-note@-2{{attribute is here}}
   1066 
   1067 #endif // __has_feature(cxx_variable_templates)
   1068 
   1069 
   1070 
   1071 //===----------------------------------------------------------------------===//
   1072 // Class template members
   1073 //===----------------------------------------------------------------------===//
   1074 
   1075 // Import individual members of a class template.
   1076 template<typename T>
   1077 struct ImportClassTmplMembers {
   1078   __declspec(dllimport)                void normalDecl();
   1079 #ifdef GNU
   1080 // expected-note@+2{{previous attribute is here}}
   1081 #endif
   1082   __declspec(dllimport) void normalDef(); // expected-note{{previous declaration is here}}
   1083   __declspec(dllimport)                void normalInlineDef();
   1084   __declspec(dllimport) virtual        void virtualDecl();
   1085 #ifdef GNU
   1086 // expected-note@+2{{previous attribute is here}}
   1087 #endif
   1088   __declspec(dllimport) virtual void virtualDef(); // expected-note{{previous declaration is here}}
   1089   __declspec(dllimport) virtual        void virtualInlineDef();
   1090   __declspec(dllimport) static         void staticDecl();
   1091 #ifdef GNU
   1092 // expected-note@+2{{previous attribute is here}}
   1093 #endif
   1094   __declspec(dllimport) static void staticDef(); // expected-note{{previous declaration is here}}
   1095   __declspec(dllimport) static         void staticInlineDef();
   1096 
   1097 #ifdef GNU
   1098 // expected-warning@+7{{'dllimport' attribute ignored on inline function}}
   1099 // expected-warning@+7{{'dllimport' attribute ignored on inline function}}
   1100 // expected-warning@+7{{'dllimport' attribute ignored on inline function}}
   1101 // expected-warning@+7{{'dllimport' attribute ignored on inline function}}
   1102 // expected-warning@+7{{'dllimport' attribute ignored on inline function}}
   1103 // expected-warning@+7{{'dllimport' attribute ignored on inline function}}
   1104 #endif
   1105   __declspec(dllimport)                void normalInclass() {}
   1106   __declspec(dllimport)         inline void normalInlineDecl();
   1107   __declspec(dllimport) virtual        void virtualInclass() {}
   1108   __declspec(dllimport) virtual inline void virtualInlineDecl();
   1109   __declspec(dllimport) static         void staticInclass() {}
   1110   __declspec(dllimport) static  inline void staticInlineDecl();
   1111 
   1112 protected:
   1113   __declspec(dllimport)                void protectedDecl();
   1114 private:
   1115   __declspec(dllimport)                void privateDecl();
   1116 public:
   1117 
   1118   __declspec(dllimport)                int  Field; // expected-warning{{'dllimport' attribute only applies to variables, functions and classes}}
   1119   __declspec(dllimport) static         int  StaticField;
   1120   __declspec(dllimport) static         int  StaticFieldDef; // expected-note{{attribute is here}}
   1121   __declspec(dllimport) static  const  int  StaticConstField;
   1122   __declspec(dllimport) static  const  int  StaticConstFieldDef; // expected-note{{attribute is here}}
   1123   __declspec(dllimport) static  const  int  StaticConstFieldEqualInit = 1;
   1124   __declspec(dllimport) static  const  int  StaticConstFieldBraceInit{1};
   1125   __declspec(dllimport) constexpr static int ConstexprField = 1;
   1126   __declspec(dllimport) constexpr static int ConstexprFieldDef = 1; // expected-note{{attribute is here}}
   1127 };
   1128 
   1129 // NB: MSVC is inconsistent here and disallows *InlineDef on class templates,
   1130 // but allows it on classes. We allow both.
   1131 #ifdef MS
   1132 // expected-warning@+5{{'ImportClassTmplMembers::normalDef' redeclared without 'dllimport' attribute: 'dllexport' attribute added}}
   1133 #else
   1134 // expected-warning@+3{{'ImportClassTmplMembers::normalDef' redeclared without 'dllimport' attribute: previous 'dllimport' ignored}}
   1135 #endif
   1136 template <typename T>
   1137 void ImportClassTmplMembers<T>::normalDef() {}
   1138 #ifdef GNU
   1139 // expected-warning@+2{{'ImportClassTmplMembers::normalInlineDef' redeclared inline; 'dllimport' attribute ignored}}
   1140 #endif
   1141 template<typename T> inline void ImportClassTmplMembers<T>::normalInlineDef() {}
   1142 template<typename T>        void ImportClassTmplMembers<T>::normalInlineDecl() {}
   1143 #ifdef MS
   1144 // expected-warning@+5{{'ImportClassTmplMembers::virtualDef' redeclared without 'dllimport' attribute: 'dllexport' attribute added}}
   1145 #else
   1146 // expected-warning@+3{{'ImportClassTmplMembers::virtualDef' redeclared without 'dllimport' attribute: previous 'dllimport' ignored}}
   1147 #endif
   1148 template <typename T>
   1149 void ImportClassTmplMembers<T>::virtualDef() {}
   1150 #ifdef GNU
   1151 // expected-warning@+2{{'ImportClassTmplMembers::virtualInlineDef' redeclared inline; 'dllimport' attribute ignored}}
   1152 #endif
   1153 template<typename T> inline void ImportClassTmplMembers<T>::virtualInlineDef() {}
   1154 template<typename T>        void ImportClassTmplMembers<T>::virtualInlineDecl() {}
   1155 #ifdef MS
   1156 // expected-warning@+5{{'ImportClassTmplMembers::staticDef' redeclared without 'dllimport' attribute: 'dllexport' attribute added}}
   1157 #else
   1158 // expected-warning@+3{{'ImportClassTmplMembers::staticDef' redeclared without 'dllimport' attribute: previous 'dllimport' ignored}}
   1159 #endif
   1160 template <typename T>
   1161 void ImportClassTmplMembers<T>::staticDef() {}
   1162 #ifdef GNU
   1163 // expected-warning@+2{{'ImportClassTmplMembers::staticInlineDef' redeclared inline; 'dllimport' attribute ignored}}
   1164 #endif
   1165 template<typename T> inline void ImportClassTmplMembers<T>::staticInlineDef() {}
   1166 template<typename T>        void ImportClassTmplMembers<T>::staticInlineDecl() {}
   1167 
   1168 template<typename T>        int  ImportClassTmplMembers<T>::StaticFieldDef; // expected-warning{{definition of dllimport static field}}
   1169 template<typename T> const  int  ImportClassTmplMembers<T>::StaticConstFieldDef = 1; // expected-warning{{definition of dllimport static field}}
   1170 template<typename T> constexpr int ImportClassTmplMembers<T>::ConstexprFieldDef; // expected-warning{{definition of dllimport static field}}
   1171 
   1172 
   1173 // Redeclarations cannot add dllimport.
   1174 template<typename T>
   1175 struct CTMR /*ClassTmplMemberRedecl*/ {
   1176                  void normalDef();         // expected-note{{previous declaration is here}}
   1177           inline void normalInlineDecl();  // expected-note{{previous declaration is here}}
   1178   virtual        void virtualDef();        // expected-note{{previous declaration is here}}
   1179   virtual inline void virtualInlineDecl(); // expected-note{{previous declaration is here}}
   1180   static         void staticDef();         // expected-note{{previous declaration is here}}
   1181   static  inline void staticInlineDecl();  // expected-note{{previous declaration is here}}
   1182 
   1183 #ifdef MS
   1184 // expected-note@+4{{previous declaration is here}}
   1185 // expected-note@+4{{previous declaration is here}}
   1186 // expected-note@+4{{previous declaration is here}}
   1187 #endif
   1188                  void normalInlineDef();
   1189   virtual        void virtualInlineDef();
   1190   static         void staticInlineDef();
   1191 
   1192   static         int  StaticField;         // expected-note{{previous declaration is here}}
   1193   static  const  int  StaticConstField;    // expected-note{{previous declaration is here}}
   1194   constexpr static int ConstexprField = 1; // expected-note{{previous declaration is here}}
   1195 };
   1196 
   1197 template<typename T> __declspec(dllimport)        void CTMR<T>::normalDef() {}         // expected-error{{redeclaration of 'CTMR::normalDef' cannot add 'dllimport' attribute}}
   1198                                                                                        // expected-error@-1{{dllimport cannot be applied to non-inline function definition}}
   1199 template<typename T> __declspec(dllimport)        void CTMR<T>::normalInlineDecl() {}  // expected-error{{redeclaration of 'CTMR::normalInlineDecl' cannot add 'dllimport' attribute}}
   1200 template<typename T> __declspec(dllimport)        void CTMR<T>::virtualDef() {}        // expected-error{{redeclaration of 'CTMR::virtualDef' cannot add 'dllimport' attribute}}
   1201                                                                                        // expected-error@-1{{dllimport cannot be applied to non-inline function definition}}
   1202 template<typename T> __declspec(dllimport)        void CTMR<T>::virtualInlineDecl() {} // expected-error{{redeclaration of 'CTMR::virtualInlineDecl' cannot add 'dllimport' attribute}}
   1203 template<typename T> __declspec(dllimport)        void CTMR<T>::staticDef() {}         // expected-error{{redeclaration of 'CTMR::staticDef' cannot add 'dllimport' attribute}}
   1204                                                                                        // expected-error@-1{{dllimport cannot be applied to non-inline function definition}}
   1205 template<typename T> __declspec(dllimport)        void CTMR<T>::staticInlineDecl() {}  // expected-error{{redeclaration of 'CTMR::staticInlineDecl' cannot add 'dllimport' attribute}}
   1206 
   1207 #ifdef MS
   1208 template<typename T> __declspec(dllimport) inline void CTMR<T>::normalInlineDef() {}   // expected-error{{redeclaration of 'CTMR::normalInlineDef' cannot add 'dllimport' attribute}}
   1209 template<typename T> __declspec(dllimport) inline void CTMR<T>::virtualInlineDef() {}  // expected-error{{redeclaration of 'CTMR::virtualInlineDef' cannot add 'dllimport' attribute}}
   1210 template<typename T> __declspec(dllimport) inline void CTMR<T>::staticInlineDef() {}   // expected-error{{redeclaration of 'CTMR::staticInlineDef' cannot add 'dllimport' attribute}}
   1211 #else
   1212 template<typename T> __declspec(dllimport) inline void CTMR<T>::normalInlineDef() {}   // expected-warning{{'dllimport' attribute ignored on inline function}}
   1213 template<typename T> __declspec(dllimport) inline void CTMR<T>::virtualInlineDef() {}  // expected-warning{{'dllimport' attribute ignored on inline function}}
   1214 template<typename T> __declspec(dllimport) inline void CTMR<T>::staticInlineDef() {}   // expected-warning{{'dllimport' attribute ignored on inline function}}
   1215 #endif
   1216 
   1217 template<typename T> __declspec(dllimport)        int  CTMR<T>::StaticField = 1;       // expected-error{{redeclaration of 'CTMR::StaticField' cannot add 'dllimport' attribute}}
   1218                                                                                        // expected-warning@-1{{definition of dllimport static field}}
   1219                                                                                        // expected-note@-2{{attribute is here}}
   1220 template<typename T> __declspec(dllimport) const  int  CTMR<T>::StaticConstField = 1;  // expected-error{{redeclaration of 'CTMR::StaticConstField' cannot add 'dllimport' attribute}}
   1221                                                                                        // expected-warning@-1{{definition of dllimport static field}}
   1222                                                                                        // expected-note@-2{{attribute is here}}
   1223 template<typename T> __declspec(dllimport) constexpr int CTMR<T>::ConstexprField;      // expected-error{{redeclaration of 'CTMR::ConstexprField' cannot add 'dllimport' attribute}}
   1224                                                                                        // expected-warning@-1{{definition of dllimport static field}}
   1225                                                                                        // expected-note@-2{{attribute is here}}
   1226 
   1227 
   1228 
   1229 //===----------------------------------------------------------------------===//
   1230 // Class template member templates
   1231 //===----------------------------------------------------------------------===//
   1232 
   1233 template<typename T>
   1234 struct ImportClsTmplMemTmpl {
   1235   template<typename U> __declspec(dllimport)               void normalDecl();
   1236   template<typename U> __declspec(dllimport)               void normalDef(); // expected-note{{previous declaration is here}} expected-note{{previous attribute is here}}
   1237   template<typename U> __declspec(dllimport)               void normalInlineDef();
   1238   template<typename U> __declspec(dllimport) static        void staticDecl();
   1239   template<typename U> __declspec(dllimport) static        void staticDef(); // expected-note{{previous declaration is here}} expected-note{{previous attribute is here}}
   1240   template<typename U> __declspec(dllimport) static        void staticInlineDef();
   1241 
   1242 #ifdef GNU
   1243   // expected-warning@+5{{'dllimport' attribute ignored on inline function}}
   1244   // expected-warning@+5{{'dllimport' attribute ignored on inline function}}
   1245   // expected-warning@+5{{'dllimport' attribute ignored on inline function}}
   1246   // expected-warning@+5{{'dllimport' attribute ignored on inline function}}
   1247 #endif
   1248   template<typename U> __declspec(dllimport)               void normalInclass() {}
   1249   template<typename U> __declspec(dllimport)        inline void normalInlineDecl();
   1250   template<typename U> __declspec(dllimport) static        void staticInclass() {}
   1251   template<typename U> __declspec(dllimport) static inline void staticInlineDecl();
   1252 
   1253 #if __has_feature(cxx_variable_templates)
   1254   template<typename U> __declspec(dllimport) static        int  StaticField;
   1255   template<typename U> __declspec(dllimport) static        int  StaticFieldDef; // expected-note{{attribute is here}}
   1256   template<typename U> __declspec(dllimport) static const  int  StaticConstField;
   1257   template<typename U> __declspec(dllimport) static const  int  StaticConstFieldDef; // expected-note{{attribute is here}}
   1258   template<typename U> __declspec(dllimport) static const  int  StaticConstFieldEqualInit = 1;
   1259   template<typename U> __declspec(dllimport) static const  int  StaticConstFieldBraceInit{1};
   1260   template<typename U> __declspec(dllimport) constexpr static int ConstexprField = 1;
   1261   template<typename U> __declspec(dllimport) constexpr static int ConstexprFieldDef = 1; // expected-note{{attribute is here}}
   1262 #endif // __has_feature(cxx_variable_templates)
   1263 };
   1264 
   1265 template<typename T> template<typename U>        void ImportClsTmplMemTmpl<T>::normalDef() {} // expected-warning{{'ImportClsTmplMemTmpl::normalDef' redeclared without 'dllimport' attribute: previous 'dllimport' ignored}}
   1266 template<typename T> template<typename U>        void ImportClsTmplMemTmpl<T>::normalInlineDecl() {}
   1267 template<typename T> template<typename U>        void ImportClsTmplMemTmpl<T>::staticDef() {} // expected-warning{{'ImportClsTmplMemTmpl::staticDef' redeclared without 'dllimport' attribute: previous 'dllimport' ignored}}
   1268 template<typename T> template<typename U>        void ImportClsTmplMemTmpl<T>::staticInlineDecl() {}
   1269 
   1270 #ifdef GNU
   1271 // expected-warning@+3{{'ImportClsTmplMemTmpl::normalInlineDef' redeclared inline; 'dllimport' attribute ignored}}
   1272 // expected-warning@+3{{'ImportClsTmplMemTmpl::staticInlineDef' redeclared inline; 'dllimport' attribute ignored}}
   1273 #endif
   1274 template<typename T> template<typename U> inline void ImportClsTmplMemTmpl<T>::normalInlineDef() {}
   1275 template<typename T> template<typename U> inline void ImportClsTmplMemTmpl<T>::staticInlineDef() {}
   1276 
   1277 #if __has_feature(cxx_variable_templates)
   1278 template<typename T> template<typename U>        int  ImportClsTmplMemTmpl<T>::StaticFieldDef; // expected-warning{{definition of dllimport static field}}
   1279 template<typename T> template<typename U> const  int  ImportClsTmplMemTmpl<T>::StaticConstFieldDef = 1; // expected-warning{{definition of dllimport static field}}
   1280 template<typename T> template<typename U> constexpr int ImportClsTmplMemTmpl<T>::ConstexprFieldDef; // expected-warning{{definition of dllimport static field}}
   1281 #endif // __has_feature(cxx_variable_templates)
   1282 
   1283 
   1284 // Redeclarations cannot add dllimport.
   1285 template<typename T>
   1286 struct CTMTR /*ClassTmplMemberTmplRedecl*/ {
   1287   template<typename U>               void normalDef();         // expected-note{{previous declaration is here}}
   1288   template<typename U>        inline void normalInlineDecl();  // expected-note{{previous declaration is here}}
   1289   template<typename U> static        void staticDef();         // expected-note{{previous declaration is here}}
   1290   template<typename U> static inline void staticInlineDecl();  // expected-note{{previous declaration is here}}
   1291 
   1292 #ifdef MS
   1293   // expected-note@+3{{previous declaration is here}}
   1294   // expected-note@+3{{previous declaration is here}}
   1295 #endif
   1296   template<typename U>               void normalInlineDef();
   1297   template<typename U> static        void staticInlineDef();
   1298 
   1299 #if __has_feature(cxx_variable_templates)
   1300   template<typename U> static        int  StaticField;         // expected-note{{previous declaration is here}}
   1301   template<typename U> static const  int  StaticConstField;    // expected-note{{previous declaration is here}}
   1302   template<typename U> constexpr static int ConstexprField = 1; // expected-note{{previous declaration is here}}
   1303 #endif // __has_feature(cxx_variable_templates)
   1304 };
   1305 
   1306 template<typename T> template<typename U> __declspec(dllimport)        void CTMTR<T>::normalDef() {}         // expected-error{{redeclaration of 'CTMTR::normalDef' cannot add 'dllimport' attribute}}
   1307                                                                                                              // expected-error@-1{{dllimport cannot be applied to non-inline function definition}}
   1308 template<typename T> template<typename U> __declspec(dllimport)        void CTMTR<T>::normalInlineDecl() {}  // expected-error{{redeclaration of 'CTMTR::normalInlineDecl' cannot add 'dllimport' attribute}}
   1309 template<typename T> template<typename U> __declspec(dllimport)        void CTMTR<T>::staticDef() {}         // expected-error{{redeclaration of 'CTMTR::staticDef' cannot add 'dllimport' attribute}}
   1310                                                                                                              // expected-error@-1{{dllimport cannot be applied to non-inline function definition}}
   1311 template<typename T> template<typename U> __declspec(dllimport)        void CTMTR<T>::staticInlineDecl() {}  // expected-error{{redeclaration of 'CTMTR::staticInlineDecl' cannot add 'dllimport' attribute}}
   1312 
   1313 #ifdef MS
   1314 template<typename T> template<typename U> __declspec(dllimport) inline void CTMTR<T>::normalInlineDef() {}   // expected-error{{redeclaration of 'CTMTR::normalInlineDef' cannot add 'dllimport' attribute}}
   1315 template<typename T> template<typename U> __declspec(dllimport) inline void CTMTR<T>::staticInlineDef() {}   // expected-error{{redeclaration of 'CTMTR::staticInlineDef' cannot add 'dllimport' attribute}}
   1316 #else
   1317 template<typename T> template<typename U> __declspec(dllimport) inline void CTMTR<T>::normalInlineDef() {}   // expected-warning{{'dllimport' attribute ignored on inline function}}
   1318 template<typename T> template<typename U> __declspec(dllimport) inline void CTMTR<T>::staticInlineDef() {}   // expected-warning{{'dllimport' attribute ignored on inline function}}
   1319 #endif
   1320 
   1321 #if __has_feature(cxx_variable_templates)
   1322 template<typename T> template<typename U> __declspec(dllimport)        int  CTMTR<T>::StaticField = 1;       // expected-error{{redeclaration of 'CTMTR::StaticField' cannot add 'dllimport' attribute}}
   1323                                                                                                              // expected-warning@-1{{definition of dllimport static field}}
   1324                                                                                                              // expected-note@-2{{attribute is here}}
   1325 template<typename T> template<typename U> __declspec(dllimport) const  int  CTMTR<T>::StaticConstField = 1;  // expected-error{{redeclaration of 'CTMTR::StaticConstField' cannot add 'dllimport' attribute}}
   1326                                                                                                              // expected-warning@-1{{definition of dllimport static field}}
   1327                                                                                                              // expected-note@-2{{attribute is here}}
   1328 template<typename T> template<typename U> __declspec(dllimport) constexpr int CTMTR<T>::ConstexprField;      // expected-error{{redeclaration of 'CTMTR::ConstexprField' cannot add 'dllimport' attribute}}
   1329                                                                                                              // expected-warning@-1{{definition of dllimport static field}}
   1330                                                                                                              // expected-note@-2{{attribute is here}}
   1331 #endif // __has_feature(cxx_variable_templates)
   1332 
   1333 
   1334 
   1335 //===----------------------------------------------------------------------===//
   1336 // Classes
   1337 //===----------------------------------------------------------------------===//
   1338 
   1339 namespace {
   1340   struct __declspec(dllimport) AnonymousClass {}; // expected-error{{(anonymous namespace)::AnonymousClass' must have external linkage when declared 'dllimport'}}
   1341 }
   1342 
   1343 class __declspec(dllimport) ClassDecl;
   1344 
   1345 class __declspec(dllimport) ClassDef { };
   1346 
   1347 template <typename T> class ClassTemplate {};
   1348 
   1349 #ifdef MS
   1350 // expected-note@+5{{previous attribute is here}}
   1351 // expected-note@+4{{previous attribute is here}}
   1352 // expected-error@+4{{attribute 'dllexport' cannot be applied to member of 'dllimport' class}}
   1353 // expected-error@+4{{attribute 'dllimport' cannot be applied to member of 'dllimport' class}}
   1354 #endif
   1355 class __declspec(dllimport) ImportClassWithDllMember {
   1356   void __declspec(dllexport) foo();
   1357   void __declspec(dllimport) bar();
   1358 };
   1359 
   1360 #ifdef MS
   1361 // expected-note@+5{{previous attribute is here}}
   1362 // expected-note@+4{{previous attribute is here}}
   1363 // expected-error@+4{{attribute 'dllimport' cannot be applied to member of 'dllexport' class}}
   1364 // expected-error@+4{{attribute 'dllexport' cannot be applied to member of 'dllexport' class}}
   1365 #endif
   1366 template <typename T> class __declspec(dllexport) ExportClassWithDllMember {
   1367   void __declspec(dllimport) foo();
   1368   void __declspec(dllexport) bar();
   1369 };
   1370 
   1371 namespace ImportedExplicitSpecialization {
   1372 template <typename T> struct S { static int x; };
   1373 template <typename T> int S<T>::x = sizeof(T);
   1374 template <> struct __declspec(dllimport) S<int> { static int x; }; // expected-note{{attribute is here}}
   1375 int S<int>::x = -1; // expected-error{{definition of dllimport static field not allowed}}
   1376 }
   1377 
   1378 namespace PR19988 {
   1379 // Don't error about applying delete to dllimport member function when instantiating.
   1380 template <typename> struct __declspec(dllimport) S {
   1381   void foo() = delete;
   1382 };
   1383 S<int> s;
   1384 }
   1385 
   1386 #ifdef MS
   1387 // expected-warning@+3{{'dllimport' attribute ignored}}
   1388 #endif
   1389 template <typename T> struct PartiallySpecializedClassTemplate {};
   1390 template <typename T> struct __declspec(dllimport) PartiallySpecializedClassTemplate<T*> { void f() {} };
   1391 
   1392 template <typename T> struct ExpliciallySpecializedClassTemplate {};
   1393 template <> struct __declspec(dllimport) ExpliciallySpecializedClassTemplate<int> { void f() {} };
   1394 
   1395 
   1396 //===----------------------------------------------------------------------===//
   1397 // Classes with template base classes
   1398 //===----------------------------------------------------------------------===//
   1399 
   1400 template <typename T> class __declspec(dllexport) ExportedClassTemplate {};
   1401 
   1402 template <typename T> class __declspec(dllimport) ImportedClassTemplate {};
   1403 
   1404 // ClassTemplate<int> gets imported.
   1405 class __declspec(dllimport) DerivedFromTemplate : public ClassTemplate<int> {};
   1406 
   1407 // ClassTemplate<int> is already imported.
   1408 class __declspec(dllimport) DerivedFromTemplate2 : public ClassTemplate<int> {};
   1409 
   1410 // ImportedClassTemplate is expliitly imported.
   1411 class __declspec(dllimport) DerivedFromImportedTemplate : public ImportedClassTemplate<int> {};
   1412 
   1413 // ExportedClassTemplate is explicitly exported.
   1414 class __declspec(dllimport) DerivedFromExportedTemplate : public ExportedClassTemplate<int> {};
   1415 
   1416 class DerivedFromTemplateD : public ClassTemplate<double> {};
   1417 // Base class previously implicitly instantiated without attribute; it will get propagated.
   1418 class __declspec(dllimport) DerivedFromTemplateD2 : public ClassTemplate<double> {};
   1419 
   1420 // Base class has explicit instantiation declaration; the attribute will get propagated.
   1421 extern template class ClassTemplate<float>;
   1422 class __declspec(dllimport) DerivedFromTemplateF : public ClassTemplate<float> {};
   1423 
   1424 class __declspec(dllimport) DerivedFromTemplateB : public ClassTemplate<bool> {};
   1425 // The second derived class doesn't change anything, the attribute that was propagated first wins.
   1426 class __declspec(dllexport) DerivedFromTemplateB2 : public ClassTemplate<bool> {};
   1427 
   1428 template <typename T> struct ExplicitlySpecializedTemplate { void func() {} };
   1429 #ifdef MS
   1430 // expected-note@+2{{class template 'ExplicitlySpecializedTemplate<int>' was explicitly specialized here}}
   1431 #endif
   1432 template <> struct ExplicitlySpecializedTemplate<int> { void func() {} };
   1433 template <typename T> struct ExplicitlyExportSpecializedTemplate { void func() {} };
   1434 template <> struct __declspec(dllexport) ExplicitlyExportSpecializedTemplate<int> { void func() {} };
   1435 template <typename T> struct ExplicitlyImportSpecializedTemplate { void func() {} };
   1436 template <> struct __declspec(dllimport) ExplicitlyImportSpecializedTemplate<int> { void func() {} };
   1437 
   1438 template <typename T> struct ExplicitlyInstantiatedTemplate { void func() {} };
   1439 #ifdef MS
   1440 // expected-note@+2{{class template 'ExplicitlyInstantiatedTemplate<int>' was instantiated here}}
   1441 #endif
   1442 template struct ExplicitlyInstantiatedTemplate<int>;
   1443 template <typename T> struct ExplicitlyExportInstantiatedTemplate { void func() {} };
   1444 template struct __declspec(dllexport) ExplicitlyExportInstantiatedTemplate<int>;
   1445 template <typename T> struct ExplicitlyImportInstantiatedTemplate { void func() {} };
   1446 template struct __declspec(dllimport) ExplicitlyImportInstantiatedTemplate<int>;
   1447 
   1448 #ifdef MS
   1449 // expected-warning@+3{{propagating dll attribute to explicitly specialized base class template without dll attribute is not supported}}
   1450 // expected-note@+2{{attribute is here}}
   1451 #endif
   1452 struct __declspec(dllimport) DerivedFromExplicitlySpecializedTemplate : public ExplicitlySpecializedTemplate<int> {};
   1453 
   1454 // Base class already specialized with export attribute.
   1455 struct __declspec(dllimport) DerivedFromExplicitlyExportSpecializedTemplate : public ExplicitlyExportSpecializedTemplate<int> {};
   1456 
   1457 // Base class already specialized with import attribute.
   1458 struct __declspec(dllimport) DerivedFromExplicitlyImportSpecializedTemplate : public ExplicitlyImportSpecializedTemplate<int> {};
   1459 
   1460 #ifdef MS
   1461 // expected-warning@+3{{propagating dll attribute to already instantiated base class template without dll attribute is not supported}}
   1462 // expected-note@+2{{attribute is here}}
   1463 #endif
   1464 struct __declspec(dllimport) DerivedFromExplicitlyInstantiatedTemplate : public ExplicitlyInstantiatedTemplate<int> {};
   1465 
   1466 // Base class already instantiated with export attribute.
   1467 struct __declspec(dllimport) DerivedFromExplicitlyExportInstantiatedTemplate : public ExplicitlyExportInstantiatedTemplate<int> {};
   1468 
   1469 // Base class already instantiated with import attribute.
   1470 struct __declspec(dllimport) DerivedFromExplicitlyImportInstantiatedTemplate : public ExplicitlyImportInstantiatedTemplate<int> {};
   1471 
   1472 template <typename T> struct ExplicitInstantiationDeclTemplateBase { void func() {} };
   1473 extern template struct ExplicitInstantiationDeclTemplateBase<int>;
   1474 struct __declspec(dllimport) DerivedFromExplicitInstantiationDeclTemplateBase : public ExplicitInstantiationDeclTemplateBase<int> {};
   1475 
   1476 //===----------------------------------------------------------------------===//
   1477 // Lambdas
   1478 //===----------------------------------------------------------------------===//
   1479 // The MS ABI doesn't provide a stable mangling for lambdas, so they can't be imported or exported.
   1480 #ifdef MS
   1481 // expected-error@+4{{lambda cannot be declared 'dllimport'}}
   1482 #else
   1483 // expected-warning@+2{{'dllimport' attribute ignored on inline function}}
   1484 #endif
   1485 auto Lambda = []() __declspec(dllimport) -> bool { return true; };
   1486