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