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