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