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