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