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