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