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