• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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