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