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