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 -DPS %s
8 // RUN: %clang_cc1 -triple x86_64-sie-ps5 -fsyntax-only -fdeclspec -verify -std=c++1y -Wunsupported-dll-base-class-template -DPS %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
; };
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}}
40 //===----------------------------------------------------------------------===//
42 //===----------------------------------------------------------------------===//
44 // Export declaration.
45 __declspec(dllexport
) extern int ExternGlobalDecl
;
47 // dllexport implies a definition.
48 __declspec(dllexport
) int GlobalDef
;
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;
59 __declspec(dllexport
) extern int GlobalRedecl1
;
60 __declspec(dllexport
) int GlobalRedecl1
;
62 __declspec(dllexport
) extern 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}}
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'}}
77 namespace { __declspec(dllexport
) int InternalGlobal
; } // expected-error{{'(anonymous namespace)::InternalGlobal' must have external linkage when declared 'dllexport'}}
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;
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'}}
134 namespace { template<typename T
> __declspec(dllexport
) int InternalVarTmpl
; } // expected-error{{'(anonymous namespace)::InternalVarTmpl' must have external linkage when declared 'dllexport'}}
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 //===----------------------------------------------------------------------===//
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() {}
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();
204 __declspec(dllexport
) void inlineDef();
205 inline void inlineDef() {}
208 __declspec(dllexport
) void redecl1();
209 __declspec(dllexport
) void redecl1() {}
211 __declspec(dllexport
) 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}}
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}}
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() {}
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() {}
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 //===----------------------------------------------------------------------===//
346 //===----------------------------------------------------------------------===//
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) || defined(PS)
357 // expected-warning@+3{{'dllexport' attribute ignored}}
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) || defined(PS)
375 // expected-note@+2{{attribute is here}}
377 template <typename T
> struct __declspec(dllexport
) ExportedTemplateWithExplicitInstantiationDecl
{
378 int f() { return sizeof(T
); } // no-error
380 #if defined(MS) || defined (WI) || defined(PS)
381 // expected-warning@+2{{explicit instantiation declaration should not be 'dllexport'}}
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 #if defined(MS) || defined(PS)
394 // expected-note@+3{{forward declaration of 'IncompleteType4'}}
395 // expected-note@+3{{in instantiation of member function 'BaseClassTemplateOfExportedClass<IncompleteType4>::f' requested here}}
397 struct IncompleteType4
;
398 template <typename T
> struct BaseClassTemplateOfExportedClass
{
399 #if defined(MS) || defined(PS)
400 // expected-error@+2{{invalid application of 'sizeof' to an incomplete type 'IncompleteType4'}}
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) || defined(PS)
416 // expected-warning@+2{{explicit instantiation declaration should not be 'dllexport'}} expected-note@+2{{attribute is here}}
418 extern template struct __declspec(dllexport
) ExplicitInstantiationDeclTemplate
<int>;
420 template <typename T
> struct __declspec(dllexport
) ExplicitInstantiationDeclExportedTemplate
{};
421 #if defined(MS) || defined (WI) || defined(PS)
422 // expected-note@-2{{attribute is here}}
423 // expected-warning@+2{{explicit instantiation declaration should not be 'dllexport'}}
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 class __declspec(dllexport
) ExportedClass
{};
438 class __declspec(dllimport
) ImportedClass
{};
440 template <typename T
> class ClassTemplate
{};
441 #if not defined(MS) && not defined(PS)
442 // expected-error@+2{{'ExportedClassTemplate<LocalCRTP>' must have external linkage when declared 'dllexport'}}
444 template <typename T
> class __declspec(dllexport
) ExportedClassTemplate
{};
445 template <typename T
> class __declspec(dllimport
) ImportedClassTemplate
{};
447 template <typename T
> struct ExplicitlySpecializedTemplate
{ void func() {} };
448 #if defined(MS) || defined(PS)
449 // expected-note@+2{{class template 'ExplicitlySpecializedTemplate<int>' was explicitly specialized here}}
451 template <> struct ExplicitlySpecializedTemplate
<int> { void func() {} };
452 template <typename T
> struct ExplicitlyExportSpecializedTemplate
{ void func() {} };
453 template <> struct __declspec(dllexport
) ExplicitlyExportSpecializedTemplate
<int> { void func() {} };
454 template <typename T
> struct ExplicitlyImportSpecializedTemplate
{ void func() {} };
455 template <> struct __declspec(dllimport
) ExplicitlyImportSpecializedTemplate
<int> { void func() {} };
457 template <typename T
> struct ExplicitlyInstantiatedTemplate
{ void func() {} };
458 #if defined(MS) || defined(PS)
459 // expected-note@+2{{class template 'ExplicitlyInstantiatedTemplate<int>' was instantiated here}}
461 template struct ExplicitlyInstantiatedTemplate
<int>;
462 template <typename T
> struct ExplicitlyExportInstantiatedTemplate
{ void func() {} };
463 template struct __declspec(dllexport
) ExplicitlyExportInstantiatedTemplate
<int>;
464 template <typename T
> struct ExplicitlyExportDeclaredInstantiatedTemplate
{ void func() {} };
465 extern template struct ExplicitlyExportDeclaredInstantiatedTemplate
<int>;
466 #if not defined(MS) && not defined (WI) && not defined(PS)
467 // expected-warning@+2{{'dllexport' attribute ignored on explicit instantiation definition}}
469 template struct __declspec(dllexport
) ExplicitlyExportDeclaredInstantiatedTemplate
<int>;
470 template <typename T
> struct ExplicitlyImportInstantiatedTemplate
{ void func() {} };
471 template struct __declspec(dllimport
) ExplicitlyImportInstantiatedTemplate
<int>;
473 // ClassTemplate<int> gets exported.
474 class __declspec(dllexport
) DerivedFromTemplate
: public ClassTemplate
<int> {};
476 // ClassTemplate<int> is already exported.
477 class __declspec(dllexport
) DerivedFromTemplate2
: public ClassTemplate
<int> {};
479 // ExportedTemplate is explicitly exported.
480 class __declspec(dllexport
) DerivedFromExportedTemplate
: public ExportedClassTemplate
<int> {};
482 // ImportedTemplate is explicitly imported.
483 class __declspec(dllexport
) DerivedFromImportedTemplate
: public ImportedClassTemplate
<int> {};
485 class DerivedFromTemplateD
: public ClassTemplate
<double> {};
486 // Base class previously implicitly instantiated without attribute; it will get propagated.
487 class __declspec(dllexport
) DerivedFromTemplateD2
: public ClassTemplate
<double> {};
489 // Base class has explicit instantiation declaration; the attribute will get propagated.
490 extern template class ClassTemplate
<float>;
491 class __declspec(dllexport
) DerivedFromTemplateF
: public ClassTemplate
<float> {};
493 class __declspec(dllexport
) DerivedFromTemplateB
: public ClassTemplate
<bool> {};
494 // The second derived class doesn't change anything, the attribute that was propagated first wins.
495 class __declspec(dllimport
) DerivedFromTemplateB2
: public ClassTemplate
<bool> {};
497 #if defined(MS) || defined(PS)
498 // expected-warning@+3{{propagating dll attribute to explicitly specialized base class template without dll attribute is not supported}}
499 // expected-note@+2{{attribute is here}}
501 struct __declspec(dllexport
) DerivedFromExplicitlySpecializedTemplate
: public ExplicitlySpecializedTemplate
<int> {};
503 // Base class alredy specialized with export attribute.
504 struct __declspec(dllexport
) DerivedFromExplicitlyExportSpecializedTemplate
: public ExplicitlyExportSpecializedTemplate
<int> {};
506 // Base class already specialized with import attribute.
507 struct __declspec(dllexport
) DerivedFromExplicitlyImportSpecializedTemplate
: public ExplicitlyImportSpecializedTemplate
<int> {};
509 #if defined(MS) || defined(PS)
510 // expected-warning@+3{{propagating dll attribute to already instantiated base class template without dll attribute is not supported}}
511 // expected-note@+2{{attribute is here}}
513 struct __declspec(dllexport
) DerivedFromExplicitlyInstantiatedTemplate
: public ExplicitlyInstantiatedTemplate
<int> {};
515 // Base class already instantiated with export attribute.
516 struct __declspec(dllexport
) DerivedFromExplicitlyExportInstantiatedTemplate
: public ExplicitlyExportInstantiatedTemplate
<int> {};
518 // Base class already instantiated with import attribute.
519 struct __declspec(dllexport
) DerivedFromExplicitlyImportInstantiatedTemplate
: public ExplicitlyImportInstantiatedTemplate
<int> {};
521 template <typename T
> struct ExplicitInstantiationDeclTemplateBase
{ void func() {} };
522 extern template struct ExplicitInstantiationDeclTemplateBase
<int>;
523 struct __declspec(dllexport
) DerivedFromExplicitInstantiationDeclTemplateBase
: public ExplicitInstantiationDeclTemplateBase
<int> {};
526 // MSVC allows deriving from exported template classes in local contexts.
527 class LocalDerivedFromExportedClass
: public ExportedClass
{};
528 class LocalDerivedFromExportedTemplate
: public ExportedClassTemplate
<int> {};
529 #if not defined(MS) && not defined (PS)
530 // expected-note@+2{{in instantiation of template class 'ExportedClassTemplate<LocalCRTP>' requested here}}
532 class LocalCRTP
: public ExportedClassTemplate
<LocalCRTP
> {};
535 //===----------------------------------------------------------------------===//
537 //===----------------------------------------------------------------------===//
539 // dllexport takes precedence over dllimport if both are specified.
540 __attribute__((dllimport
, dllexport
)) extern int PrecedenceExternGlobal1A
; // expected-warning{{'dllimport' attribute ignored}}
541 __declspec(dllimport
) __declspec(dllexport
) extern int PrecedenceExternGlobal1B
; // expected-warning{{'dllimport' attribute ignored}}
543 __attribute__((dllexport
, dllimport
)) extern int PrecedenceExternGlobal2A
; // expected-warning{{'dllimport' attribute ignored}}
544 __declspec(dllexport
) __declspec(dllimport
) extern int PrecedenceExternGlobal2B
; // expected-warning{{'dllimport' attribute ignored}}
546 __attribute__((dllimport
, dllexport
)) int PrecedenceGlobal1A
; // expected-warning{{'dllimport' attribute ignored}}
547 __declspec(dllimport
) __declspec(dllexport
) int PrecedenceGlobal1B
; // expected-warning{{'dllimport' attribute ignored}}
549 __attribute__((dllexport
, dllimport
)) int PrecedenceGlobal2A
; // expected-warning{{'dllimport' attribute ignored}}
550 __declspec(dllexport
) __declspec(dllimport
) int PrecedenceGlobal2B
; // expected-warning{{'dllimport' attribute ignored}}
552 __declspec(dllexport
) extern int PrecedenceExternGlobalRedecl1
;
553 __declspec(dllimport
) extern int PrecedenceExternGlobalRedecl1
; // expected-warning{{'dllimport' attribute ignored}}
555 __declspec(dllimport
) extern int PrecedenceExternGlobalRedecl2
; // expected-warning{{'dllimport' attribute ignored}}
556 __declspec(dllexport
) extern int PrecedenceExternGlobalRedecl2
;
558 __declspec(dllexport
) extern int PrecedenceGlobalRedecl1
;
559 __declspec(dllimport
) int PrecedenceGlobalRedecl1
; // expected-warning{{'dllimport' attribute ignored}}
561 __declspec(dllimport
) extern int PrecedenceGlobalRedecl2
; // expected-warning{{'dllimport' attribute ignored}}
562 __declspec(dllexport
) int PrecedenceGlobalRedecl2
;
564 void __attribute__((dllimport
, dllexport
)) precedence1A() {} // expected-warning{{'dllimport' attribute ignored}}
565 void __declspec(dllimport
) __declspec(dllexport
) precedence1B() {} // expected-warning{{'dllimport' attribute ignored}}
567 void __attribute__((dllexport
, dllimport
)) precedence2A() {} // expected-warning{{'dllimport' attribute ignored}}
568 void __declspec(dllexport
) __declspec(dllimport
) precedence2B() {} // expected-warning{{'dllimport' attribute ignored}}
570 void __declspec(dllimport
) precedenceRedecl1(); // expected-warning{{'dllimport' attribute ignored}}
571 void __declspec(dllexport
) precedenceRedecl1() {}
573 void __declspec(dllexport
) precedenceRedecl2();
574 void __declspec(dllimport
) precedenceRedecl2() {} // expected-warning{{'dllimport' attribute ignored}}
578 //===----------------------------------------------------------------------===//
580 //===----------------------------------------------------------------------===//
582 // Export individual members of a class.
583 struct ExportMembers
{
585 __declspec(dllexport
) void normalDef();
588 __declspec(dllexport
) void normalDecl();
589 __declspec(dllexport
) void normalDef();
590 __declspec(dllexport
) void normalInclass() {}
591 __declspec(dllexport
) void normalInlineDef();
592 __declspec(dllexport
) inline void normalInlineDecl();
593 __declspec(dllexport
) virtual void virtualDecl();
594 __declspec(dllexport
) virtual void virtualDef();
595 __declspec(dllexport
) virtual void virtualInclass() {}
596 __declspec(dllexport
) virtual void virtualInlineDef();
597 __declspec(dllexport
) virtual inline void virtualInlineDecl();
598 __declspec(dllexport
) static void staticDecl();
599 __declspec(dllexport
) static void staticDef();
600 __declspec(dllexport
) static void staticInclass() {}
601 __declspec(dllexport
) static void staticInlineDef();
602 __declspec(dllexport
) static inline void staticInlineDecl();
605 __declspec(dllexport
) void protectedDef();
607 __declspec(dllexport
) void privateDef();
610 __declspec(dllexport
) int Field
; // expected-warning{{'dllexport' attribute only applies to}}
611 __declspec(dllexport
) static int StaticField
;
612 __declspec(dllexport
) static int StaticFieldDef
;
613 __declspec(dllexport
) static const int StaticConstField
;
614 __declspec(dllexport
) static const int StaticConstFieldDef
;
615 __declspec(dllexport
) static const int StaticConstFieldEqualInit
= 1;
616 __declspec(dllexport
) static const int StaticConstFieldBraceInit
{1};
617 __declspec(dllexport
) constexpr static int ConstexprField
= 1;
618 __declspec(dllexport
) constexpr static int ConstexprFieldDef
= 1;
621 void ExportMembers::Nested::normalDef() {}
622 void ExportMembers::normalDef() {}
623 inline void ExportMembers::normalInlineDef() {}
624 void ExportMembers::normalInlineDecl() {}
625 void ExportMembers::virtualDef() {}
626 inline void ExportMembers::virtualInlineDef() {}
627 void ExportMembers::virtualInlineDecl() {}
628 void ExportMembers::staticDef() {}
629 inline void ExportMembers::staticInlineDef() {}
630 void ExportMembers::staticInlineDecl() {}
631 void ExportMembers::protectedDef() {}
632 void ExportMembers::privateDef() {}
634 int ExportMembers::StaticFieldDef
;
635 const int ExportMembers::StaticConstFieldDef
= 1;
636 constexpr int ExportMembers::ConstexprFieldDef
;
639 // Export on member definitions.
640 struct ExportMemberDefs
{
641 __declspec(dllexport
) void normalDef();
642 __declspec(dllexport
) void normalInlineDef();
643 __declspec(dllexport
) inline void normalInlineDecl();
644 __declspec(dllexport
) virtual void virtualDef();
645 __declspec(dllexport
) virtual void virtualInlineDef();
646 __declspec(dllexport
) virtual inline void virtualInlineDecl();
647 __declspec(dllexport
) static void staticDef();
648 __declspec(dllexport
) static void staticInlineDef();
649 __declspec(dllexport
) static inline void staticInlineDecl();
651 __declspec(dllexport
) static int StaticField
;
652 __declspec(dllexport
) static const int StaticConstField
;
653 __declspec(dllexport
) constexpr static int ConstexprField
= 1;
656 __declspec(dllexport
) void ExportMemberDefs::normalDef() {}
657 __declspec(dllexport
) inline void ExportMemberDefs::normalInlineDef() {}
658 __declspec(dllexport
) void ExportMemberDefs::normalInlineDecl() {}
659 __declspec(dllexport
) void ExportMemberDefs::virtualDef() {}
660 __declspec(dllexport
) inline void ExportMemberDefs::virtualInlineDef() {}
661 __declspec(dllexport
) void ExportMemberDefs::virtualInlineDecl() {}
662 __declspec(dllexport
) void ExportMemberDefs::staticDef() {}
663 __declspec(dllexport
) inline void ExportMemberDefs::staticInlineDef() {}
664 __declspec(dllexport
) void ExportMemberDefs::staticInlineDecl() {}
666 __declspec(dllexport
) int ExportMemberDefs::StaticField
;
667 __declspec(dllexport
) const int ExportMemberDefs::StaticConstField
= 1;
668 __declspec(dllexport
) constexpr int ExportMemberDefs::ConstexprField
;
671 // Export special member functions.
672 struct ExportSpecials
{
673 __declspec(dllexport
) ExportSpecials() {}
674 __declspec(dllexport
) ~ExportSpecials();
675 __declspec(dllexport
) inline ExportSpecials(const ExportSpecials
&);
676 __declspec(dllexport
) ExportSpecials
& operator=(const ExportSpecials
&);
677 __declspec(dllexport
) ExportSpecials(ExportSpecials
&&);
678 __declspec(dllexport
) ExportSpecials
& operator=(ExportSpecials
&&);
681 ExportSpecials::~ExportSpecials() {}
682 ExportSpecials::ExportSpecials(const ExportSpecials
&) {}
683 inline ExportSpecials
& ExportSpecials::operator=(const ExportSpecials
&) { return *this; }
684 ExportSpecials::ExportSpecials(ExportSpecials
&&) {}
685 ExportSpecials
& ExportSpecials::operator=(ExportSpecials
&&) { return *this; }
688 // Export allocation functions.
689 extern "C" void* malloc(__SIZE_TYPE__ size
);
690 extern "C" void free(void* p
);
692 __declspec(dllexport
) void* operator new(__SIZE_TYPE__
);
693 __declspec(dllexport
) void* operator new[](__SIZE_TYPE__
);
694 __declspec(dllexport
) void operator delete(void*);
695 __declspec(dllexport
) void operator delete[](void*);
697 void* ExportAlloc::operator new(__SIZE_TYPE__ n
) { return malloc(n
); }
698 void* ExportAlloc::operator new[](__SIZE_TYPE__ n
) { return malloc(n
); }
699 void ExportAlloc::operator delete(void* p
) { free(p
); }
700 void ExportAlloc::operator delete[](void* p
) { free(p
); }
703 // Export deleted member functions.
704 struct ExportDeleted
{
705 __declspec(dllexport
) ExportDeleted() = delete; // expected-error{{attribute 'dllexport' cannot be applied to a deleted function}}
706 __declspec(dllexport
) ~ExportDeleted() = delete; // expected-error{{attribute 'dllexport' cannot be applied to a deleted function}}
707 __declspec(dllexport
) ExportDeleted(const ExportDeleted
&) = delete; // expected-error{{attribute 'dllexport' cannot be applied to a deleted function}}
708 __declspec(dllexport
) ExportDeleted
& operator=(const ExportDeleted
&) = delete; // expected-error{{attribute 'dllexport' cannot be applied to a deleted function}}
709 __declspec(dllexport
) ExportDeleted(ExportDeleted
&&) = delete; // expected-error{{attribute 'dllexport' cannot be applied to a deleted function}}
710 __declspec(dllexport
) ExportDeleted
& operator=(ExportDeleted
&&) = delete; // expected-error{{attribute 'dllexport' cannot be applied to a deleted function}}
711 __declspec(dllexport
) void deleted() = delete; // expected-error{{attribute 'dllexport' cannot be applied to a deleted function}}
715 // Export defaulted member functions.
716 struct ExportDefaulted
{
717 __declspec(dllexport
) ExportDefaulted() = default;
718 __declspec(dllexport
) ~ExportDefaulted() = default;
719 __declspec(dllexport
) ExportDefaulted(const ExportDefaulted
&) = default;
720 __declspec(dllexport
) ExportDefaulted
& operator=(const ExportDefaulted
&) = default;
721 __declspec(dllexport
) ExportDefaulted(ExportDefaulted
&&) = default;
722 __declspec(dllexport
) ExportDefaulted
& operator=(ExportDefaulted
&&) = default;
726 // Export defaulted member function definitions.
727 struct ExportDefaultedDefs
{
728 __declspec(dllexport
) ExportDefaultedDefs();
729 __declspec(dllexport
) ~ExportDefaultedDefs();
731 __declspec(dllexport
) inline ExportDefaultedDefs(const ExportDefaultedDefs
&);
732 __declspec(dllexport
) ExportDefaultedDefs
& operator=(const ExportDefaultedDefs
&);
734 __declspec(dllexport
) ExportDefaultedDefs(ExportDefaultedDefs
&&);
735 __declspec(dllexport
) ExportDefaultedDefs
& operator=(ExportDefaultedDefs
&&);
738 // Export definitions.
739 __declspec(dllexport
) ExportDefaultedDefs::ExportDefaultedDefs() = default;
740 ExportDefaultedDefs::~ExportDefaultedDefs() = default;
742 // Export inline declaration and definition.
743 __declspec(dllexport
) ExportDefaultedDefs::ExportDefaultedDefs(const ExportDefaultedDefs
&) = default;
744 inline ExportDefaultedDefs
& ExportDefaultedDefs::operator=(const ExportDefaultedDefs
&) = default;
746 __declspec(dllexport
) ExportDefaultedDefs::ExportDefaultedDefs(ExportDefaultedDefs
&&) = default;
747 ExportDefaultedDefs
& ExportDefaultedDefs::operator=(ExportDefaultedDefs
&&) = default;
750 // Redeclarations cannot add dllexport.
751 struct MemberRedecl
{
752 void normalDef(); // expected-note{{previous declaration is here}}
753 void normalInlineDef(); // expected-note{{previous declaration is here}}
754 inline void normalInlineDecl(); // expected-note{{previous declaration is here}}
755 virtual void virtualDef(); // expected-note{{previous declaration is here}}
756 virtual void virtualInlineDef(); // expected-note{{previous declaration is here}}
757 virtual inline void virtualInlineDecl(); // expected-note{{previous declaration is here}}
758 static void staticDef(); // expected-note{{previous declaration is here}}
759 static void staticInlineDef(); // expected-note{{previous declaration is here}}
760 static inline void staticInlineDecl(); // expected-note{{previous declaration is here}}
762 static int StaticField
; // expected-note{{previous declaration is here}}
763 static const int StaticConstField
; // expected-note{{previous declaration is here}}
764 constexpr static int ConstexprField
= 1; // expected-note-re{{previous {{(declaration|definition)}} is here}}
767 __declspec(dllexport
) void MemberRedecl::normalDef() {} // expected-error{{redeclaration of 'MemberRedecl::normalDef' cannot add 'dllexport' attribute}}
768 __declspec(dllexport
) inline void MemberRedecl::normalInlineDef() {} // expected-error{{redeclaration of 'MemberRedecl::normalInlineDef' cannot add 'dllexport' attribute}}
769 __declspec(dllexport
) void MemberRedecl::normalInlineDecl() {} // expected-error{{redeclaration of 'MemberRedecl::normalInlineDecl' cannot add 'dllexport' attribute}}
770 __declspec(dllexport
) void MemberRedecl::virtualDef() {} // expected-error{{redeclaration of 'MemberRedecl::virtualDef' cannot add 'dllexport' attribute}}
771 __declspec(dllexport
) inline void MemberRedecl::virtualInlineDef() {} // expected-error{{redeclaration of 'MemberRedecl::virtualInlineDef' cannot add 'dllexport' attribute}}
772 __declspec(dllexport
) void MemberRedecl::virtualInlineDecl() {} // expected-error{{redeclaration of 'MemberRedecl::virtualInlineDecl' cannot add 'dllexport' attribute}}
773 __declspec(dllexport
) void MemberRedecl::staticDef() {} // expected-error{{redeclaration of 'MemberRedecl::staticDef' cannot add 'dllexport' attribute}}
774 __declspec(dllexport
) inline void MemberRedecl::staticInlineDef() {} // expected-error{{redeclaration of 'MemberRedecl::staticInlineDef' cannot add 'dllexport' attribute}}
775 __declspec(dllexport
) void MemberRedecl::staticInlineDecl() {} // expected-error{{redeclaration of 'MemberRedecl::staticInlineDecl' cannot add 'dllexport' attribute}}
777 __declspec(dllexport
) int MemberRedecl::StaticField
= 1; // expected-error{{redeclaration of 'MemberRedecl::StaticField' cannot add 'dllexport' attribute}}
778 __declspec(dllexport
) const int MemberRedecl::StaticConstField
= 1; // expected-error{{redeclaration of 'MemberRedecl::StaticConstField' cannot add 'dllexport' attribute}}
780 // expected-warning@+4{{attribute declaration must precede definition}}
782 // expected-error@+2{{redeclaration of 'MemberRedecl::ConstexprField' cannot add 'dllexport' attribute}}
784 __declspec(dllexport
) constexpr int MemberRedecl::ConstexprField
;
787 struct __declspec(dllexport
) ClassWithMultipleDefaultCtors
{
788 ClassWithMultipleDefaultCtors(int = 40) {} // expected-error{{'__declspec(dllexport)' cannot be applied to more than one default constructor}}
789 ClassWithMultipleDefaultCtors(int = 30, ...) {} // expected-note{{declared here}}
791 template <typename T
>
792 struct ClassTemplateWithMultipleDefaultCtors
{
793 __declspec(dllexport
) ClassTemplateWithMultipleDefaultCtors(int = 40) {} // expected-error{{'__declspec(dllexport)' cannot be applied to more than one default constructor}}
794 __declspec(dllexport
) ClassTemplateWithMultipleDefaultCtors(int = 30, ...) {} // expected-note{{declared here}}
797 template <typename T
> struct HasDefaults
{
798 HasDefaults(int x
= sizeof(T
)) {} // expected-error {{invalid application of 'sizeof'}}
800 template struct __declspec(dllexport
) HasDefaults
<char>;
803 __declspec(dllexport
) // expected-note {{in instantiation of default function argument expression for 'HasDefaults<void>' required here}}
804 HasDefaults
<void>; // expected-note {{in instantiation of member function 'HasDefaults<void>::HasDefaults' requested here}}
806 template <typename T
> struct HasDefaults2
{
807 __declspec(dllexport
) // expected-note {{in instantiation of default function argument expression for 'HasDefaults2<void>' required here}}
808 HasDefaults2(int x
= sizeof(T
)) {} // expected-error {{invalid application of 'sizeof'}}
810 template struct HasDefaults2
<void>; // expected-note {{in instantiation of member function 'HasDefaults2<void>::HasDefaults2' requested here}}
812 template <typename T
> struct __declspec(dllexport
) HasDefaults3
{ // expected-note{{in instantiation of default function argument expression for 'HasDefaults3<void>' required here}}
813 HasDefaults3(int x
= sizeof(T
)) {} // expected-error {{invalid application of 'sizeof'}}
815 template <> HasDefaults3
<void>::HasDefaults3(int) {};
819 //===----------------------------------------------------------------------===//
820 // Class member templates
821 //===----------------------------------------------------------------------===//
823 struct ExportMemberTmpl
{
824 template<typename T
> __declspec(dllexport
) void normalDecl();
825 template<typename T
> __declspec(dllexport
) void normalDef();
826 template<typename T
> __declspec(dllexport
) void normalInclass() {}
827 template<typename T
> __declspec(dllexport
) void normalInlineDef();
828 template<typename T
> __declspec(dllexport
) inline void normalInlineDecl();
829 template<typename T
> __declspec(dllexport
) static void staticDecl();
830 template<typename T
> __declspec(dllexport
) static void staticDef();
831 template<typename T
> __declspec(dllexport
) static void staticInclass() {}
832 template<typename T
> __declspec(dllexport
) static void staticInlineDef();
833 template<typename T
> __declspec(dllexport
) static inline void staticInlineDecl();
835 #if __has_feature(cxx_variable_templates)
836 template<typename T
> __declspec(dllexport
) static int StaticField
;
837 template<typename T
> __declspec(dllexport
) static int StaticFieldDef
;
838 template<typename T
> __declspec(dllexport
) static const int StaticConstField
;
839 template<typename T
> __declspec(dllexport
) static const int StaticConstFieldDef
;
840 template<typename T
> __declspec(dllexport
) static const int StaticConstFieldEqualInit
= 1;
841 template<typename T
> __declspec(dllexport
) static const int StaticConstFieldBraceInit
{1};
842 template<typename T
> __declspec(dllexport
) constexpr static int ConstexprField
= 1;
843 template<typename T
> __declspec(dllexport
) constexpr static int ConstexprFieldDef
= 1;
844 #endif // __has_feature(cxx_variable_templates)
847 template<typename T
> void ExportMemberTmpl::normalDef() {}
848 template<typename T
> inline void ExportMemberTmpl::normalInlineDef() {}
849 template<typename T
> void ExportMemberTmpl::normalInlineDecl() {}
850 template<typename T
> void ExportMemberTmpl::staticDef() {}
851 template<typename T
> inline void ExportMemberTmpl::staticInlineDef() {}
852 template<typename T
> void ExportMemberTmpl::staticInlineDecl() {}
854 #if __has_feature(cxx_variable_templates)
855 template<typename T
> int ExportMemberTmpl::StaticFieldDef
;
856 template<typename T
> const int ExportMemberTmpl::StaticConstFieldDef
= 1;
857 template<typename T
> constexpr int ExportMemberTmpl::ConstexprFieldDef
;
858 #endif // __has_feature(cxx_variable_templates)
861 // Redeclarations cannot add dllexport.
862 struct MemTmplRedecl
{
863 template<typename T
> void normalDef(); // expected-note{{previous declaration is here}}
864 template<typename T
> void normalInlineDef(); // expected-note{{previous declaration is here}}
865 template<typename T
> inline void normalInlineDecl(); // expected-note{{previous declaration is here}}
866 template<typename T
> static void staticDef(); // expected-note{{previous declaration is here}}
867 template<typename T
> static void staticInlineDef(); // expected-note{{previous declaration is here}}
868 template<typename T
> static inline void staticInlineDecl(); // expected-note{{previous declaration is here}}
870 #if __has_feature(cxx_variable_templates)
871 template<typename T
> static int StaticField
; // expected-note{{previous declaration is here}}
872 template<typename T
> static const int StaticConstField
; // expected-note{{previous declaration is here}}
873 template<typename T
> constexpr static int ConstexprField
= 1; // expected-note-re{{previous {{(declaration|definition)}} is here}}
874 #endif // __has_feature(cxx_variable_templates)
877 template<typename T
> __declspec(dllexport
) void MemTmplRedecl::normalDef() {} // expected-error{{redeclaration of 'MemTmplRedecl::normalDef' cannot add 'dllexport' attribute}}
878 template<typename T
> __declspec(dllexport
) inline void MemTmplRedecl::normalInlineDef() {} // expected-error{{redeclaration of 'MemTmplRedecl::normalInlineDef' cannot add 'dllexport' attribute}}
879 template<typename T
> __declspec(dllexport
) void MemTmplRedecl::normalInlineDecl() {} // expected-error{{redeclaration of 'MemTmplRedecl::normalInlineDecl' cannot add 'dllexport' attribute}}
880 template<typename T
> __declspec(dllexport
) void MemTmplRedecl::staticDef() {} // expected-error{{redeclaration of 'MemTmplRedecl::staticDef' cannot add 'dllexport' attribute}}
881 template<typename T
> __declspec(dllexport
) inline void MemTmplRedecl::staticInlineDef() {} // expected-error{{redeclaration of 'MemTmplRedecl::staticInlineDef' cannot add 'dllexport' attribute}}
882 template<typename T
> __declspec(dllexport
) void MemTmplRedecl::staticInlineDecl() {} // expected-error{{redeclaration of 'MemTmplRedecl::staticInlineDecl' cannot add 'dllexport' attribute}}
884 #if __has_feature(cxx_variable_templates)
885 template<typename T
> __declspec(dllexport
) int MemTmplRedecl::StaticField
= 1; // expected-error{{redeclaration of 'MemTmplRedecl::StaticField' cannot add 'dllexport' attribute}}
886 template<typename T
> __declspec(dllexport
) const int MemTmplRedecl::StaticConstField
= 1; // expected-error{{redeclaration of 'MemTmplRedecl::StaticConstField' cannot add 'dllexport' attribute}}
889 // expected-warning@+4{{attribute declaration must precede definition}}
891 // expected-error@+2{{redeclaration of 'MemTmplRedecl::ConstexprField' cannot add 'dllexport' attribute}}
893 template<typename T
> __declspec(dllexport
) constexpr int MemTmplRedecl::ConstexprField
;
894 #endif // __has_feature(cxx_variable_templates)
899 template<typename T
> void normalDef() {}
900 template<typename T
> __declspec(dllexport
) void exportedNormal() {}
901 template<typename T
> static void staticDef() {}
902 template<typename T
> __declspec(dllexport
) static void exportedStatic() {}
905 // Export implicit instantiation of an exported member function template.
906 void useMemFunTmpl() {
907 MemFunTmpl().exportedNormal
<ImplicitInst_Exported
>();
908 MemFunTmpl().exportedStatic
<ImplicitInst_Exported
>();
911 // Export explicit instantiation declaration of an exported member function
913 extern template void MemFunTmpl::exportedNormal
<ExplicitDecl_Exported
>();
914 template void MemFunTmpl::exportedNormal
<ExplicitDecl_Exported
>();
916 extern template void MemFunTmpl::exportedStatic
<ExplicitDecl_Exported
>();
917 template void MemFunTmpl::exportedStatic
<ExplicitDecl_Exported
>();
919 // Export explicit instantiation definition of an exported member function
921 template void MemFunTmpl::exportedNormal
<ExplicitInst_Exported
>();
922 template void MemFunTmpl::exportedStatic
<ExplicitInst_Exported
>();
924 // Export specialization of an exported member function template.
925 template<> __declspec(dllexport
) void MemFunTmpl::exportedNormal
<ExplicitSpec_Exported
>();
926 template<> __declspec(dllexport
) void MemFunTmpl::exportedNormal
<ExplicitSpec_Def_Exported
>() {}
927 template<> __declspec(dllexport
) inline void MemFunTmpl::exportedNormal
<ExplicitSpec_InlineDef_Exported
>() {}
929 template<> __declspec(dllexport
) void MemFunTmpl::exportedStatic
<ExplicitSpec_Exported
>();
930 template<> __declspec(dllexport
) void MemFunTmpl::exportedStatic
<ExplicitSpec_Def_Exported
>() {}
931 template<> __declspec(dllexport
) inline void MemFunTmpl::exportedStatic
<ExplicitSpec_InlineDef_Exported
>() {}
933 // Not exporting specialization of an exported member function template without
934 // explicit dllexport.
935 template<> void MemFunTmpl::exportedNormal
<ExplicitSpec_NotExported
>() {}
936 template<> void MemFunTmpl::exportedStatic
<ExplicitSpec_NotExported
>() {}
939 // Export explicit instantiation declaration of a non-exported member function
941 extern template __declspec(dllexport
) void MemFunTmpl::normalDef
<ExplicitDecl_Exported
>();
942 template __declspec(dllexport
) void MemFunTmpl::normalDef
<ExplicitDecl_Exported
>();
944 extern template __declspec(dllexport
) void MemFunTmpl::staticDef
<ExplicitDecl_Exported
>();
945 template __declspec(dllexport
) void MemFunTmpl::staticDef
<ExplicitDecl_Exported
>();
947 // Export explicit instantiation definition of a non-exported member function
949 template __declspec(dllexport
) void MemFunTmpl::normalDef
<ExplicitInst_Exported
>();
950 template __declspec(dllexport
) void MemFunTmpl::staticDef
<ExplicitInst_Exported
>();
952 // Export specialization of a non-exported member function template.
953 template<> __declspec(dllexport
) void MemFunTmpl::normalDef
<ExplicitSpec_Exported
>();
954 template<> __declspec(dllexport
) void MemFunTmpl::normalDef
<ExplicitSpec_Def_Exported
>() {}
955 template<> __declspec(dllexport
) inline void MemFunTmpl::normalDef
<ExplicitSpec_InlineDef_Exported
>() {}
957 template<> __declspec(dllexport
) void MemFunTmpl::staticDef
<ExplicitSpec_Exported
>();
958 template<> __declspec(dllexport
) void MemFunTmpl::staticDef
<ExplicitSpec_Def_Exported
>() {}
959 template<> __declspec(dllexport
) inline void MemFunTmpl::staticDef
<ExplicitSpec_InlineDef_Exported
>() {}
963 #if __has_feature(cxx_variable_templates)
965 template<typename T
> static const int StaticVar
= 1;
966 template<typename T
> __declspec(dllexport
) static const int ExportedStaticVar
= 1;
968 template<typename T
> const int MemVarTmpl::StaticVar
;
969 template<typename T
> const int MemVarTmpl::ExportedStaticVar
;
971 // Export implicit instantiation of an exported member variable template.
972 int useMemVarTmpl() { return MemVarTmpl::ExportedStaticVar
<ImplicitInst_Exported
>; }
974 // Export explicit instantiation declaration of an exported member variable
976 extern template const int MemVarTmpl::ExportedStaticVar
<ExplicitDecl_Exported
>;
977 template const int MemVarTmpl::ExportedStaticVar
<ExplicitDecl_Exported
>;
979 // Export explicit instantiation definition of an exported member variable
981 template const int MemVarTmpl::ExportedStaticVar
<ExplicitInst_Exported
>;
983 // Export specialization of an exported member variable template.
984 template<> __declspec(dllexport
) const int MemVarTmpl::ExportedStaticVar
<ExplicitSpec_Exported
>;
985 template<> __declspec(dllexport
) const int MemVarTmpl::ExportedStaticVar
<ExplicitSpec_Def_Exported
> = 1;
987 // Not exporting specialization of an exported member variable template without
988 // explicit dllexport.
989 template<> const int MemVarTmpl::ExportedStaticVar
<ExplicitSpec_NotExported
>;
992 // Export explicit instantiation declaration of a non-exported member variable
994 extern template __declspec(dllexport
) const int MemVarTmpl::StaticVar
<ExplicitDecl_Exported
>;
995 template __declspec(dllexport
) const int MemVarTmpl::StaticVar
<ExplicitDecl_Exported
>;
997 // Export explicit instantiation definition of a non-exported member variable
999 template __declspec(dllexport
) const int MemVarTmpl::StaticVar
<ExplicitInst_Exported
>;
1001 // Export specialization of a non-exported member variable template.
1002 template<> __declspec(dllexport
) const int MemVarTmpl::StaticVar
<ExplicitSpec_Exported
>;
1003 template<> __declspec(dllexport
) const int MemVarTmpl::StaticVar
<ExplicitSpec_Def_Exported
> = 1;
1005 #endif // __has_feature(cxx_variable_templates)
1009 //===----------------------------------------------------------------------===//
1010 // Class template members
1011 //===----------------------------------------------------------------------===//
1013 // Export individual members of a class template.
1014 template<typename T
>
1015 struct ExportClassTmplMembers
{
1016 __declspec(dllexport
) void normalDecl();
1017 __declspec(dllexport
) void normalDef();
1018 __declspec(dllexport
) void normalInclass() {}
1019 __declspec(dllexport
) void normalInlineDef();
1020 __declspec(dllexport
) inline void normalInlineDecl();
1021 __declspec(dllexport
) virtual void virtualDecl();
1022 __declspec(dllexport
) virtual void virtualDef();
1023 __declspec(dllexport
) virtual void virtualInclass() {}
1024 __declspec(dllexport
) virtual void virtualInlineDef();
1025 __declspec(dllexport
) virtual inline void virtualInlineDecl();
1026 __declspec(dllexport
) static void staticDecl();
1027 __declspec(dllexport
) static void staticDef();
1028 __declspec(dllexport
) static void staticInclass() {}
1029 __declspec(dllexport
) static void staticInlineDef();
1030 __declspec(dllexport
) static inline void staticInlineDecl();
1033 __declspec(dllexport
) void protectedDef();
1035 __declspec(dllexport
) void privateDef();
1038 __declspec(dllexport
) int Field
; // expected-warning{{'dllexport' attribute only applies to}}
1039 __declspec(dllexport
) static int StaticField
;
1040 __declspec(dllexport
) static int StaticFieldDef
;
1041 __declspec(dllexport
) static const int StaticConstField
;
1042 __declspec(dllexport
) static const int StaticConstFieldDef
;
1043 __declspec(dllexport
) static const int StaticConstFieldEqualInit
= 1;
1044 __declspec(dllexport
) static const int StaticConstFieldBraceInit
{1};
1045 __declspec(dllexport
) constexpr static int ConstexprField
= 1;
1046 __declspec(dllexport
) constexpr static int ConstexprFieldDef
= 1;
1049 template<typename T
> void ExportClassTmplMembers
<T
>::normalDef() {}
1050 template<typename T
> inline void ExportClassTmplMembers
<T
>::normalInlineDef() {}
1051 template<typename T
> void ExportClassTmplMembers
<T
>::normalInlineDecl() {}
1052 template<typename T
> void ExportClassTmplMembers
<T
>::virtualDef() {}
1053 template<typename T
> inline void ExportClassTmplMembers
<T
>::virtualInlineDef() {}
1054 template<typename T
> void ExportClassTmplMembers
<T
>::virtualInlineDecl() {}
1055 template<typename T
> void ExportClassTmplMembers
<T
>::staticDef() {}
1056 template<typename T
> inline void ExportClassTmplMembers
<T
>::staticInlineDef() {}
1057 template<typename T
> void ExportClassTmplMembers
<T
>::staticInlineDecl() {}
1058 template<typename T
> void ExportClassTmplMembers
<T
>::protectedDef() {}
1059 template<typename T
> void ExportClassTmplMembers
<T
>::privateDef() {}
1061 template<typename T
> int ExportClassTmplMembers
<T
>::StaticFieldDef
;
1062 template<typename T
> const int ExportClassTmplMembers
<T
>::StaticConstFieldDef
= 1;
1063 template<typename T
> constexpr int ExportClassTmplMembers
<T
>::ConstexprFieldDef
;
1065 template struct ExportClassTmplMembers
<ImplicitInst_Exported
>;
1068 // Redeclarations cannot add dllexport.
1069 template<typename T
>
1070 struct CTMR
/*ClassTmplMemberRedecl*/ {
1071 void normalDef(); // expected-note{{previous declaration is here}}
1072 void normalInlineDef(); // expected-note{{previous declaration is here}}
1073 inline void normalInlineDecl(); // expected-note{{previous declaration is here}}
1074 virtual void virtualDef(); // expected-note{{previous declaration is here}}
1075 virtual void virtualInlineDef(); // expected-note{{previous declaration is here}}
1076 virtual inline void virtualInlineDecl(); // expected-note{{previous declaration is here}}
1077 static void staticDef(); // expected-note{{previous declaration is here}}
1078 static void staticInlineDef(); // expected-note{{previous declaration is here}}
1079 static inline void staticInlineDecl(); // expected-note{{previous declaration is here}}
1081 static int StaticField
; // expected-note{{previous declaration is here}}
1082 static const int StaticConstField
; // expected-note{{previous declaration is here}}
1083 constexpr static int ConstexprField
= 1; // expected-note-re{{previous {{(definition|declaration)}} is here}}
1086 template<typename T
> __declspec(dllexport
) void CTMR
<T
>::normalDef() {} // expected-error{{redeclaration of 'CTMR::normalDef' cannot add 'dllexport' attribute}}
1087 template<typename T
> __declspec(dllexport
) inline void CTMR
<T
>::normalInlineDef() {} // expected-error{{redeclaration of 'CTMR::normalInlineDef' cannot add 'dllexport' attribute}}
1088 template<typename T
> __declspec(dllexport
) void CTMR
<T
>::normalInlineDecl() {} // expected-error{{redeclaration of 'CTMR::normalInlineDecl' cannot add 'dllexport' attribute}}
1089 template<typename T
> __declspec(dllexport
) void CTMR
<T
>::virtualDef() {} // expected-error{{redeclaration of 'CTMR::virtualDef' cannot add 'dllexport' attribute}}
1090 template<typename T
> __declspec(dllexport
) inline void CTMR
<T
>::virtualInlineDef() {} // expected-error{{redeclaration of 'CTMR::virtualInlineDef' cannot add 'dllexport' attribute}}
1091 template<typename T
> __declspec(dllexport
) void CTMR
<T
>::virtualInlineDecl() {} // expected-error{{redeclaration of 'CTMR::virtualInlineDecl' cannot add 'dllexport' attribute}}
1092 template<typename T
> __declspec(dllexport
) void CTMR
<T
>::staticDef() {} // expected-error{{redeclaration of 'CTMR::staticDef' cannot add 'dllexport' attribute}}
1093 template<typename T
> __declspec(dllexport
) inline void CTMR
<T
>::staticInlineDef() {} // expected-error{{redeclaration of 'CTMR::staticInlineDef' cannot add 'dllexport' attribute}}
1094 template<typename T
> __declspec(dllexport
) void CTMR
<T
>::staticInlineDecl() {} // expected-error{{redeclaration of 'CTMR::staticInlineDecl' cannot add 'dllexport' attribute}}
1096 template<typename T
> __declspec(dllexport
) int CTMR
<T
>::StaticField
= 1; // expected-error{{redeclaration of 'CTMR::StaticField' cannot add 'dllexport' attribute}}
1097 template<typename T
> __declspec(dllexport
) const int CTMR
<T
>::StaticConstField
= 1; // expected-error{{redeclaration of 'CTMR::StaticConstField' cannot add 'dllexport' attribute}}
1099 // expected-warning@+4{{attribute declaration must precede definition}}
1101 // expected-error@+2{{redeclaration of 'CTMR::ConstexprField' cannot add 'dllexport' attribute}}
1103 template<typename T
> __declspec(dllexport
) constexpr int CTMR
<T
>::ConstexprField
;
1105 // MSVC exports explicit specialization of exported class template member
1106 // function, and errors on such definitions. MinGW does not treat them as
1109 // expected-error@+2{{attribute 'dllexport' cannot be applied to a deleted function}}
1111 template <> void ExportClassTmplMembers
<int>::normalDecl() = delete;
1114 //===----------------------------------------------------------------------===//
1115 // Class template member templates
1116 //===----------------------------------------------------------------------===//
1118 template<typename T
>
1119 struct ExportClsTmplMemTmpl
{
1120 template<typename U
> __declspec(dllexport
) void normalDecl();
1121 template<typename U
> __declspec(dllexport
) void normalDef();
1122 template<typename U
> __declspec(dllexport
) void normalInclass() {}
1123 template<typename U
> __declspec(dllexport
) void normalInlineDef();
1124 template<typename U
> __declspec(dllexport
) inline void normalInlineDecl();
1125 template<typename U
> __declspec(dllexport
) static void staticDecl();
1126 template<typename U
> __declspec(dllexport
) static void staticDef();
1127 template<typename U
> __declspec(dllexport
) static void staticInclass() {}
1128 template<typename U
> __declspec(dllexport
) static void staticInlineDef();
1129 template<typename U
> __declspec(dllexport
) static inline void staticInlineDecl();
1131 #if __has_feature(cxx_variable_templates)
1132 template<typename U
> __declspec(dllexport
) static int StaticField
;
1133 template<typename U
> __declspec(dllexport
) static int StaticFieldDef
;
1134 template<typename U
> __declspec(dllexport
) static const int StaticConstField
;
1135 template<typename U
> __declspec(dllexport
) static const int StaticConstFieldDef
;
1136 template<typename U
> __declspec(dllexport
) static const int StaticConstFieldEqualInit
= 1;
1137 template<typename U
> __declspec(dllexport
) static const int StaticConstFieldBraceInit
{1};
1138 template<typename U
> __declspec(dllexport
) constexpr static int ConstexprField
= 1;
1139 template<typename U
> __declspec(dllexport
) constexpr static int ConstexprFieldDef
= 1;
1140 #endif // __has_feature(cxx_variable_templates)
1143 template<typename T
> template<typename U
> void ExportClsTmplMemTmpl
<T
>::normalDef() {}
1144 template<typename T
> template<typename U
> inline void ExportClsTmplMemTmpl
<T
>::normalInlineDef() {}
1145 template<typename T
> template<typename U
> void ExportClsTmplMemTmpl
<T
>::normalInlineDecl() {}
1146 template<typename T
> template<typename U
> void ExportClsTmplMemTmpl
<T
>::staticDef() {}
1147 template<typename T
> template<typename U
> inline void ExportClsTmplMemTmpl
<T
>::staticInlineDef() {}
1148 template<typename T
> template<typename U
> void ExportClsTmplMemTmpl
<T
>::staticInlineDecl() {}
1150 #if __has_feature(cxx_variable_templates)
1151 template<typename T
> template<typename U
> int ExportClsTmplMemTmpl
<T
>::StaticFieldDef
;
1152 template<typename T
> template<typename U
> const int ExportClsTmplMemTmpl
<T
>::StaticConstFieldDef
= 1;
1153 template<typename T
> template<typename U
> constexpr int ExportClsTmplMemTmpl
<T
>::ConstexprFieldDef
;
1154 #endif // __has_feature(cxx_variable_templates)
1157 // Redeclarations cannot add dllexport.
1158 template<typename T
>
1159 struct CTMTR
/*ClassTmplMemberTmplRedecl*/ {
1160 template<typename U
> void normalDef(); // expected-note{{previous declaration is here}}
1161 template<typename U
> void normalInlineDef(); // expected-note{{previous declaration is here}}
1162 template<typename U
> inline void normalInlineDecl(); // expected-note{{previous declaration is here}}
1163 template<typename U
> static void staticDef(); // expected-note{{previous declaration is here}}
1164 template<typename U
> static void staticInlineDef(); // expected-note{{previous declaration is here}}
1165 template<typename U
> static inline void staticInlineDecl(); // expected-note{{previous declaration is here}}
1167 #if __has_feature(cxx_variable_templates)
1168 template<typename U
> static int StaticField
; // expected-note{{previous declaration is here}}
1169 template<typename U
> static const int StaticConstField
; // expected-note{{previous declaration is here}}
1170 template<typename U
> constexpr static int ConstexprField
= 1; // expected-note-re{{previous {{(declaration|definition)}} is here}}
1171 #endif // __has_feature(cxx_variable_templates)
1174 template<typename T
> template<typename U
> __declspec(dllexport
) void CTMTR
<T
>::normalDef() {} // expected-error{{redeclaration of 'CTMTR::normalDef' cannot add 'dllexport' attribute}}
1175 template<typename T
> template<typename U
> __declspec(dllexport
) inline void CTMTR
<T
>::normalInlineDef() {} // expected-error{{redeclaration of 'CTMTR::normalInlineDef' cannot add 'dllexport' attribute}}
1176 template<typename T
> template<typename U
> __declspec(dllexport
) void CTMTR
<T
>::normalInlineDecl() {} // expected-error{{redeclaration of 'CTMTR::normalInlineDecl' cannot add 'dllexport' attribute}}
1177 template<typename T
> template<typename U
> __declspec(dllexport
) void CTMTR
<T
>::staticDef() {} // expected-error{{redeclaration of 'CTMTR::staticDef' cannot add 'dllexport' attribute}}
1178 template<typename T
> template<typename U
> __declspec(dllexport
) inline void CTMTR
<T
>::staticInlineDef() {} // expected-error{{redeclaration of 'CTMTR::staticInlineDef' cannot add 'dllexport' attribute}}
1179 template<typename T
> template<typename U
> __declspec(dllexport
) void CTMTR
<T
>::staticInlineDecl() {} // expected-error{{redeclaration of 'CTMTR::staticInlineDecl' cannot add 'dllexport' attribute}}
1181 #if __has_feature(cxx_variable_templates)
1182 template<typename T
> template<typename U
> __declspec(dllexport
) int CTMTR
<T
>::StaticField
= 1; // expected-error{{redeclaration of 'CTMTR::StaticField' cannot add 'dllexport' attribute}}
1183 template<typename T
> template<typename U
> __declspec(dllexport
) const int CTMTR
<T
>::StaticConstField
= 1; // expected-error{{redeclaration of 'CTMTR::StaticConstField' cannot add 'dllexport' attribute}}
1185 // expected-warning@+4{{attribute declaration must precede definition}}
1187 // expected-error@+2{{redeclaration of 'CTMTR::ConstexprField' cannot add 'dllexport' attribute}}
1189 template<typename T
> template<typename U
> __declspec(dllexport
) constexpr int CTMTR
<T
>::ConstexprField
;
1190 #endif // __has_feature(cxx_variable_templates)
1192 // FIXME: Precedence rules seem to be different for classes.
1194 //===----------------------------------------------------------------------===//
1196 //===----------------------------------------------------------------------===//
1197 // The MS ABI doesn't provide a stable mangling for lambdas, so they can't be imported or exported.
1198 #if defined(MS) || defined (WI) || defined(PS)
1199 // expected-error@+2{{lambda cannot be declared 'dllexport'}}
1201 auto Lambda
= []() __declspec(dllexport
) -> bool { return true; };