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