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