Clang Project

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