blob: 3bb9d224f727179d84844748804acbf922c55d3b [file] [log] [blame]
Stephen Hines176edba2014-12-01 14:53:08 -08001// RUN: %clang_cc1 -triple i686-win32 -fsyntax-only -verify -std=c++11 -Wunsupported-dll-base-class-template -DMS %s
2// RUN: %clang_cc1 -triple x86_64-win32 -fsyntax-only -verify -std=c++1y -Wunsupported-dll-base-class-template -DMS %s
3// RUN: %clang_cc1 -triple i686-mingw32 -fsyntax-only -verify -std=c++1y -Wunsupported-dll-base-class-template %s
4// RUN: %clang_cc1 -triple x86_64-mingw32 -fsyntax-only -verify -std=c++11 -Wunsupported-dll-base-class-template %s
Stephen Hines651f13c2014-04-23 16:59:28 -07005
6// Helper structs to make templates more expressive.
7struct ImplicitInst_Exported {};
8struct ExplicitDecl_Exported {};
9struct ExplicitInst_Exported {};
10struct ExplicitSpec_Exported {};
11struct ExplicitSpec_Def_Exported {};
12struct ExplicitSpec_InlineDef_Exported {};
13struct ExplicitSpec_NotExported {};
14namespace { struct Internal {}; }
15struct External { int v; };
16
17
18// Invalid usage.
Stephen Hinesc568f1e2014-07-21 00:47:37 -070019__declspec(dllexport) typedef int typedef1; // expected-warning{{'dllexport' attribute only applies to variables, functions and classes}}
20typedef __declspec(dllexport) int typedef2; // expected-warning{{'dllexport' attribute only applies to variables, functions and classes}}
21typedef int __declspec(dllexport) typedef3; // expected-warning{{'dllexport' attribute only applies to variables, functions and classes}}
22typedef __declspec(dllexport) void (*FunTy)(); // expected-warning{{'dllexport' attribute only applies to variables, functions and classes}}
23enum __declspec(dllexport) Enum {}; // expected-warning{{'dllexport' attribute only applies to variables, functions and classes}}
Stephen Hines651f13c2014-04-23 16:59:28 -070024#if __has_feature(cxx_strong_enums)
Stephen Hinesc568f1e2014-07-21 00:47:37 -070025 enum class __declspec(dllexport) EnumClass {}; // expected-warning{{'dllexport' attribute only applies to variables, functions and classes}}
Stephen Hines651f13c2014-04-23 16:59:28 -070026#endif
27
28
29
30//===----------------------------------------------------------------------===//
31// Globals
32//===----------------------------------------------------------------------===//
33
34// Export declaration.
35__declspec(dllexport) extern int ExternGlobalDecl;
36
37// dllexport implies a definition.
38__declspec(dllexport) int GlobalDef;
39
40// Export definition.
41__declspec(dllexport) int GlobalInit1 = 1;
42int __declspec(dllexport) GlobalInit2 = 1;
43
44// Declare, then export definition.
45__declspec(dllexport) extern int GlobalDeclInit;
46int GlobalDeclInit = 1;
47
48// Redeclarations
49__declspec(dllexport) extern int GlobalRedecl1;
50__declspec(dllexport) int GlobalRedecl1;
51
52__declspec(dllexport) extern int GlobalRedecl2;
53 int GlobalRedecl2;
54
55 extern int GlobalRedecl3; // expected-note{{previous declaration is here}}
Stephen Hines176edba2014-12-01 14:53:08 -080056__declspec(dllexport) extern int GlobalRedecl3; // expected-warning{{redeclaration of 'GlobalRedecl3' should not add 'dllexport' attribute}}
57
58extern "C" {
59 extern int GlobalRedecl4; // expected-note{{previous declaration is here}}
60__declspec(dllexport) extern int GlobalRedecl4; // expected-warning{{redeclaration of 'GlobalRedecl4' should not add 'dllexport' attribute}}
61}
Stephen Hines651f13c2014-04-23 16:59:28 -070062
63// External linkage is required.
64__declspec(dllexport) static int StaticGlobal; // expected-error{{'StaticGlobal' must have external linkage when declared 'dllexport'}}
65__declspec(dllexport) Internal InternalTypeGlobal; // expected-error{{'InternalTypeGlobal' must have external linkage when declared 'dllexport'}}
66namespace { __declspec(dllexport) int InternalGlobal; } // expected-error{{'(anonymous namespace)::InternalGlobal' must have external linkage when declared 'dllexport'}}
67namespace ns { __declspec(dllexport) int ExternalGlobal; }
68
69__declspec(dllexport) auto InternalAutoTypeGlobal = Internal(); // expected-error{{'InternalAutoTypeGlobal' must have external linkage when declared 'dllexport'}}
70__declspec(dllexport) auto ExternalAutoTypeGlobal = External();
71
Stephen Hines176edba2014-12-01 14:53:08 -080072// Thread local variables are invalid.
73__declspec(dllexport) __thread int ThreadLocalGlobal; // expected-error{{'ThreadLocalGlobal' cannot be thread local when declared 'dllexport'}}
74
Stephen Hines651f13c2014-04-23 16:59:28 -070075// Export in local scope.
76void functionScope() {
77 __declspec(dllexport) int LocalVarDecl; // expected-error{{'LocalVarDecl' must have external linkage when declared 'dllexport'}}
78 __declspec(dllexport) int LocalVarDef = 1; // expected-error{{'LocalVarDef' must have external linkage when declared 'dllexport'}}
79 __declspec(dllexport) extern int ExternLocalVarDecl;
80 __declspec(dllexport) static int StaticLocalVar; // expected-error{{'StaticLocalVar' must have external linkage when declared 'dllexport'}}
81}
82
83
84
85//===----------------------------------------------------------------------===//
Stephen Hines6bcf27b2014-05-29 04:14:42 -070086// Variable templates
87//===----------------------------------------------------------------------===//
88#if __has_feature(cxx_variable_templates)
89
90// Export declaration.
91template<typename T> __declspec(dllexport) extern int ExternVarTmplDecl;
92
93// dllexport implies a definition.
94template<typename T> __declspec(dllexport) int VarTmplDef;
95
96// Export definition.
97template<typename T> __declspec(dllexport) int VarTmplInit1 = 1;
98template<typename T> int __declspec(dllexport) VarTmplInit2 = 1;
99
100// Declare, then export definition.
101template<typename T> __declspec(dllexport) extern int VarTmplDeclInit;
102template<typename T> int VarTmplDeclInit = 1;
103
104// Redeclarations
105template<typename T> __declspec(dllexport) extern int VarTmplRedecl1;
106template<typename T> __declspec(dllexport) int VarTmplRedecl1 = 1;
107
108template<typename T> __declspec(dllexport) extern int VarTmplRedecl2;
109template<typename T> int VarTmplRedecl2 = 1;
110
111template<typename T> extern int VarTmplRedecl3; // expected-note{{previous declaration is here}}
112template<typename T> __declspec(dllexport) extern int VarTmplRedecl3; // expected-error{{redeclaration of 'VarTmplRedecl3' cannot add 'dllexport' attribute}}
113
114// External linkage is required.
115template<typename T> __declspec(dllexport) static int StaticVarTmpl; // expected-error{{'StaticVarTmpl' must have external linkage when declared 'dllexport'}}
116template<typename T> __declspec(dllexport) Internal InternalTypeVarTmpl; // expected-error{{'InternalTypeVarTmpl' must have external linkage when declared 'dllexport'}}
117namespace { template<typename T> __declspec(dllexport) int InternalVarTmpl; } // expected-error{{'(anonymous namespace)::InternalVarTmpl' must have external linkage when declared 'dllexport'}}
118namespace ns { template<typename T> __declspec(dllexport) int ExternalVarTmpl = 1; }
119
120template<typename T> __declspec(dllexport) auto InternalAutoTypeVarTmpl = Internal(); // expected-error{{'InternalAutoTypeVarTmpl' must have external linkage when declared 'dllexport'}}
121template<typename T> __declspec(dllexport) auto ExternalAutoTypeVarTmpl = External();
122template External ExternalAutoTypeVarTmpl<ExplicitInst_Exported>;
123
124
125template<typename T> int VarTmpl = 1;
126template<typename T> __declspec(dllexport) int ExportedVarTmpl = 1;
127
128// Export implicit instantiation of an exported variable template.
129int useVarTmpl() { return ExportedVarTmpl<ImplicitInst_Exported>; }
130
131// Export explicit instantiation declaration of an exported variable template.
132extern template int ExportedVarTmpl<ExplicitDecl_Exported>;
133 template int ExportedVarTmpl<ExplicitDecl_Exported>;
134
135// Export explicit instantiation definition of an exported variable template.
136template __declspec(dllexport) int ExportedVarTmpl<ExplicitInst_Exported>;
137
138// Export specialization of an exported variable template.
139template<> __declspec(dllexport) int ExportedVarTmpl<ExplicitSpec_Exported>;
140template<> __declspec(dllexport) int ExportedVarTmpl<ExplicitSpec_Def_Exported> = 1;
141
142// Not exporting specialization of an exported variable template without
143// explicit dllexport.
144template<> int ExportedVarTmpl<ExplicitSpec_NotExported>;
145
146
147// Export explicit instantiation declaration of a non-exported variable template.
148extern template __declspec(dllexport) int VarTmpl<ExplicitDecl_Exported>;
149 template __declspec(dllexport) int VarTmpl<ExplicitDecl_Exported>;
150
151// Export explicit instantiation definition of a non-exported variable template.
152template __declspec(dllexport) int VarTmpl<ExplicitInst_Exported>;
153
154// Export specialization of a non-exported variable template.
155template<> __declspec(dllexport) int VarTmpl<ExplicitSpec_Exported>;
156template<> __declspec(dllexport) int VarTmpl<ExplicitSpec_Def_Exported> = 1;
157
158#endif // __has_feature(cxx_variable_templates)
159
160
161
162//===----------------------------------------------------------------------===//
Stephen Hines651f13c2014-04-23 16:59:28 -0700163// Functions
164//===----------------------------------------------------------------------===//
165
166// Export function declaration. Check different placements.
167__attribute__((dllexport)) void decl1A(); // Sanity check with __attribute__
168__declspec(dllexport) void decl1B();
169
170void __attribute__((dllexport)) decl2A();
171void __declspec(dllexport) decl2B();
172
173// Export function definition.
174__declspec(dllexport) void def() {}
175
176// extern "C"
177extern "C" __declspec(dllexport) void externC() {}
178
179// Export inline function.
Stephen Hines6bcf27b2014-05-29 04:14:42 -0700180__declspec(dllexport) inline void inlineFunc1() {}
181inline void __attribute__((dllexport)) inlineFunc2() {}
Stephen Hines651f13c2014-04-23 16:59:28 -0700182
Stephen Hines6bcf27b2014-05-29 04:14:42 -0700183__declspec(dllexport) inline void inlineDecl();
Stephen Hines651f13c2014-04-23 16:59:28 -0700184 void inlineDecl() {}
185
186__declspec(dllexport) void inlineDef();
187 inline void inlineDef() {}
188
189// Redeclarations
190__declspec(dllexport) void redecl1();
191__declspec(dllexport) void redecl1() {}
192
193__declspec(dllexport) void redecl2();
194 void redecl2() {}
195
196 void redecl3(); // expected-note{{previous declaration is here}}
Stephen Hines176edba2014-12-01 14:53:08 -0800197__declspec(dllexport) void redecl3(); // expected-warning{{redeclaration of 'redecl3' should not add 'dllexport' attribute}}
Stephen Hines651f13c2014-04-23 16:59:28 -0700198
Stephen Hines176edba2014-12-01 14:53:08 -0800199extern "C" {
Stephen Hines6bcf27b2014-05-29 04:14:42 -0700200 void redecl4(); // expected-note{{previous declaration is here}}
Stephen Hines176edba2014-12-01 14:53:08 -0800201__declspec(dllexport) void redecl4(); // expected-warning{{redeclaration of 'redecl4' should not add 'dllexport' attribute}}
202}
203
204 void redecl5(); // expected-note{{previous declaration is here}}
205__declspec(dllexport) inline void redecl5() {} // expected-warning{{redeclaration of 'redecl5' should not add 'dllexport' attribute}}
Stephen Hines6bcf27b2014-05-29 04:14:42 -0700206
Stephen Hines651f13c2014-04-23 16:59:28 -0700207// Friend functions
208struct FuncFriend {
209 friend __declspec(dllexport) void friend1();
210 friend __declspec(dllexport) void friend2();
211 friend void friend3(); // expected-note{{previous declaration is here}}
Stephen Hines6bcf27b2014-05-29 04:14:42 -0700212 friend void friend4(); // expected-note{{previous declaration is here}}
Stephen Hines651f13c2014-04-23 16:59:28 -0700213};
214__declspec(dllexport) void friend1() {}
215 void friend2() {}
Stephen Hines176edba2014-12-01 14:53:08 -0800216__declspec(dllexport) void friend3() {} // expected-warning{{redeclaration of 'friend3' should not add 'dllexport' attribute}}
217__declspec(dllexport) inline void friend4() {} // expected-warning{{redeclaration of 'friend4' should not add 'dllexport' attribute}}
Stephen Hines651f13c2014-04-23 16:59:28 -0700218
219// Implicit declarations can be redeclared with dllexport.
220__declspec(dllexport) void* operator new(__SIZE_TYPE__ n);
221
222// External linkage is required.
223__declspec(dllexport) static int staticFunc(); // expected-error{{'staticFunc' must have external linkage when declared 'dllexport'}}
224__declspec(dllexport) Internal internalRetFunc(); // expected-error{{'internalRetFunc' must have external linkage when declared 'dllexport'}}
225namespace { __declspec(dllexport) void internalFunc() {} } // expected-error{{'(anonymous namespace)::internalFunc' must have external linkage when declared 'dllexport'}}
226namespace ns { __declspec(dllexport) void externalFunc() {} }
227
Stephen Hinesc568f1e2014-07-21 00:47:37 -0700228// Export deleted function.
229__declspec(dllexport) void deletedFunc() = delete; // expected-error{{attribute 'dllexport' cannot be applied to a deleted function}}
230__declspec(dllexport) inline void deletedInlineFunc() = delete; // expected-error{{attribute 'dllexport' cannot be applied to a deleted function}}
231
Stephen Hines651f13c2014-04-23 16:59:28 -0700232
233
234//===----------------------------------------------------------------------===//
235// Function templates
236//===----------------------------------------------------------------------===//
237
238// Export function template declaration. Check different placements.
239template<typename T> __declspec(dllexport) void funcTmplDecl1();
240template<typename T> void __declspec(dllexport) funcTmplDecl2();
241
242// Export function template definition.
243template<typename T> __declspec(dllexport) void funcTmplDef() {}
244
Stephen Hines6bcf27b2014-05-29 04:14:42 -0700245// Export inline function template.
246template<typename T> __declspec(dllexport) inline void inlineFuncTmpl1() {}
247template<typename T> inline void __attribute__((dllexport)) inlineFuncTmpl2() {}
248
249template<typename T> __declspec(dllexport) inline void inlineFuncTmplDecl();
250template<typename T> void inlineFuncTmplDecl() {}
251
252template<typename T> __declspec(dllexport) void inlineFuncTmplDef();
253template<typename T> inline void inlineFuncTmplDef() {}
254
Stephen Hines651f13c2014-04-23 16:59:28 -0700255// Redeclarations
256template<typename T> __declspec(dllexport) void funcTmplRedecl1();
257template<typename T> __declspec(dllexport) void funcTmplRedecl1() {}
258
259template<typename T> __declspec(dllexport) void funcTmplRedecl2();
260template<typename T> void funcTmplRedecl2() {}
261
262template<typename T> void funcTmplRedecl3(); // expected-note{{previous declaration is here}}
263template<typename T> __declspec(dllexport) void funcTmplRedecl3(); // expected-error{{redeclaration of 'funcTmplRedecl3' cannot add 'dllexport' attribute}}
264
Stephen Hines6bcf27b2014-05-29 04:14:42 -0700265template<typename T> void funcTmplRedecl4(); // expected-note{{previous declaration is here}}
266template<typename T> __declspec(dllexport) inline void funcTmplRedecl4() {} // expected-error{{redeclaration of 'funcTmplRedecl4' cannot add 'dllexport' attribute}}
267
Stephen Hines651f13c2014-04-23 16:59:28 -0700268// Function template friends
269struct FuncTmplFriend {
270 template<typename T> friend __declspec(dllexport) void funcTmplFriend1();
271 template<typename T> friend __declspec(dllexport) void funcTmplFriend2();
272 template<typename T> friend void funcTmplFriend3(); // expected-note{{previous declaration is here}}
Stephen Hines6bcf27b2014-05-29 04:14:42 -0700273 template<typename T> friend void funcTmplFriend4(); // expected-note{{previous declaration is here}}
Stephen Hines651f13c2014-04-23 16:59:28 -0700274};
275template<typename T> __declspec(dllexport) void funcTmplFriend1() {}
276template<typename T> void funcTmplFriend2() {}
277template<typename T> __declspec(dllexport) void funcTmplFriend3() {} // expected-error{{redeclaration of 'funcTmplFriend3' cannot add 'dllexport' attribute}}
Stephen Hines6bcf27b2014-05-29 04:14:42 -0700278template<typename T> __declspec(dllexport) inline void funcTmplFriend4() {} // expected-error{{redeclaration of 'funcTmplFriend4' cannot add 'dllexport' attribute}}
Stephen Hines651f13c2014-04-23 16:59:28 -0700279
280// External linkage is required.
281template<typename T> __declspec(dllexport) static int staticFuncTmpl(); // expected-error{{'staticFuncTmpl' must have external linkage when declared 'dllexport'}}
282template<typename T> __declspec(dllexport) Internal internalRetFuncTmpl(); // expected-error{{'internalRetFuncTmpl' must have external linkage when declared 'dllexport'}}
283namespace { template<typename T> __declspec(dllexport) void internalFuncTmpl(); } // expected-error{{'(anonymous namespace)::internalFuncTmpl' must have external linkage when declared 'dllexport'}}
284namespace ns { template<typename T> __declspec(dllexport) void externalFuncTmpl(); }
285
286
287template<typename T> void funcTmpl() {}
288template<typename T> __declspec(dllexport) void exportedFuncTmplDecl();
289template<typename T> __declspec(dllexport) void exportedFuncTmpl() {}
290
291// Export implicit instantiation of an exported function template.
292void useFunTmplDecl() { exportedFuncTmplDecl<ImplicitInst_Exported>(); }
293void useFunTmplDef() { exportedFuncTmpl<ImplicitInst_Exported>(); }
294
295// Export explicit instantiation declaration of an exported function template.
296extern template void exportedFuncTmpl<ExplicitDecl_Exported>();
297 template void exportedFuncTmpl<ExplicitDecl_Exported>();
298
299// Export explicit instantiation definition of an exported function template.
300template void exportedFuncTmpl<ExplicitInst_Exported>();
301
302// Export specialization of an exported function template.
303template<> __declspec(dllexport) void exportedFuncTmpl<ExplicitSpec_Exported>();
304template<> __declspec(dllexport) void exportedFuncTmpl<ExplicitSpec_Def_Exported>() {}
Stephen Hines6bcf27b2014-05-29 04:14:42 -0700305template<> __declspec(dllexport) inline void exportedFuncTmpl<ExplicitSpec_InlineDef_Exported>() {}
Stephen Hines651f13c2014-04-23 16:59:28 -0700306
307// Not exporting specialization of an exported function template without
308// explicit dllexport.
309template<> void exportedFuncTmpl<ExplicitSpec_NotExported>() {}
310
311
312// Export explicit instantiation declaration of a non-exported function template.
313extern template __declspec(dllexport) void funcTmpl<ExplicitDecl_Exported>();
314 template __declspec(dllexport) void funcTmpl<ExplicitDecl_Exported>();
315
316// Export explicit instantiation definition of a non-exported function template.
317template __declspec(dllexport) void funcTmpl<ExplicitInst_Exported>();
318
319// Export specialization of a non-exported function template.
320template<> __declspec(dllexport) void funcTmpl<ExplicitSpec_Exported>();
321template<> __declspec(dllexport) void funcTmpl<ExplicitSpec_Def_Exported>() {}
Stephen Hines6bcf27b2014-05-29 04:14:42 -0700322template<> __declspec(dllexport) inline void funcTmpl<ExplicitSpec_InlineDef_Exported>() {}
Stephen Hines651f13c2014-04-23 16:59:28 -0700323
324
325
326//===----------------------------------------------------------------------===//
Stephen Hinesc568f1e2014-07-21 00:47:37 -0700327// Classes
328//===----------------------------------------------------------------------===//
329
Stephen Hines176edba2014-12-01 14:53:08 -0800330namespace {
331 struct __declspec(dllexport) AnonymousClass {}; // expected-error{{(anonymous namespace)::AnonymousClass' must have external linkage when declared 'dllexport'}}
332}
333
Stephen Hinesc568f1e2014-07-21 00:47:37 -0700334class __declspec(dllexport) ClassDecl;
335
336class __declspec(dllexport) ClassDef {};
337
338#ifdef MS
339// expected-warning@+3{{'dllexport' attribute ignored}}
340#endif
341template <typename T> struct PartiallySpecializedClassTemplate {};
342template <typename T> struct __declspec(dllexport) PartiallySpecializedClassTemplate<T*> { void f() {} };
343
344template <typename T> struct ExpliciallySpecializedClassTemplate {};
345template <> struct __declspec(dllexport) ExpliciallySpecializedClassTemplate<int> { void f() {} };
346
Stephen Hines176edba2014-12-01 14:53:08 -0800347// Don't instantiate class members of implicitly instantiated templates, even if they are exported.
348struct IncompleteType;
349template <typename T> struct __declspec(dllexport) ImplicitlyInstantiatedExportedTemplate {
350 int f() { return sizeof(T); } // no-error
351};
352ImplicitlyInstantiatedExportedTemplate<IncompleteType> implicitlyInstantiatedExportedTemplate;
353
354// Don't instantiate class members of templates with explicit instantiation declarations, even if they are exported.
355struct IncompleteType2;
Stephen Hines0e2c34f2015-03-23 12:09:02 -0700356template <typename T> struct __declspec(dllexport) ExportedTemplateWithExplicitInstantiationDecl { // expected-note{{attribute is here}}
Stephen Hines176edba2014-12-01 14:53:08 -0800357 int f() { return sizeof(T); } // no-error
358};
Stephen Hines0e2c34f2015-03-23 12:09:02 -0700359extern template struct ExportedTemplateWithExplicitInstantiationDecl<IncompleteType2>; // expected-warning{{explicit instantiation declaration should not be 'dllexport'}}
Stephen Hines176edba2014-12-01 14:53:08 -0800360
361// Instantiate class members for explicitly instantiated exported templates.
362struct IncompleteType3; // expected-note{{forward declaration of 'IncompleteType3'}}
363template <typename T> struct __declspec(dllexport) ExplicitlyInstantiatedExportedTemplate {
364 int f() { return sizeof(T); } // expected-error{{invalid application of 'sizeof' to an incomplete type 'IncompleteType3'}}
365};
366template struct ExplicitlyInstantiatedExportedTemplate<IncompleteType3>; // expected-note{{in instantiation of member function 'ExplicitlyInstantiatedExportedTemplate<IncompleteType3>::f' requested here}}
367
368// In MS mode, instantiate members of class templates that are base classes of exported classes.
369#ifdef MS
370 // expected-note@+3{{forward declaration of 'IncompleteType4'}}
371 // expected-note@+3{{in instantiation of member function 'BaseClassTemplateOfExportedClass<IncompleteType4>::f' requested here}}
372#endif
373struct IncompleteType4;
374template <typename T> struct BaseClassTemplateOfExportedClass {
375#ifdef MS
376 // expected-error@+2{{invalid application of 'sizeof' to an incomplete type 'IncompleteType4'}}
377#endif
378 int f() { return sizeof(T); };
379};
380struct __declspec(dllexport) ExportedBaseClass : public BaseClassTemplateOfExportedClass<IncompleteType4> {};
381
382// Don't instantiate members of explicitly exported class templates that are base classes of exported classes.
383struct IncompleteType5;
384template <typename T> struct __declspec(dllexport) ExportedBaseClassTemplateOfExportedClass {
385 int f() { return sizeof(T); }; // no-error
386};
387struct __declspec(dllexport) ExportedBaseClass2 : public ExportedBaseClassTemplateOfExportedClass<IncompleteType5> {};
388
Stephen Hines0e2c34f2015-03-23 12:09:02 -0700389// Warn about explicit instantiation declarations of dllexport classes.
390template <typename T> struct ExplicitInstantiationDeclTemplate {};
391extern template struct __declspec(dllexport) ExplicitInstantiationDeclTemplate<int>; // expected-warning{{explicit instantiation declaration should not be 'dllexport'}} expected-note{{attribute is here}}
Stephen Hines176edba2014-12-01 14:53:08 -0800392
Stephen Hines0e2c34f2015-03-23 12:09:02 -0700393template <typename T> struct __declspec(dllexport) ExplicitInstantiationDeclExportedTemplate {}; // expected-note{{attribute is here}}
394extern template struct ExplicitInstantiationDeclExportedTemplate<int>; // expected-warning{{explicit instantiation declaration should not be 'dllexport'}}
Stephen Hinesc568f1e2014-07-21 00:47:37 -0700395
396//===----------------------------------------------------------------------===//
397// Classes with template base classes
398//===----------------------------------------------------------------------===//
399
400template <typename T> class ClassTemplate {};
401template <typename T> class __declspec(dllexport) ExportedClassTemplate {};
402template <typename T> class __declspec(dllimport) ImportedClassTemplate {};
403
404template <typename T> struct ExplicitlySpecializedTemplate { void func() {} };
405#ifdef MS
406// expected-note@+2{{class template 'ExplicitlySpecializedTemplate<int>' was explicitly specialized here}}
407#endif
408template <> struct ExplicitlySpecializedTemplate<int> { void func() {} };
409template <typename T> struct ExplicitlyExportSpecializedTemplate { void func() {} };
410template <> struct __declspec(dllexport) ExplicitlyExportSpecializedTemplate<int> { void func() {} };
411template <typename T> struct ExplicitlyImportSpecializedTemplate { void func() {} };
412template <> struct __declspec(dllimport) ExplicitlyImportSpecializedTemplate<int> { void func() {} };
413
414template <typename T> struct ExplicitlyInstantiatedTemplate { void func() {} };
415#ifdef MS
416// expected-note@+2{{class template 'ExplicitlyInstantiatedTemplate<int>' was instantiated here}}
417#endif
418template struct ExplicitlyInstantiatedTemplate<int>;
419template <typename T> struct ExplicitlyExportInstantiatedTemplate { void func() {} };
420template struct __declspec(dllexport) ExplicitlyExportInstantiatedTemplate<int>;
421template <typename T> struct ExplicitlyImportInstantiatedTemplate { void func() {} };
422template struct __declspec(dllimport) ExplicitlyImportInstantiatedTemplate<int>;
423
424// ClassTemplate<int> gets exported.
425class __declspec(dllexport) DerivedFromTemplate : public ClassTemplate<int> {};
426
427// ClassTemplate<int> is already exported.
428class __declspec(dllexport) DerivedFromTemplate2 : public ClassTemplate<int> {};
429
430// ExportedTemplate is explicitly exported.
431class __declspec(dllexport) DerivedFromExportedTemplate : public ExportedClassTemplate<int> {};
432
433// ImportedTemplate is explicitly imported.
434class __declspec(dllexport) DerivedFromImportedTemplate : public ImportedClassTemplate<int> {};
435
436#ifdef MS
437// expected-note@+4{{class template 'ClassTemplate<double>' was instantiated here}}
Stephen Hines176edba2014-12-01 14:53:08 -0800438// expected-warning@+4{{propagating dll attribute to already instantiated base class template without dll attribute is not supported}}
Stephen Hinesc568f1e2014-07-21 00:47:37 -0700439// expected-note@+3{{attribute is here}}
440#endif
441class DerivedFromTemplateD : public ClassTemplate<double> {};
442class __declspec(dllexport) DerivedFromTemplateD2 : public ClassTemplate<double> {};
443
444#ifdef MS
445// expected-note@+4{{class template 'ClassTemplate<bool>' was instantiated here}}
Stephen Hines176edba2014-12-01 14:53:08 -0800446// expected-warning@+4{{propagating dll attribute to already instantiated base class template with different dll attribute is not supported}}
Stephen Hinesc568f1e2014-07-21 00:47:37 -0700447// expected-note@+3{{attribute is here}}
448#endif
449class __declspec(dllimport) DerivedFromTemplateB : public ClassTemplate<bool> {};
450class __declspec(dllexport) DerivedFromTemplateB2 : public ClassTemplate<bool> {};
451
452#ifdef MS
Stephen Hines176edba2014-12-01 14:53:08 -0800453// expected-warning@+3{{propagating dll attribute to explicitly specialized base class template without dll attribute is not supported}}
Stephen Hinesc568f1e2014-07-21 00:47:37 -0700454// expected-note@+2{{attribute is here}}
455#endif
456struct __declspec(dllexport) DerivedFromExplicitlySpecializedTemplate : public ExplicitlySpecializedTemplate<int> {};
457
458// Base class alredy specialized with export attribute.
459struct __declspec(dllexport) DerivedFromExplicitlyExportSpecializedTemplate : public ExplicitlyExportSpecializedTemplate<int> {};
460
461// Base class already specialized with import attribute.
462struct __declspec(dllexport) DerivedFromExplicitlyImportSpecializedTemplate : public ExplicitlyImportSpecializedTemplate<int> {};
463
464#ifdef MS
Stephen Hines176edba2014-12-01 14:53:08 -0800465// expected-warning@+3{{propagating dll attribute to already instantiated base class template without dll attribute is not supported}}
Stephen Hinesc568f1e2014-07-21 00:47:37 -0700466// expected-note@+2{{attribute is here}}
467#endif
468struct __declspec(dllexport) DerivedFromExplicitlyInstantiatedTemplate : public ExplicitlyInstantiatedTemplate<int> {};
469
470// Base class already instantiated with export attribute.
471struct __declspec(dllexport) DerivedFromExplicitlyExportInstantiatedTemplate : public ExplicitlyExportInstantiatedTemplate<int> {};
472
473// Base class already instantiated with import attribute.
474struct __declspec(dllexport) DerivedFromExplicitlyImportInstantiatedTemplate : public ExplicitlyImportInstantiatedTemplate<int> {};
475
476
477//===----------------------------------------------------------------------===//
Stephen Hines651f13c2014-04-23 16:59:28 -0700478// Precedence
479//===----------------------------------------------------------------------===//
480
481// dllexport takes precedence over dllimport if both are specified.
482__attribute__((dllimport, dllexport)) extern int PrecedenceExternGlobal1A; // expected-warning{{'dllimport' attribute ignored}}
483__declspec(dllimport) __declspec(dllexport) extern int PrecedenceExternGlobal1B; // expected-warning{{'dllimport' attribute ignored}}
484
485__attribute__((dllexport, dllimport)) extern int PrecedenceExternGlobal2A; // expected-warning{{'dllimport' attribute ignored}}
486__declspec(dllexport) __declspec(dllimport) extern int PrecedenceExternGlobal2B; // expected-warning{{'dllimport' attribute ignored}}
487
488__attribute__((dllimport, dllexport)) int PrecedenceGlobal1A; // expected-warning{{'dllimport' attribute ignored}}
489__declspec(dllimport) __declspec(dllexport) int PrecedenceGlobal1B; // expected-warning{{'dllimport' attribute ignored}}
490
491__attribute__((dllexport, dllimport)) int PrecedenceGlobal2A; // expected-warning{{'dllimport' attribute ignored}}
492__declspec(dllexport) __declspec(dllimport) int PrecedenceGlobal2B; // expected-warning{{'dllimport' attribute ignored}}
493
494__declspec(dllexport) extern int PrecedenceExternGlobalRedecl1;
495__declspec(dllimport) extern int PrecedenceExternGlobalRedecl1; // expected-warning{{'dllimport' attribute ignored}}
496
497__declspec(dllimport) extern int PrecedenceExternGlobalRedecl2; // expected-warning{{'dllimport' attribute ignored}}
498__declspec(dllexport) extern int PrecedenceExternGlobalRedecl2;
499
500__declspec(dllexport) extern int PrecedenceGlobalRedecl1;
501__declspec(dllimport) int PrecedenceGlobalRedecl1; // expected-warning{{'dllimport' attribute ignored}}
502
503__declspec(dllimport) extern int PrecedenceGlobalRedecl2; // expected-warning{{'dllimport' attribute ignored}}
504__declspec(dllexport) int PrecedenceGlobalRedecl2;
505
506void __attribute__((dllimport, dllexport)) precedence1A() {} // expected-warning{{'dllimport' attribute ignored}}
507void __declspec(dllimport) __declspec(dllexport) precedence1B() {} // expected-warning{{'dllimport' attribute ignored}}
508
509void __attribute__((dllexport, dllimport)) precedence2A() {} // expected-warning{{'dllimport' attribute ignored}}
510void __declspec(dllexport) __declspec(dllimport) precedence2B() {} // expected-warning{{'dllimport' attribute ignored}}
511
512void __declspec(dllimport) precedenceRedecl1(); // expected-warning{{'dllimport' attribute ignored}}
513void __declspec(dllexport) precedenceRedecl1() {}
514
515void __declspec(dllexport) precedenceRedecl2();
516void __declspec(dllimport) precedenceRedecl2() {} // expected-warning{{'dllimport' attribute ignored}}
Stephen Hines6bcf27b2014-05-29 04:14:42 -0700517
518
519
520//===----------------------------------------------------------------------===//
521// Class members
522//===----------------------------------------------------------------------===//
523
524// Export individual members of a class.
525struct ExportMembers {
526 struct Nested {
527 __declspec(dllexport) void normalDef();
528 };
529
530 __declspec(dllexport) void normalDecl();
531 __declspec(dllexport) void normalDef();
532 __declspec(dllexport) void normalInclass() {}
533 __declspec(dllexport) void normalInlineDef();
534 __declspec(dllexport) inline void normalInlineDecl();
535 __declspec(dllexport) virtual void virtualDecl();
536 __declspec(dllexport) virtual void virtualDef();
537 __declspec(dllexport) virtual void virtualInclass() {}
538 __declspec(dllexport) virtual void virtualInlineDef();
539 __declspec(dllexport) virtual inline void virtualInlineDecl();
540 __declspec(dllexport) static void staticDecl();
541 __declspec(dllexport) static void staticDef();
542 __declspec(dllexport) static void staticInclass() {}
543 __declspec(dllexport) static void staticInlineDef();
544 __declspec(dllexport) static inline void staticInlineDecl();
545
546protected:
547 __declspec(dllexport) void protectedDef();
548private:
549 __declspec(dllexport) void privateDef();
Stephen Hinesc568f1e2014-07-21 00:47:37 -0700550public:
551
552 __declspec(dllexport) int Field; // expected-warning{{'dllexport' attribute only applies to variables, functions and classes}}
553 __declspec(dllexport) static int StaticField;
554 __declspec(dllexport) static int StaticFieldDef;
555 __declspec(dllexport) static const int StaticConstField;
556 __declspec(dllexport) static const int StaticConstFieldDef;
557 __declspec(dllexport) static const int StaticConstFieldEqualInit = 1;
558 __declspec(dllexport) static const int StaticConstFieldBraceInit{1};
559 __declspec(dllexport) constexpr static int ConstexprField = 1;
560 __declspec(dllexport) constexpr static int ConstexprFieldDef = 1;
Stephen Hines6bcf27b2014-05-29 04:14:42 -0700561};
562
563 void ExportMembers::Nested::normalDef() {}
564 void ExportMembers::normalDef() {}
565inline void ExportMembers::normalInlineDef() {}
566 void ExportMembers::normalInlineDecl() {}
567 void ExportMembers::virtualDef() {}
568inline void ExportMembers::virtualInlineDef() {}
569 void ExportMembers::virtualInlineDecl() {}
570 void ExportMembers::staticDef() {}
571inline void ExportMembers::staticInlineDef() {}
572 void ExportMembers::staticInlineDecl() {}
573 void ExportMembers::protectedDef() {}
574 void ExportMembers::privateDef() {}
575
Stephen Hinesc568f1e2014-07-21 00:47:37 -0700576 int ExportMembers::StaticFieldDef;
577const int ExportMembers::StaticConstFieldDef = 1;
578constexpr int ExportMembers::ConstexprFieldDef;
579
Stephen Hines6bcf27b2014-05-29 04:14:42 -0700580
581// Export on member definitions.
582struct ExportMemberDefs {
583 __declspec(dllexport) void normalDef();
584 __declspec(dllexport) void normalInlineDef();
585 __declspec(dllexport) inline void normalInlineDecl();
586 __declspec(dllexport) virtual void virtualDef();
587 __declspec(dllexport) virtual void virtualInlineDef();
588 __declspec(dllexport) virtual inline void virtualInlineDecl();
589 __declspec(dllexport) static void staticDef();
590 __declspec(dllexport) static void staticInlineDef();
591 __declspec(dllexport) static inline void staticInlineDecl();
Stephen Hinesc568f1e2014-07-21 00:47:37 -0700592
593 __declspec(dllexport) static int StaticField;
594 __declspec(dllexport) static const int StaticConstField;
595 __declspec(dllexport) constexpr static int ConstexprField = 1;
Stephen Hines6bcf27b2014-05-29 04:14:42 -0700596};
597
598__declspec(dllexport) void ExportMemberDefs::normalDef() {}
599__declspec(dllexport) inline void ExportMemberDefs::normalInlineDef() {}
600__declspec(dllexport) void ExportMemberDefs::normalInlineDecl() {}
601__declspec(dllexport) void ExportMemberDefs::virtualDef() {}
602__declspec(dllexport) inline void ExportMemberDefs::virtualInlineDef() {}
603__declspec(dllexport) void ExportMemberDefs::virtualInlineDecl() {}
604__declspec(dllexport) void ExportMemberDefs::staticDef() {}
605__declspec(dllexport) inline void ExportMemberDefs::staticInlineDef() {}
606__declspec(dllexport) void ExportMemberDefs::staticInlineDecl() {}
607
Stephen Hinesc568f1e2014-07-21 00:47:37 -0700608__declspec(dllexport) int ExportMemberDefs::StaticField;
609__declspec(dllexport) const int ExportMemberDefs::StaticConstField = 1;
610__declspec(dllexport) constexpr int ExportMemberDefs::ConstexprField;
611
Stephen Hines6bcf27b2014-05-29 04:14:42 -0700612
613// Export special member functions.
614struct ExportSpecials {
615 __declspec(dllexport) ExportSpecials() {}
616 __declspec(dllexport) ~ExportSpecials();
617 __declspec(dllexport) inline ExportSpecials(const ExportSpecials&);
618 __declspec(dllexport) ExportSpecials& operator=(const ExportSpecials&);
619 __declspec(dllexport) ExportSpecials(ExportSpecials&&);
620 __declspec(dllexport) ExportSpecials& operator=(ExportSpecials&&);
621};
622
623ExportSpecials::~ExportSpecials() {}
624ExportSpecials::ExportSpecials(const ExportSpecials&) {}
625inline ExportSpecials& ExportSpecials::operator=(const ExportSpecials&) { return *this; }
626ExportSpecials::ExportSpecials(ExportSpecials&&) {}
627ExportSpecials& ExportSpecials::operator=(ExportSpecials&&) { return *this; }
628
629
630// Export allocation functions.
631extern "C" void* malloc(__SIZE_TYPE__ size);
632extern "C" void free(void* p);
633struct ExportAlloc {
634 __declspec(dllexport) void* operator new(__SIZE_TYPE__);
635 __declspec(dllexport) void* operator new[](__SIZE_TYPE__);
636 __declspec(dllexport) void operator delete(void*);
637 __declspec(dllexport) void operator delete[](void*);
638};
639void* ExportAlloc::operator new(__SIZE_TYPE__ n) { return malloc(n); }
640void* ExportAlloc::operator new[](__SIZE_TYPE__ n) { return malloc(n); }
641void ExportAlloc::operator delete(void* p) { free(p); }
642void ExportAlloc::operator delete[](void* p) { free(p); }
643
644
Stephen Hinesc568f1e2014-07-21 00:47:37 -0700645// Export deleted member functions.
646struct ExportDeleted {
647 __declspec(dllexport) ExportDeleted() = delete; // expected-error{{attribute 'dllexport' cannot be applied to a deleted function}}
648 __declspec(dllexport) ~ExportDeleted() = delete; // expected-error{{attribute 'dllexport' cannot be applied to a deleted function}}
649 __declspec(dllexport) ExportDeleted(const ExportDeleted&) = delete; // expected-error{{attribute 'dllexport' cannot be applied to a deleted function}}
650 __declspec(dllexport) ExportDeleted& operator=(const ExportDeleted&) = delete; // expected-error{{attribute 'dllexport' cannot be applied to a deleted function}}
651 __declspec(dllexport) ExportDeleted(ExportDeleted&&) = delete; // expected-error{{attribute 'dllexport' cannot be applied to a deleted function}}
652 __declspec(dllexport) ExportDeleted& operator=(ExportDeleted&&) = delete; // expected-error{{attribute 'dllexport' cannot be applied to a deleted function}}
653 __declspec(dllexport) void deleted() = delete; // expected-error{{attribute 'dllexport' cannot be applied to a deleted function}}
654};
655
656
Stephen Hines6bcf27b2014-05-29 04:14:42 -0700657// Export defaulted member functions.
658struct ExportDefaulted {
659 __declspec(dllexport) ExportDefaulted() = default;
660 __declspec(dllexport) ~ExportDefaulted() = default;
661 __declspec(dllexport) ExportDefaulted(const ExportDefaulted&) = default;
662 __declspec(dllexport) ExportDefaulted& operator=(const ExportDefaulted&) = default;
663 __declspec(dllexport) ExportDefaulted(ExportDefaulted&&) = default;
664 __declspec(dllexport) ExportDefaulted& operator=(ExportDefaulted&&) = default;
665};
666
667
668// Export defaulted member function definitions.
669struct ExportDefaultedDefs {
670 __declspec(dllexport) ExportDefaultedDefs();
671 __declspec(dllexport) ~ExportDefaultedDefs();
672
673 __declspec(dllexport) inline ExportDefaultedDefs(const ExportDefaultedDefs&);
674 __declspec(dllexport) ExportDefaultedDefs& operator=(const ExportDefaultedDefs&);
675
676 __declspec(dllexport) ExportDefaultedDefs(ExportDefaultedDefs&&);
677 __declspec(dllexport) ExportDefaultedDefs& operator=(ExportDefaultedDefs&&);
678};
679
680// Export definitions.
681__declspec(dllexport) ExportDefaultedDefs::ExportDefaultedDefs() = default;
682ExportDefaultedDefs::~ExportDefaultedDefs() = default;
683
684// Export inline declaration and definition.
685__declspec(dllexport) ExportDefaultedDefs::ExportDefaultedDefs(const ExportDefaultedDefs&) = default;
686inline ExportDefaultedDefs& ExportDefaultedDefs::operator=(const ExportDefaultedDefs&) = default;
687
688__declspec(dllexport) ExportDefaultedDefs::ExportDefaultedDefs(ExportDefaultedDefs&&) = default;
689ExportDefaultedDefs& ExportDefaultedDefs::operator=(ExportDefaultedDefs&&) = default;
690
691
692// Redeclarations cannot add dllexport.
693struct MemberRedecl {
694 void normalDef(); // expected-note{{previous declaration is here}}
695 void normalInlineDef(); // expected-note{{previous declaration is here}}
696 inline void normalInlineDecl(); // expected-note{{previous declaration is here}}
697 virtual void virtualDef(); // expected-note{{previous declaration is here}}
698 virtual void virtualInlineDef(); // expected-note{{previous declaration is here}}
699 virtual inline void virtualInlineDecl(); // expected-note{{previous declaration is here}}
700 static void staticDef(); // expected-note{{previous declaration is here}}
701 static void staticInlineDef(); // expected-note{{previous declaration is here}}
702 static inline void staticInlineDecl(); // expected-note{{previous declaration is here}}
Stephen Hinesc568f1e2014-07-21 00:47:37 -0700703
704 static int StaticField; // expected-note{{previous declaration is here}}
705 static const int StaticConstField; // expected-note{{previous declaration is here}}
706 constexpr static int ConstexprField = 1; // expected-note{{previous declaration is here}}
Stephen Hines6bcf27b2014-05-29 04:14:42 -0700707};
708
709__declspec(dllexport) void MemberRedecl::normalDef() {} // expected-error{{redeclaration of 'MemberRedecl::normalDef' cannot add 'dllexport' attribute}}
710__declspec(dllexport) inline void MemberRedecl::normalInlineDef() {} // expected-error{{redeclaration of 'MemberRedecl::normalInlineDef' cannot add 'dllexport' attribute}}
711__declspec(dllexport) void MemberRedecl::normalInlineDecl() {} // expected-error{{redeclaration of 'MemberRedecl::normalInlineDecl' cannot add 'dllexport' attribute}}
712__declspec(dllexport) void MemberRedecl::virtualDef() {} // expected-error{{redeclaration of 'MemberRedecl::virtualDef' cannot add 'dllexport' attribute}}
713__declspec(dllexport) inline void MemberRedecl::virtualInlineDef() {} // expected-error{{redeclaration of 'MemberRedecl::virtualInlineDef' cannot add 'dllexport' attribute}}
714__declspec(dllexport) void MemberRedecl::virtualInlineDecl() {} // expected-error{{redeclaration of 'MemberRedecl::virtualInlineDecl' cannot add 'dllexport' attribute}}
715__declspec(dllexport) void MemberRedecl::staticDef() {} // expected-error{{redeclaration of 'MemberRedecl::staticDef' cannot add 'dllexport' attribute}}
716__declspec(dllexport) inline void MemberRedecl::staticInlineDef() {} // expected-error{{redeclaration of 'MemberRedecl::staticInlineDef' cannot add 'dllexport' attribute}}
717__declspec(dllexport) void MemberRedecl::staticInlineDecl() {} // expected-error{{redeclaration of 'MemberRedecl::staticInlineDecl' cannot add 'dllexport' attribute}}
718
Stephen Hinesc568f1e2014-07-21 00:47:37 -0700719__declspec(dllexport) int MemberRedecl::StaticField = 1; // expected-error{{redeclaration of 'MemberRedecl::StaticField' cannot add 'dllexport' attribute}}
720__declspec(dllexport) const int MemberRedecl::StaticConstField = 1; // expected-error{{redeclaration of 'MemberRedecl::StaticConstField' cannot add 'dllexport' attribute}}
721__declspec(dllexport) constexpr int MemberRedecl::ConstexprField; // expected-error{{redeclaration of 'MemberRedecl::ConstexprField' cannot add 'dllexport' attribute}}
722
Stephen Hines6bcf27b2014-05-29 04:14:42 -0700723
724
725//===----------------------------------------------------------------------===//
726// Class member templates
727//===----------------------------------------------------------------------===//
728
729struct ExportMemberTmpl {
730 template<typename T> __declspec(dllexport) void normalDecl();
731 template<typename T> __declspec(dllexport) void normalDef();
732 template<typename T> __declspec(dllexport) void normalInclass() {}
733 template<typename T> __declspec(dllexport) void normalInlineDef();
734 template<typename T> __declspec(dllexport) inline void normalInlineDecl();
735 template<typename T> __declspec(dllexport) static void staticDecl();
736 template<typename T> __declspec(dllexport) static void staticDef();
737 template<typename T> __declspec(dllexport) static void staticInclass() {}
738 template<typename T> __declspec(dllexport) static void staticInlineDef();
739 template<typename T> __declspec(dllexport) static inline void staticInlineDecl();
Stephen Hinesc568f1e2014-07-21 00:47:37 -0700740
741#if __has_feature(cxx_variable_templates)
742 template<typename T> __declspec(dllexport) static int StaticField;
743 template<typename T> __declspec(dllexport) static int StaticFieldDef;
744 template<typename T> __declspec(dllexport) static const int StaticConstField;
745 template<typename T> __declspec(dllexport) static const int StaticConstFieldDef;
746 template<typename T> __declspec(dllexport) static const int StaticConstFieldEqualInit = 1;
747 template<typename T> __declspec(dllexport) static const int StaticConstFieldBraceInit{1};
748 template<typename T> __declspec(dllexport) constexpr static int ConstexprField = 1;
749 template<typename T> __declspec(dllexport) constexpr static int ConstexprFieldDef = 1;
750#endif // __has_feature(cxx_variable_templates)
Stephen Hines6bcf27b2014-05-29 04:14:42 -0700751};
752
753template<typename T> void ExportMemberTmpl::normalDef() {}
754template<typename T> inline void ExportMemberTmpl::normalInlineDef() {}
755template<typename T> void ExportMemberTmpl::normalInlineDecl() {}
756template<typename T> void ExportMemberTmpl::staticDef() {}
757template<typename T> inline void ExportMemberTmpl::staticInlineDef() {}
758template<typename T> void ExportMemberTmpl::staticInlineDecl() {}
759
Stephen Hinesc568f1e2014-07-21 00:47:37 -0700760#if __has_feature(cxx_variable_templates)
761template<typename T> int ExportMemberTmpl::StaticFieldDef;
762template<typename T> const int ExportMemberTmpl::StaticConstFieldDef = 1;
763template<typename T> constexpr int ExportMemberTmpl::ConstexprFieldDef;
764#endif // __has_feature(cxx_variable_templates)
Stephen Hines6bcf27b2014-05-29 04:14:42 -0700765
766
767// Redeclarations cannot add dllexport.
768struct MemTmplRedecl {
769 template<typename T> void normalDef(); // expected-note{{previous declaration is here}}
770 template<typename T> void normalInlineDef(); // expected-note{{previous declaration is here}}
771 template<typename T> inline void normalInlineDecl(); // expected-note{{previous declaration is here}}
772 template<typename T> static void staticDef(); // expected-note{{previous declaration is here}}
773 template<typename T> static void staticInlineDef(); // expected-note{{previous declaration is here}}
774 template<typename T> static inline void staticInlineDecl(); // expected-note{{previous declaration is here}}
Stephen Hinesc568f1e2014-07-21 00:47:37 -0700775
776#if __has_feature(cxx_variable_templates)
777 template<typename T> static int StaticField; // expected-note{{previous declaration is here}}
778 template<typename T> static const int StaticConstField; // expected-note{{previous declaration is here}}
779 template<typename T> constexpr static int ConstexprField = 1; // expected-note{{previous declaration is here}}
780#endif // __has_feature(cxx_variable_templates)
Stephen Hines6bcf27b2014-05-29 04:14:42 -0700781};
782
783template<typename T> __declspec(dllexport) void MemTmplRedecl::normalDef() {} // expected-error{{redeclaration of 'MemTmplRedecl::normalDef' cannot add 'dllexport' attribute}}
784template<typename T> __declspec(dllexport) inline void MemTmplRedecl::normalInlineDef() {} // expected-error{{redeclaration of 'MemTmplRedecl::normalInlineDef' cannot add 'dllexport' attribute}}
785template<typename T> __declspec(dllexport) void MemTmplRedecl::normalInlineDecl() {} // expected-error{{redeclaration of 'MemTmplRedecl::normalInlineDecl' cannot add 'dllexport' attribute}}
786template<typename T> __declspec(dllexport) void MemTmplRedecl::staticDef() {} // expected-error{{redeclaration of 'MemTmplRedecl::staticDef' cannot add 'dllexport' attribute}}
787template<typename T> __declspec(dllexport) inline void MemTmplRedecl::staticInlineDef() {} // expected-error{{redeclaration of 'MemTmplRedecl::staticInlineDef' cannot add 'dllexport' attribute}}
788template<typename T> __declspec(dllexport) void MemTmplRedecl::staticInlineDecl() {} // expected-error{{redeclaration of 'MemTmplRedecl::staticInlineDecl' cannot add 'dllexport' attribute}}
789
Stephen Hinesc568f1e2014-07-21 00:47:37 -0700790#if __has_feature(cxx_variable_templates)
791template<typename T> __declspec(dllexport) int MemTmplRedecl::StaticField = 1; // expected-error{{redeclaration of 'MemTmplRedecl::StaticField' cannot add 'dllexport' attribute}}
792template<typename T> __declspec(dllexport) const int MemTmplRedecl::StaticConstField = 1; // expected-error{{redeclaration of 'MemTmplRedecl::StaticConstField' cannot add 'dllexport' attribute}}
793template<typename T> __declspec(dllexport) constexpr int MemTmplRedecl::ConstexprField; // expected-error{{redeclaration of 'MemTmplRedecl::ConstexprField' cannot add 'dllexport' attribute}}
794#endif // __has_feature(cxx_variable_templates)
795
Stephen Hines6bcf27b2014-05-29 04:14:42 -0700796
797
798struct MemFunTmpl {
799 template<typename T> void normalDef() {}
800 template<typename T> __declspec(dllexport) void exportedNormal() {}
801 template<typename T> static void staticDef() {}
802 template<typename T> __declspec(dllexport) static void exportedStatic() {}
803};
804
805// Export implicit instantiation of an exported member function template.
806void useMemFunTmpl() {
807 MemFunTmpl().exportedNormal<ImplicitInst_Exported>();
808 MemFunTmpl().exportedStatic<ImplicitInst_Exported>();
809}
810
811// Export explicit instantiation declaration of an exported member function
812// template.
813extern template void MemFunTmpl::exportedNormal<ExplicitDecl_Exported>();
814 template void MemFunTmpl::exportedNormal<ExplicitDecl_Exported>();
815
816extern template void MemFunTmpl::exportedStatic<ExplicitDecl_Exported>();
817 template void MemFunTmpl::exportedStatic<ExplicitDecl_Exported>();
818
819// Export explicit instantiation definition of an exported member function
820// template.
821template void MemFunTmpl::exportedNormal<ExplicitInst_Exported>();
822template void MemFunTmpl::exportedStatic<ExplicitInst_Exported>();
823
824// Export specialization of an exported member function template.
825template<> __declspec(dllexport) void MemFunTmpl::exportedNormal<ExplicitSpec_Exported>();
826template<> __declspec(dllexport) void MemFunTmpl::exportedNormal<ExplicitSpec_Def_Exported>() {}
827template<> __declspec(dllexport) inline void MemFunTmpl::exportedNormal<ExplicitSpec_InlineDef_Exported>() {}
828
829template<> __declspec(dllexport) void MemFunTmpl::exportedStatic<ExplicitSpec_Exported>();
830template<> __declspec(dllexport) void MemFunTmpl::exportedStatic<ExplicitSpec_Def_Exported>() {}
831template<> __declspec(dllexport) inline void MemFunTmpl::exportedStatic<ExplicitSpec_InlineDef_Exported>() {}
832
833// Not exporting specialization of an exported member function template without
834// explicit dllexport.
835template<> void MemFunTmpl::exportedNormal<ExplicitSpec_NotExported>() {}
836template<> void MemFunTmpl::exportedStatic<ExplicitSpec_NotExported>() {}
837
838
839// Export explicit instantiation declaration of a non-exported member function
840// template.
841extern template __declspec(dllexport) void MemFunTmpl::normalDef<ExplicitDecl_Exported>();
842 template __declspec(dllexport) void MemFunTmpl::normalDef<ExplicitDecl_Exported>();
843
844extern template __declspec(dllexport) void MemFunTmpl::staticDef<ExplicitDecl_Exported>();
845 template __declspec(dllexport) void MemFunTmpl::staticDef<ExplicitDecl_Exported>();
846
847// Export explicit instantiation definition of a non-exported member function
848// template.
849template __declspec(dllexport) void MemFunTmpl::normalDef<ExplicitInst_Exported>();
850template __declspec(dllexport) void MemFunTmpl::staticDef<ExplicitInst_Exported>();
851
852// Export specialization of a non-exported member function template.
853template<> __declspec(dllexport) void MemFunTmpl::normalDef<ExplicitSpec_Exported>();
854template<> __declspec(dllexport) void MemFunTmpl::normalDef<ExplicitSpec_Def_Exported>() {}
855template<> __declspec(dllexport) inline void MemFunTmpl::normalDef<ExplicitSpec_InlineDef_Exported>() {}
856
857template<> __declspec(dllexport) void MemFunTmpl::staticDef<ExplicitSpec_Exported>();
858template<> __declspec(dllexport) void MemFunTmpl::staticDef<ExplicitSpec_Def_Exported>() {}
859template<> __declspec(dllexport) inline void MemFunTmpl::staticDef<ExplicitSpec_InlineDef_Exported>() {}
860
861
862
Stephen Hinesc568f1e2014-07-21 00:47:37 -0700863#if __has_feature(cxx_variable_templates)
864struct MemVarTmpl {
865 template<typename T> static const int StaticVar = 1;
866 template<typename T> __declspec(dllexport) static const int ExportedStaticVar = 1;
867};
868template<typename T> const int MemVarTmpl::StaticVar;
869template<typename T> const int MemVarTmpl::ExportedStaticVar;
870
871// Export implicit instantiation of an exported member variable template.
872int useMemVarTmpl() { return MemVarTmpl::ExportedStaticVar<ImplicitInst_Exported>; }
873
874// Export explicit instantiation declaration of an exported member variable
875// template.
876extern template const int MemVarTmpl::ExportedStaticVar<ExplicitDecl_Exported>;
877 template const int MemVarTmpl::ExportedStaticVar<ExplicitDecl_Exported>;
878
879// Export explicit instantiation definition of an exported member variable
880// template.
881template const int MemVarTmpl::ExportedStaticVar<ExplicitInst_Exported>;
882
883// Export specialization of an exported member variable template.
884template<> __declspec(dllexport) const int MemVarTmpl::ExportedStaticVar<ExplicitSpec_Exported>;
885template<> __declspec(dllexport) const int MemVarTmpl::ExportedStaticVar<ExplicitSpec_Def_Exported> = 1;
886
887// Not exporting specialization of an exported member variable template without
888// explicit dllexport.
889template<> const int MemVarTmpl::ExportedStaticVar<ExplicitSpec_NotExported>;
890
891
892// Export explicit instantiation declaration of a non-exported member variable
893// template.
894extern template __declspec(dllexport) const int MemVarTmpl::StaticVar<ExplicitDecl_Exported>;
895 template __declspec(dllexport) const int MemVarTmpl::StaticVar<ExplicitDecl_Exported>;
896
897// Export explicit instantiation definition of a non-exported member variable
898// template.
899template __declspec(dllexport) const int MemVarTmpl::StaticVar<ExplicitInst_Exported>;
900
901// Export specialization of a non-exported member variable template.
902template<> __declspec(dllexport) const int MemVarTmpl::StaticVar<ExplicitSpec_Exported>;
903template<> __declspec(dllexport) const int MemVarTmpl::StaticVar<ExplicitSpec_Def_Exported> = 1;
904
905#endif // __has_feature(cxx_variable_templates)
906
907
908
Stephen Hines6bcf27b2014-05-29 04:14:42 -0700909//===----------------------------------------------------------------------===//
910// Class template members
911//===----------------------------------------------------------------------===//
912
913// Export individual members of a class template.
914template<typename T>
915struct ExportClassTmplMembers {
916 __declspec(dllexport) void normalDecl();
917 __declspec(dllexport) void normalDef();
918 __declspec(dllexport) void normalInclass() {}
919 __declspec(dllexport) void normalInlineDef();
920 __declspec(dllexport) inline void normalInlineDecl();
921 __declspec(dllexport) virtual void virtualDecl();
922 __declspec(dllexport) virtual void virtualDef();
923 __declspec(dllexport) virtual void virtualInclass() {}
924 __declspec(dllexport) virtual void virtualInlineDef();
925 __declspec(dllexport) virtual inline void virtualInlineDecl();
926 __declspec(dllexport) static void staticDecl();
927 __declspec(dllexport) static void staticDef();
928 __declspec(dllexport) static void staticInclass() {}
929 __declspec(dllexport) static void staticInlineDef();
930 __declspec(dllexport) static inline void staticInlineDecl();
931
932protected:
933 __declspec(dllexport) void protectedDef();
934private:
935 __declspec(dllexport) void privateDef();
Stephen Hinesc568f1e2014-07-21 00:47:37 -0700936public:
937
938 __declspec(dllexport) int Field; // expected-warning{{'dllexport' attribute only applies to variables, functions and classes}}
939 __declspec(dllexport) static int StaticField;
940 __declspec(dllexport) static int StaticFieldDef;
941 __declspec(dllexport) static const int StaticConstField;
942 __declspec(dllexport) static const int StaticConstFieldDef;
943 __declspec(dllexport) static const int StaticConstFieldEqualInit = 1;
944 __declspec(dllexport) static const int StaticConstFieldBraceInit{1};
945 __declspec(dllexport) constexpr static int ConstexprField = 1;
946 __declspec(dllexport) constexpr static int ConstexprFieldDef = 1;
Stephen Hines6bcf27b2014-05-29 04:14:42 -0700947};
948
949template<typename T> void ExportClassTmplMembers<T>::normalDef() {}
950template<typename T> inline void ExportClassTmplMembers<T>::normalInlineDef() {}
951template<typename T> void ExportClassTmplMembers<T>::normalInlineDecl() {}
952template<typename T> void ExportClassTmplMembers<T>::virtualDef() {}
953template<typename T> inline void ExportClassTmplMembers<T>::virtualInlineDef() {}
954template<typename T> void ExportClassTmplMembers<T>::virtualInlineDecl() {}
955template<typename T> void ExportClassTmplMembers<T>::staticDef() {}
956template<typename T> inline void ExportClassTmplMembers<T>::staticInlineDef() {}
957template<typename T> void ExportClassTmplMembers<T>::staticInlineDecl() {}
958template<typename T> void ExportClassTmplMembers<T>::protectedDef() {}
959template<typename T> void ExportClassTmplMembers<T>::privateDef() {}
960
Stephen Hinesc568f1e2014-07-21 00:47:37 -0700961template<typename T> int ExportClassTmplMembers<T>::StaticFieldDef;
962template<typename T> const int ExportClassTmplMembers<T>::StaticConstFieldDef = 1;
963template<typename T> constexpr int ExportClassTmplMembers<T>::ConstexprFieldDef;
964
Stephen Hines6bcf27b2014-05-29 04:14:42 -0700965template struct ExportClassTmplMembers<ImplicitInst_Exported>;
966
967
968// Redeclarations cannot add dllexport.
969template<typename T>
970struct CTMR /*ClassTmplMemberRedecl*/ {
971 void normalDef(); // expected-note{{previous declaration is here}}
972 void normalInlineDef(); // expected-note{{previous declaration is here}}
973 inline void normalInlineDecl(); // expected-note{{previous declaration is here}}
974 virtual void virtualDef(); // expected-note{{previous declaration is here}}
975 virtual void virtualInlineDef(); // expected-note{{previous declaration is here}}
976 virtual inline void virtualInlineDecl(); // expected-note{{previous declaration is here}}
977 static void staticDef(); // expected-note{{previous declaration is here}}
978 static void staticInlineDef(); // expected-note{{previous declaration is here}}
979 static inline void staticInlineDecl(); // expected-note{{previous declaration is here}}
Stephen Hinesc568f1e2014-07-21 00:47:37 -0700980
981 static int StaticField; // expected-note{{previous declaration is here}}
982 static const int StaticConstField; // expected-note{{previous declaration is here}}
983 constexpr static int ConstexprField = 1; // expected-note{{previous declaration is here}}
Stephen Hines6bcf27b2014-05-29 04:14:42 -0700984};
985
986template<typename T> __declspec(dllexport) void CTMR<T>::normalDef() {} // expected-error{{redeclaration of 'CTMR::normalDef' cannot add 'dllexport' attribute}}
987template<typename T> __declspec(dllexport) inline void CTMR<T>::normalInlineDef() {} // expected-error{{redeclaration of 'CTMR::normalInlineDef' cannot add 'dllexport' attribute}}
988template<typename T> __declspec(dllexport) void CTMR<T>::normalInlineDecl() {} // expected-error{{redeclaration of 'CTMR::normalInlineDecl' cannot add 'dllexport' attribute}}
989template<typename T> __declspec(dllexport) void CTMR<T>::virtualDef() {} // expected-error{{redeclaration of 'CTMR::virtualDef' cannot add 'dllexport' attribute}}
990template<typename T> __declspec(dllexport) inline void CTMR<T>::virtualInlineDef() {} // expected-error{{redeclaration of 'CTMR::virtualInlineDef' cannot add 'dllexport' attribute}}
991template<typename T> __declspec(dllexport) void CTMR<T>::virtualInlineDecl() {} // expected-error{{redeclaration of 'CTMR::virtualInlineDecl' cannot add 'dllexport' attribute}}
992template<typename T> __declspec(dllexport) void CTMR<T>::staticDef() {} // expected-error{{redeclaration of 'CTMR::staticDef' cannot add 'dllexport' attribute}}
993template<typename T> __declspec(dllexport) inline void CTMR<T>::staticInlineDef() {} // expected-error{{redeclaration of 'CTMR::staticInlineDef' cannot add 'dllexport' attribute}}
994template<typename T> __declspec(dllexport) void CTMR<T>::staticInlineDecl() {} // expected-error{{redeclaration of 'CTMR::staticInlineDecl' cannot add 'dllexport' attribute}}
995
Stephen Hinesc568f1e2014-07-21 00:47:37 -0700996template<typename T> __declspec(dllexport) int CTMR<T>::StaticField = 1; // expected-error{{redeclaration of 'CTMR::StaticField' cannot add 'dllexport' attribute}}
997template<typename T> __declspec(dllexport) const int CTMR<T>::StaticConstField = 1; // expected-error{{redeclaration of 'CTMR::StaticConstField' cannot add 'dllexport' attribute}}
998template<typename T> __declspec(dllexport) constexpr int CTMR<T>::ConstexprField; // expected-error{{redeclaration of 'CTMR::ConstexprField' cannot add 'dllexport' attribute}}
999
Stephen Hines6bcf27b2014-05-29 04:14:42 -07001000
1001
1002//===----------------------------------------------------------------------===//
1003// Class template member templates
1004//===----------------------------------------------------------------------===//
1005
1006template<typename T>
1007struct ExportClsTmplMemTmpl {
1008 template<typename U> __declspec(dllexport) void normalDecl();
1009 template<typename U> __declspec(dllexport) void normalDef();
1010 template<typename U> __declspec(dllexport) void normalInclass() {}
1011 template<typename U> __declspec(dllexport) void normalInlineDef();
1012 template<typename U> __declspec(dllexport) inline void normalInlineDecl();
1013 template<typename U> __declspec(dllexport) static void staticDecl();
1014 template<typename U> __declspec(dllexport) static void staticDef();
1015 template<typename U> __declspec(dllexport) static void staticInclass() {}
1016 template<typename U> __declspec(dllexport) static void staticInlineDef();
1017 template<typename U> __declspec(dllexport) static inline void staticInlineDecl();
Stephen Hinesc568f1e2014-07-21 00:47:37 -07001018
1019#if __has_feature(cxx_variable_templates)
1020 template<typename U> __declspec(dllexport) static int StaticField;
1021 template<typename U> __declspec(dllexport) static int StaticFieldDef;
1022 template<typename U> __declspec(dllexport) static const int StaticConstField;
1023 template<typename U> __declspec(dllexport) static const int StaticConstFieldDef;
1024 template<typename U> __declspec(dllexport) static const int StaticConstFieldEqualInit = 1;
1025 template<typename U> __declspec(dllexport) static const int StaticConstFieldBraceInit{1};
1026 template<typename U> __declspec(dllexport) constexpr static int ConstexprField = 1;
1027 template<typename U> __declspec(dllexport) constexpr static int ConstexprFieldDef = 1;
1028#endif // __has_feature(cxx_variable_templates)
Stephen Hines6bcf27b2014-05-29 04:14:42 -07001029};
1030
1031template<typename T> template<typename U> void ExportClsTmplMemTmpl<T>::normalDef() {}
1032template<typename T> template<typename U> inline void ExportClsTmplMemTmpl<T>::normalInlineDef() {}
1033template<typename T> template<typename U> void ExportClsTmplMemTmpl<T>::normalInlineDecl() {}
1034template<typename T> template<typename U> void ExportClsTmplMemTmpl<T>::staticDef() {}
1035template<typename T> template<typename U> inline void ExportClsTmplMemTmpl<T>::staticInlineDef() {}
1036template<typename T> template<typename U> void ExportClsTmplMemTmpl<T>::staticInlineDecl() {}
1037
Stephen Hinesc568f1e2014-07-21 00:47:37 -07001038#if __has_feature(cxx_variable_templates)
1039template<typename T> template<typename U> int ExportClsTmplMemTmpl<T>::StaticFieldDef;
1040template<typename T> template<typename U> const int ExportClsTmplMemTmpl<T>::StaticConstFieldDef = 1;
1041template<typename T> template<typename U> constexpr int ExportClsTmplMemTmpl<T>::ConstexprFieldDef;
1042#endif // __has_feature(cxx_variable_templates)
1043
Stephen Hines6bcf27b2014-05-29 04:14:42 -07001044
1045// Redeclarations cannot add dllexport.
1046template<typename T>
1047struct CTMTR /*ClassTmplMemberTmplRedecl*/ {
1048 template<typename U> void normalDef(); // expected-note{{previous declaration is here}}
1049 template<typename U> void normalInlineDef(); // expected-note{{previous declaration is here}}
1050 template<typename U> inline void normalInlineDecl(); // expected-note{{previous declaration is here}}
1051 template<typename U> static void staticDef(); // expected-note{{previous declaration is here}}
1052 template<typename U> static void staticInlineDef(); // expected-note{{previous declaration is here}}
1053 template<typename U> static inline void staticInlineDecl(); // expected-note{{previous declaration is here}}
Stephen Hinesc568f1e2014-07-21 00:47:37 -07001054
1055#if __has_feature(cxx_variable_templates)
1056 template<typename U> static int StaticField; // expected-note{{previous declaration is here}}
1057 template<typename U> static const int StaticConstField; // expected-note{{previous declaration is here}}
1058 template<typename U> constexpr static int ConstexprField = 1; // expected-note{{previous declaration is here}}
1059#endif // __has_feature(cxx_variable_templates)
Stephen Hines6bcf27b2014-05-29 04:14:42 -07001060};
1061
1062template<typename T> template<typename U> __declspec(dllexport) void CTMTR<T>::normalDef() {} // expected-error{{redeclaration of 'CTMTR::normalDef' cannot add 'dllexport' attribute}}
1063template<typename T> template<typename U> __declspec(dllexport) inline void CTMTR<T>::normalInlineDef() {} // expected-error{{redeclaration of 'CTMTR::normalInlineDef' cannot add 'dllexport' attribute}}
1064template<typename T> template<typename U> __declspec(dllexport) void CTMTR<T>::normalInlineDecl() {} // expected-error{{redeclaration of 'CTMTR::normalInlineDecl' cannot add 'dllexport' attribute}}
1065template<typename T> template<typename U> __declspec(dllexport) void CTMTR<T>::staticDef() {} // expected-error{{redeclaration of 'CTMTR::staticDef' cannot add 'dllexport' attribute}}
1066template<typename T> template<typename U> __declspec(dllexport) inline void CTMTR<T>::staticInlineDef() {} // expected-error{{redeclaration of 'CTMTR::staticInlineDef' cannot add 'dllexport' attribute}}
1067template<typename T> template<typename U> __declspec(dllexport) void CTMTR<T>::staticInlineDecl() {} // expected-error{{redeclaration of 'CTMTR::staticInlineDecl' cannot add 'dllexport' attribute}}
Stephen Hinesc568f1e2014-07-21 00:47:37 -07001068
1069#if __has_feature(cxx_variable_templates)
1070template<typename T> template<typename U> __declspec(dllexport) int CTMTR<T>::StaticField = 1; // expected-error{{redeclaration of 'CTMTR::StaticField' cannot add 'dllexport' attribute}}
1071template<typename T> template<typename U> __declspec(dllexport) const int CTMTR<T>::StaticConstField = 1; // expected-error{{redeclaration of 'CTMTR::StaticConstField' cannot add 'dllexport' attribute}}
1072template<typename T> template<typename U> __declspec(dllexport) constexpr int CTMTR<T>::ConstexprField; // expected-error{{redeclaration of 'CTMTR::ConstexprField' cannot add 'dllexport' attribute}}
1073#endif // __has_feature(cxx_variable_templates)
1074
1075// FIXME: Precedence rules seem to be different for classes.