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