]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - test/SemaCXX/dllimport.cpp
Vendor import of clang trunk r242221:
[FreeBSD/FreeBSD.git] / test / SemaCXX / dllimport.cpp
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 -DGNU %s
4 // RUN: %clang_cc1 -triple x86_64-mingw32 -fsyntax-only -fms-extensions -verify -std=c++11 -Wunsupported-dll-base-class-template -DGNU %s
5
6 // Helper structs to make templates more expressive.
7 struct ImplicitInst_Imported {};
8 struct ExplicitDecl_Imported {};
9 struct ExplicitInst_Imported {};
10 struct ExplicitSpec_Imported {};
11 struct ExplicitSpec_Def_Imported {};
12 struct ExplicitSpec_InlineDef_Imported {};
13 struct ExplicitSpec_NotImported {};
14 namespace { struct Internal {}; }
15
16
17 // Invalid usage.
18 __declspec(dllimport) typedef int typedef1; // expected-warning{{'dllimport' attribute only applies to variables, functions and classes}}
19 typedef __declspec(dllimport) int typedef2; // expected-warning{{'dllimport' attribute only applies to variables, functions and classes}}
20 typedef int __declspec(dllimport) typedef3; // expected-warning{{'dllimport' attribute only applies to variables, functions and classes}}
21 typedef __declspec(dllimport) void (*FunTy)(); // expected-warning{{'dllimport' attribute only applies to variables, functions and classes}}
22 enum __declspec(dllimport) Enum {}; // expected-warning{{'dllimport' attribute only applies to variables, functions and classes}}
23 #if __has_feature(cxx_strong_enums)
24   enum class __declspec(dllimport) EnumClass {}; // expected-warning{{'dllimport' attribute only applies to variables, functions and classes}}
25 #endif
26
27
28
29 //===----------------------------------------------------------------------===//
30 // Globals
31 //===----------------------------------------------------------------------===//
32
33 // Import declaration.
34 __declspec(dllimport) extern int ExternGlobalDecl;
35
36 // dllimport implies a declaration.
37 __declspec(dllimport) int GlobalDecl;
38 int **__attribute__((dllimport))* GlobalDeclChunkAttr;
39 int GlobalDeclAttr __attribute__((dllimport));
40
41 // Not allowed on definitions.
42 __declspec(dllimport) extern int ExternGlobalInit = 1; // expected-error{{definition of dllimport data}}
43 __declspec(dllimport) int GlobalInit1 = 1; // expected-error{{definition of dllimport data}}
44 int __declspec(dllimport) GlobalInit2 = 1; // expected-error{{definition of dllimport data}}
45
46 // Declare, then reject definition.
47 __declspec(dllimport) extern int ExternGlobalDeclInit; // expected-note{{previous declaration is here}} expected-note{{previous attribute is here}}
48 int ExternGlobalDeclInit = 1; // expected-warning{{'ExternGlobalDeclInit' redeclared without 'dllimport' attribute: previous 'dllimport' ignored}}
49
50 __declspec(dllimport) int GlobalDeclInit; // expected-note{{previous declaration is here}} expected-note{{previous attribute is here}}
51 int GlobalDeclInit = 1; // expected-warning{{'GlobalDeclInit' redeclared without 'dllimport' attribute: previous 'dllimport' ignored}}
52
53 int *__attribute__((dllimport)) GlobalDeclChunkAttrInit; // expected-note{{previous declaration is here}} expected-note{{previous attribute is here}}
54 int *GlobalDeclChunkAttrInit = 0; // expected-warning{{'GlobalDeclChunkAttrInit' redeclared without 'dllimport' attribute: previous 'dllimport' ignored}}
55
56 int GlobalDeclAttrInit __attribute__((dllimport)); // expected-note{{previous declaration is here}} expected-note{{previous attribute is here}}
57 int GlobalDeclAttrInit = 1; // expected-warning{{'GlobalDeclAttrInit' redeclared without 'dllimport' attribute: previous 'dllimport' ignored}}
58
59 // Redeclarations
60 __declspec(dllimport) extern int GlobalRedecl1;
61 __declspec(dllimport) extern int GlobalRedecl1;
62
63 __declspec(dllimport) int GlobalRedecl2a;
64 __declspec(dllimport) int GlobalRedecl2a;
65
66 int *__attribute__((dllimport)) GlobalRedecl2b;
67 int *__attribute__((dllimport)) GlobalRedecl2b;
68
69 int GlobalRedecl2c __attribute__((dllimport));
70 int GlobalRedecl2c __attribute__((dllimport));
71
72 // NB: MSVC issues a warning and makes GlobalRedecl3 dllexport. We follow GCC
73 // and drop the dllimport with a warning.
74 __declspec(dllimport) extern int GlobalRedecl3; // expected-note{{previous declaration is here}} expected-note{{previous attribute is here}}
75                       extern int GlobalRedecl3; // expected-warning{{'GlobalRedecl3' redeclared without 'dllimport' attribute: previous 'dllimport' ignored}}
76
77                       extern int GlobalRedecl4; // expected-note{{previous declaration is here}}
78 __declspec(dllimport) extern int GlobalRedecl4; // expected-warning{{redeclaration of 'GlobalRedecl4' should not add 'dllimport' attribute}}
79
80 extern "C" {
81                       extern int GlobalRedecl5; // expected-note{{previous declaration is here}}
82 __declspec(dllimport) extern int GlobalRedecl5; // expected-warning{{redeclaration of 'GlobalRedecl5' should not add 'dllimport' attribute}}
83 }
84
85 // External linkage is required.
86 __declspec(dllimport) static int StaticGlobal; // expected-error{{'StaticGlobal' must have external linkage when declared 'dllimport'}}
87 __declspec(dllimport) Internal InternalTypeGlobal; // expected-error{{'InternalTypeGlobal' must have external linkage when declared 'dllimport'}}
88 namespace    { __declspec(dllimport) int InternalGlobal; } // expected-error{{'(anonymous namespace)::InternalGlobal' must have external linkage when declared 'dllimport'}}
89 namespace ns { __declspec(dllimport) int ExternalGlobal; }
90
91 __declspec(dllimport) auto InternalAutoTypeGlobal = Internal(); // expected-error{{'InternalAutoTypeGlobal' must have external linkage when declared 'dllimport'}}
92                                                                 // expected-error@-1{{definition of dllimport data}}
93
94 // Thread local variables are invalid.
95 __declspec(dllimport) __thread int ThreadLocalGlobal; // expected-error{{'ThreadLocalGlobal' cannot be thread local when declared 'dllimport'}}
96
97 // Import in local scope.
98 __declspec(dllimport) float LocalRedecl1; // expected-note{{previous declaration is here}}
99 __declspec(dllimport) float LocalRedecl2; // expected-note{{previous declaration is here}}
100 __declspec(dllimport) float LocalRedecl3; // expected-note{{previous declaration is here}}
101 void functionScope() {
102   __declspec(dllimport) int LocalRedecl1; // expected-error{{redeclaration of 'LocalRedecl1' with a different type: 'int' vs 'float'}}
103   int *__attribute__((dllimport)) LocalRedecl2; // expected-error{{redeclaration of 'LocalRedecl2' with a different type: 'int *' vs 'float'}}
104   int LocalRedecl3 __attribute__((dllimport)); // expected-error{{redeclaration of 'LocalRedecl3' with a different type: 'int' vs 'float'}}
105
106   __declspec(dllimport)        int LocalVarDecl;
107   __declspec(dllimport)        int LocalVarDef = 1; // expected-error{{definition of dllimport data}}
108   __declspec(dllimport) extern int ExternLocalVarDecl;
109   __declspec(dllimport) extern int ExternLocalVarDef = 1; // expected-error{{definition of dllimport data}}
110   __declspec(dllimport) static int StaticLocalVar; // expected-error{{'StaticLocalVar' must have external linkage when declared 'dllimport'}}
111 }
112
113
114
115 //===----------------------------------------------------------------------===//
116 // Variable templates
117 //===----------------------------------------------------------------------===//
118 #if __has_feature(cxx_variable_templates)
119
120 // Import declaration.
121 template<typename T> __declspec(dllimport) extern int ExternVarTmplDecl;
122
123 // dllimport implies a declaration.
124 template<typename T> __declspec(dllimport) int VarTmplDecl;
125
126 // Not allowed on definitions.
127 template<typename T> __declspec(dllimport) extern int ExternVarTmplInit = 1; // expected-error{{definition of dllimport data}}
128 template<typename T> __declspec(dllimport) int VarTmplInit1 = 1; // expected-error{{definition of dllimport data}}
129 template<typename T> int __declspec(dllimport) VarTmplInit2 = 1; // expected-error{{definition of dllimport data}}
130
131 // Declare, then reject definition.
132 template<typename T> __declspec(dllimport) extern int ExternVarTmplDeclInit; // expected-note{{previous declaration is here}} expected-note{{previous attribute is here}}
133 template<typename T>                              int ExternVarTmplDeclInit = 1; // expected-warning{{'ExternVarTmplDeclInit' redeclared without 'dllimport' attribute: previous 'dllimport' ignored}}
134
135 template<typename T> __declspec(dllimport) int VarTmplDeclInit; // expected-note{{previous declaration is here}} expected-note{{previous attribute is here}}
136 template<typename T>                       int VarTmplDeclInit = 1; // expected-warning{{'VarTmplDeclInit' redeclared without 'dllimport' attribute: previous 'dllimport' ignored}}
137
138 // Redeclarations
139 template<typename T> __declspec(dllimport) extern int VarTmplRedecl1;
140 template<typename T> __declspec(dllimport) extern int VarTmplRedecl1;
141
142 template<typename T> __declspec(dllimport) int VarTmplRedecl2;
143 template<typename T> __declspec(dllimport) int VarTmplRedecl2;
144
145 template<typename T> __declspec(dllimport) extern int VarTmplRedecl3; // expected-note{{previous declaration is here}} expected-note{{previous attribute is here}}
146 template<typename T>                       extern int VarTmplRedecl3; // expected-warning{{'VarTmplRedecl3' redeclared without 'dllimport' attribute: previous 'dllimport' ignored}}
147
148 template<typename T>                       extern int VarTmplRedecl4; // expected-note{{previous declaration is here}}
149 template<typename T> __declspec(dllimport) extern int VarTmplRedecl4; // expected-error{{redeclaration of 'VarTmplRedecl4' cannot add 'dllimport' attribute}}
150
151 // External linkage is required.
152 template<typename T> __declspec(dllimport) static int StaticVarTmpl; // expected-error{{'StaticVarTmpl' must have external linkage when declared 'dllimport'}}
153 template<typename T> __declspec(dllimport) Internal InternalTypeVarTmpl; // expected-error{{'InternalTypeVarTmpl' must have external linkage when declared 'dllimport'}}
154 namespace    { template<typename T> __declspec(dllimport) int InternalVarTmpl; } // expected-error{{'(anonymous namespace)::InternalVarTmpl' must have external linkage when declared 'dllimport'}}
155 namespace ns { template<typename T> __declspec(dllimport) int ExternalVarTmpl; }
156
157 template<typename T> __declspec(dllimport) auto InternalAutoTypeVarTmpl = Internal(); // expected-error{{definition of dllimport data}} // expected-error{{'InternalAutoTypeVarTmpl' must have external linkage when declared 'dllimport'}}
158
159
160 template<typename T> int VarTmpl;
161 template<typename T> __declspec(dllimport) int ImportedVarTmpl;
162
163 // Import implicit instantiation of an imported variable template.
164 int useVarTmpl() { return ImportedVarTmpl<ImplicitInst_Imported>; }
165
166 // Import explicit instantiation declaration of an imported variable template.
167 extern template int ImportedVarTmpl<ExplicitDecl_Imported>;
168
169 // An explicit instantiation definition of an imported variable template cannot
170 // be imported because the template must be defined which is illegal.
171
172 // Import specialization of an imported variable template.
173 template<> __declspec(dllimport) int ImportedVarTmpl<ExplicitSpec_Imported>;
174 template<> __declspec(dllimport) int ImportedVarTmpl<ExplicitSpec_Def_Imported> = 1; // expected-error{{definition of dllimport data}}
175
176 // Not importing specialization of an imported variable template without
177 // explicit dllimport.
178 template<> int ImportedVarTmpl<ExplicitSpec_NotImported>;
179
180
181 // Import explicit instantiation declaration of a non-imported variable template.
182 extern template __declspec(dllimport) int VarTmpl<ExplicitDecl_Imported>;
183
184 // Import explicit instantiation definition of a non-imported variable template.
185 template __declspec(dllimport) int VarTmpl<ExplicitInst_Imported>;
186
187 // Import specialization of a non-imported variable template.
188 template<> __declspec(dllimport) int VarTmpl<ExplicitSpec_Imported>;
189 template<> __declspec(dllimport) int VarTmpl<ExplicitSpec_Def_Imported> = 1; // expected-error{{definition of dllimport data}}
190
191 #endif // __has_feature(cxx_variable_templates)
192
193
194 //===----------------------------------------------------------------------===//
195 // Functions
196 //===----------------------------------------------------------------------===//
197
198 // Import function declaration. Check different placements.
199 __attribute__((dllimport)) void decl1A(); // Sanity check with __attribute__
200 __declspec(dllimport)      void decl1B();
201
202 void __attribute__((dllimport)) decl2A();
203 void __declspec(dllimport)      decl2B();
204
205 // Not allowed on function definitions.
206 __declspec(dllimport) void def() {} // expected-error{{dllimport cannot be applied to non-inline function definition}}
207
208 // extern  "C"
209 extern "C" __declspec(dllimport) void externC();
210
211 // Import inline function.
212 #ifdef GNU
213 // expected-warning@+3{{'dllimport' attribute ignored on inline function}}
214 // expected-warning@+3{{'dllimport' attribute ignored on inline function}}
215 #endif
216 __declspec(dllimport) inline void inlineFunc1() {}
217 inline void __attribute__((dllimport)) inlineFunc2() {}
218
219 #ifdef GNU
220 // expected-warning@+2{{'dllimport' attribute ignored on inline function}}
221 #endif
222 __declspec(dllimport) inline void inlineDecl();
223                              void inlineDecl() {}
224
225 __declspec(dllimport) void inlineDef();
226 #ifdef GNU
227 // expected-warning@+2{{'inlineDef' redeclared inline; 'dllimport' attribute ignored}}
228 #endif
229                inline void inlineDef() {}
230
231 // Redeclarations
232 __declspec(dllimport) void redecl1();
233 __declspec(dllimport) void redecl1();
234
235 // NB: MSVC issues a warning and makes redecl2/redecl3 dllexport. We follow GCC
236 // and drop the dllimport with a warning.
237 __declspec(dllimport) void redecl2(); // expected-note{{previous declaration is here}} expected-note{{previous attribute is here}}
238                       void redecl2(); // expected-warning{{'redecl2' redeclared without 'dllimport' attribute: previous 'dllimport' ignored}}
239
240 __declspec(dllimport) void redecl3(); // expected-note{{previous declaration is here}} expected-note{{previous attribute is here}}
241                       void redecl3() {} // expected-warning{{'redecl3' redeclared without 'dllimport' attribute: previous 'dllimport' ignored}}
242
243                       void redecl4(); // expected-note{{previous declaration is here}}
244 __declspec(dllimport) void redecl4(); // expected-warning{{redeclaration of 'redecl4' should not add 'dllimport' attribute}}
245
246 extern "C" {
247                       void redecl5(); // expected-note{{previous declaration is here}}
248 __declspec(dllimport) void redecl5(); // expected-warning{{redeclaration of 'redecl5' should not add 'dllimport' attribute}}
249 }
250
251 #ifdef MS
252                       void redecl6(); // expected-note{{previous declaration is here}}
253 __declspec(dllimport) inline void redecl6() {} // expected-warning{{redeclaration of 'redecl6' should not add 'dllimport' attribute}}
254 #else
255                       void redecl6();
256 __declspec(dllimport) inline void redecl6() {} // expected-warning{{'dllimport' attribute ignored on inline function}}
257 #endif
258
259 // Friend functions
260 struct FuncFriend {
261   friend __declspec(dllimport) void friend1();
262   friend __declspec(dllimport) void friend2(); // expected-note{{previous declaration is here}} expected-note{{previous attribute is here}}
263   friend __declspec(dllimport) void friend3(); // expected-note{{previous declaration is here}} expected-note{{previous attribute is here}}
264   friend                       void friend4(); // expected-note{{previous declaration is here}}
265 #ifdef MS
266 // expected-note@+2{{previous declaration is here}}
267 #endif
268   friend                       void friend5();
269 };
270 __declspec(dllimport) void friend1();
271                       void friend2(); // expected-warning{{'friend2' redeclared without 'dllimport' attribute: previous 'dllimport' ignored}}
272                       void friend3() {} // expected-warning{{'friend3' redeclared without 'dllimport' attribute: previous 'dllimport' ignored}}
273 __declspec(dllimport) void friend4(); // expected-warning{{redeclaration of 'friend4' should not add 'dllimport' attribute}}
274 #ifdef MS
275 __declspec(dllimport) inline void friend5() {} // expected-warning{{redeclaration of 'friend5' should not add 'dllimport' attribute}}
276 #else
277 __declspec(dllimport) inline void friend5() {} // expected-warning{{'dllimport' attribute ignored on inline function}}
278 #endif
279
280
281 void __declspec(dllimport) friend6(); // expected-note{{previous declaration is here}} expected-note{{previous attribute is here}}
282 void __declspec(dllimport) friend7();
283 struct FuncFriend2 {
284   friend void friend6(); // expected-warning{{'friend6' redeclared without 'dllimport' attribute: previous 'dllimport' ignored}}
285   friend void ::friend7();
286 };
287
288 // Implicit declarations can be redeclared with dllimport.
289 __declspec(dllimport) void* operator new(__SIZE_TYPE__ n);
290
291 // External linkage is required.
292 __declspec(dllimport) static int staticFunc(); // expected-error{{'staticFunc' must have external linkage when declared 'dllimport'}}
293 __declspec(dllimport) Internal internalRetFunc(); // expected-error{{'internalRetFunc' must have external linkage when declared 'dllimport'}}
294 namespace    { __declspec(dllimport) void internalFunc(); } // expected-error{{'(anonymous namespace)::internalFunc' must have external linkage when declared 'dllimport'}}
295 namespace ns { __declspec(dllimport) void externalFunc(); }
296
297 // Import deleted functions.
298 // FIXME: Deleted functions are definitions so a missing inline is diagnosed
299 // here which is irrelevant. But because the delete keyword is parsed later
300 // there is currently no straight-forward way to avoid this diagnostic.
301 __declspec(dllimport) void deletedFunc() = delete; // expected-error{{attribute 'dllimport' cannot be applied to a deleted function}} expected-error{{dllimport cannot be applied to non-inline function definition}}
302 #ifdef MS
303 __declspec(dllimport) inline void deletedInlineFunc() = delete; // expected-error{{attribute 'dllimport' cannot be applied to a deleted function}}
304 #else
305 __declspec(dllimport) inline void deletedInlineFunc() = delete; // expected-warning{{'dllimport' attribute ignored on inline function}}
306 #endif
307
308
309
310 //===----------------------------------------------------------------------===//
311 // Function templates
312 //===----------------------------------------------------------------------===//
313
314 // Import function template declaration. Check different placements.
315 template<typename T> __declspec(dllimport) void funcTmplDecl1();
316 template<typename T> void __declspec(dllimport) funcTmplDecl2();
317
318 // Import function template definition.
319 template<typename T> __declspec(dllimport) void funcTmplDef() {} // expected-error{{dllimport cannot be applied to non-inline function definition}}
320
321 // Import inline function template.
322 #ifdef GNU
323 // expected-warning@+5{{'dllimport' attribute ignored on inline function}}
324 // expected-warning@+5{{'dllimport' attribute ignored on inline function}}
325 // expected-warning@+6{{'dllimport' attribute ignored on inline function}}
326 // expected-warning@+9{{'inlineFuncTmplDef' redeclared inline; 'dllimport' attribute ignored}}
327 #endif
328 template<typename T> __declspec(dllimport) inline void inlineFuncTmpl1() {}
329 template<typename T> inline void __attribute__((dllimport)) inlineFuncTmpl2() {}
330
331 template<typename T> __declspec(dllimport) inline void inlineFuncTmplDecl();
332 template<typename T>                              void inlineFuncTmplDecl() {}
333
334 template<typename T> __declspec(dllimport) void inlineFuncTmplDef();
335 template<typename T>                inline void inlineFuncTmplDef() {}
336
337 // Redeclarations
338 template<typename T> __declspec(dllimport) void funcTmplRedecl1();
339 template<typename T> __declspec(dllimport) void funcTmplRedecl1();
340
341 template<typename T> __declspec(dllimport) void funcTmplRedecl2(); // expected-note{{previous declaration is here}} expected-note{{previous attribute is here}}
342 template<typename T>                       void funcTmplRedecl2(); // expected-warning{{'funcTmplRedecl2' redeclared without 'dllimport' attribute: previous 'dllimport' ignored}}
343
344 template<typename T> __declspec(dllimport) void funcTmplRedecl3(); // expected-note{{previous declaration is here}} expected-note{{previous attribute is here}}
345 template<typename T>                       void funcTmplRedecl3() {} // expected-warning{{'funcTmplRedecl3' redeclared without 'dllimport' attribute: previous 'dllimport' ignored}}
346
347 template<typename T>                       void funcTmplRedecl4(); // expected-note{{previous declaration is here}}
348 template<typename T> __declspec(dllimport) void funcTmplRedecl4(); // expected-error{{redeclaration of 'funcTmplRedecl4' cannot add 'dllimport' attribute}}
349
350 #ifdef MS
351 template<typename T>                       void funcTmplRedecl5(); // expected-note{{previous declaration is here}}
352 template<typename T> __declspec(dllimport) inline void funcTmplRedecl5() {} // expected-error{{redeclaration of 'funcTmplRedecl5' cannot add 'dllimport' attribute}}
353 #endif
354
355 // Function template friends
356 struct FuncTmplFriend {
357   template<typename T> friend __declspec(dllimport) void funcTmplFriend1();
358   template<typename T> friend __declspec(dllimport) void funcTmplFriend2(); // expected-note{{previous declaration is here}} expected-note{{previous attribute is here}}
359   template<typename T> friend __declspec(dllimport) void funcTmplFriend3(); // expected-note{{previous declaration is here}} expected-note{{previous attribute is here}}
360   template<typename T> friend                       void funcTmplFriend4(); // expected-note{{previous declaration is here}}
361 #ifdef GNU
362 // expected-warning@+2{{'dllimport' attribute ignored on inline function}}
363 #endif
364   template<typename T> friend __declspec(dllimport) inline void funcTmplFriend5();
365 };
366 template<typename T> __declspec(dllimport) void funcTmplFriend1();
367 template<typename T>                       void funcTmplFriend2(); // expected-warning{{'funcTmplFriend2' redeclared without 'dllimport' attribute: previous 'dllimport' ignored}}
368 template<typename T>                       void funcTmplFriend3() {} // expected-warning{{'funcTmplFriend3' redeclared without 'dllimport' attribute: previous 'dllimport' ignored}}
369 template<typename T> __declspec(dllimport) void funcTmplFriend4(); // expected-error{{redeclaration of 'funcTmplFriend4' cannot add 'dllimport' attribute}}
370 template<typename T>                       inline void funcTmplFriend5() {}
371
372 // External linkage is required.
373 template<typename T> __declspec(dllimport) static int staticFuncTmpl(); // expected-error{{'staticFuncTmpl' must have external linkage when declared 'dllimport'}}
374 template<typename T> __declspec(dllimport) Internal internalRetFuncTmpl(); // expected-error{{'internalRetFuncTmpl' must have external linkage when declared 'dllimport'}}
375 namespace    { template<typename T> __declspec(dllimport) void internalFuncTmpl(); } // expected-error{{'(anonymous namespace)::internalFuncTmpl' must have external linkage when declared 'dllimport'}}
376 namespace ns { template<typename T> __declspec(dllimport) void externalFuncTmpl(); }
377
378
379 template<typename T> void funcTmpl() {}
380 template<typename T> inline void inlineFuncTmpl() {}
381 template<typename T> __declspec(dllimport) void importedFuncTmplDecl();
382 #ifdef GNU
383 // expected-warning@+2{{'dllimport' attribute ignored on inline function}}
384 #endif
385 template<typename T> __declspec(dllimport) inline void importedFuncTmpl() {}
386
387 // Import implicit instantiation of an imported function template.
388 void useFunTmplDecl() { importedFuncTmplDecl<ImplicitInst_Imported>(); }
389 void useFunTmplDef() { importedFuncTmpl<ImplicitInst_Imported>(); }
390
391 // Import explicit instantiation declaration of an imported function template.
392 extern template void importedFuncTmpl<ExplicitDecl_Imported>();
393
394 // Import explicit instantiation definition of an imported function template.
395 // NB: MSVC fails this instantiation without explicit dllimport which is most
396 // likely a bug because an implicit instantiation is accepted.
397 template void importedFuncTmpl<ExplicitInst_Imported>();
398
399 // Import specialization of an imported function template. A definition must be
400 // declared inline.
401 template<> __declspec(dllimport) void importedFuncTmpl<ExplicitSpec_Imported>();
402 template<> __declspec(dllimport) void importedFuncTmpl<ExplicitSpec_Def_Imported>() {} // expected-error{{dllimport cannot be applied to non-inline function definition}}
403 #ifdef MS
404 template<> __declspec(dllimport) inline void importedFuncTmpl<ExplicitSpec_InlineDef_Imported>() {}
405 #endif
406
407 // Not importing specialization of an imported function template without
408 // explicit dllimport.
409 template<> void importedFuncTmpl<ExplicitSpec_NotImported>() {}
410
411
412 // Import explicit instantiation declaration of a non-imported function template.
413 extern template __declspec(dllimport) void funcTmpl<ExplicitDecl_Imported>();
414 #ifdef GNU
415 // expected-warning@+2{{'dllimport' attribute ignored on inline function}}
416 #endif
417 extern template __declspec(dllimport) void inlineFuncTmpl<ExplicitDecl_Imported>();
418
419 // Import explicit instantiation definition of a non-imported function template.
420 template __declspec(dllimport) void funcTmpl<ExplicitInst_Imported>();
421 #ifdef GNU
422 // expected-warning@+2{{'dllimport' attribute ignored on inline function}}
423 #endif
424 template __declspec(dllimport) void inlineFuncTmpl<ExplicitInst_Imported>();
425
426 // Import specialization of a non-imported function template. A definition must
427 // be declared inline.
428 template<> __declspec(dllimport) void funcTmpl<ExplicitSpec_Imported>();
429 template<> __declspec(dllimport) void funcTmpl<ExplicitSpec_Def_Imported>() {} // expected-error{{dllimport cannot be applied to non-inline function definition}}
430 #ifdef GNU
431 // expected-warning@+2{{'dllimport' attribute ignored on inline function}}
432 #endif
433 template<> __declspec(dllimport) inline void funcTmpl<ExplicitSpec_InlineDef_Imported>() {}
434
435
436 //===----------------------------------------------------------------------===//
437 // Class members
438 //===----------------------------------------------------------------------===//
439
440 // Import individual members of a class.
441 struct ImportMembers {
442   struct Nested {
443     __declspec(dllimport) void normalDecl();
444     __declspec(dllimport) void normalDef(); // expected-note{{previous declaration is here}} expected-note{{previous attribute is here}}
445   };
446
447 #ifdef GNU
448 // expected-warning@+5{{'dllimport' attribute ignored on inline function}}
449 // expected-warning@+6{{'dllimport' attribute ignored on inline function}}
450 #endif
451   __declspec(dllimport)                void normalDecl();
452   __declspec(dllimport)                void normalDef(); // expected-note{{previous declaration is here}} expected-note{{previous attribute is here}}
453   __declspec(dllimport)                void normalInclass() {}
454   __declspec(dllimport)                void normalInlineDef();
455   __declspec(dllimport)         inline void normalInlineDecl();
456 #ifdef GNU
457 // expected-warning@+5{{'dllimport' attribute ignored on inline function}}
458 // expected-warning@+6{{'dllimport' attribute ignored on inline function}}
459 #endif
460   __declspec(dllimport) virtual        void virtualDecl();
461   __declspec(dllimport) virtual        void virtualDef(); // expected-note{{previous declaration is here}} expected-note{{previous attribute is here}}
462   __declspec(dllimport) virtual        void virtualInclass() {}
463   __declspec(dllimport) virtual        void virtualInlineDef();
464   __declspec(dllimport) virtual inline void virtualInlineDecl();
465 #ifdef GNU
466 // expected-warning@+5{{'dllimport' attribute ignored on inline function}}
467 // expected-warning@+6{{'dllimport' attribute ignored on inline function}}
468 #endif
469   __declspec(dllimport) static         void staticDecl();
470   __declspec(dllimport) static         void staticDef(); // expected-note{{previous declaration is here}} expected-note{{previous attribute is here}}
471   __declspec(dllimport) static         void staticInclass() {}
472   __declspec(dllimport) static         void staticInlineDef();
473   __declspec(dllimport) static  inline void staticInlineDecl();
474
475 protected:
476   __declspec(dllimport)                void protectedDecl();
477 private:
478   __declspec(dllimport)                void privateDecl();
479 public:
480
481   __declspec(dllimport)                int  Field; // expected-warning{{'dllimport' attribute only applies to variables, functions and classes}}
482   __declspec(dllimport) static         int  StaticField;
483   __declspec(dllimport) static         int  StaticFieldDef; // expected-note{{attribute is here}}
484   __declspec(dllimport) static  const  int  StaticConstField;
485   __declspec(dllimport) static  const  int  StaticConstFieldDef; // expected-note{{attribute is here}}
486   __declspec(dllimport) static  const  int  StaticConstFieldEqualInit = 1;
487   __declspec(dllimport) static  const  int  StaticConstFieldBraceInit{1};
488   __declspec(dllimport) constexpr static int ConstexprField = 1;
489   __declspec(dllimport) constexpr static int ConstexprFieldDef = 1; // expected-note{{attribute is here}}
490 };
491
492        void ImportMembers::Nested::normalDef() {} // expected-warning{{'ImportMembers::Nested::normalDef' redeclared without 'dllimport' attribute: previous 'dllimport' ignored}}
493        void ImportMembers::normalDef() {} // expected-warning{{'ImportMembers::normalDef' redeclared without 'dllimport' attribute: previous 'dllimport' ignored}}
494 #ifdef GNU
495 // expected-warning@+2{{'ImportMembers::normalInlineDef' redeclared inline; 'dllimport' attribute ignored}}
496 #endif
497 inline void ImportMembers::normalInlineDef() {}
498        void ImportMembers::normalInlineDecl() {}
499        void ImportMembers::virtualDef() {} // expected-warning{{'ImportMembers::virtualDef' redeclared without 'dllimport' attribute: previous 'dllimport' ignored}}
500 #ifdef GNU
501 // expected-warning@+2{{'ImportMembers::virtualInlineDef' redeclared inline; 'dllimport' attribute ignored}}
502 #endif
503 inline void ImportMembers::virtualInlineDef() {}
504        void ImportMembers::virtualInlineDecl() {}
505        void ImportMembers::staticDef() {} // expected-warning{{'ImportMembers::staticDef' redeclared without 'dllimport' attribute: previous 'dllimport' ignored}}
506 #ifdef GNU
507 // expected-warning@+2{{'ImportMembers::staticInlineDef' redeclared inline; 'dllimport' attribute ignored}}
508 #endif
509 inline void ImportMembers::staticInlineDef() {}
510        void ImportMembers::staticInlineDecl() {}
511
512        int  ImportMembers::StaticFieldDef; // expected-error{{definition of dllimport static field not allowed}}
513 const  int  ImportMembers::StaticConstFieldDef = 1; // expected-error{{definition of dllimport static field not allowed}}
514 constexpr int ImportMembers::ConstexprFieldDef; // expected-error{{definition of dllimport static field not allowed}}
515
516
517 // Import on member definitions.
518 struct ImportMemberDefs {
519   __declspec(dllimport)                void normalDef();
520   __declspec(dllimport)                void normalInlineDef();
521   __declspec(dllimport) virtual        void virtualDef();
522   __declspec(dllimport) virtual        void virtualInlineDef();
523   __declspec(dllimport) static         void staticDef();
524   __declspec(dllimport) static         void staticInlineDef();
525 #ifdef MS
526   __declspec(dllimport)         inline void normalInlineDecl();
527   __declspec(dllimport) virtual inline void virtualInlineDecl();
528   __declspec(dllimport) static  inline void staticInlineDecl();
529 #endif
530
531   __declspec(dllimport) static         int  StaticField;
532   __declspec(dllimport) static  const  int  StaticConstField;
533   __declspec(dllimport) constexpr static int ConstexprField = 1;
534 };
535
536 __declspec(dllimport)        void ImportMemberDefs::normalDef() {} // expected-error{{dllimport cannot be applied to non-inline function definition}}
537 __declspec(dllimport)        void ImportMemberDefs::virtualDef() {} // expected-error{{dllimport cannot be applied to non-inline function definition}}
538 __declspec(dllimport)        void ImportMemberDefs::staticDef() {} // expected-error{{dllimport cannot be applied to non-inline function definition}}
539 #ifdef MS
540 __declspec(dllimport) inline void ImportMemberDefs::normalInlineDef() {}
541 __declspec(dllimport)        void ImportMemberDefs::normalInlineDecl() {}
542 __declspec(dllimport) inline void ImportMemberDefs::virtualInlineDef() {}
543 __declspec(dllimport)        void ImportMemberDefs::virtualInlineDecl() {}
544 __declspec(dllimport) inline void ImportMemberDefs::staticInlineDef() {}
545 __declspec(dllimport)        void ImportMemberDefs::staticInlineDecl() {}
546 #endif
547
548 __declspec(dllimport)        int  ImportMemberDefs::StaticField; // expected-error{{definition of dllimport static field not allowed}} expected-note{{attribute is here}}
549 __declspec(dllimport) const  int  ImportMemberDefs::StaticConstField = 1; // expected-error{{definition of dllimport static field not allowed}} expected-note{{attribute is here}}
550 __declspec(dllimport) constexpr int ImportMemberDefs::ConstexprField; // expected-error{{definition of dllimport static field not allowed}} expected-note{{attribute is here}}
551
552
553 // Import special member functions.
554 struct ImportSpecials {
555   __declspec(dllimport) ImportSpecials();
556   __declspec(dllimport) ~ImportSpecials();
557   __declspec(dllimport) ImportSpecials(const ImportSpecials&);
558   __declspec(dllimport) ImportSpecials& operator=(const ImportSpecials&);
559   __declspec(dllimport) ImportSpecials(ImportSpecials&&);
560   __declspec(dllimport) ImportSpecials& operator=(ImportSpecials&&);
561 };
562
563
564 // Import deleted member functions.
565 struct ImportDeleted {
566 #ifdef MS
567   __declspec(dllimport) ImportDeleted() = delete; // expected-error{{attribute 'dllimport' cannot be applied to a deleted function}}
568   __declspec(dllimport) ~ImportDeleted() = delete; // expected-error{{attribute 'dllimport' cannot be applied to a deleted function}}
569   __declspec(dllimport) ImportDeleted(const ImportDeleted&) = delete; // expected-error{{attribute 'dllimport' cannot be applied to a deleted function}}
570   __declspec(dllimport) ImportDeleted& operator=(const ImportDeleted&) = delete; // expected-error{{attribute 'dllimport' cannot be applied to a deleted function}}
571   __declspec(dllimport) ImportDeleted(ImportDeleted&&) = delete; // expected-error{{attribute 'dllimport' cannot be applied to a deleted function}}
572   __declspec(dllimport) ImportDeleted& operator=(ImportDeleted&&) = delete; // expected-error{{attribute 'dllimport' cannot be applied to a deleted function}}
573   __declspec(dllimport) void deleted() = delete; // expected-error{{attribute 'dllimport' cannot be applied to a deleted function}}
574 #else
575   __declspec(dllimport) ImportDeleted() = delete; // expected-warning{{'dllimport' attribute ignored on inline function}}
576   __declspec(dllimport) ~ImportDeleted() = delete; // expected-warning{{'dllimport' attribute ignored on inline function}}
577   __declspec(dllimport) ImportDeleted(const ImportDeleted&) = delete; // expected-warning{{'dllimport' attribute ignored on inline function}}
578   __declspec(dllimport) ImportDeleted& operator=(const ImportDeleted&) = delete; // expected-warning{{'dllimport' attribute ignored on inline function}}
579   __declspec(dllimport) ImportDeleted(ImportDeleted&&) = delete; // expected-warning{{'dllimport' attribute ignored on inline function}}
580   __declspec(dllimport) ImportDeleted& operator=(ImportDeleted&&) = delete; // expected-warning{{'dllimport' attribute ignored on inline function}}
581   __declspec(dllimport) void deleted() = delete; // expected-warning{{'dllimport' attribute ignored on inline function}}
582 #endif
583 };
584
585
586 // Import allocation functions.
587 struct ImportAlloc {
588   __declspec(dllimport) void* operator new(__SIZE_TYPE__);
589   __declspec(dllimport) void* operator new[](__SIZE_TYPE__);
590   __declspec(dllimport) void operator delete(void*);
591   __declspec(dllimport) void operator delete[](void*);
592 };
593
594
595 // Import defaulted member functions.
596 struct ImportDefaulted {
597 #ifdef GNU
598   // expected-warning@+7{{'dllimport' attribute ignored on inline function}}
599   // expected-warning@+7{{'dllimport' attribute ignored on inline function}}
600   // expected-warning@+7{{'dllimport' attribute ignored on inline function}}
601   // expected-warning@+7{{'dllimport' attribute ignored on inline function}}
602   // expected-warning@+7{{'dllimport' attribute ignored on inline function}}
603   // expected-warning@+7{{'dllimport' attribute ignored on inline function}}
604 #endif
605   __declspec(dllimport) ImportDefaulted() = default;
606   __declspec(dllimport) ~ImportDefaulted() = default;
607   __declspec(dllimport) ImportDefaulted(const ImportDefaulted&) = default;
608   __declspec(dllimport) ImportDefaulted& operator=(const ImportDefaulted&) = default;
609   __declspec(dllimport) ImportDefaulted(ImportDefaulted&&) = default;
610   __declspec(dllimport) ImportDefaulted& operator=(ImportDefaulted&&) = default;
611 };
612
613
614 // Import defaulted member function definitions.
615 struct ImportDefaultedDefs {
616   __declspec(dllimport) ImportDefaultedDefs();
617   __declspec(dllimport) ~ImportDefaultedDefs(); // expected-note{{previous declaration is here}} expected-note{{previous attribute is here}}
618
619 #ifdef GNU
620 // expected-warning@+3{{'dllimport' attribute ignored on inline function}}
621 // expected-note@+2{{previous declaration is here}}
622 #endif
623   __declspec(dllimport) inline ImportDefaultedDefs(const ImportDefaultedDefs&);
624   __declspec(dllimport) ImportDefaultedDefs& operator=(const ImportDefaultedDefs&);
625
626   __declspec(dllimport) ImportDefaultedDefs(ImportDefaultedDefs&&);
627   __declspec(dllimport) ImportDefaultedDefs& operator=(ImportDefaultedDefs&&); // expected-note{{previous declaration is here}} expected-note{{previous attribute is here}}
628 };
629
630 // Not allowed on definitions.
631 __declspec(dllimport) ImportDefaultedDefs::ImportDefaultedDefs() = default; // expected-error{{dllimport cannot be applied to non-inline function definition}}
632
633 // dllimport cannot be dropped.
634 ImportDefaultedDefs::~ImportDefaultedDefs() = default; // expected-warning{{'ImportDefaultedDefs::~ImportDefaultedDefs' redeclared without 'dllimport' attribute: previous 'dllimport' ignored}}
635
636 // Import inline declaration and definition.
637 #ifdef GNU
638 // expected-error@+3{{redeclaration of 'ImportDefaultedDefs::ImportDefaultedDefs' cannot add 'dllimport' attribute}}
639 // expected-warning@+3{{'ImportDefaultedDefs::operator=' redeclared inline; 'dllimport' attribute ignored}}
640 #endif
641 __declspec(dllimport) ImportDefaultedDefs::ImportDefaultedDefs(const ImportDefaultedDefs&) = default;
642 inline ImportDefaultedDefs& ImportDefaultedDefs::operator=(const ImportDefaultedDefs&) = default;
643
644 __declspec(dllimport) ImportDefaultedDefs::ImportDefaultedDefs(ImportDefaultedDefs&&) = default; // expected-error{{dllimport cannot be applied to non-inline function definition}}
645 ImportDefaultedDefs& ImportDefaultedDefs::operator=(ImportDefaultedDefs&&) = default; // expected-warning{{'ImportDefaultedDefs::operator=' redeclared without 'dllimport' attribute: previous 'dllimport' ignored}}
646
647
648 // Redeclarations cannot add dllimport.
649 struct MemberRedecl {
650                  void normalDef();         // expected-note{{previous declaration is here}}
651           inline void normalInlineDecl();  // expected-note{{previous declaration is here}}
652   virtual        void virtualDef();        // expected-note{{previous declaration is here}}
653   virtual inline void virtualInlineDecl(); // expected-note{{previous declaration is here}}
654   static         void staticDef();         // expected-note{{previous declaration is here}}
655   static  inline void staticInlineDecl();  // expected-note{{previous declaration is here}}
656
657 #ifdef MS
658   // expected-note@+4{{previous declaration is here}}
659   // expected-note@+4{{previous declaration is here}}
660   // expected-note@+4{{previous declaration is here}}
661 #endif
662                  void normalInlineDef();
663   virtual        void virtualInlineDef();
664   static         void staticInlineDef();
665
666   static         int  StaticField;         // expected-note{{previous declaration is here}}
667   static  const  int  StaticConstField;    // expected-note{{previous declaration is here}}
668   constexpr static int ConstexprField = 1; // expected-note{{previous declaration is here}}
669 };
670
671 __declspec(dllimport)        void MemberRedecl::normalDef() {}         // expected-error{{redeclaration of 'MemberRedecl::normalDef' cannot add 'dllimport' attribute}}
672                                                                        // expected-error@-1{{dllimport cannot be applied to non-inline function definition}}
673 __declspec(dllimport)        void MemberRedecl::normalInlineDecl() {}  // expected-error{{redeclaration of 'MemberRedecl::normalInlineDecl' cannot add 'dllimport' attribute}}
674 __declspec(dllimport)        void MemberRedecl::virtualDef() {}        // expected-error{{redeclaration of 'MemberRedecl::virtualDef' cannot add 'dllimport' attribute}}
675                                                                        // expected-error@-1{{dllimport cannot be applied to non-inline function definition}}
676 __declspec(dllimport)        void MemberRedecl::virtualInlineDecl() {} // expected-error{{redeclaration of 'MemberRedecl::virtualInlineDecl' cannot add 'dllimport' attribute}}
677 __declspec(dllimport)        void MemberRedecl::staticDef() {}         // expected-error{{redeclaration of 'MemberRedecl::staticDef' cannot add 'dllimport' attribute}}
678                                                                        // expected-error@-1{{dllimport cannot be applied to non-inline function definition}}
679 __declspec(dllimport)        void MemberRedecl::staticInlineDecl() {}  // expected-error{{redeclaration of 'MemberRedecl::staticInlineDecl' cannot add 'dllimport' attribute}}
680
681 #ifdef MS
682 __declspec(dllimport) inline void MemberRedecl::normalInlineDef() {}   // expected-error{{redeclaration of 'MemberRedecl::normalInlineDef' cannot add 'dllimport' attribute}}
683 __declspec(dllimport) inline void MemberRedecl::virtualInlineDef() {}  // expected-error{{redeclaration of 'MemberRedecl::virtualInlineDef' cannot add 'dllimport' attribute}}
684 __declspec(dllimport) inline void MemberRedecl::staticInlineDef() {}   // expected-error{{redeclaration of 'MemberRedecl::staticInlineDef' cannot add 'dllimport' attribute}}
685 #else
686 __declspec(dllimport) inline void MemberRedecl::normalInlineDef() {}   // expected-warning{{'dllimport' attribute ignored on inline function}}
687 __declspec(dllimport) inline void MemberRedecl::virtualInlineDef() {}  // expected-warning{{'dllimport' attribute ignored on inline function}}
688 __declspec(dllimport) inline void MemberRedecl::staticInlineDef() {}   // expected-warning{{'dllimport' attribute ignored on inline function}}
689 #endif
690
691
692
693 __declspec(dllimport)        int  MemberRedecl::StaticField = 1;       // expected-error{{redeclaration of 'MemberRedecl::StaticField' cannot add 'dllimport' attribute}}
694                                                                        // expected-error@-1{{definition of dllimport static field not allowed}}
695                                                                        // expected-note@-2{{attribute is here}}
696 __declspec(dllimport) const  int  MemberRedecl::StaticConstField = 1;  // expected-error{{redeclaration of 'MemberRedecl::StaticConstField' cannot add 'dllimport' attribute}}
697                                                                        // expected-error@-1{{definition of dllimport static field not allowed}}
698                                                                        // expected-note@-2{{attribute is here}}
699 __declspec(dllimport) constexpr int MemberRedecl::ConstexprField;      // expected-error{{redeclaration of 'MemberRedecl::ConstexprField' cannot add 'dllimport' attribute}}
700                                                                        // expected-error@-1{{definition of dllimport static field not allowed}}
701                                                                        // expected-note@-2{{attribute is here}}
702
703
704
705 //===----------------------------------------------------------------------===//
706 // Class member templates
707 //===----------------------------------------------------------------------===//
708
709 struct ImportMemberTmpl {
710   template<typename T> __declspec(dllimport)               void normalDecl();
711   template<typename T> __declspec(dllimport)               void normalDef(); // expected-note{{previous declaration is here}} expected-note{{previous attribute is here}}
712   template<typename T> __declspec(dllimport)               void normalInlineDef();
713   template<typename T> __declspec(dllimport) static        void staticDecl();
714   template<typename T> __declspec(dllimport) static        void staticDef(); // expected-note{{previous declaration is here}} expected-note{{previous attribute is here}}
715   template<typename T> __declspec(dllimport) static        void staticInlineDef();
716
717 #ifdef GNU
718   // expected-warning@+5{{'dllimport' attribute ignored on inline function}}
719   // expected-warning@+5{{'dllimport' attribute ignored on inline function}}
720   // expected-warning@+5{{'dllimport' attribute ignored on inline function}}
721   // expected-warning@+5{{'dllimport' attribute ignored on inline function}}
722 #endif
723   template<typename T> __declspec(dllimport)               void normalInclass() {}
724   template<typename T> __declspec(dllimport)        inline void normalInlineDecl();
725   template<typename T> __declspec(dllimport) static        void staticInclass() {}
726   template<typename T> __declspec(dllimport) static inline void staticInlineDecl();
727
728 #if __has_feature(cxx_variable_templates)
729   template<typename T> __declspec(dllimport) static        int  StaticField;
730   template<typename T> __declspec(dllimport) static        int  StaticFieldDef; // expected-note{{attribute is here}}
731   template<typename T> __declspec(dllimport) static const  int  StaticConstField;
732   template<typename T> __declspec(dllimport) static const  int  StaticConstFieldDef; // expected-note{{attribute is here}}
733   template<typename T> __declspec(dllimport) static const  int  StaticConstFieldEqualInit = 1;
734   template<typename T> __declspec(dllimport) static const  int  StaticConstFieldBraceInit{1};
735   template<typename T> __declspec(dllimport) constexpr static int ConstexprField = 1;
736   template<typename T> __declspec(dllimport) constexpr static int ConstexprFieldDef = 1; // expected-note{{attribute is here}}
737 #endif // __has_feature(cxx_variable_templates)
738 };
739
740 template<typename T>        void ImportMemberTmpl::normalDef() {} // expected-warning{{'ImportMemberTmpl::normalDef' redeclared without 'dllimport' attribute: previous 'dllimport' ignored}}
741 template<typename T>        void ImportMemberTmpl::normalInlineDecl() {}
742 template<typename T>        void ImportMemberTmpl::staticDef() {} // expected-warning{{'ImportMemberTmpl::staticDef' redeclared without 'dllimport' attribute: previous 'dllimport' ignored}}
743 template<typename T>        void ImportMemberTmpl::staticInlineDecl() {}
744
745 #ifdef GNU
746 // expected-warning@+3{{ImportMemberTmpl::normalInlineDef' redeclared inline; 'dllimport' attribute ignored}}
747 // expected-warning@+3{{ImportMemberTmpl::staticInlineDef' redeclared inline; 'dllimport' attribute ignored}}
748 #endif
749 template<typename T> inline void ImportMemberTmpl::normalInlineDef() {}
750 template<typename T> inline void ImportMemberTmpl::staticInlineDef() {}
751
752 #if __has_feature(cxx_variable_templates)
753 template<typename T>        int  ImportMemberTmpl::StaticFieldDef; // expected-error{{definition of dllimport static field not allowed}}
754 template<typename T> const  int  ImportMemberTmpl::StaticConstFieldDef = 1; // expected-error{{definition of dllimport static field not allowed}}
755 template<typename T> constexpr int ImportMemberTmpl::ConstexprFieldDef; // expected-error{{definition of dllimport static field not allowed}}
756 #endif // __has_feature(cxx_variable_templates)
757
758
759 // Redeclarations cannot add dllimport.
760 struct MemTmplRedecl {
761   template<typename T>               void normalDef();         // expected-note{{previous declaration is here}}
762   template<typename T>        inline void normalInlineDecl();  // expected-note{{previous declaration is here}}
763   template<typename T> static        void staticDef();         // expected-note{{previous declaration is here}}
764   template<typename T> static inline void staticInlineDecl();  // expected-note{{previous declaration is here}}
765
766 #ifdef MS
767 // expected-note@+3{{previous declaration is here}}
768 // expected-note@+3{{previous declaration is here}}
769 #endif
770   template<typename T>               void normalInlineDef();
771   template<typename T> static        void staticInlineDef();
772
773 #if __has_feature(cxx_variable_templates)
774   template<typename T> static        int  StaticField;         // expected-note{{previous declaration is here}}
775   template<typename T> static const  int  StaticConstField;    // expected-note{{previous declaration is here}}
776   template<typename T> constexpr static int ConstexprField = 1; // expected-note{{previous declaration is here}}
777 #endif // __has_feature(cxx_variable_templates)
778 };
779
780 template<typename T> __declspec(dllimport)        void MemTmplRedecl::normalDef() {}        // expected-error{{redeclaration of 'MemTmplRedecl::normalDef' cannot add 'dllimport' attribute}}
781                                                                                             // expected-error@-1{{dllimport cannot be applied to non-inline function definition}}
782 #ifdef MS
783 template<typename T> __declspec(dllimport) inline void MemTmplRedecl::normalInlineDef() {}  // expected-error{{redeclaration of 'MemTmplRedecl::normalInlineDef' cannot add 'dllimport' attribute}}
784 #else
785 template<typename T> __declspec(dllimport) inline void MemTmplRedecl::normalInlineDef() {}  // expected-warning{{'dllimport' attribute ignored on inline function}}
786 #endif
787 template<typename T> __declspec(dllimport)        void MemTmplRedecl::normalInlineDecl() {} // expected-error{{redeclaration of 'MemTmplRedecl::normalInlineDecl' cannot add 'dllimport' attribute}}
788 template<typename T> __declspec(dllimport)        void MemTmplRedecl::staticDef() {}        // expected-error{{redeclaration of 'MemTmplRedecl::staticDef' cannot add 'dllimport' attribute}}
789                                                                                             // expected-error@-1{{dllimport cannot be applied to non-inline function definition}}
790 #ifdef MS
791 template<typename T> __declspec(dllimport) inline void MemTmplRedecl::staticInlineDef() {}  // expected-error{{redeclaration of 'MemTmplRedecl::staticInlineDef' cannot add 'dllimport' attribute}}
792 #else
793 template<typename T> __declspec(dllimport) inline void MemTmplRedecl::staticInlineDef() {}  // expected-warning{{'dllimport' attribute ignored on inline function}}
794 #endif
795 template<typename T> __declspec(dllimport)        void MemTmplRedecl::staticInlineDecl() {} // expected-error{{redeclaration of 'MemTmplRedecl::staticInlineDecl' cannot add 'dllimport' attribute}}
796
797 #if __has_feature(cxx_variable_templates)
798 template<typename T> __declspec(dllimport)        int  MemTmplRedecl::StaticField = 1;      // expected-error{{redeclaration of 'MemTmplRedecl::StaticField' cannot add 'dllimport' attribute}}
799                                                                                             // expected-error@-1{{definition of dllimport static field not allowed}}
800                                                                                             // expected-note@-2{{attribute is here}}
801 template<typename T> __declspec(dllimport) const  int  MemTmplRedecl::StaticConstField = 1; // expected-error{{redeclaration of 'MemTmplRedecl::StaticConstField' cannot add 'dllimport' attribute}}
802                                                                                             // expected-error@-1{{definition of dllimport static field not allowed}}
803                                                                                             // expected-note@-2{{attribute is here}}
804 template<typename T> __declspec(dllimport) constexpr int MemTmplRedecl::ConstexprField;     // expected-error{{redeclaration of 'MemTmplRedecl::ConstexprField' cannot add 'dllimport' attribute}}
805                                                                                             // expected-error@-1{{definition of dllimport static field not allowed}}
806                                                                                             // expected-note@-2{{attribute is here}}
807 #endif // __has_feature(cxx_variable_templates)
808
809
810
811 struct MemFunTmpl {
812   template<typename T>                              void normalDef() {}
813 #ifdef GNU
814   // expected-warning@+2{{'dllimport' attribute ignored on inline function}}
815 #endif
816   template<typename T> __declspec(dllimport)        void importedNormal() {}
817   template<typename T>                       static void staticDef() {}
818 #ifdef GNU
819   // expected-warning@+2{{'dllimport' attribute ignored on inline function}}
820 #endif
821   template<typename T> __declspec(dllimport) static void importedStatic() {}
822 };
823
824 // Import implicit instantiation of an imported member function template.
825 void useMemFunTmpl() {
826   MemFunTmpl().importedNormal<ImplicitInst_Imported>();
827   MemFunTmpl().importedStatic<ImplicitInst_Imported>();
828 }
829
830 // Import explicit instantiation declaration of an imported member function
831 // template.
832 extern template void MemFunTmpl::importedNormal<ExplicitDecl_Imported>();
833 extern template void MemFunTmpl::importedStatic<ExplicitDecl_Imported>();
834
835 // Import explicit instantiation definition of an imported member function
836 // template.
837 // NB: MSVC fails this instantiation without explicit dllimport.
838 template void MemFunTmpl::importedNormal<ExplicitInst_Imported>();
839 template void MemFunTmpl::importedStatic<ExplicitInst_Imported>();
840
841 // Import specialization of an imported member function template.
842 template<> __declspec(dllimport) void MemFunTmpl::importedNormal<ExplicitSpec_Imported>();
843 template<> __declspec(dllimport) void MemFunTmpl::importedNormal<ExplicitSpec_Def_Imported>() {} // error on mingw
844 #ifdef GNU
845   // expected-warning@+2{{'dllimport' attribute ignored on inline function}}
846 #endif
847 template<> __declspec(dllimport) inline void MemFunTmpl::importedNormal<ExplicitSpec_InlineDef_Imported>() {}
848 #if 1
849 // FIXME: This should not be an error when targeting MSVC. (PR21406)
850 // expected-error@-7{{dllimport cannot be applied to non-inline function definition}}
851 #endif
852
853 template<> __declspec(dllimport) void MemFunTmpl::importedStatic<ExplicitSpec_Imported>();
854 template<> __declspec(dllimport) void MemFunTmpl::importedStatic<ExplicitSpec_Def_Imported>() {} // error on mingw
855 #ifdef GNU
856   // expected-warning@+2{{'dllimport' attribute ignored on inline function}}
857 #endif
858 template<> __declspec(dllimport) inline void MemFunTmpl::importedStatic<ExplicitSpec_InlineDef_Imported>() {}
859 #if 1
860 // FIXME: This should not be an error when targeting MSVC. (PR21406)
861 // expected-error@-7{{dllimport cannot be applied to non-inline function definition}}
862 #endif
863
864 // Not importing specialization of an imported member function template without
865 // explicit dllimport.
866 template<> void MemFunTmpl::importedNormal<ExplicitSpec_NotImported>() {}
867 template<> void MemFunTmpl::importedStatic<ExplicitSpec_NotImported>() {}
868
869
870 // Import explicit instantiation declaration of a non-imported member function
871 // template.
872 #ifdef GNU
873 // expected-warning@+3{{'dllimport' attribute ignored on inline function}}
874 // expected-warning@+3{{'dllimport' attribute ignored on inline function}}
875 #endif
876 extern template __declspec(dllimport) void MemFunTmpl::normalDef<ExplicitDecl_Imported>();
877 extern template __declspec(dllimport) void MemFunTmpl::staticDef<ExplicitDecl_Imported>();
878
879 // Import explicit instantiation definition of a non-imported member function
880 // template.
881 #ifdef GNU
882 // expected-warning@+3{{'dllimport' attribute ignored on inline function}}
883 // expected-warning@+3{{'dllimport' attribute ignored on inline function}}
884 #endif
885 template __declspec(dllimport) void MemFunTmpl::normalDef<ExplicitInst_Imported>();
886 template __declspec(dllimport) void MemFunTmpl::staticDef<ExplicitInst_Imported>();
887
888 // Import specialization of a non-imported member function template.
889 template<> __declspec(dllimport) void MemFunTmpl::normalDef<ExplicitSpec_Imported>();
890 template<> __declspec(dllimport) void MemFunTmpl::normalDef<ExplicitSpec_Def_Imported>() {} // error on mingw
891 #ifdef GNU
892   // expected-warning@+2{{'dllimport' attribute ignored on inline function}}
893 #endif
894 template<> __declspec(dllimport) inline void MemFunTmpl::normalDef<ExplicitSpec_InlineDef_Imported>() {}
895 #if 1
896 // FIXME: This should not be an error when targeting MSVC. (PR21406)
897 // expected-error@-7{{dllimport cannot be applied to non-inline function definition}}
898 #endif
899
900 template<> __declspec(dllimport) void MemFunTmpl::staticDef<ExplicitSpec_Imported>();
901 template<> __declspec(dllimport) void MemFunTmpl::staticDef<ExplicitSpec_Def_Imported>() {} // error on mingw
902 #ifdef GNU
903   // expected-warning@+2{{'dllimport' attribute ignored on inline function}}
904 #endif
905 template<> __declspec(dllimport) inline void MemFunTmpl::staticDef<ExplicitSpec_InlineDef_Imported>() {}
906 #if 1
907 // FIXME: This should not be an error when targeting MSVC. (PR21406)
908 // expected-error@-7{{dllimport cannot be applied to non-inline function definition}}
909 #endif
910
911
912
913 #if __has_feature(cxx_variable_templates)
914 struct MemVarTmpl {
915   template<typename T>                       static const int StaticVar = 1;
916   template<typename T> __declspec(dllimport) static const int ImportedStaticVar = 1;
917 };
918
919 // Import implicit instantiation of an imported member variable template.
920 int useMemVarTmpl() { return MemVarTmpl::ImportedStaticVar<ImplicitInst_Imported>; }
921
922 // Import explicit instantiation declaration of an imported member variable
923 // template.
924 extern template const int MemVarTmpl::ImportedStaticVar<ExplicitDecl_Imported>;
925
926 // An explicit instantiation definition of an imported member variable template
927 // cannot be imported because the template must be defined which is illegal. The
928 // in-class initializer does not count.
929
930 // Import specialization of an imported member variable template.
931 template<> __declspec(dllimport) const int MemVarTmpl::ImportedStaticVar<ExplicitSpec_Imported>;
932 template<> __declspec(dllimport) const int MemVarTmpl::ImportedStaticVar<ExplicitSpec_Def_Imported> = 1;
933                                                                                 // expected-error@-1{{definition of dllimport static field not allowed}}
934                                                                                 // expected-note@-2{{attribute is here}}
935
936 // Not importing specialization of a member variable template without explicit
937 // dllimport.
938 template<> const int MemVarTmpl::ImportedStaticVar<ExplicitSpec_NotImported>;
939
940
941 // Import explicit instantiation declaration of a non-imported member variable
942 // template.
943 extern template __declspec(dllimport) const int MemVarTmpl::StaticVar<ExplicitDecl_Imported>;
944
945 // An explicit instantiation definition of a non-imported member variable template
946 // cannot be imported because the template must be defined which is illegal. The
947 // in-class initializer does not count.
948
949 // Import specialization of a non-imported member variable template.
950 template<> __declspec(dllimport) const int MemVarTmpl::StaticVar<ExplicitSpec_Imported>;
951 template<> __declspec(dllimport) const int MemVarTmpl::StaticVar<ExplicitSpec_Def_Imported> = 1;
952                                                                                 // expected-error@-1{{definition of dllimport static field not allowed}}
953                                                                                 // expected-note@-2{{attribute is here}}
954
955 #endif // __has_feature(cxx_variable_templates)
956
957
958
959 //===----------------------------------------------------------------------===//
960 // Class template members
961 //===----------------------------------------------------------------------===//
962
963 // Import individual members of a class template.
964 template<typename T>
965 struct ImportClassTmplMembers {
966   __declspec(dllimport)                void normalDecl();
967   __declspec(dllimport)                void normalDef(); // expected-note{{previous declaration is here}} expected-note{{previous attribute is here}}
968   __declspec(dllimport)                void normalInlineDef();
969   __declspec(dllimport) virtual        void virtualDecl();
970   __declspec(dllimport) virtual        void virtualDef(); // expected-note{{previous declaration is here}} expected-note{{previous attribute is here}}
971   __declspec(dllimport) virtual        void virtualInlineDef();
972   __declspec(dllimport) static         void staticDecl();
973   __declspec(dllimport) static         void staticDef(); // expected-note{{previous declaration is here}} expected-note{{previous attribute is here}}
974   __declspec(dllimport) static         void staticInlineDef();
975
976 #ifdef GNU
977 // expected-warning@+7{{'dllimport' attribute ignored on inline function}}
978 // expected-warning@+7{{'dllimport' attribute ignored on inline function}}
979 // expected-warning@+7{{'dllimport' attribute ignored on inline function}}
980 // expected-warning@+7{{'dllimport' attribute ignored on inline function}}
981 // expected-warning@+7{{'dllimport' attribute ignored on inline function}}
982 // expected-warning@+7{{'dllimport' attribute ignored on inline function}}
983 #endif
984   __declspec(dllimport)                void normalInclass() {}
985   __declspec(dllimport)         inline void normalInlineDecl();
986   __declspec(dllimport) virtual        void virtualInclass() {}
987   __declspec(dllimport) virtual inline void virtualInlineDecl();
988   __declspec(dllimport) static         void staticInclass() {}
989   __declspec(dllimport) static  inline void staticInlineDecl();
990
991 protected:
992   __declspec(dllimport)                void protectedDecl();
993 private:
994   __declspec(dllimport)                void privateDecl();
995 public:
996
997   __declspec(dllimport)                int  Field; // expected-warning{{'dllimport' attribute only applies to variables, functions and classes}}
998   __declspec(dllimport) static         int  StaticField;
999   __declspec(dllimport) static         int  StaticFieldDef; // expected-note{{attribute is here}}
1000   __declspec(dllimport) static  const  int  StaticConstField;
1001   __declspec(dllimport) static  const  int  StaticConstFieldDef; // expected-note{{attribute is here}}
1002   __declspec(dllimport) static  const  int  StaticConstFieldEqualInit = 1;
1003   __declspec(dllimport) static  const  int  StaticConstFieldBraceInit{1};
1004   __declspec(dllimport) constexpr static int ConstexprField = 1;
1005   __declspec(dllimport) constexpr static int ConstexprFieldDef = 1; // expected-note{{attribute is here}}
1006 };
1007
1008 // NB: MSVC is inconsistent here and disallows *InlineDef on class templates,
1009 // but allows it on classes. We allow both.
1010 template<typename T>        void ImportClassTmplMembers<T>::normalDef() {} // expected-warning{{'ImportClassTmplMembers::normalDef' redeclared without 'dllimport' attribute: previous 'dllimport' ignored}}
1011 #ifdef GNU
1012 // expected-warning@+2{{'ImportClassTmplMembers::normalInlineDef' redeclared inline; 'dllimport' attribute ignored}}
1013 #endif
1014 template<typename T> inline void ImportClassTmplMembers<T>::normalInlineDef() {}
1015 template<typename T>        void ImportClassTmplMembers<T>::normalInlineDecl() {}
1016 template<typename T>        void ImportClassTmplMembers<T>::virtualDef() {} // expected-warning{{'ImportClassTmplMembers::virtualDef' redeclared without 'dllimport' attribute: previous 'dllimport' ignored}}
1017 #ifdef GNU
1018 // expected-warning@+2{{'ImportClassTmplMembers::virtualInlineDef' redeclared inline; 'dllimport' attribute ignored}}
1019 #endif
1020 template<typename T> inline void ImportClassTmplMembers<T>::virtualInlineDef() {}
1021 template<typename T>        void ImportClassTmplMembers<T>::virtualInlineDecl() {}
1022 template<typename T>        void ImportClassTmplMembers<T>::staticDef() {} // expected-warning{{'ImportClassTmplMembers::staticDef' redeclared without 'dllimport' attribute: previous 'dllimport' ignored}}
1023 #ifdef GNU
1024 // expected-warning@+2{{'ImportClassTmplMembers::staticInlineDef' redeclared inline; 'dllimport' attribute ignored}}
1025 #endif
1026 template<typename T> inline void ImportClassTmplMembers<T>::staticInlineDef() {}
1027 template<typename T>        void ImportClassTmplMembers<T>::staticInlineDecl() {}
1028
1029 template<typename T>        int  ImportClassTmplMembers<T>::StaticFieldDef; // expected-warning{{definition of dllimport static field}}
1030 template<typename T> const  int  ImportClassTmplMembers<T>::StaticConstFieldDef = 1; // expected-warning{{definition of dllimport static field}}
1031 template<typename T> constexpr int ImportClassTmplMembers<T>::ConstexprFieldDef; // expected-warning{{definition of dllimport static field}}
1032
1033
1034 // Redeclarations cannot add dllimport.
1035 template<typename T>
1036 struct CTMR /*ClassTmplMemberRedecl*/ {
1037                  void normalDef();         // expected-note{{previous declaration is here}}
1038           inline void normalInlineDecl();  // expected-note{{previous declaration is here}}
1039   virtual        void virtualDef();        // expected-note{{previous declaration is here}}
1040   virtual inline void virtualInlineDecl(); // expected-note{{previous declaration is here}}
1041   static         void staticDef();         // expected-note{{previous declaration is here}}
1042   static  inline void staticInlineDecl();  // expected-note{{previous declaration is here}}
1043
1044 #ifdef MS
1045 // expected-note@+4{{previous declaration is here}}
1046 // expected-note@+4{{previous declaration is here}}
1047 // expected-note@+4{{previous declaration is here}}
1048 #endif
1049                  void normalInlineDef();
1050   virtual        void virtualInlineDef();
1051   static         void staticInlineDef();
1052
1053   static         int  StaticField;         // expected-note{{previous declaration is here}}
1054   static  const  int  StaticConstField;    // expected-note{{previous declaration is here}}
1055   constexpr static int ConstexprField = 1; // expected-note{{previous declaration is here}}
1056 };
1057
1058 template<typename T> __declspec(dllimport)        void CTMR<T>::normalDef() {}         // expected-error{{redeclaration of 'CTMR::normalDef' cannot add 'dllimport' attribute}}
1059                                                                                        // expected-error@-1{{dllimport cannot be applied to non-inline function definition}}
1060 template<typename T> __declspec(dllimport)        void CTMR<T>::normalInlineDecl() {}  // expected-error{{redeclaration of 'CTMR::normalInlineDecl' cannot add 'dllimport' attribute}}
1061 template<typename T> __declspec(dllimport)        void CTMR<T>::virtualDef() {}        // expected-error{{redeclaration of 'CTMR::virtualDef' cannot add 'dllimport' attribute}}
1062                                                                                        // expected-error@-1{{dllimport cannot be applied to non-inline function definition}}
1063 template<typename T> __declspec(dllimport)        void CTMR<T>::virtualInlineDecl() {} // expected-error{{redeclaration of 'CTMR::virtualInlineDecl' cannot add 'dllimport' attribute}}
1064 template<typename T> __declspec(dllimport)        void CTMR<T>::staticDef() {}         // expected-error{{redeclaration of 'CTMR::staticDef' cannot add 'dllimport' attribute}}
1065                                                                                        // expected-error@-1{{dllimport cannot be applied to non-inline function definition}}
1066 template<typename T> __declspec(dllimport)        void CTMR<T>::staticInlineDecl() {}  // expected-error{{redeclaration of 'CTMR::staticInlineDecl' cannot add 'dllimport' attribute}}
1067
1068 #ifdef MS
1069 template<typename T> __declspec(dllimport) inline void CTMR<T>::normalInlineDef() {}   // expected-error{{redeclaration of 'CTMR::normalInlineDef' cannot add 'dllimport' attribute}}
1070 template<typename T> __declspec(dllimport) inline void CTMR<T>::virtualInlineDef() {}  // expected-error{{redeclaration of 'CTMR::virtualInlineDef' cannot add 'dllimport' attribute}}
1071 template<typename T> __declspec(dllimport) inline void CTMR<T>::staticInlineDef() {}   // expected-error{{redeclaration of 'CTMR::staticInlineDef' cannot add 'dllimport' attribute}}
1072 #else
1073 template<typename T> __declspec(dllimport) inline void CTMR<T>::normalInlineDef() {}   // expected-warning{{'dllimport' attribute ignored on inline function}}
1074 template<typename T> __declspec(dllimport) inline void CTMR<T>::virtualInlineDef() {}  // expected-warning{{'dllimport' attribute ignored on inline function}}
1075 template<typename T> __declspec(dllimport) inline void CTMR<T>::staticInlineDef() {}   // expected-warning{{'dllimport' attribute ignored on inline function}}
1076 #endif
1077
1078 template<typename T> __declspec(dllimport)        int  CTMR<T>::StaticField = 1;       // expected-error{{redeclaration of 'CTMR::StaticField' cannot add 'dllimport' attribute}}
1079                                                                                        // expected-warning@-1{{definition of dllimport static field}}
1080                                                                                        // expected-note@-2{{attribute is here}}
1081 template<typename T> __declspec(dllimport) const  int  CTMR<T>::StaticConstField = 1;  // expected-error{{redeclaration of 'CTMR::StaticConstField' cannot add 'dllimport' attribute}}
1082                                                                                        // expected-warning@-1{{definition of dllimport static field}}
1083                                                                                        // expected-note@-2{{attribute is here}}
1084 template<typename T> __declspec(dllimport) constexpr int CTMR<T>::ConstexprField;      // expected-error{{redeclaration of 'CTMR::ConstexprField' cannot add 'dllimport' attribute}}
1085                                                                                        // expected-warning@-1{{definition of dllimport static field}}
1086                                                                                        // expected-note@-2{{attribute is here}}
1087
1088
1089
1090 //===----------------------------------------------------------------------===//
1091 // Class template member templates
1092 //===----------------------------------------------------------------------===//
1093
1094 template<typename T>
1095 struct ImportClsTmplMemTmpl {
1096   template<typename U> __declspec(dllimport)               void normalDecl();
1097   template<typename U> __declspec(dllimport)               void normalDef(); // expected-note{{previous declaration is here}} expected-note{{previous attribute is here}}
1098   template<typename U> __declspec(dllimport)               void normalInlineDef();
1099   template<typename U> __declspec(dllimport) static        void staticDecl();
1100   template<typename U> __declspec(dllimport) static        void staticDef(); // expected-note{{previous declaration is here}} expected-note{{previous attribute is here}}
1101   template<typename U> __declspec(dllimport) static        void staticInlineDef();
1102
1103 #ifdef GNU
1104   // expected-warning@+5{{'dllimport' attribute ignored on inline function}}
1105   // expected-warning@+5{{'dllimport' attribute ignored on inline function}}
1106   // expected-warning@+5{{'dllimport' attribute ignored on inline function}}
1107   // expected-warning@+5{{'dllimport' attribute ignored on inline function}}
1108 #endif
1109   template<typename U> __declspec(dllimport)               void normalInclass() {}
1110   template<typename U> __declspec(dllimport)        inline void normalInlineDecl();
1111   template<typename U> __declspec(dllimport) static        void staticInclass() {}
1112   template<typename U> __declspec(dllimport) static inline void staticInlineDecl();
1113
1114 #if __has_feature(cxx_variable_templates)
1115   template<typename U> __declspec(dllimport) static        int  StaticField;
1116   template<typename U> __declspec(dllimport) static        int  StaticFieldDef; // expected-note{{attribute is here}}
1117   template<typename U> __declspec(dllimport) static const  int  StaticConstField;
1118   template<typename U> __declspec(dllimport) static const  int  StaticConstFieldDef; // expected-note{{attribute is here}}
1119   template<typename U> __declspec(dllimport) static const  int  StaticConstFieldEqualInit = 1;
1120   template<typename U> __declspec(dllimport) static const  int  StaticConstFieldBraceInit{1};
1121   template<typename U> __declspec(dllimport) constexpr static int ConstexprField = 1;
1122   template<typename U> __declspec(dllimport) constexpr static int ConstexprFieldDef = 1; // expected-note{{attribute is here}}
1123 #endif // __has_feature(cxx_variable_templates)
1124 };
1125
1126 template<typename T> template<typename U>        void ImportClsTmplMemTmpl<T>::normalDef() {} // expected-warning{{'ImportClsTmplMemTmpl::normalDef' redeclared without 'dllimport' attribute: previous 'dllimport' ignored}}
1127 template<typename T> template<typename U>        void ImportClsTmplMemTmpl<T>::normalInlineDecl() {}
1128 template<typename T> template<typename U>        void ImportClsTmplMemTmpl<T>::staticDef() {} // expected-warning{{'ImportClsTmplMemTmpl::staticDef' redeclared without 'dllimport' attribute: previous 'dllimport' ignored}}
1129 template<typename T> template<typename U>        void ImportClsTmplMemTmpl<T>::staticInlineDecl() {}
1130
1131 #ifdef GNU
1132 // expected-warning@+3{{'ImportClsTmplMemTmpl::normalInlineDef' redeclared inline; 'dllimport' attribute ignored}}
1133 // expected-warning@+3{{'ImportClsTmplMemTmpl::staticInlineDef' redeclared inline; 'dllimport' attribute ignored}}
1134 #endif
1135 template<typename T> template<typename U> inline void ImportClsTmplMemTmpl<T>::normalInlineDef() {}
1136 template<typename T> template<typename U> inline void ImportClsTmplMemTmpl<T>::staticInlineDef() {}
1137
1138 #if __has_feature(cxx_variable_templates)
1139 template<typename T> template<typename U>        int  ImportClsTmplMemTmpl<T>::StaticFieldDef; // expected-warning{{definition of dllimport static field}}
1140 template<typename T> template<typename U> const  int  ImportClsTmplMemTmpl<T>::StaticConstFieldDef = 1; // expected-warning{{definition of dllimport static field}}
1141 template<typename T> template<typename U> constexpr int ImportClsTmplMemTmpl<T>::ConstexprFieldDef; // expected-warning{{definition of dllimport static field}}
1142 #endif // __has_feature(cxx_variable_templates)
1143
1144
1145 // Redeclarations cannot add dllimport.
1146 template<typename T>
1147 struct CTMTR /*ClassTmplMemberTmplRedecl*/ {
1148   template<typename U>               void normalDef();         // expected-note{{previous declaration is here}}
1149   template<typename U>        inline void normalInlineDecl();  // expected-note{{previous declaration is here}}
1150   template<typename U> static        void staticDef();         // expected-note{{previous declaration is here}}
1151   template<typename U> static inline void staticInlineDecl();  // expected-note{{previous declaration is here}}
1152
1153 #ifdef MS
1154   // expected-note@+3{{previous declaration is here}}
1155   // expected-note@+3{{previous declaration is here}}
1156 #endif
1157   template<typename U>               void normalInlineDef();
1158   template<typename U> static        void staticInlineDef();
1159
1160 #if __has_feature(cxx_variable_templates)
1161   template<typename U> static        int  StaticField;         // expected-note{{previous declaration is here}}
1162   template<typename U> static const  int  StaticConstField;    // expected-note{{previous declaration is here}}
1163   template<typename U> constexpr static int ConstexprField = 1; // expected-note{{previous declaration is here}}
1164 #endif // __has_feature(cxx_variable_templates)
1165 };
1166
1167 template<typename T> template<typename U> __declspec(dllimport)        void CTMTR<T>::normalDef() {}         // expected-error{{redeclaration of 'CTMTR::normalDef' cannot add 'dllimport' attribute}}
1168                                                                                                              // expected-error@-1{{dllimport cannot be applied to non-inline function definition}}
1169 template<typename T> template<typename U> __declspec(dllimport)        void CTMTR<T>::normalInlineDecl() {}  // expected-error{{redeclaration of 'CTMTR::normalInlineDecl' cannot add 'dllimport' attribute}}
1170 template<typename T> template<typename U> __declspec(dllimport)        void CTMTR<T>::staticDef() {}         // expected-error{{redeclaration of 'CTMTR::staticDef' cannot add 'dllimport' attribute}}
1171                                                                                                              // expected-error@-1{{dllimport cannot be applied to non-inline function definition}}
1172 template<typename T> template<typename U> __declspec(dllimport)        void CTMTR<T>::staticInlineDecl() {}  // expected-error{{redeclaration of 'CTMTR::staticInlineDecl' cannot add 'dllimport' attribute}}
1173
1174 #ifdef MS
1175 template<typename T> template<typename U> __declspec(dllimport) inline void CTMTR<T>::normalInlineDef() {}   // expected-error{{redeclaration of 'CTMTR::normalInlineDef' cannot add 'dllimport' attribute}}
1176 template<typename T> template<typename U> __declspec(dllimport) inline void CTMTR<T>::staticInlineDef() {}   // expected-error{{redeclaration of 'CTMTR::staticInlineDef' cannot add 'dllimport' attribute}}
1177 #else
1178 template<typename T> template<typename U> __declspec(dllimport) inline void CTMTR<T>::normalInlineDef() {}   // expected-warning{{'dllimport' attribute ignored on inline function}}
1179 template<typename T> template<typename U> __declspec(dllimport) inline void CTMTR<T>::staticInlineDef() {}   // expected-warning{{'dllimport' attribute ignored on inline function}}
1180 #endif
1181
1182 #if __has_feature(cxx_variable_templates)
1183 template<typename T> template<typename U> __declspec(dllimport)        int  CTMTR<T>::StaticField = 1;       // expected-error{{redeclaration of 'CTMTR::StaticField' cannot add 'dllimport' attribute}}
1184                                                                                                              // expected-warning@-1{{definition of dllimport static field}}
1185                                                                                                              // expected-note@-2{{attribute is here}}
1186 template<typename T> template<typename U> __declspec(dllimport) const  int  CTMTR<T>::StaticConstField = 1;  // expected-error{{redeclaration of 'CTMTR::StaticConstField' cannot add 'dllimport' attribute}}
1187                                                                                                              // expected-warning@-1{{definition of dllimport static field}}
1188                                                                                                              // expected-note@-2{{attribute is here}}
1189 template<typename T> template<typename U> __declspec(dllimport) constexpr int CTMTR<T>::ConstexprField;      // expected-error{{redeclaration of 'CTMTR::ConstexprField' cannot add 'dllimport' attribute}}
1190                                                                                                              // expected-warning@-1{{definition of dllimport static field}}
1191                                                                                                              // expected-note@-2{{attribute is here}}
1192 #endif // __has_feature(cxx_variable_templates)
1193
1194
1195
1196 //===----------------------------------------------------------------------===//
1197 // Classes
1198 //===----------------------------------------------------------------------===//
1199
1200 namespace {
1201   struct __declspec(dllimport) AnonymousClass {}; // expected-error{{(anonymous namespace)::AnonymousClass' must have external linkage when declared 'dllimport'}}
1202 }
1203
1204 class __declspec(dllimport) ClassDecl;
1205
1206 class __declspec(dllimport) ClassDef { };
1207
1208 template <typename T> class ClassTemplate {};
1209
1210 #ifdef MS
1211 // expected-note@+5{{previous attribute is here}}
1212 // expected-note@+4{{previous attribute is here}}
1213 // expected-error@+4{{attribute 'dllexport' cannot be applied to member of 'dllimport' class}}
1214 // expected-error@+4{{attribute 'dllimport' cannot be applied to member of 'dllimport' class}}
1215 #endif
1216 class __declspec(dllimport) ImportClassWithDllMember {
1217   void __declspec(dllexport) foo();
1218   void __declspec(dllimport) bar();
1219 };
1220
1221 #ifdef MS
1222 // expected-note@+5{{previous attribute is here}}
1223 // expected-note@+4{{previous attribute is here}}
1224 // expected-error@+4{{attribute 'dllimport' cannot be applied to member of 'dllexport' class}}
1225 // expected-error@+4{{attribute 'dllexport' cannot be applied to member of 'dllexport' class}}
1226 #endif
1227 template <typename T> class __declspec(dllexport) ExportClassWithDllMember {
1228   void __declspec(dllimport) foo();
1229   void __declspec(dllexport) bar();
1230 };
1231
1232 namespace ImportedExplicitSpecialization {
1233 template <typename T> struct S { static int x; };
1234 template <typename T> int S<T>::x = sizeof(T);
1235 template <> struct __declspec(dllimport) S<int> { static int x; }; // expected-note{{attribute is here}}
1236 int S<int>::x = -1; // expected-error{{definition of dllimport static field not allowed}}
1237 }
1238
1239 namespace PR19988 {
1240 // Don't error about applying delete to dllimport member function when instantiating.
1241 template <typename> struct __declspec(dllimport) S {
1242   void foo() = delete;
1243 };
1244 S<int> s;
1245 }
1246
1247 #ifdef MS
1248 // expected-warning@+3{{'dllimport' attribute ignored}}
1249 #endif
1250 template <typename T> struct PartiallySpecializedClassTemplate {};
1251 template <typename T> struct __declspec(dllimport) PartiallySpecializedClassTemplate<T*> { void f() {} };
1252
1253 template <typename T> struct ExpliciallySpecializedClassTemplate {};
1254 template <> struct __declspec(dllimport) ExpliciallySpecializedClassTemplate<int> { void f() {} };
1255
1256
1257 //===----------------------------------------------------------------------===//
1258 // Classes with template base classes
1259 //===----------------------------------------------------------------------===//
1260
1261 template <typename T> class __declspec(dllexport) ExportedClassTemplate {};
1262
1263 template <typename T> class __declspec(dllimport) ImportedClassTemplate {};
1264
1265 // ClassTemplate<int> gets imported.
1266 class __declspec(dllimport) DerivedFromTemplate : public ClassTemplate<int> {};
1267
1268 // ClassTemplate<int> is already imported.
1269 class __declspec(dllimport) DerivedFromTemplate2 : public ClassTemplate<int> {};
1270
1271 // ImportedClassTemplate is expliitly imported.
1272 class __declspec(dllimport) DerivedFromImportedTemplate : public ImportedClassTemplate<int> {};
1273
1274 // ExportedClassTemplate is explicitly exported.
1275 class __declspec(dllimport) DerivedFromExportedTemplate : public ExportedClassTemplate<int> {};
1276
1277 class DerivedFromTemplateD : public ClassTemplate<double> {};
1278 // Base class previously implicitly instantiated without attribute; it will get propagated.
1279 class __declspec(dllimport) DerivedFromTemplateD2 : public ClassTemplate<double> {};
1280
1281 // Base class has explicit instantiation declaration; the attribute will get propagated.
1282 extern template class ClassTemplate<float>;
1283 class __declspec(dllimport) DerivedFromTemplateF : public ClassTemplate<float> {};
1284
1285 class __declspec(dllimport) DerivedFromTemplateB : public ClassTemplate<bool> {};
1286 // The second derived class doesn't change anything, the attribute that was propagated first wins.
1287 class __declspec(dllexport) DerivedFromTemplateB2 : public ClassTemplate<bool> {};
1288
1289 template <typename T> struct ExplicitlySpecializedTemplate { void func() {} };
1290 #ifdef MS
1291 // expected-note@+2{{class template 'ExplicitlySpecializedTemplate<int>' was explicitly specialized here}}
1292 #endif
1293 template <> struct ExplicitlySpecializedTemplate<int> { void func() {} };
1294 template <typename T> struct ExplicitlyExportSpecializedTemplate { void func() {} };
1295 template <> struct __declspec(dllexport) ExplicitlyExportSpecializedTemplate<int> { void func() {} };
1296 template <typename T> struct ExplicitlyImportSpecializedTemplate { void func() {} };
1297 template <> struct __declspec(dllimport) ExplicitlyImportSpecializedTemplate<int> { void func() {} };
1298
1299 template <typename T> struct ExplicitlyInstantiatedTemplate { void func() {} };
1300 #ifdef MS
1301 // expected-note@+2{{class template 'ExplicitlyInstantiatedTemplate<int>' was instantiated here}}
1302 #endif
1303 template struct ExplicitlyInstantiatedTemplate<int>;
1304 template <typename T> struct ExplicitlyExportInstantiatedTemplate { void func() {} };
1305 template struct __declspec(dllexport) ExplicitlyExportInstantiatedTemplate<int>;
1306 template <typename T> struct ExplicitlyImportInstantiatedTemplate { void func() {} };
1307 template struct __declspec(dllimport) ExplicitlyImportInstantiatedTemplate<int>;
1308
1309 #ifdef MS
1310 // expected-warning@+3{{propagating dll attribute to explicitly specialized base class template without dll attribute is not supported}}
1311 // expected-note@+2{{attribute is here}}
1312 #endif
1313 struct __declspec(dllimport) DerivedFromExplicitlySpecializedTemplate : public ExplicitlySpecializedTemplate<int> {};
1314
1315 // Base class already specialized with export attribute.
1316 struct __declspec(dllimport) DerivedFromExplicitlyExportSpecializedTemplate : public ExplicitlyExportSpecializedTemplate<int> {};
1317
1318 // Base class already specialized with import attribute.
1319 struct __declspec(dllimport) DerivedFromExplicitlyImportSpecializedTemplate : public ExplicitlyImportSpecializedTemplate<int> {};
1320
1321 #ifdef MS
1322 // expected-warning@+3{{propagating dll attribute to already instantiated base class template without dll attribute is not supported}}
1323 // expected-note@+2{{attribute is here}}
1324 #endif
1325 struct __declspec(dllimport) DerivedFromExplicitlyInstantiatedTemplate : public ExplicitlyInstantiatedTemplate<int> {};
1326
1327 // Base class already instantiated with export attribute.
1328 struct __declspec(dllimport) DerivedFromExplicitlyExportInstantiatedTemplate : public ExplicitlyExportInstantiatedTemplate<int> {};
1329
1330 // Base class already instantiated with import attribute.
1331 struct __declspec(dllimport) DerivedFromExplicitlyImportInstantiatedTemplate : public ExplicitlyImportInstantiatedTemplate<int> {};
1332
1333 template <typename T> struct ExplicitInstantiationDeclTemplateBase { void func() {} };
1334 extern template struct ExplicitInstantiationDeclTemplateBase<int>;
1335 struct __declspec(dllimport) DerivedFromExplicitInstantiationDeclTemplateBase : public ExplicitInstantiationDeclTemplateBase<int> {};