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