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