[clang] Handle __declspec() attributes in using
[llvm-project.git] / clang / test / SemaCXX / dllexport.cpp
blobbd4b0a7c78df094fb1c8c5b9d59ffe7bbaedafff
1 // RUN: %clang_cc1 -triple i686-win32 -fsyntax-only -fms-extensions -verify -std=c++11 -Wunsupported-dll-base-class-template -DMS %s
2 // RUN: %clang_cc1 -triple x86_64-win32 -fsyntax-only -fms-extensions -verify -std=c++1y -Wunsupported-dll-base-class-template -DMS %s
3 // RUN: %clang_cc1 -triple i686-mingw32 -fsyntax-only -fms-extensions -verify -std=c++1y -Wunsupported-dll-base-class-template -DGNU %s
4 // RUN: %clang_cc1 -triple x86_64-mingw32 -fsyntax-only -fms-extensions -verify -std=c++11 -Wunsupported-dll-base-class-template -DGNU %s
5 // RUN: %clang_cc1 -triple i686-windows-itanium -fsyntax-only -fms-extensions -verify -std=c++11 -Wunsupported-dll-base-class-template -DWI %s
6 // RUN: %clang_cc1 -triple x86_64-windows-itanium -fsyntax-only -fms-extensions -verify -std=c++1y -Wunsupported-dll-base-class-template -DWI %s
7 // RUN: %clang_cc1 -triple x86_64-scei-ps4 -fsyntax-only -fdeclspec -verify -std=c++11 -Wunsupported-dll-base-class-template -DWI %s
8 // RUN: %clang_cc1 -triple x86_64-sie-ps5 -fsyntax-only -fdeclspec -verify -std=c++1y -Wunsupported-dll-base-class-template -DWI %s
10 // Helper structs to make templates more expressive.
11 struct ImplicitInst_Exported {};
12 struct ExplicitDecl_Exported {};
13 struct ExplicitInst_Exported {};
14 struct ExplicitSpec_Exported {};
15 struct ExplicitSpec_Def_Exported {};
16 struct ExplicitSpec_InlineDef_Exported {};
17 struct ExplicitSpec_NotExported {};
18 namespace { struct Internal {}; }
19 struct External { int v; };
22 // Invalid usage.
23 __declspec(dllexport) typedef int typedef1;
24 // expected-warning@-1{{'dllexport' attribute only applies to functions, variables, classes, and Objective-C interfaces}}
25 typedef __declspec(dllexport) int typedef2;
26 // expected-warning@-1{{'dllexport' attribute only applies to}}
27 typedef int __declspec(dllexport) typedef3;
28 // expected-warning@-1{{'dllexport' attribute only applies to}}
29 typedef __declspec(dllexport) void (*FunTy)();
30 // expected-warning@-1{{'dllexport' attribute only applies to}}
31 enum __declspec(dllexport) Enum {};
32 // expected-warning@-1{{'dllexport' attribute only applies to}}
33 #if __has_feature(cxx_strong_enums)
34 enum class __declspec(dllexport) EnumClass {};
35 // expected-warning@-1{{'dllexport' attribute only applies to}}
36 #endif
40 //===----------------------------------------------------------------------===//
41 // Globals
42 //===----------------------------------------------------------------------===//
44 // Export declaration.
45 __declspec(dllexport) extern int ExternGlobalDecl;
47 // dllexport implies a definition.
48 __declspec(dllexport) int GlobalDef;
50 // Export definition.
51 __declspec(dllexport) int GlobalInit1 = 1;
52 int __declspec(dllexport) GlobalInit2 = 1;
54 // Declare, then export definition.
55 __declspec(dllexport) extern int GlobalDeclInit;
56 int GlobalDeclInit = 1;
58 // Redeclarations
59 __declspec(dllexport) extern int GlobalRedecl1;
60 __declspec(dllexport) int GlobalRedecl1;
62 __declspec(dllexport) extern int GlobalRedecl2;
63 int GlobalRedecl2;
65 extern int GlobalRedecl3; // expected-note{{previous declaration is here}}
66 __declspec(dllexport) extern int GlobalRedecl3; // expected-warning{{redeclaration of 'GlobalRedecl3' should not add 'dllexport' attribute}}
68 extern "C" {
69 extern int GlobalRedecl4; // expected-note{{previous declaration is here}}
70 __declspec(dllexport) extern int GlobalRedecl4; // expected-warning{{redeclaration of 'GlobalRedecl4' should not add 'dllexport' attribute}}
73 // External linkage is required.
74 __declspec(dllexport) static int StaticGlobal; // expected-error{{'StaticGlobal' must have external linkage when declared 'dllexport'}}
75 __declspec(dllexport) Internal InternalTypeGlobal; // expected-error{{'InternalTypeGlobal' must have external linkage when declared 'dllexport'}}
76 #ifndef MS
77 namespace { __declspec(dllexport) int InternalGlobal; } // expected-error{{'(anonymous namespace)::InternalGlobal' must have external linkage when declared 'dllexport'}}
78 #endif
79 namespace ns { __declspec(dllexport) int ExternalGlobal; }
81 __declspec(dllexport) auto InternalAutoTypeGlobal = Internal(); // expected-error{{'InternalAutoTypeGlobal' must have external linkage when declared 'dllexport'}}
82 __declspec(dllexport) auto ExternalAutoTypeGlobal = External();
84 // Thread local variables are invalid.
85 __declspec(dllexport) __thread int ThreadLocalGlobal; // expected-error{{'ThreadLocalGlobal' cannot be thread local when declared 'dllexport'}}
86 // But a static local TLS var in an export function is OK.
87 inline void __declspec(dllexport) ExportedInlineWithThreadLocal() {
88 static __thread int OK; // no-error
91 // Export in local scope.
92 void functionScope() {
93 __declspec(dllexport) int LocalVarDecl; // expected-error{{'LocalVarDecl' must have external linkage when declared 'dllexport'}}
94 __declspec(dllexport) int LocalVarDef = 1; // expected-error{{'LocalVarDef' must have external linkage when declared 'dllexport'}}
95 __declspec(dllexport) extern int ExternLocalVarDecl;
96 __declspec(dllexport) static int StaticLocalVar; // expected-error{{'StaticLocalVar' must have external linkage when declared 'dllexport'}}
101 //===----------------------------------------------------------------------===//
102 // Variable templates
103 //===----------------------------------------------------------------------===//
104 #if __has_feature(cxx_variable_templates)
106 // Export declaration.
107 template<typename T> __declspec(dllexport) extern int ExternVarTmplDecl;
109 // dllexport implies a definition.
110 template<typename T> __declspec(dllexport) int VarTmplDef;
112 // Export definition.
113 template<typename T> __declspec(dllexport) int VarTmplInit1 = 1;
114 template<typename T> int __declspec(dllexport) VarTmplInit2 = 1;
116 // Declare, then export definition.
117 template<typename T> __declspec(dllexport) extern int VarTmplDeclInit;
118 template<typename T> int VarTmplDeclInit = 1;
120 // Redeclarations
121 template<typename T> __declspec(dllexport) extern int VarTmplRedecl1;
122 template<typename T> __declspec(dllexport) int VarTmplRedecl1 = 1;
124 template<typename T> __declspec(dllexport) extern int VarTmplRedecl2;
125 template<typename T> int VarTmplRedecl2 = 1;
127 template<typename T> extern int VarTmplRedecl3; // expected-note{{previous declaration is here}}
128 template<typename T> __declspec(dllexport) extern int VarTmplRedecl3; // expected-error{{redeclaration of 'VarTmplRedecl3' cannot add 'dllexport' attribute}}
130 // External linkage is required.
131 template<typename T> __declspec(dllexport) static int StaticVarTmpl; // expected-error{{'StaticVarTmpl' must have external linkage when declared 'dllexport'}}
132 template<typename T> __declspec(dllexport) Internal InternalTypeVarTmpl; // expected-error{{'InternalTypeVarTmpl' must have external linkage when declared 'dllexport'}}
133 #ifndef MS
134 namespace { template<typename T> __declspec(dllexport) int InternalVarTmpl; } // expected-error{{'(anonymous namespace)::InternalVarTmpl' must have external linkage when declared 'dllexport'}}
135 #endif
136 namespace ns { template<typename T> __declspec(dllexport) int ExternalVarTmpl = 1; }
138 template<typename T> __declspec(dllexport) auto InternalAutoTypeVarTmpl = Internal(); // expected-error{{'InternalAutoTypeVarTmpl' must have external linkage when declared 'dllexport'}}
139 template<typename T> __declspec(dllexport) auto ExternalAutoTypeVarTmpl = External();
140 template External ExternalAutoTypeVarTmpl<ExplicitInst_Exported>;
143 template<typename T> int VarTmpl = 1;
144 template<typename T> __declspec(dllexport) int ExportedVarTmpl = 1;
146 // Export implicit instantiation of an exported variable template.
147 int useVarTmpl() { return ExportedVarTmpl<ImplicitInst_Exported>; }
149 // Export explicit instantiation declaration of an exported variable template.
150 extern template int ExportedVarTmpl<ExplicitDecl_Exported>;
151 template int ExportedVarTmpl<ExplicitDecl_Exported>;
153 // Export explicit instantiation definition of an exported variable template.
154 template __declspec(dllexport) int ExportedVarTmpl<ExplicitInst_Exported>;
156 // Export specialization of an exported variable template.
157 template<> __declspec(dllexport) int ExportedVarTmpl<ExplicitSpec_Exported>;
158 template<> __declspec(dllexport) int ExportedVarTmpl<ExplicitSpec_Def_Exported> = 1;
160 // Not exporting specialization of an exported variable template without
161 // explicit dllexport.
162 template<> int ExportedVarTmpl<ExplicitSpec_NotExported>;
165 // Export explicit instantiation declaration of a non-exported variable template.
166 extern template __declspec(dllexport) int VarTmpl<ExplicitDecl_Exported>;
167 template __declspec(dllexport) int VarTmpl<ExplicitDecl_Exported>;
169 // Export explicit instantiation definition of a non-exported variable template.
170 template __declspec(dllexport) int VarTmpl<ExplicitInst_Exported>;
172 // Export specialization of a non-exported variable template.
173 template<> __declspec(dllexport) int VarTmpl<ExplicitSpec_Exported>;
174 template<> __declspec(dllexport) int VarTmpl<ExplicitSpec_Def_Exported> = 1;
176 #endif // __has_feature(cxx_variable_templates)
180 //===----------------------------------------------------------------------===//
181 // Functions
182 //===----------------------------------------------------------------------===//
184 // Export function declaration. Check different placements.
185 __attribute__((dllexport)) void decl1A(); // Correctness check with __attribute__
186 __declspec(dllexport) void decl1B();
188 void __attribute__((dllexport)) decl2A();
189 void __declspec(dllexport) decl2B();
191 // Export function definition.
192 __declspec(dllexport) void def() {}
194 // extern "C"
195 extern "C" __declspec(dllexport) void externC() {}
197 // Export inline function.
198 __declspec(dllexport) inline void inlineFunc1() {}
199 inline void __attribute__((dllexport)) inlineFunc2() {}
201 __declspec(dllexport) inline void inlineDecl();
202 void inlineDecl() {}
204 __declspec(dllexport) void inlineDef();
205 inline void inlineDef() {}
207 // Redeclarations
208 __declspec(dllexport) void redecl1();
209 __declspec(dllexport) void redecl1() {}
211 __declspec(dllexport) void redecl2();
212 void redecl2() {}
214 void redecl3(); // expected-note{{previous declaration is here}}
215 __declspec(dllexport) void redecl3(); // expected-warning{{redeclaration of 'redecl3' should not add 'dllexport' attribute}}
217 extern "C" {
218 void redecl4(); // expected-note{{previous declaration is here}}
219 __declspec(dllexport) void redecl4(); // expected-warning{{redeclaration of 'redecl4' should not add 'dllexport' attribute}}
222 void redecl5(); // expected-note{{previous declaration is here}}
223 __declspec(dllexport) inline void redecl5() {} // expected-warning{{redeclaration of 'redecl5' should not add 'dllexport' attribute}}
225 // Friend functions
226 struct FuncFriend {
227 friend __declspec(dllexport) void friend1();
228 friend __declspec(dllexport) void friend2();
229 friend void friend3(); // expected-note{{previous declaration is here}}
230 friend void friend4(); // expected-note{{previous declaration is here}}
232 __declspec(dllexport) void friend1() {}
233 void friend2() {}
234 __declspec(dllexport) void friend3() {} // expected-warning{{redeclaration of 'friend3' should not add 'dllexport' attribute}}
235 __declspec(dllexport) inline void friend4() {} // expected-warning{{redeclaration of 'friend4' should not add 'dllexport' attribute}}
237 // Implicit declarations can be redeclared with dllexport.
238 __declspec(dllexport) void* operator new(__SIZE_TYPE__ n);
240 // External linkage is required.
241 __declspec(dllexport) static int staticFunc(); // expected-error{{'staticFunc' must have external linkage when declared 'dllexport'}}
242 __declspec(dllexport) Internal internalRetFunc(); // expected-error{{'internalRetFunc' must have external linkage when declared 'dllexport'}}
243 namespace { __declspec(dllexport) void internalFunc() {} } // expected-error{{'(anonymous namespace)::internalFunc' must have external linkage when declared 'dllexport'}}
244 namespace ns { __declspec(dllexport) void externalFunc() {} }
246 // Export deleted function.
247 __declspec(dllexport) void deletedFunc() = delete; // expected-error{{attribute 'dllexport' cannot be applied to a deleted function}}
248 __declspec(dllexport) inline void deletedInlineFunc() = delete; // expected-error{{attribute 'dllexport' cannot be applied to a deleted function}}
252 //===----------------------------------------------------------------------===//
253 // Function templates
254 //===----------------------------------------------------------------------===//
256 // Export function template declaration. Check different placements.
257 template<typename T> __declspec(dllexport) void funcTmplDecl1();
258 template<typename T> void __declspec(dllexport) funcTmplDecl2();
260 // Export function template definition.
261 template<typename T> __declspec(dllexport) void funcTmplDef() {}
263 // Export inline function template.
264 template<typename T> __declspec(dllexport) inline void inlineFuncTmpl1() {}
265 template<typename T> inline void __attribute__((dllexport)) inlineFuncTmpl2() {}
267 template<typename T> __declspec(dllexport) inline void inlineFuncTmplDecl();
268 template<typename T> void inlineFuncTmplDecl() {}
270 template<typename T> __declspec(dllexport) void inlineFuncTmplDef();
271 template<typename T> inline void inlineFuncTmplDef() {}
273 // Redeclarations
274 template<typename T> __declspec(dllexport) void funcTmplRedecl1();
275 template<typename T> __declspec(dllexport) void funcTmplRedecl1() {}
277 template<typename T> __declspec(dllexport) void funcTmplRedecl2();
278 template<typename T> void funcTmplRedecl2() {}
280 template<typename T> void funcTmplRedecl3(); // expected-note{{previous declaration is here}}
281 template<typename T> __declspec(dllexport) void funcTmplRedecl3(); // expected-error{{redeclaration of 'funcTmplRedecl3' cannot add 'dllexport' attribute}}
283 template<typename T> void funcTmplRedecl4(); // expected-note{{previous declaration is here}}
284 template<typename T> __declspec(dllexport) inline void funcTmplRedecl4() {} // expected-error{{redeclaration of 'funcTmplRedecl4' cannot add 'dllexport' attribute}}
286 // Function template friends
287 struct FuncTmplFriend {
288 template<typename T> friend __declspec(dllexport) void funcTmplFriend1();
289 template<typename T> friend __declspec(dllexport) void funcTmplFriend2();
290 template<typename T> friend void funcTmplFriend3(); // expected-note{{previous declaration is here}}
291 template<typename T> friend void funcTmplFriend4(); // expected-note{{previous declaration is here}}
293 template<typename T> __declspec(dllexport) void funcTmplFriend1() {}
294 template<typename T> void funcTmplFriend2() {}
295 template<typename T> __declspec(dllexport) void funcTmplFriend3() {} // expected-error{{redeclaration of 'funcTmplFriend3' cannot add 'dllexport' attribute}}
296 template<typename T> __declspec(dllexport) inline void funcTmplFriend4() {} // expected-error{{redeclaration of 'funcTmplFriend4' cannot add 'dllexport' attribute}}
298 // External linkage is required.
299 template<typename T> __declspec(dllexport) static int staticFuncTmpl(); // expected-error{{'staticFuncTmpl' must have external linkage when declared 'dllexport'}}
300 template<typename T> __declspec(dllexport) Internal internalRetFuncTmpl(); // expected-error{{'internalRetFuncTmpl' must have external linkage when declared 'dllexport'}}
301 namespace { template<typename T> __declspec(dllexport) void internalFuncTmpl(); } // expected-error{{'(anonymous namespace)::internalFuncTmpl' must have external linkage when declared 'dllexport'}}
302 namespace ns { template<typename T> __declspec(dllexport) void externalFuncTmpl(); }
305 template<typename T> void funcTmpl() {}
306 template<typename T> __declspec(dllexport) void exportedFuncTmplDecl();
307 template<typename T> __declspec(dllexport) void exportedFuncTmpl() {}
309 // Export implicit instantiation of an exported function template.
310 void useFunTmplDecl() { exportedFuncTmplDecl<ImplicitInst_Exported>(); }
311 void useFunTmplDef() { exportedFuncTmpl<ImplicitInst_Exported>(); }
313 // Export explicit instantiation declaration of an exported function template.
314 extern template void exportedFuncTmpl<ExplicitDecl_Exported>();
315 template void exportedFuncTmpl<ExplicitDecl_Exported>();
317 // Export explicit instantiation definition of an exported function template.
318 template void exportedFuncTmpl<ExplicitInst_Exported>();
320 // Export specialization of an exported function template.
321 template<> __declspec(dllexport) void exportedFuncTmpl<ExplicitSpec_Exported>();
322 template<> __declspec(dllexport) void exportedFuncTmpl<ExplicitSpec_Def_Exported>() {}
323 template<> __declspec(dllexport) inline void exportedFuncTmpl<ExplicitSpec_InlineDef_Exported>() {}
325 // Not exporting specialization of an exported function template without
326 // explicit dllexport.
327 template<> void exportedFuncTmpl<ExplicitSpec_NotExported>() {}
330 // Export explicit instantiation declaration of a non-exported function template.
331 extern template __declspec(dllexport) void funcTmpl<ExplicitDecl_Exported>();
332 template __declspec(dllexport) void funcTmpl<ExplicitDecl_Exported>();
334 // Export explicit instantiation definition of a non-exported function template.
335 template __declspec(dllexport) void funcTmpl<ExplicitInst_Exported>();
337 // Export specialization of a non-exported function template.
338 template<> __declspec(dllexport) void funcTmpl<ExplicitSpec_Exported>();
339 template<> __declspec(dllexport) void funcTmpl<ExplicitSpec_Def_Exported>() {}
340 template<> __declspec(dllexport) inline void funcTmpl<ExplicitSpec_InlineDef_Exported>() {}
344 //===----------------------------------------------------------------------===//
345 // Classes
346 //===----------------------------------------------------------------------===//
348 namespace {
349 struct __declspec(dllexport) AnonymousClass {}; // expected-error{{(anonymous namespace)::AnonymousClass' must have external linkage when declared 'dllexport'}}
352 class __declspec(dllexport) ClassDecl;
354 class __declspec(dllexport) ClassDef {};
356 #if defined(MS) || defined (WI)
357 // expected-warning@+3{{'dllexport' attribute ignored}}
358 #endif
359 template <typename T> struct PartiallySpecializedClassTemplate {};
360 template <typename T> struct __declspec(dllexport) PartiallySpecializedClassTemplate<T*> { void f() {} };
362 template <typename T> struct ExpliciallySpecializedClassTemplate {};
363 template <> struct __declspec(dllexport) ExpliciallySpecializedClassTemplate<int> { void f() {} };
365 // Don't instantiate class members of implicitly instantiated templates, even if they are exported.
366 struct IncompleteType;
367 template <typename T> struct __declspec(dllexport) ImplicitlyInstantiatedExportedTemplate {
368 int f() { return sizeof(T); } // no-error
370 ImplicitlyInstantiatedExportedTemplate<IncompleteType> implicitlyInstantiatedExportedTemplate;
372 // Don't instantiate class members of templates with explicit instantiation declarations, even if they are exported.
373 struct IncompleteType2;
374 #if defined(MS) || defined (WI)
375 // expected-note@+2{{attribute is here}}
376 #endif
377 template <typename T> struct __declspec(dllexport) ExportedTemplateWithExplicitInstantiationDecl {
378 int f() { return sizeof(T); } // no-error
380 #if defined(MS) || defined (WI)
381 // expected-warning@+2{{explicit instantiation declaration should not be 'dllexport'}}
382 #endif
383 extern template struct ExportedTemplateWithExplicitInstantiationDecl<IncompleteType2>;
385 // Instantiate class members for explicitly instantiated exported templates.
386 struct IncompleteType3; // expected-note{{forward declaration of 'IncompleteType3'}}
387 template <typename T> struct __declspec(dllexport) ExplicitlyInstantiatedExportedTemplate {
388 int f() { return sizeof(T); } // expected-error{{invalid application of 'sizeof' to an incomplete type 'IncompleteType3'}}
390 template struct ExplicitlyInstantiatedExportedTemplate<IncompleteType3>; // expected-note{{in instantiation of member function 'ExplicitlyInstantiatedExportedTemplate<IncompleteType3>::f' requested here}}
392 // In MS mode, instantiate members of class templates that are base classes of exported classes.
393 #ifdef MS
394 // expected-note@+3{{forward declaration of 'IncompleteType4'}}
395 // expected-note@+3{{in instantiation of member function 'BaseClassTemplateOfExportedClass<IncompleteType4>::f' requested here}}
396 #endif
397 struct IncompleteType4;
398 template <typename T> struct BaseClassTemplateOfExportedClass {
399 #ifdef MS
400 // expected-error@+2{{invalid application of 'sizeof' to an incomplete type 'IncompleteType4'}}
401 #endif
402 int f() { return sizeof(T); };
404 struct __declspec(dllexport) ExportedBaseClass : public BaseClassTemplateOfExportedClass<IncompleteType4> {};
406 // Don't instantiate members of explicitly exported class templates that are base classes of exported classes.
407 struct IncompleteType5;
408 template <typename T> struct __declspec(dllexport) ExportedBaseClassTemplateOfExportedClass {
409 int f() { return sizeof(T); }; // no-error
411 struct __declspec(dllexport) ExportedBaseClass2 : public ExportedBaseClassTemplateOfExportedClass<IncompleteType5> {};
413 // Warn about explicit instantiation declarations of dllexport classes.
414 template <typename T> struct ExplicitInstantiationDeclTemplate {};
415 #if defined(MS) || defined (WI)
416 // expected-warning@+2{{explicit instantiation declaration should not be 'dllexport'}} expected-note@+2{{attribute is here}}
417 #endif
418 extern template struct __declspec(dllexport) ExplicitInstantiationDeclTemplate<int>;
420 template <typename T> struct __declspec(dllexport) ExplicitInstantiationDeclExportedTemplate {};
421 #if defined(MS) || defined (WI)
422 // expected-note@-2{{attribute is here}}
423 // expected-warning@+2{{explicit instantiation declaration should not be 'dllexport'}}
424 #endif
425 extern template struct ExplicitInstantiationDeclExportedTemplate<int>;
427 namespace { struct InternalLinkageType {}; }
428 struct __declspec(dllexport) PR23308 {
429 void f(InternalLinkageType*);
431 void PR23308::f(InternalLinkageType*) {} // No error; we don't try to export f because it has internal linkage.
433 //===----------------------------------------------------------------------===//
434 // Classes with template base classes
435 //===----------------------------------------------------------------------===//
437 template <typename T> class ClassTemplate {};
438 template <typename T> class __declspec(dllexport) ExportedClassTemplate {};
439 template <typename T> class __declspec(dllimport) ImportedClassTemplate {};
441 template <typename T> struct ExplicitlySpecializedTemplate { void func() {} };
442 #ifdef MS
443 // expected-note@+2{{class template 'ExplicitlySpecializedTemplate<int>' was explicitly specialized here}}
444 #endif
445 template <> struct ExplicitlySpecializedTemplate<int> { void func() {} };
446 template <typename T> struct ExplicitlyExportSpecializedTemplate { void func() {} };
447 template <> struct __declspec(dllexport) ExplicitlyExportSpecializedTemplate<int> { void func() {} };
448 template <typename T> struct ExplicitlyImportSpecializedTemplate { void func() {} };
449 template <> struct __declspec(dllimport) ExplicitlyImportSpecializedTemplate<int> { void func() {} };
451 template <typename T> struct ExplicitlyInstantiatedTemplate { void func() {} };
452 #ifdef MS
453 // expected-note@+2{{class template 'ExplicitlyInstantiatedTemplate<int>' was instantiated here}}
454 #endif
455 template struct ExplicitlyInstantiatedTemplate<int>;
456 template <typename T> struct ExplicitlyExportInstantiatedTemplate { void func() {} };
457 template struct __declspec(dllexport) ExplicitlyExportInstantiatedTemplate<int>;
458 template <typename T> struct ExplicitlyExportDeclaredInstantiatedTemplate { void func() {} };
459 extern template struct ExplicitlyExportDeclaredInstantiatedTemplate<int>;
460 #if not defined(MS) && not defined (WI)
461 // expected-warning@+2{{'dllexport' attribute ignored on explicit instantiation definition}}
462 #endif
463 template struct __declspec(dllexport) ExplicitlyExportDeclaredInstantiatedTemplate<int>;
464 template <typename T> struct ExplicitlyImportInstantiatedTemplate { void func() {} };
465 template struct __declspec(dllimport) ExplicitlyImportInstantiatedTemplate<int>;
467 // ClassTemplate<int> gets exported.
468 class __declspec(dllexport) DerivedFromTemplate : public ClassTemplate<int> {};
470 // ClassTemplate<int> is already exported.
471 class __declspec(dllexport) DerivedFromTemplate2 : public ClassTemplate<int> {};
473 // ExportedTemplate is explicitly exported.
474 class __declspec(dllexport) DerivedFromExportedTemplate : public ExportedClassTemplate<int> {};
476 // ImportedTemplate is explicitly imported.
477 class __declspec(dllexport) DerivedFromImportedTemplate : public ImportedClassTemplate<int> {};
479 class DerivedFromTemplateD : public ClassTemplate<double> {};
480 // Base class previously implicitly instantiated without attribute; it will get propagated.
481 class __declspec(dllexport) DerivedFromTemplateD2 : public ClassTemplate<double> {};
483 // Base class has explicit instantiation declaration; the attribute will get propagated.
484 extern template class ClassTemplate<float>;
485 class __declspec(dllexport) DerivedFromTemplateF : public ClassTemplate<float> {};
487 class __declspec(dllexport) DerivedFromTemplateB : public ClassTemplate<bool> {};
488 // The second derived class doesn't change anything, the attribute that was propagated first wins.
489 class __declspec(dllimport) DerivedFromTemplateB2 : public ClassTemplate<bool> {};
491 #ifdef MS
492 // expected-warning@+3{{propagating dll attribute to explicitly specialized base class template without dll attribute is not supported}}
493 // expected-note@+2{{attribute is here}}
494 #endif
495 struct __declspec(dllexport) DerivedFromExplicitlySpecializedTemplate : public ExplicitlySpecializedTemplate<int> {};
497 // Base class alredy specialized with export attribute.
498 struct __declspec(dllexport) DerivedFromExplicitlyExportSpecializedTemplate : public ExplicitlyExportSpecializedTemplate<int> {};
500 // Base class already specialized with import attribute.
501 struct __declspec(dllexport) DerivedFromExplicitlyImportSpecializedTemplate : public ExplicitlyImportSpecializedTemplate<int> {};
503 #ifdef MS
504 // expected-warning@+3{{propagating dll attribute to already instantiated base class template without dll attribute is not supported}}
505 // expected-note@+2{{attribute is here}}
506 #endif
507 struct __declspec(dllexport) DerivedFromExplicitlyInstantiatedTemplate : public ExplicitlyInstantiatedTemplate<int> {};
509 // Base class already instantiated with export attribute.
510 struct __declspec(dllexport) DerivedFromExplicitlyExportInstantiatedTemplate : public ExplicitlyExportInstantiatedTemplate<int> {};
512 // Base class already instantiated with import attribute.
513 struct __declspec(dllexport) DerivedFromExplicitlyImportInstantiatedTemplate : public ExplicitlyImportInstantiatedTemplate<int> {};
515 template <typename T> struct ExplicitInstantiationDeclTemplateBase { void func() {} };
516 extern template struct ExplicitInstantiationDeclTemplateBase<int>;
517 struct __declspec(dllexport) DerivedFromExplicitInstantiationDeclTemplateBase : public ExplicitInstantiationDeclTemplateBase<int> {};
520 //===----------------------------------------------------------------------===//
521 // Precedence
522 //===----------------------------------------------------------------------===//
524 // dllexport takes precedence over dllimport if both are specified.
525 __attribute__((dllimport, dllexport)) extern int PrecedenceExternGlobal1A; // expected-warning{{'dllimport' attribute ignored}}
526 __declspec(dllimport) __declspec(dllexport) extern int PrecedenceExternGlobal1B; // expected-warning{{'dllimport' attribute ignored}}
528 __attribute__((dllexport, dllimport)) extern int PrecedenceExternGlobal2A; // expected-warning{{'dllimport' attribute ignored}}
529 __declspec(dllexport) __declspec(dllimport) extern int PrecedenceExternGlobal2B; // expected-warning{{'dllimport' attribute ignored}}
531 __attribute__((dllimport, dllexport)) int PrecedenceGlobal1A; // expected-warning{{'dllimport' attribute ignored}}
532 __declspec(dllimport) __declspec(dllexport) int PrecedenceGlobal1B; // expected-warning{{'dllimport' attribute ignored}}
534 __attribute__((dllexport, dllimport)) int PrecedenceGlobal2A; // expected-warning{{'dllimport' attribute ignored}}
535 __declspec(dllexport) __declspec(dllimport) int PrecedenceGlobal2B; // expected-warning{{'dllimport' attribute ignored}}
537 __declspec(dllexport) extern int PrecedenceExternGlobalRedecl1;
538 __declspec(dllimport) extern int PrecedenceExternGlobalRedecl1; // expected-warning{{'dllimport' attribute ignored}}
540 __declspec(dllimport) extern int PrecedenceExternGlobalRedecl2; // expected-warning{{'dllimport' attribute ignored}}
541 __declspec(dllexport) extern int PrecedenceExternGlobalRedecl2;
543 __declspec(dllexport) extern int PrecedenceGlobalRedecl1;
544 __declspec(dllimport) int PrecedenceGlobalRedecl1; // expected-warning{{'dllimport' attribute ignored}}
546 __declspec(dllimport) extern int PrecedenceGlobalRedecl2; // expected-warning{{'dllimport' attribute ignored}}
547 __declspec(dllexport) int PrecedenceGlobalRedecl2;
549 void __attribute__((dllimport, dllexport)) precedence1A() {} // expected-warning{{'dllimport' attribute ignored}}
550 void __declspec(dllimport) __declspec(dllexport) precedence1B() {} // expected-warning{{'dllimport' attribute ignored}}
552 void __attribute__((dllexport, dllimport)) precedence2A() {} // expected-warning{{'dllimport' attribute ignored}}
553 void __declspec(dllexport) __declspec(dllimport) precedence2B() {} // expected-warning{{'dllimport' attribute ignored}}
555 void __declspec(dllimport) precedenceRedecl1(); // expected-warning{{'dllimport' attribute ignored}}
556 void __declspec(dllexport) precedenceRedecl1() {}
558 void __declspec(dllexport) precedenceRedecl2();
559 void __declspec(dllimport) precedenceRedecl2() {} // expected-warning{{'dllimport' attribute ignored}}
563 //===----------------------------------------------------------------------===//
564 // Class members
565 //===----------------------------------------------------------------------===//
567 // Export individual members of a class.
568 struct ExportMembers {
569 struct Nested {
570 __declspec(dllexport) void normalDef();
573 __declspec(dllexport) void normalDecl();
574 __declspec(dllexport) void normalDef();
575 __declspec(dllexport) void normalInclass() {}
576 __declspec(dllexport) void normalInlineDef();
577 __declspec(dllexport) inline void normalInlineDecl();
578 __declspec(dllexport) virtual void virtualDecl();
579 __declspec(dllexport) virtual void virtualDef();
580 __declspec(dllexport) virtual void virtualInclass() {}
581 __declspec(dllexport) virtual void virtualInlineDef();
582 __declspec(dllexport) virtual inline void virtualInlineDecl();
583 __declspec(dllexport) static void staticDecl();
584 __declspec(dllexport) static void staticDef();
585 __declspec(dllexport) static void staticInclass() {}
586 __declspec(dllexport) static void staticInlineDef();
587 __declspec(dllexport) static inline void staticInlineDecl();
589 protected:
590 __declspec(dllexport) void protectedDef();
591 private:
592 __declspec(dllexport) void privateDef();
593 public:
595 __declspec(dllexport) int Field; // expected-warning{{'dllexport' attribute only applies to}}
596 __declspec(dllexport) static int StaticField;
597 __declspec(dllexport) static int StaticFieldDef;
598 __declspec(dllexport) static const int StaticConstField;
599 __declspec(dllexport) static const int StaticConstFieldDef;
600 __declspec(dllexport) static const int StaticConstFieldEqualInit = 1;
601 __declspec(dllexport) static const int StaticConstFieldBraceInit{1};
602 __declspec(dllexport) constexpr static int ConstexprField = 1;
603 __declspec(dllexport) constexpr static int ConstexprFieldDef = 1;
606 void ExportMembers::Nested::normalDef() {}
607 void ExportMembers::normalDef() {}
608 inline void ExportMembers::normalInlineDef() {}
609 void ExportMembers::normalInlineDecl() {}
610 void ExportMembers::virtualDef() {}
611 inline void ExportMembers::virtualInlineDef() {}
612 void ExportMembers::virtualInlineDecl() {}
613 void ExportMembers::staticDef() {}
614 inline void ExportMembers::staticInlineDef() {}
615 void ExportMembers::staticInlineDecl() {}
616 void ExportMembers::protectedDef() {}
617 void ExportMembers::privateDef() {}
619 int ExportMembers::StaticFieldDef;
620 const int ExportMembers::StaticConstFieldDef = 1;
621 constexpr int ExportMembers::ConstexprFieldDef;
624 // Export on member definitions.
625 struct ExportMemberDefs {
626 __declspec(dllexport) void normalDef();
627 __declspec(dllexport) void normalInlineDef();
628 __declspec(dllexport) inline void normalInlineDecl();
629 __declspec(dllexport) virtual void virtualDef();
630 __declspec(dllexport) virtual void virtualInlineDef();
631 __declspec(dllexport) virtual inline void virtualInlineDecl();
632 __declspec(dllexport) static void staticDef();
633 __declspec(dllexport) static void staticInlineDef();
634 __declspec(dllexport) static inline void staticInlineDecl();
636 __declspec(dllexport) static int StaticField;
637 __declspec(dllexport) static const int StaticConstField;
638 __declspec(dllexport) constexpr static int ConstexprField = 1;
641 __declspec(dllexport) void ExportMemberDefs::normalDef() {}
642 __declspec(dllexport) inline void ExportMemberDefs::normalInlineDef() {}
643 __declspec(dllexport) void ExportMemberDefs::normalInlineDecl() {}
644 __declspec(dllexport) void ExportMemberDefs::virtualDef() {}
645 __declspec(dllexport) inline void ExportMemberDefs::virtualInlineDef() {}
646 __declspec(dllexport) void ExportMemberDefs::virtualInlineDecl() {}
647 __declspec(dllexport) void ExportMemberDefs::staticDef() {}
648 __declspec(dllexport) inline void ExportMemberDefs::staticInlineDef() {}
649 __declspec(dllexport) void ExportMemberDefs::staticInlineDecl() {}
651 __declspec(dllexport) int ExportMemberDefs::StaticField;
652 __declspec(dllexport) const int ExportMemberDefs::StaticConstField = 1;
653 __declspec(dllexport) constexpr int ExportMemberDefs::ConstexprField;
656 // Export special member functions.
657 struct ExportSpecials {
658 __declspec(dllexport) ExportSpecials() {}
659 __declspec(dllexport) ~ExportSpecials();
660 __declspec(dllexport) inline ExportSpecials(const ExportSpecials&);
661 __declspec(dllexport) ExportSpecials& operator=(const ExportSpecials&);
662 __declspec(dllexport) ExportSpecials(ExportSpecials&&);
663 __declspec(dllexport) ExportSpecials& operator=(ExportSpecials&&);
666 ExportSpecials::~ExportSpecials() {}
667 ExportSpecials::ExportSpecials(const ExportSpecials&) {}
668 inline ExportSpecials& ExportSpecials::operator=(const ExportSpecials&) { return *this; }
669 ExportSpecials::ExportSpecials(ExportSpecials&&) {}
670 ExportSpecials& ExportSpecials::operator=(ExportSpecials&&) { return *this; }
673 // Export allocation functions.
674 extern "C" void* malloc(__SIZE_TYPE__ size);
675 extern "C" void free(void* p);
676 struct ExportAlloc {
677 __declspec(dllexport) void* operator new(__SIZE_TYPE__);
678 __declspec(dllexport) void* operator new[](__SIZE_TYPE__);
679 __declspec(dllexport) void operator delete(void*);
680 __declspec(dllexport) void operator delete[](void*);
682 void* ExportAlloc::operator new(__SIZE_TYPE__ n) { return malloc(n); }
683 void* ExportAlloc::operator new[](__SIZE_TYPE__ n) { return malloc(n); }
684 void ExportAlloc::operator delete(void* p) { free(p); }
685 void ExportAlloc::operator delete[](void* p) { free(p); }
688 // Export deleted member functions.
689 struct ExportDeleted {
690 __declspec(dllexport) ExportDeleted() = delete; // expected-error{{attribute 'dllexport' cannot be applied to a deleted function}}
691 __declspec(dllexport) ~ExportDeleted() = delete; // expected-error{{attribute 'dllexport' cannot be applied to a deleted function}}
692 __declspec(dllexport) ExportDeleted(const ExportDeleted&) = delete; // expected-error{{attribute 'dllexport' cannot be applied to a deleted function}}
693 __declspec(dllexport) ExportDeleted& operator=(const ExportDeleted&) = delete; // expected-error{{attribute 'dllexport' cannot be applied to a deleted function}}
694 __declspec(dllexport) ExportDeleted(ExportDeleted&&) = delete; // expected-error{{attribute 'dllexport' cannot be applied to a deleted function}}
695 __declspec(dllexport) ExportDeleted& operator=(ExportDeleted&&) = delete; // expected-error{{attribute 'dllexport' cannot be applied to a deleted function}}
696 __declspec(dllexport) void deleted() = delete; // expected-error{{attribute 'dllexport' cannot be applied to a deleted function}}
700 // Export defaulted member functions.
701 struct ExportDefaulted {
702 __declspec(dllexport) ExportDefaulted() = default;
703 __declspec(dllexport) ~ExportDefaulted() = default;
704 __declspec(dllexport) ExportDefaulted(const ExportDefaulted&) = default;
705 __declspec(dllexport) ExportDefaulted& operator=(const ExportDefaulted&) = default;
706 __declspec(dllexport) ExportDefaulted(ExportDefaulted&&) = default;
707 __declspec(dllexport) ExportDefaulted& operator=(ExportDefaulted&&) = default;
711 // Export defaulted member function definitions.
712 struct ExportDefaultedDefs {
713 __declspec(dllexport) ExportDefaultedDefs();
714 __declspec(dllexport) ~ExportDefaultedDefs();
716 __declspec(dllexport) inline ExportDefaultedDefs(const ExportDefaultedDefs&);
717 __declspec(dllexport) ExportDefaultedDefs& operator=(const ExportDefaultedDefs&);
719 __declspec(dllexport) ExportDefaultedDefs(ExportDefaultedDefs&&);
720 __declspec(dllexport) ExportDefaultedDefs& operator=(ExportDefaultedDefs&&);
723 // Export definitions.
724 __declspec(dllexport) ExportDefaultedDefs::ExportDefaultedDefs() = default;
725 ExportDefaultedDefs::~ExportDefaultedDefs() = default;
727 // Export inline declaration and definition.
728 __declspec(dllexport) ExportDefaultedDefs::ExportDefaultedDefs(const ExportDefaultedDefs&) = default;
729 inline ExportDefaultedDefs& ExportDefaultedDefs::operator=(const ExportDefaultedDefs&) = default;
731 __declspec(dllexport) ExportDefaultedDefs::ExportDefaultedDefs(ExportDefaultedDefs&&) = default;
732 ExportDefaultedDefs& ExportDefaultedDefs::operator=(ExportDefaultedDefs&&) = default;
735 // Redeclarations cannot add dllexport.
736 struct MemberRedecl {
737 void normalDef(); // expected-note{{previous declaration is here}}
738 void normalInlineDef(); // expected-note{{previous declaration is here}}
739 inline void normalInlineDecl(); // expected-note{{previous declaration is here}}
740 virtual void virtualDef(); // expected-note{{previous declaration is here}}
741 virtual void virtualInlineDef(); // expected-note{{previous declaration is here}}
742 virtual inline void virtualInlineDecl(); // expected-note{{previous declaration is here}}
743 static void staticDef(); // expected-note{{previous declaration is here}}
744 static void staticInlineDef(); // expected-note{{previous declaration is here}}
745 static inline void staticInlineDecl(); // expected-note{{previous declaration is here}}
747 static int StaticField; // expected-note{{previous declaration is here}}
748 static const int StaticConstField; // expected-note{{previous declaration is here}}
749 constexpr static int ConstexprField = 1; // expected-note-re{{previous {{(declaration|definition)}} is here}}
752 __declspec(dllexport) void MemberRedecl::normalDef() {} // expected-error{{redeclaration of 'MemberRedecl::normalDef' cannot add 'dllexport' attribute}}
753 __declspec(dllexport) inline void MemberRedecl::normalInlineDef() {} // expected-error{{redeclaration of 'MemberRedecl::normalInlineDef' cannot add 'dllexport' attribute}}
754 __declspec(dllexport) void MemberRedecl::normalInlineDecl() {} // expected-error{{redeclaration of 'MemberRedecl::normalInlineDecl' cannot add 'dllexport' attribute}}
755 __declspec(dllexport) void MemberRedecl::virtualDef() {} // expected-error{{redeclaration of 'MemberRedecl::virtualDef' cannot add 'dllexport' attribute}}
756 __declspec(dllexport) inline void MemberRedecl::virtualInlineDef() {} // expected-error{{redeclaration of 'MemberRedecl::virtualInlineDef' cannot add 'dllexport' attribute}}
757 __declspec(dllexport) void MemberRedecl::virtualInlineDecl() {} // expected-error{{redeclaration of 'MemberRedecl::virtualInlineDecl' cannot add 'dllexport' attribute}}
758 __declspec(dllexport) void MemberRedecl::staticDef() {} // expected-error{{redeclaration of 'MemberRedecl::staticDef' cannot add 'dllexport' attribute}}
759 __declspec(dllexport) inline void MemberRedecl::staticInlineDef() {} // expected-error{{redeclaration of 'MemberRedecl::staticInlineDef' cannot add 'dllexport' attribute}}
760 __declspec(dllexport) void MemberRedecl::staticInlineDecl() {} // expected-error{{redeclaration of 'MemberRedecl::staticInlineDecl' cannot add 'dllexport' attribute}}
762 __declspec(dllexport) int MemberRedecl::StaticField = 1; // expected-error{{redeclaration of 'MemberRedecl::StaticField' cannot add 'dllexport' attribute}}
763 __declspec(dllexport) const int MemberRedecl::StaticConstField = 1; // expected-error{{redeclaration of 'MemberRedecl::StaticConstField' cannot add 'dllexport' attribute}}
764 #ifdef MS
765 // expected-warning@+4{{attribute declaration must precede definition}}
766 #else
767 // expected-error@+2{{redeclaration of 'MemberRedecl::ConstexprField' cannot add 'dllexport' attribute}}
768 #endif
769 __declspec(dllexport) constexpr int MemberRedecl::ConstexprField;
771 #ifdef MS
772 struct __declspec(dllexport) ClassWithMultipleDefaultCtors {
773 ClassWithMultipleDefaultCtors(int = 40) {} // expected-error{{'__declspec(dllexport)' cannot be applied to more than one default constructor}}
774 ClassWithMultipleDefaultCtors(int = 30, ...) {} // expected-note{{declared here}}
776 template <typename T>
777 struct ClassTemplateWithMultipleDefaultCtors {
778 __declspec(dllexport) ClassTemplateWithMultipleDefaultCtors(int = 40) {} // expected-error{{'__declspec(dllexport)' cannot be applied to more than one default constructor}}
779 __declspec(dllexport) ClassTemplateWithMultipleDefaultCtors(int = 30, ...) {} // expected-note{{declared here}}
782 template <typename T> struct HasDefaults {
783 HasDefaults(int x = sizeof(T)) {} // expected-error {{invalid application of 'sizeof'}}
785 template struct __declspec(dllexport) HasDefaults<char>;
787 template struct
788 __declspec(dllexport) // expected-note {{in instantiation of default function argument expression for 'HasDefaults<void>' required here}}
789 HasDefaults<void>; // expected-note {{in instantiation of member function 'HasDefaults<void>::HasDefaults' requested here}}
791 template <typename T> struct HasDefaults2 {
792 __declspec(dllexport) // expected-note {{in instantiation of default function argument expression for 'HasDefaults2<void>' required here}}
793 HasDefaults2(int x = sizeof(T)) {} // expected-error {{invalid application of 'sizeof'}}
795 template struct HasDefaults2<void>; // expected-note {{in instantiation of member function 'HasDefaults2<void>::HasDefaults2' requested here}}
797 template <typename T> struct __declspec(dllexport) HasDefaults3 { // expected-note{{in instantiation of default function argument expression for 'HasDefaults3<void>' required here}}
798 HasDefaults3(int x = sizeof(T)) {} // expected-error {{invalid application of 'sizeof'}}
800 template <> HasDefaults3<void>::HasDefaults3(int) {};
802 #endif
804 //===----------------------------------------------------------------------===//
805 // Class member templates
806 //===----------------------------------------------------------------------===//
808 struct ExportMemberTmpl {
809 template<typename T> __declspec(dllexport) void normalDecl();
810 template<typename T> __declspec(dllexport) void normalDef();
811 template<typename T> __declspec(dllexport) void normalInclass() {}
812 template<typename T> __declspec(dllexport) void normalInlineDef();
813 template<typename T> __declspec(dllexport) inline void normalInlineDecl();
814 template<typename T> __declspec(dllexport) static void staticDecl();
815 template<typename T> __declspec(dllexport) static void staticDef();
816 template<typename T> __declspec(dllexport) static void staticInclass() {}
817 template<typename T> __declspec(dllexport) static void staticInlineDef();
818 template<typename T> __declspec(dllexport) static inline void staticInlineDecl();
820 #if __has_feature(cxx_variable_templates)
821 template<typename T> __declspec(dllexport) static int StaticField;
822 template<typename T> __declspec(dllexport) static int StaticFieldDef;
823 template<typename T> __declspec(dllexport) static const int StaticConstField;
824 template<typename T> __declspec(dllexport) static const int StaticConstFieldDef;
825 template<typename T> __declspec(dllexport) static const int StaticConstFieldEqualInit = 1;
826 template<typename T> __declspec(dllexport) static const int StaticConstFieldBraceInit{1};
827 template<typename T> __declspec(dllexport) constexpr static int ConstexprField = 1;
828 template<typename T> __declspec(dllexport) constexpr static int ConstexprFieldDef = 1;
829 #endif // __has_feature(cxx_variable_templates)
832 template<typename T> void ExportMemberTmpl::normalDef() {}
833 template<typename T> inline void ExportMemberTmpl::normalInlineDef() {}
834 template<typename T> void ExportMemberTmpl::normalInlineDecl() {}
835 template<typename T> void ExportMemberTmpl::staticDef() {}
836 template<typename T> inline void ExportMemberTmpl::staticInlineDef() {}
837 template<typename T> void ExportMemberTmpl::staticInlineDecl() {}
839 #if __has_feature(cxx_variable_templates)
840 template<typename T> int ExportMemberTmpl::StaticFieldDef;
841 template<typename T> const int ExportMemberTmpl::StaticConstFieldDef = 1;
842 template<typename T> constexpr int ExportMemberTmpl::ConstexprFieldDef;
843 #endif // __has_feature(cxx_variable_templates)
846 // Redeclarations cannot add dllexport.
847 struct MemTmplRedecl {
848 template<typename T> void normalDef(); // expected-note{{previous declaration is here}}
849 template<typename T> void normalInlineDef(); // expected-note{{previous declaration is here}}
850 template<typename T> inline void normalInlineDecl(); // expected-note{{previous declaration is here}}
851 template<typename T> static void staticDef(); // expected-note{{previous declaration is here}}
852 template<typename T> static void staticInlineDef(); // expected-note{{previous declaration is here}}
853 template<typename T> static inline void staticInlineDecl(); // expected-note{{previous declaration is here}}
855 #if __has_feature(cxx_variable_templates)
856 template<typename T> static int StaticField; // expected-note{{previous declaration is here}}
857 template<typename T> static const int StaticConstField; // expected-note{{previous declaration is here}}
858 template<typename T> constexpr static int ConstexprField = 1; // expected-note-re{{previous {{(declaration|definition)}} is here}}
859 #endif // __has_feature(cxx_variable_templates)
862 template<typename T> __declspec(dllexport) void MemTmplRedecl::normalDef() {} // expected-error{{redeclaration of 'MemTmplRedecl::normalDef' cannot add 'dllexport' attribute}}
863 template<typename T> __declspec(dllexport) inline void MemTmplRedecl::normalInlineDef() {} // expected-error{{redeclaration of 'MemTmplRedecl::normalInlineDef' cannot add 'dllexport' attribute}}
864 template<typename T> __declspec(dllexport) void MemTmplRedecl::normalInlineDecl() {} // expected-error{{redeclaration of 'MemTmplRedecl::normalInlineDecl' cannot add 'dllexport' attribute}}
865 template<typename T> __declspec(dllexport) void MemTmplRedecl::staticDef() {} // expected-error{{redeclaration of 'MemTmplRedecl::staticDef' cannot add 'dllexport' attribute}}
866 template<typename T> __declspec(dllexport) inline void MemTmplRedecl::staticInlineDef() {} // expected-error{{redeclaration of 'MemTmplRedecl::staticInlineDef' cannot add 'dllexport' attribute}}
867 template<typename T> __declspec(dllexport) void MemTmplRedecl::staticInlineDecl() {} // expected-error{{redeclaration of 'MemTmplRedecl::staticInlineDecl' cannot add 'dllexport' attribute}}
869 #if __has_feature(cxx_variable_templates)
870 template<typename T> __declspec(dllexport) int MemTmplRedecl::StaticField = 1; // expected-error{{redeclaration of 'MemTmplRedecl::StaticField' cannot add 'dllexport' attribute}}
871 template<typename T> __declspec(dllexport) const int MemTmplRedecl::StaticConstField = 1; // expected-error{{redeclaration of 'MemTmplRedecl::StaticConstField' cannot add 'dllexport' attribute}}
873 #ifdef MS
874 // expected-warning@+4{{attribute declaration must precede definition}}
875 #else
876 // expected-error@+2{{redeclaration of 'MemTmplRedecl::ConstexprField' cannot add 'dllexport' attribute}}
877 #endif
878 template<typename T> __declspec(dllexport) constexpr int MemTmplRedecl::ConstexprField;
879 #endif // __has_feature(cxx_variable_templates)
883 struct MemFunTmpl {
884 template<typename T> void normalDef() {}
885 template<typename T> __declspec(dllexport) void exportedNormal() {}
886 template<typename T> static void staticDef() {}
887 template<typename T> __declspec(dllexport) static void exportedStatic() {}
890 // Export implicit instantiation of an exported member function template.
891 void useMemFunTmpl() {
892 MemFunTmpl().exportedNormal<ImplicitInst_Exported>();
893 MemFunTmpl().exportedStatic<ImplicitInst_Exported>();
896 // Export explicit instantiation declaration of an exported member function
897 // template.
898 extern template void MemFunTmpl::exportedNormal<ExplicitDecl_Exported>();
899 template void MemFunTmpl::exportedNormal<ExplicitDecl_Exported>();
901 extern template void MemFunTmpl::exportedStatic<ExplicitDecl_Exported>();
902 template void MemFunTmpl::exportedStatic<ExplicitDecl_Exported>();
904 // Export explicit instantiation definition of an exported member function
905 // template.
906 template void MemFunTmpl::exportedNormal<ExplicitInst_Exported>();
907 template void MemFunTmpl::exportedStatic<ExplicitInst_Exported>();
909 // Export specialization of an exported member function template.
910 template<> __declspec(dllexport) void MemFunTmpl::exportedNormal<ExplicitSpec_Exported>();
911 template<> __declspec(dllexport) void MemFunTmpl::exportedNormal<ExplicitSpec_Def_Exported>() {}
912 template<> __declspec(dllexport) inline void MemFunTmpl::exportedNormal<ExplicitSpec_InlineDef_Exported>() {}
914 template<> __declspec(dllexport) void MemFunTmpl::exportedStatic<ExplicitSpec_Exported>();
915 template<> __declspec(dllexport) void MemFunTmpl::exportedStatic<ExplicitSpec_Def_Exported>() {}
916 template<> __declspec(dllexport) inline void MemFunTmpl::exportedStatic<ExplicitSpec_InlineDef_Exported>() {}
918 // Not exporting specialization of an exported member function template without
919 // explicit dllexport.
920 template<> void MemFunTmpl::exportedNormal<ExplicitSpec_NotExported>() {}
921 template<> void MemFunTmpl::exportedStatic<ExplicitSpec_NotExported>() {}
924 // Export explicit instantiation declaration of a non-exported member function
925 // template.
926 extern template __declspec(dllexport) void MemFunTmpl::normalDef<ExplicitDecl_Exported>();
927 template __declspec(dllexport) void MemFunTmpl::normalDef<ExplicitDecl_Exported>();
929 extern template __declspec(dllexport) void MemFunTmpl::staticDef<ExplicitDecl_Exported>();
930 template __declspec(dllexport) void MemFunTmpl::staticDef<ExplicitDecl_Exported>();
932 // Export explicit instantiation definition of a non-exported member function
933 // template.
934 template __declspec(dllexport) void MemFunTmpl::normalDef<ExplicitInst_Exported>();
935 template __declspec(dllexport) void MemFunTmpl::staticDef<ExplicitInst_Exported>();
937 // Export specialization of a non-exported member function template.
938 template<> __declspec(dllexport) void MemFunTmpl::normalDef<ExplicitSpec_Exported>();
939 template<> __declspec(dllexport) void MemFunTmpl::normalDef<ExplicitSpec_Def_Exported>() {}
940 template<> __declspec(dllexport) inline void MemFunTmpl::normalDef<ExplicitSpec_InlineDef_Exported>() {}
942 template<> __declspec(dllexport) void MemFunTmpl::staticDef<ExplicitSpec_Exported>();
943 template<> __declspec(dllexport) void MemFunTmpl::staticDef<ExplicitSpec_Def_Exported>() {}
944 template<> __declspec(dllexport) inline void MemFunTmpl::staticDef<ExplicitSpec_InlineDef_Exported>() {}
948 #if __has_feature(cxx_variable_templates)
949 struct MemVarTmpl {
950 template<typename T> static const int StaticVar = 1;
951 template<typename T> __declspec(dllexport) static const int ExportedStaticVar = 1;
953 template<typename T> const int MemVarTmpl::StaticVar;
954 template<typename T> const int MemVarTmpl::ExportedStaticVar;
956 // Export implicit instantiation of an exported member variable template.
957 int useMemVarTmpl() { return MemVarTmpl::ExportedStaticVar<ImplicitInst_Exported>; }
959 // Export explicit instantiation declaration of an exported member variable
960 // template.
961 extern template const int MemVarTmpl::ExportedStaticVar<ExplicitDecl_Exported>;
962 template const int MemVarTmpl::ExportedStaticVar<ExplicitDecl_Exported>;
964 // Export explicit instantiation definition of an exported member variable
965 // template.
966 template const int MemVarTmpl::ExportedStaticVar<ExplicitInst_Exported>;
968 // Export specialization of an exported member variable template.
969 template<> __declspec(dllexport) const int MemVarTmpl::ExportedStaticVar<ExplicitSpec_Exported>;
970 template<> __declspec(dllexport) const int MemVarTmpl::ExportedStaticVar<ExplicitSpec_Def_Exported> = 1;
972 // Not exporting specialization of an exported member variable template without
973 // explicit dllexport.
974 template<> const int MemVarTmpl::ExportedStaticVar<ExplicitSpec_NotExported>;
977 // Export explicit instantiation declaration of a non-exported member variable
978 // template.
979 extern template __declspec(dllexport) const int MemVarTmpl::StaticVar<ExplicitDecl_Exported>;
980 template __declspec(dllexport) const int MemVarTmpl::StaticVar<ExplicitDecl_Exported>;
982 // Export explicit instantiation definition of a non-exported member variable
983 // template.
984 template __declspec(dllexport) const int MemVarTmpl::StaticVar<ExplicitInst_Exported>;
986 // Export specialization of a non-exported member variable template.
987 template<> __declspec(dllexport) const int MemVarTmpl::StaticVar<ExplicitSpec_Exported>;
988 template<> __declspec(dllexport) const int MemVarTmpl::StaticVar<ExplicitSpec_Def_Exported> = 1;
990 #endif // __has_feature(cxx_variable_templates)
994 //===----------------------------------------------------------------------===//
995 // Class template members
996 //===----------------------------------------------------------------------===//
998 // Export individual members of a class template.
999 template<typename T>
1000 struct ExportClassTmplMembers {
1001 __declspec(dllexport) void normalDecl();
1002 __declspec(dllexport) void normalDef();
1003 __declspec(dllexport) void normalInclass() {}
1004 __declspec(dllexport) void normalInlineDef();
1005 __declspec(dllexport) inline void normalInlineDecl();
1006 __declspec(dllexport) virtual void virtualDecl();
1007 __declspec(dllexport) virtual void virtualDef();
1008 __declspec(dllexport) virtual void virtualInclass() {}
1009 __declspec(dllexport) virtual void virtualInlineDef();
1010 __declspec(dllexport) virtual inline void virtualInlineDecl();
1011 __declspec(dllexport) static void staticDecl();
1012 __declspec(dllexport) static void staticDef();
1013 __declspec(dllexport) static void staticInclass() {}
1014 __declspec(dllexport) static void staticInlineDef();
1015 __declspec(dllexport) static inline void staticInlineDecl();
1017 protected:
1018 __declspec(dllexport) void protectedDef();
1019 private:
1020 __declspec(dllexport) void privateDef();
1021 public:
1023 __declspec(dllexport) int Field; // expected-warning{{'dllexport' attribute only applies to}}
1024 __declspec(dllexport) static int StaticField;
1025 __declspec(dllexport) static int StaticFieldDef;
1026 __declspec(dllexport) static const int StaticConstField;
1027 __declspec(dllexport) static const int StaticConstFieldDef;
1028 __declspec(dllexport) static const int StaticConstFieldEqualInit = 1;
1029 __declspec(dllexport) static const int StaticConstFieldBraceInit{1};
1030 __declspec(dllexport) constexpr static int ConstexprField = 1;
1031 __declspec(dllexport) constexpr static int ConstexprFieldDef = 1;
1034 template<typename T> void ExportClassTmplMembers<T>::normalDef() {}
1035 template<typename T> inline void ExportClassTmplMembers<T>::normalInlineDef() {}
1036 template<typename T> void ExportClassTmplMembers<T>::normalInlineDecl() {}
1037 template<typename T> void ExportClassTmplMembers<T>::virtualDef() {}
1038 template<typename T> inline void ExportClassTmplMembers<T>::virtualInlineDef() {}
1039 template<typename T> void ExportClassTmplMembers<T>::virtualInlineDecl() {}
1040 template<typename T> void ExportClassTmplMembers<T>::staticDef() {}
1041 template<typename T> inline void ExportClassTmplMembers<T>::staticInlineDef() {}
1042 template<typename T> void ExportClassTmplMembers<T>::staticInlineDecl() {}
1043 template<typename T> void ExportClassTmplMembers<T>::protectedDef() {}
1044 template<typename T> void ExportClassTmplMembers<T>::privateDef() {}
1046 template<typename T> int ExportClassTmplMembers<T>::StaticFieldDef;
1047 template<typename T> const int ExportClassTmplMembers<T>::StaticConstFieldDef = 1;
1048 template<typename T> constexpr int ExportClassTmplMembers<T>::ConstexprFieldDef;
1050 template struct ExportClassTmplMembers<ImplicitInst_Exported>;
1053 // Redeclarations cannot add dllexport.
1054 template<typename T>
1055 struct CTMR /*ClassTmplMemberRedecl*/ {
1056 void normalDef(); // expected-note{{previous declaration is here}}
1057 void normalInlineDef(); // expected-note{{previous declaration is here}}
1058 inline void normalInlineDecl(); // expected-note{{previous declaration is here}}
1059 virtual void virtualDef(); // expected-note{{previous declaration is here}}
1060 virtual void virtualInlineDef(); // expected-note{{previous declaration is here}}
1061 virtual inline void virtualInlineDecl(); // expected-note{{previous declaration is here}}
1062 static void staticDef(); // expected-note{{previous declaration is here}}
1063 static void staticInlineDef(); // expected-note{{previous declaration is here}}
1064 static inline void staticInlineDecl(); // expected-note{{previous declaration is here}}
1066 static int StaticField; // expected-note{{previous declaration is here}}
1067 static const int StaticConstField; // expected-note{{previous declaration is here}}
1068 constexpr static int ConstexprField = 1; // expected-note-re{{previous {{(definition|declaration)}} is here}}
1071 template<typename T> __declspec(dllexport) void CTMR<T>::normalDef() {} // expected-error{{redeclaration of 'CTMR::normalDef' cannot add 'dllexport' attribute}}
1072 template<typename T> __declspec(dllexport) inline void CTMR<T>::normalInlineDef() {} // expected-error{{redeclaration of 'CTMR::normalInlineDef' cannot add 'dllexport' attribute}}
1073 template<typename T> __declspec(dllexport) void CTMR<T>::normalInlineDecl() {} // expected-error{{redeclaration of 'CTMR::normalInlineDecl' cannot add 'dllexport' attribute}}
1074 template<typename T> __declspec(dllexport) void CTMR<T>::virtualDef() {} // expected-error{{redeclaration of 'CTMR::virtualDef' cannot add 'dllexport' attribute}}
1075 template<typename T> __declspec(dllexport) inline void CTMR<T>::virtualInlineDef() {} // expected-error{{redeclaration of 'CTMR::virtualInlineDef' cannot add 'dllexport' attribute}}
1076 template<typename T> __declspec(dllexport) void CTMR<T>::virtualInlineDecl() {} // expected-error{{redeclaration of 'CTMR::virtualInlineDecl' cannot add 'dllexport' attribute}}
1077 template<typename T> __declspec(dllexport) void CTMR<T>::staticDef() {} // expected-error{{redeclaration of 'CTMR::staticDef' cannot add 'dllexport' attribute}}
1078 template<typename T> __declspec(dllexport) inline void CTMR<T>::staticInlineDef() {} // expected-error{{redeclaration of 'CTMR::staticInlineDef' cannot add 'dllexport' attribute}}
1079 template<typename T> __declspec(dllexport) void CTMR<T>::staticInlineDecl() {} // expected-error{{redeclaration of 'CTMR::staticInlineDecl' cannot add 'dllexport' attribute}}
1081 template<typename T> __declspec(dllexport) int CTMR<T>::StaticField = 1; // expected-error{{redeclaration of 'CTMR::StaticField' cannot add 'dllexport' attribute}}
1082 template<typename T> __declspec(dllexport) const int CTMR<T>::StaticConstField = 1; // expected-error{{redeclaration of 'CTMR::StaticConstField' cannot add 'dllexport' attribute}}
1083 #ifdef MS
1084 // expected-warning@+4{{attribute declaration must precede definition}}
1085 #else
1086 // expected-error@+2{{redeclaration of 'CTMR::ConstexprField' cannot add 'dllexport' attribute}}
1087 #endif
1088 template<typename T> __declspec(dllexport) constexpr int CTMR<T>::ConstexprField;
1090 // MSVC exports explicit specialization of exported class template member
1091 // function, and errors on such definitions. MinGW does not treat them as
1092 // dllexport.
1093 #if !defined(GNU)
1094 // expected-error@+2{{attribute 'dllexport' cannot be applied to a deleted function}}
1095 #endif
1096 template <> void ExportClassTmplMembers<int>::normalDecl() = delete;
1099 //===----------------------------------------------------------------------===//
1100 // Class template member templates
1101 //===----------------------------------------------------------------------===//
1103 template<typename T>
1104 struct ExportClsTmplMemTmpl {
1105 template<typename U> __declspec(dllexport) void normalDecl();
1106 template<typename U> __declspec(dllexport) void normalDef();
1107 template<typename U> __declspec(dllexport) void normalInclass() {}
1108 template<typename U> __declspec(dllexport) void normalInlineDef();
1109 template<typename U> __declspec(dllexport) inline void normalInlineDecl();
1110 template<typename U> __declspec(dllexport) static void staticDecl();
1111 template<typename U> __declspec(dllexport) static void staticDef();
1112 template<typename U> __declspec(dllexport) static void staticInclass() {}
1113 template<typename U> __declspec(dllexport) static void staticInlineDef();
1114 template<typename U> __declspec(dllexport) static inline void staticInlineDecl();
1116 #if __has_feature(cxx_variable_templates)
1117 template<typename U> __declspec(dllexport) static int StaticField;
1118 template<typename U> __declspec(dllexport) static int StaticFieldDef;
1119 template<typename U> __declspec(dllexport) static const int StaticConstField;
1120 template<typename U> __declspec(dllexport) static const int StaticConstFieldDef;
1121 template<typename U> __declspec(dllexport) static const int StaticConstFieldEqualInit = 1;
1122 template<typename U> __declspec(dllexport) static const int StaticConstFieldBraceInit{1};
1123 template<typename U> __declspec(dllexport) constexpr static int ConstexprField = 1;
1124 template<typename U> __declspec(dllexport) constexpr static int ConstexprFieldDef = 1;
1125 #endif // __has_feature(cxx_variable_templates)
1128 template<typename T> template<typename U> void ExportClsTmplMemTmpl<T>::normalDef() {}
1129 template<typename T> template<typename U> inline void ExportClsTmplMemTmpl<T>::normalInlineDef() {}
1130 template<typename T> template<typename U> void ExportClsTmplMemTmpl<T>::normalInlineDecl() {}
1131 template<typename T> template<typename U> void ExportClsTmplMemTmpl<T>::staticDef() {}
1132 template<typename T> template<typename U> inline void ExportClsTmplMemTmpl<T>::staticInlineDef() {}
1133 template<typename T> template<typename U> void ExportClsTmplMemTmpl<T>::staticInlineDecl() {}
1135 #if __has_feature(cxx_variable_templates)
1136 template<typename T> template<typename U> int ExportClsTmplMemTmpl<T>::StaticFieldDef;
1137 template<typename T> template<typename U> const int ExportClsTmplMemTmpl<T>::StaticConstFieldDef = 1;
1138 template<typename T> template<typename U> constexpr int ExportClsTmplMemTmpl<T>::ConstexprFieldDef;
1139 #endif // __has_feature(cxx_variable_templates)
1142 // Redeclarations cannot add dllexport.
1143 template<typename T>
1144 struct CTMTR /*ClassTmplMemberTmplRedecl*/ {
1145 template<typename U> void normalDef(); // expected-note{{previous declaration is here}}
1146 template<typename U> void normalInlineDef(); // expected-note{{previous declaration is here}}
1147 template<typename U> inline void normalInlineDecl(); // expected-note{{previous declaration is here}}
1148 template<typename U> static void staticDef(); // expected-note{{previous declaration is here}}
1149 template<typename U> static void staticInlineDef(); // expected-note{{previous declaration is here}}
1150 template<typename U> static inline void staticInlineDecl(); // expected-note{{previous declaration is here}}
1152 #if __has_feature(cxx_variable_templates)
1153 template<typename U> static int StaticField; // expected-note{{previous declaration is here}}
1154 template<typename U> static const int StaticConstField; // expected-note{{previous declaration is here}}
1155 template<typename U> constexpr static int ConstexprField = 1; // expected-note-re{{previous {{(declaration|definition)}} is here}}
1156 #endif // __has_feature(cxx_variable_templates)
1159 template<typename T> template<typename U> __declspec(dllexport) void CTMTR<T>::normalDef() {} // expected-error{{redeclaration of 'CTMTR::normalDef' cannot add 'dllexport' attribute}}
1160 template<typename T> template<typename U> __declspec(dllexport) inline void CTMTR<T>::normalInlineDef() {} // expected-error{{redeclaration of 'CTMTR::normalInlineDef' cannot add 'dllexport' attribute}}
1161 template<typename T> template<typename U> __declspec(dllexport) void CTMTR<T>::normalInlineDecl() {} // expected-error{{redeclaration of 'CTMTR::normalInlineDecl' cannot add 'dllexport' attribute}}
1162 template<typename T> template<typename U> __declspec(dllexport) void CTMTR<T>::staticDef() {} // expected-error{{redeclaration of 'CTMTR::staticDef' cannot add 'dllexport' attribute}}
1163 template<typename T> template<typename U> __declspec(dllexport) inline void CTMTR<T>::staticInlineDef() {} // expected-error{{redeclaration of 'CTMTR::staticInlineDef' cannot add 'dllexport' attribute}}
1164 template<typename T> template<typename U> __declspec(dllexport) void CTMTR<T>::staticInlineDecl() {} // expected-error{{redeclaration of 'CTMTR::staticInlineDecl' cannot add 'dllexport' attribute}}
1166 #if __has_feature(cxx_variable_templates)
1167 template<typename T> template<typename U> __declspec(dllexport) int CTMTR<T>::StaticField = 1; // expected-error{{redeclaration of 'CTMTR::StaticField' cannot add 'dllexport' attribute}}
1168 template<typename T> template<typename U> __declspec(dllexport) const int CTMTR<T>::StaticConstField = 1; // expected-error{{redeclaration of 'CTMTR::StaticConstField' cannot add 'dllexport' attribute}}
1169 #ifdef MS
1170 // expected-warning@+4{{attribute declaration must precede definition}}
1171 #else
1172 // expected-error@+2{{redeclaration of 'CTMTR::ConstexprField' cannot add 'dllexport' attribute}}
1173 #endif
1174 template<typename T> template<typename U> __declspec(dllexport) constexpr int CTMTR<T>::ConstexprField;
1175 #endif // __has_feature(cxx_variable_templates)
1177 // FIXME: Precedence rules seem to be different for classes.
1179 //===----------------------------------------------------------------------===//
1180 // Lambdas
1181 //===----------------------------------------------------------------------===//
1182 // The MS ABI doesn't provide a stable mangling for lambdas, so they can't be imported or exported.
1183 #if defined(MS) || defined (WI)
1184 // expected-error@+2{{lambda cannot be declared 'dllexport'}}
1185 #endif
1186 auto Lambda = []() __declspec(dllexport) -> bool { return true; };