1 // RUN: %clang_cc1 -triple i686-windows-msvc -fno-rtti -fno-threadsafe-statics -fms-extensions -emit-llvm -std=c++1y -O0 -o - %s -DMSABI -w | FileCheck --check-prefix=MSC --check-prefix=M32 %s
2 // RUN: %clang_cc1 -triple x86_64-windows-msvc -fno-rtti -fno-threadsafe-statics -fms-extensions -emit-llvm -std=c++1y -O0 -o - %s -DMSABI -w | FileCheck --check-prefix=MSC --check-prefix=M64 %s
3 // RUN: %clang_cc1 -triple i686-windows-gnu -fno-rtti -fno-threadsafe-statics -fms-extensions -emit-llvm -std=c++1y -O0 -o - %s -w | FileCheck --check-prefix=GNU --check-prefix=G32 %s
4 // RUN: %clang_cc1 -triple x86_64-windows-gnu -fno-rtti -fno-threadsafe-statics -fms-extensions -emit-llvm -std=c++1y -O0 -o - %s -w | FileCheck --check-prefix=GNU --check-prefix=G64 %s
5 // RUN: %clang_cc1 -triple i686-windows-msvc -fno-rtti -fno-threadsafe-statics -fms-extensions -fms-compatibility-version=18.00 -emit-llvm -std=c++1y -O1 -disable-llvm-optzns -o - %s -DMSABI -w | FileCheck --check-prefix=MO1 --check-prefix=M18 %s
6 // RUN: %clang_cc1 -triple i686-windows-msvc -fno-rtti -fno-threadsafe-statics -fms-extensions -fms-compatibility-version=19.00 -emit-llvm -std=c++1y -O1 -disable-llvm-optzns -o - %s -DMSABI -w | FileCheck --check-prefix=MO1 --check-prefix=M19 %s
7 // RUN: %clang_cc1 -triple i686-windows-gnu -fno-rtti -fno-threadsafe-statics -fms-extensions -emit-llvm -std=c++1y -O1 -o - %s -w | FileCheck --check-prefix=GO1 %s
8
9 // CHECK-NOT doesn't play nice with CHECK-DAG, so use separate run lines.
10 // RUN: %clang_cc1 -triple i686-windows-msvc -fno-rtti -fno-threadsafe-statics -fms-extensions -emit-llvm -std=c++1y -O0 -o - %s -DMSABI -w | FileCheck --check-prefix=MSC2 %s
11 // RUN: %clang_cc1 -triple i686-windows-gnu -fno-rtti -fno-threadsafe-statics -fms-extensions -emit-llvm -std=c++1y -O0 -o - %s -w | FileCheck --check-prefix=GNU2 %s
12
13 // Helper structs to make templates more expressive.
14 struct ImplicitInst_Imported {};
15 struct ImplicitInst_NotImported {};
16 struct ExplicitDecl_Imported {};
17 struct ExplicitInst_Imported {};
18 struct ExplicitSpec_Imported {};
19 struct ExplicitSpec_Def_Imported {};
20 struct ExplicitSpec_InlineDef_Imported {};
21 struct ExplicitSpec_NotImported {};
22
23 #define JOIN2(x, y) x##y
24 #define JOIN(x, y) JOIN2(x, y)
25 #define UNIQ(name) JOIN(name, __LINE__)
26 #define USEVARTYPE(type, var) type UNIQ(use)() { return var; }
27 #define USEVAR(var) USEVARTYPE(int, var)
28 #define USE(func) void UNIQ(use)() { func(); }
29 #define USEMEMFUNC(class, func) void (class::*UNIQ(use)())() { return &class::func; }
30 #define USECLASS(class) void UNIQ(USE)() { class x; }
31 #define USECOPYASSIGN(class) class& (class::*UNIQ(use)())(class&) { return &class::operator=; }
32 #define USEMOVEASSIGN(class) class& (class::*UNIQ(use)())(class&&) { return &class::operator=; }
33
34 //===----------------------------------------------------------------------===//
35 // Globals
36 //===----------------------------------------------------------------------===//
37
38 // Import declaration.
39 // MSC-DAG: @"\01?ExternGlobalDecl@@3HA" = external dllimport global i32
40 // GNU-DAG: @ExternGlobalDecl = external dllimport global i32
41 __declspec(dllimport) extern int ExternGlobalDecl;
42 USEVAR(ExternGlobalDecl)
43
44 // dllimport implies a declaration.
45 // MSC-DAG: @"\01?GlobalDecl@@3HA" = external dllimport global i32
46 // GNU-DAG: @GlobalDecl = external dllimport global i32
47 __declspec(dllimport) int GlobalDecl;
48 USEVAR(GlobalDecl)
49
50 // Redeclarations
51 // MSC-DAG: @"\01?GlobalRedecl1@@3HA" = external dllimport global i32
52 // GNU-DAG: @GlobalRedecl1 = external dllimport global i32
53 __declspec(dllimport) extern int GlobalRedecl1;
54 __declspec(dllimport) extern int GlobalRedecl1;
55 USEVAR(GlobalRedecl1)
56
57 // MSC-DAG: @"\01?GlobalRedecl2a@@3HA" = external dllimport global i32
58 // GNU-DAG: @GlobalRedecl2a = external dllimport global i32
59 __declspec(dllimport) int GlobalRedecl2a;
60 __declspec(dllimport) int GlobalRedecl2a;
61 USEVAR(GlobalRedecl2a)
62
63 // M32-DAG: @"\01?GlobalRedecl2b@@3PAHA" = external dllimport global i32*
64 // M64-DAG: @"\01?GlobalRedecl2b@@3PEAHEA" = external dllimport global i32*
65 // GNU-DAG: @GlobalRedecl2b = external dllimport global i32*
66 int *__attribute__((dllimport)) GlobalRedecl2b;
67 int *__attribute__((dllimport)) GlobalRedecl2b;
68 USEVARTYPE(int*, GlobalRedecl2b)
69
70 // MSC-DAG: @"\01?GlobalRedecl2c@@3HA" = external dllimport global i32
71 // GNU-DAG: @GlobalRedecl2c = external dllimport global i32
72 int GlobalRedecl2c __attribute__((dllimport));
73 int GlobalRedecl2c __attribute__((dllimport));
74 USEVAR(GlobalRedecl2c)
75
76 // NB: MSC issues a warning and makes GlobalRedecl3 dllexport. We follow GCC
77 // and drop the dllimport with a warning.
78 // MSC-DAG: @"\01?GlobalRedecl3@@3HA" = external global i32
79 // GNU-DAG: @GlobalRedecl3 = external global i32
80 __declspec(dllimport) extern int GlobalRedecl3;
81 extern int GlobalRedecl3; // dllimport ignored
82 USEVAR(GlobalRedecl3)
83
84 // MSC-DAG: @"\01?ExternalGlobal@ns@@3HA" = external dllimport global i32
85 // GNU-DAG: @_ZN2ns14ExternalGlobalE = external dllimport global i32
86 namespace ns { __declspec(dllimport) int ExternalGlobal; }
87 USEVAR(ns::ExternalGlobal)
88
89 int __declspec(dllimport) f();
90 // MO1-DAG: @"\01?x@?1??inlineStaticLocalsFunc@@YAHXZ@4HA" = available_externally dllimport global i32 0
91 // MO1-DAG: @"\01??_B?1??inlineStaticLocalsFunc@@YAHXZ@51" = available_externally dllimport global i32 0
inlineStaticLocalsFunc()92 inline int __declspec(dllimport) inlineStaticLocalsFunc() {
93 static int x = f();
94 return x++;
95 };
96 USE(inlineStaticLocalsFunc);
97
98 // The address of a dllimport global cannot be used in constant initialization.
99 // M32-DAG: @"\01?arr@?1??initializationFunc@@YAPAHXZ@4QBQAHB" = internal global [1 x i32*] zeroinitializer
100 // GNU-DAG: @_ZZ18initializationFuncvE3arr = internal global [1 x i32*] zeroinitializer
initializationFunc()101 int *initializationFunc() {
102 static int *const arr[] = {&ExternGlobalDecl};
103 return arr[0];
104 }
105 USE(initializationFunc);
106
107
108 //===----------------------------------------------------------------------===//
109 // Variable templates
110 //===----------------------------------------------------------------------===//
111
112 // Import declaration.
113 // MSC-DAG: @"\01??$ExternVarTmplDecl@UImplicitInst_Imported@@@@3HA" = external dllimport global i32
114 // GNU-DAG: @_Z17ExternVarTmplDeclI21ImplicitInst_ImportedE = external dllimport global i32
115 template<typename T> __declspec(dllimport) extern int ExternVarTmplDecl;
116 USEVAR(ExternVarTmplDecl<ImplicitInst_Imported>)
117
118 // dllimport implies a declaration.
119 // MSC-DAG: @"\01??$VarTmplDecl@UImplicitInst_Imported@@@@3HA" = external dllimport global i32
120 // GNU-DAG: @_Z11VarTmplDeclI21ImplicitInst_ImportedE = external dllimport global i32
121 template<typename T> __declspec(dllimport) int VarTmplDecl;
122 USEVAR(VarTmplDecl<ImplicitInst_Imported>)
123
124 // Redeclarations
125 // MSC-DAG: @"\01??$VarTmplRedecl1@UImplicitInst_Imported@@@@3HA" = external dllimport global i32
126 // GNU-DAG: @_Z14VarTmplRedecl1I21ImplicitInst_ImportedE = external dllimport global i32
127 template<typename T> __declspec(dllimport) extern int VarTmplRedecl1;
128 template<typename T> __declspec(dllimport) extern int VarTmplRedecl1;
129 USEVAR(VarTmplRedecl1<ImplicitInst_Imported>)
130
131 // MSC-DAG: @"\01??$VarTmplRedecl2@UImplicitInst_Imported@@@@3HA" = external dllimport global i32
132 // GNU-DAG: @_Z14VarTmplRedecl2I21ImplicitInst_ImportedE = external dllimport global i32
133 template<typename T> __declspec(dllimport) int VarTmplRedecl2;
134 template<typename T> __declspec(dllimport) int VarTmplRedecl2;
135 USEVAR(VarTmplRedecl2<ImplicitInst_Imported>)
136
137 // MSC-DAG: @"\01??$VarTmplRedecl3@UImplicitInst_Imported@@@@3HA" = external global i32
138 // GNU-DAG: @_Z14VarTmplRedecl3I21ImplicitInst_ImportedE = external global i32
139 template<typename T> __declspec(dllimport) extern int VarTmplRedecl3;
140 template<typename T> extern int VarTmplRedecl3; // dllimport ignored
141 USEVAR(VarTmplRedecl3<ImplicitInst_Imported>)
142
143
144 // MSC-DAG: @"\01??$ExternalVarTmpl@UImplicitInst_Imported@@@ns@@3HA" = external dllimport global i32
145 // GNU-DAG: @_ZN2ns15ExternalVarTmplI21ImplicitInst_ImportedEE = external dllimport global i32
146 namespace ns { template<typename T> __declspec(dllimport) int ExternalVarTmpl; }
147 USEVAR(ns::ExternalVarTmpl<ImplicitInst_Imported>)
148
149
150 template<typename T> int VarTmpl;
151 template<typename T> __declspec(dllimport) int ImportedVarTmpl;
152
153 // Import implicit instantiation of an imported variable template.
154 // MSC-DAG: @"\01??$ImportedVarTmpl@UImplicitInst_Imported@@@@3HA" = external dllimport global i32
155 // GNU-DAG: @_Z15ImportedVarTmplI21ImplicitInst_ImportedE = external dllimport global i32
156 USEVAR(ImportedVarTmpl<ImplicitInst_Imported>)
157
158 // Import explicit instantiation declaration of an imported variable template.
159 // MSC-DAG: @"\01??$ImportedVarTmpl@UExplicitDecl_Imported@@@@3HA" = external dllimport global i32
160 // GNU-DAG: @_Z15ImportedVarTmplI21ExplicitDecl_ImportedE = external dllimport global i32
161 extern template int ImportedVarTmpl<ExplicitDecl_Imported>;
162 USEVAR(ImportedVarTmpl<ExplicitDecl_Imported>)
163
164 // An explicit instantiation definition of an imported variable template cannot
165 // be imported because the template must be defined which is illegal.
166
167 // Import specialization of an imported variable template.
168 // MSC-DAG: @"\01??$ImportedVarTmpl@UExplicitSpec_Imported@@@@3HA" = external dllimport global i32
169 // GNU-DAG: @_Z15ImportedVarTmplI21ExplicitSpec_ImportedE = external dllimport global i32
170 template<> __declspec(dllimport) int ImportedVarTmpl<ExplicitSpec_Imported>;
171 USEVAR(ImportedVarTmpl<ExplicitSpec_Imported>)
172
173 // Not importing specialization of an imported variable template without
174 // explicit dllimport.
175 // MSC-DAG: @"\01??$ImportedVarTmpl@UExplicitSpec_NotImported@@@@3HA" = global i32 0, align 4
176 // GNU-DAG: @_Z15ImportedVarTmplI24ExplicitSpec_NotImportedE = global i32 0, align 4
177 template<> int ImportedVarTmpl<ExplicitSpec_NotImported>;
178 USEVAR(ImportedVarTmpl<ExplicitSpec_NotImported>)
179
180 // Import explicit instantiation declaration of a non-imported variable template.
181 // MSC-DAG: @"\01??$VarTmpl@UExplicitDecl_Imported@@@@3HA" = external dllimport global i32
182 // GNU-DAG: @_Z7VarTmplI21ExplicitDecl_ImportedE = external dllimport global i32
183 extern template __declspec(dllimport) int VarTmpl<ExplicitDecl_Imported>;
184 USEVAR(VarTmpl<ExplicitDecl_Imported>)
185
186 // Import explicit instantiation definition of a non-imported variable template.
187 // MSC-DAG: @"\01??$VarTmpl@UExplicitInst_Imported@@@@3HA" = external dllimport global i32
188 // GNU-DAG: @_Z7VarTmplI21ExplicitInst_ImportedE = external dllimport global i32
189 template __declspec(dllimport) int VarTmpl<ExplicitInst_Imported>;
190 USEVAR(VarTmpl<ExplicitInst_Imported>)
191
192 // Import specialization of a non-imported variable template.
193 // MSC-DAG: @"\01??$VarTmpl@UExplicitSpec_Imported@@@@3HA" = external dllimport global i32
194 // GNU-DAG: @_Z7VarTmplI21ExplicitSpec_ImportedE = external dllimport global i32
195 template<> __declspec(dllimport) int VarTmpl<ExplicitSpec_Imported>;
196 USEVAR(VarTmpl<ExplicitSpec_Imported>)
197
198
199
200 //===----------------------------------------------------------------------===//
201 // Functions
202 //===----------------------------------------------------------------------===//
203
204 // Import function declaration.
205 // MSC-DAG: declare dllimport void @"\01?decl@@YAXXZ"()
206 // GNU-DAG: declare dllimport void @_Z4declv()
207 __declspec(dllimport) void decl();
208 USE(decl)
209
210 // extern "C"
211 // MSC-DAG: declare dllimport void @externC()
212 // GNU-DAG: declare dllimport void @externC()
213 extern "C" __declspec(dllimport) void externC();
USE(externC)214 USE(externC)
215
216 // Import inline function.
217 // MSC-DAG: declare dllimport void @"\01?inlineFunc@@YAXXZ"()
218 // GNU-DAG: define linkonce_odr void @_Z10inlineFuncv()
219 // MO1-DAG: define available_externally dllimport void @"\01?inlineFunc@@YAXXZ"()
220 // GO1-DAG: define linkonce_odr void @_Z10inlineFuncv()
221 __declspec(dllimport) inline void inlineFunc() {}
222 USE(inlineFunc)
223
224 // MSC-DAG: declare dllimport void @"\01?inlineDecl@@YAXXZ"()
225 // GNU-DAG: define linkonce_odr void @_Z10inlineDeclv()
226 // MO1-DAG: define available_externally dllimport void @"\01?inlineDecl@@YAXXZ"()
227 // GO1-DAG: define linkonce_odr void @_Z10inlineDeclv()
228 __declspec(dllimport) inline void inlineDecl();
inlineDecl()229 void inlineDecl() {}
230 USE(inlineDecl)
231
232 // MSC-DAG: declare dllimport void @"\01?inlineDef@@YAXXZ"()
233 // GNU-DAG: define linkonce_odr void @_Z9inlineDefv()
234 // MO1-DAG: define available_externally dllimport void @"\01?inlineDef@@YAXXZ"()
235 // GO1-DAG: define linkonce_odr void @_Z9inlineDefv()
236 __declspec(dllimport) void inlineDef();
inlineDef()237 inline void inlineDef() {}
USE(inlineDef)238 USE(inlineDef)
239
240 // inline attributes
241 // MSC-DAG: declare dllimport void @"\01?noinline@@YAXXZ"()
242 // GNU-DAG: define linkonce_odr void @_Z8noinlinev()
243 __declspec(dllimport) __attribute__((noinline)) inline void noinline() {}
USE(noinline)244 USE(noinline)
245
246 // MSC2-NOT: @"\01?alwaysInline@@YAXXZ"()
247 // GNU2-NOT: @_Z12alwaysInlinev()
248 __declspec(dllimport) __attribute__((always_inline)) inline void alwaysInline() {}
249 USE(alwaysInline)
250
251 // Redeclarations
252 // MSC-DAG: declare dllimport void @"\01?redecl1@@YAXXZ"()
253 // GNU-DAG: declare dllimport void @_Z7redecl1v()
254 __declspec(dllimport) void redecl1();
255 __declspec(dllimport) void redecl1();
256 USE(redecl1)
257
258 // NB: MSC issues a warning and makes redecl2/redecl3 dllexport. We follow GCC
259 // and drop the dllimport with a warning.
260 // MSC-DAG: declare void @"\01?redecl2@@YAXXZ"()
261 // GNU-DAG: declare void @_Z7redecl2v()
262 __declspec(dllimport) void redecl2();
263 void redecl2();
264 USE(redecl2)
265
266 // MSC-DAG: define void @"\01?redecl3@@YAXXZ"()
267 // GNU-DAG: define void @_Z7redecl3v()
268 __declspec(dllimport) void redecl3();
redecl3()269 void redecl3() {} // dllimport ignored
270 USE(redecl3)
271
272
273 // Friend functions
274 // MSC-DAG: declare dllimport void @"\01?friend1@@YAXXZ"()
275 // GNU-DAG: declare dllimport void @_Z7friend1v()
276 // MSC-DAG: declare void @"\01?friend2@@YAXXZ"()
277 // GNU-DAG: declare void @_Z7friend2v()
278 // MSC-DAG: define void @"\01?friend3@@YAXXZ"()
279 // GNU-DAG: define void @_Z7friend3v()
280 // MSC-DAG: declare void @"\01?friend4@@YAXXZ"()
281 // GNU-DAG: declare void @_Z7friend4v()
282 // MSC-DAG: declare dllimport void @"\01?friend5@@YAXXZ"()
283 // GNU-DAG: declare dllimport void @_Z7friend5v()
284
285 struct FuncFriend {
286 friend __declspec(dllimport) void friend1();
287 friend __declspec(dllimport) void friend2();
288 friend __declspec(dllimport) void friend3();
289 };
290 __declspec(dllimport) void friend1();
291 void friend2(); // dllimport ignored
friend3()292 void friend3() {} // dllimport ignored
293
294 __declspec(dllimport) void friend4();
295 __declspec(dllimport) void friend5();
296 struct FuncFriendRedecl {
297 friend void friend4(); // dllimport ignored
298 friend void ::friend5();
299 };
300 USE(friend1)
301 USE(friend2)
302 USE(friend3)
303 USE(friend4)
304 USE(friend5)
305
306 // Implicit declarations can be redeclared with dllimport.
307 // MSC-DAG: declare dllimport noalias i8* @"\01??2@{{YAPAXI|YAPEAX_K}}@Z"(
308 // GNU-DAG: declare dllimport noalias i8* @_Znw{{[yj]}}(
309 __declspec(dllimport) void* operator new(__SIZE_TYPE__ n);
UNIQ(use)310 void UNIQ(use)() { ::operator new(42); }
311
312 // MSC-DAG: declare dllimport void @"\01?externalFunc@ns@@YAXXZ"()
313 // GNU-DAG: declare dllimport void @_ZN2ns12externalFuncEv()
314 namespace ns { __declspec(dllimport) void externalFunc(); }
315 USE(ns::externalFunc)
316
317 // A dllimport function referencing non-imported vars or functions must not be available_externally.
318 __declspec(dllimport) int ImportedVar;
319 int NonImportedVar;
320 __declspec(dllimport) int ImportedFunc();
321 int NonImportedFunc();
ReferencingImportedVar()322 __declspec(dllimport) inline int ReferencingImportedVar() { return ImportedVar; }
323 // MO1-DAG: define available_externally dllimport i32 @"\01?ReferencingImportedVar@@YAHXZ"
ReferencingNonImportedVar()324 __declspec(dllimport) inline int ReferencingNonImportedVar() { return NonImportedVar; }
325 // MO1-DAG: declare dllimport i32 @"\01?ReferencingNonImportedVar@@YAHXZ"()
ReferencingImportedFunc()326 __declspec(dllimport) inline int ReferencingImportedFunc() { return ImportedFunc(); }
327 // MO1-DAG: define available_externally dllimport i32 @"\01?ReferencingImportedFunc@@YAHXZ"
ReferencingNonImportedFunc()328 __declspec(dllimport) inline int ReferencingNonImportedFunc() { return NonImportedFunc(); }
329 // MO1-DAG: declare dllimport i32 @"\01?ReferencingNonImportedFunc@@YAHXZ"()
330 USE(ReferencingImportedVar)
USE(ReferencingNonImportedVar)331 USE(ReferencingNonImportedVar)
332 USE(ReferencingImportedFunc)
333 USE(ReferencingNonImportedFunc)
334 // References to operator new and delete count too, despite not being DeclRefExprs.
335 __declspec(dllimport) inline int *ReferencingNonImportedNew() { return new int[2]; }
336 // MO1-DAG: declare dllimport i32* @"\01?ReferencingNonImportedNew@@YAPAHXZ"
ReferencingNonImportedDelete()337 __declspec(dllimport) inline int *ReferencingNonImportedDelete() { delete (int*)nullptr; }
338 // MO1-DAG: declare dllimport i32* @"\01?ReferencingNonImportedDelete@@YAPAHXZ"
339 USE(ReferencingNonImportedNew)
340 USE(ReferencingNonImportedDelete)
341 __declspec(dllimport) void* operator new[](__SIZE_TYPE__);
342 __declspec(dllimport) void operator delete(void*);
ReferencingImportedNew()343 __declspec(dllimport) inline int *ReferencingImportedNew() { return new int[2]; }
344 // MO1-DAG: define available_externally dllimport i32* @"\01?ReferencingImportedNew@@YAPAHXZ"
ReferencingImportedDelete()345 __declspec(dllimport) inline int *ReferencingImportedDelete() { delete (int*)nullptr; }
346 // MO1-DAG: define available_externally dllimport i32* @"\01?ReferencingImportedDelete@@YAPAHXZ"
347 USE(ReferencingImportedNew)
USE(ReferencingImportedDelete)348 USE(ReferencingImportedDelete)
349
350 // A dllimport function with a TLS variable must not be available_externally.
351 __declspec(dllimport) inline void FunctionWithTLSVar() { static __thread int x = 42; }
352 // MO1-DAG: declare dllimport void @"\01?FunctionWithTLSVar@@YAXXZ"
FunctionWithNormalVar()353 __declspec(dllimport) inline void FunctionWithNormalVar() { static int x = 42; }
354 // MO1-DAG: define available_externally dllimport void @"\01?FunctionWithNormalVar@@YAXXZ"
355 USE(FunctionWithTLSVar)
356 USE(FunctionWithNormalVar)
357
358
359 //===----------------------------------------------------------------------===//
360 // Function templates
361 //===----------------------------------------------------------------------===//
362
363 // Import function template declaration.
364 // MSC-DAG: declare dllimport void @"\01??$funcTmplDecl@UImplicitInst_Imported@@@@YAXXZ"()
365 // GNU-DAG: declare dllimport void @_Z12funcTmplDeclI21ImplicitInst_ImportedEvv()
366 template<typename T> __declspec(dllimport) void funcTmplDecl();
USE(funcTmplDecl<ImplicitInst_Imported>)367 USE(funcTmplDecl<ImplicitInst_Imported>)
368
369 // Function template definitions cannot be imported.
370
371 // Import inline function template.
372 // MSC-DAG: declare dllimport void @"\01??$inlineFuncTmpl1@UImplicitInst_Imported@@@@YAXXZ"()
373 // GNU-DAG: define linkonce_odr void @_Z15inlineFuncTmpl1I21ImplicitInst_ImportedEvv()
374 // MO1-DAG: define available_externally dllimport void @"\01??$inlineFuncTmpl1@UImplicitInst_Imported@@@@YAXXZ"()
375 // GO1-DAG: define linkonce_odr void @_Z15inlineFuncTmpl1I21ImplicitInst_ImportedEvv()
376 template<typename T> __declspec(dllimport) inline void inlineFuncTmpl1() {}
USE(inlineFuncTmpl1<ImplicitInst_Imported>)377 USE(inlineFuncTmpl1<ImplicitInst_Imported>)
378
379 // MSC-DAG: declare dllimport void @"\01??$inlineFuncTmpl2@UImplicitInst_Imported@@@@YAXXZ"()
380 // GNU-DAG: define linkonce_odr void @_Z15inlineFuncTmpl2I21ImplicitInst_ImportedEvv()
381 // MO1-DAG: define available_externally dllimport void @"\01??$inlineFuncTmpl2@UImplicitInst_Imported@@@@YAXXZ"()
382 // GO1-DAG: define linkonce_odr void @_Z15inlineFuncTmpl2I21ImplicitInst_ImportedEvv()
383 template<typename T> inline void __attribute__((dllimport)) inlineFuncTmpl2() {}
384 USE(inlineFuncTmpl2<ImplicitInst_Imported>)
385
386 // MSC-DAG: declare dllimport void @"\01??$inlineFuncTmplDecl@UImplicitInst_Imported@@@@YAXXZ"()
387 // GNU-DAG: define linkonce_odr void @_Z18inlineFuncTmplDeclI21ImplicitInst_ImportedEvv()
388 // MO1-DAG: define available_externally dllimport void @"\01??$inlineFuncTmplDecl@UImplicitInst_Imported@@@@YAXXZ"()
389 // GO1-DAG: define linkonce_odr void @_Z18inlineFuncTmplDeclI21ImplicitInst_ImportedEvv()
390 template<typename T> __declspec(dllimport) inline void inlineFuncTmplDecl();
inlineFuncTmplDecl()391 template<typename T> void inlineFuncTmplDecl() {}
392 USE(inlineFuncTmplDecl<ImplicitInst_Imported>)
393
394 // MSC-DAG: declare dllimport void @"\01??$inlineFuncTmplDef@UImplicitInst_Imported@@@@YAXXZ"()
395 // GNU-DAG: define linkonce_odr void @_Z17inlineFuncTmplDefI21ImplicitInst_ImportedEvv()
396 // MO1-DAG: define available_externally dllimport void @"\01??$inlineFuncTmplDef@UImplicitInst_Imported@@@@YAXXZ"()
397 // GO1-DAG: define linkonce_odr void @_Z17inlineFuncTmplDefI21ImplicitInst_ImportedEvv()
398 template<typename T> __declspec(dllimport) void inlineFuncTmplDef();
inlineFuncTmplDef()399 template<typename T> inline void inlineFuncTmplDef() {}
400 USE(inlineFuncTmplDef<ImplicitInst_Imported>)
401
402
403 // Redeclarations
404 // MSC-DAG: declare dllimport void @"\01??$funcTmplRedecl1@UImplicitInst_Imported@@@@YAXXZ"()
405 // GNU-DAG: declare dllimport void @_Z15funcTmplRedecl1I21ImplicitInst_ImportedEvv()
406 template<typename T> __declspec(dllimport) void funcTmplRedecl1();
407 template<typename T> __declspec(dllimport) void funcTmplRedecl1();
408 USE(funcTmplRedecl1<ImplicitInst_Imported>)
409
410 // MSC-DAG: declare void @"\01??$funcTmplRedecl2@UImplicitInst_NotImported@@@@YAXXZ"()
411 // GNU-DAG: declare void @_Z15funcTmplRedecl2I24ImplicitInst_NotImportedEvv()
412 template<typename T> __declspec(dllimport) void funcTmplRedecl2();
413 template<typename T> void funcTmplRedecl2(); // dllimport ignored
414 USE(funcTmplRedecl2<ImplicitInst_NotImported>)
415
416 // MSC-DAG: define linkonce_odr void @"\01??$funcTmplRedecl3@UImplicitInst_NotImported@@@@YAXXZ"()
417 // GNU-DAG: define linkonce_odr void @_Z15funcTmplRedecl3I24ImplicitInst_NotImportedEvv()
418 template<typename T> __declspec(dllimport) void funcTmplRedecl3();
funcTmplRedecl3()419 template<typename T> void funcTmplRedecl3() {} // dllimport ignored
420 USE(funcTmplRedecl3<ImplicitInst_NotImported>)
421
422
423 // Function template friends
424 // MSC-DAG: declare dllimport void @"\01??$funcTmplFriend1@UImplicitInst_Imported@@@@YAXXZ"()
425 // GNU-DAG: declare dllimport void @_Z15funcTmplFriend1I21ImplicitInst_ImportedEvv()
426 // MSC-DAG: declare void @"\01??$funcTmplFriend2@UImplicitInst_NotImported@@@@YAXXZ"()
427 // GNU-DAG: declare void @_Z15funcTmplFriend2I24ImplicitInst_NotImportedEvv()
428 // MSC-DAG: define linkonce_odr void @"\01??$funcTmplFriend3@UImplicitInst_NotImported@@@@YAXXZ"()
429 // GNU-DAG: define linkonce_odr void @_Z15funcTmplFriend3I24ImplicitInst_NotImportedEvv()
430 // MSC-DAG: declare dllimport void @"\01??$funcTmplFriend4@UImplicitInst_Imported@@@@YAXXZ"()
431 // GNU-DAG: define linkonce_odr void @_Z15funcTmplFriend4I21ImplicitInst_ImportedEvv()
432 struct FuncTmplFriend {
433 template<typename T> friend __declspec(dllimport) void funcTmplFriend1();
434 template<typename T> friend __declspec(dllimport) void funcTmplFriend2();
435 template<typename T> friend __declspec(dllimport) void funcTmplFriend3();
436 template<typename T> friend __declspec(dllimport) inline void funcTmplFriend4();
437 };
438 template<typename T> __declspec(dllimport) void funcTmplFriend1();
439 template<typename T> void funcTmplFriend2(); // dllimport ignored
funcTmplFriend3()440 template<typename T> void funcTmplFriend3() {} // dllimport ignored
funcTmplFriend4()441 template<typename T> inline void funcTmplFriend4() {}
442 USE(funcTmplFriend1<ImplicitInst_Imported>)
443 USE(funcTmplFriend2<ImplicitInst_NotImported>)
444 USE(funcTmplFriend3<ImplicitInst_NotImported>)
445 USE(funcTmplFriend4<ImplicitInst_Imported>)
446
447 // MSC-DAG: declare dllimport void @"\01??$externalFuncTmpl@UImplicitInst_Imported@@@ns@@YAXXZ"()
448 // GNU-DAG: declare dllimport void @_ZN2ns16externalFuncTmplI21ImplicitInst_ImportedEEvv()
449 namespace ns { template<typename T> __declspec(dllimport) void externalFuncTmpl(); }
USE(ns::externalFuncTmpl<ImplicitInst_Imported>)450 USE(ns::externalFuncTmpl<ImplicitInst_Imported>)
451
452
453 template<typename T> void funcTmpl() {}
inlineFuncTmpl()454 template<typename T> inline void inlineFuncTmpl() {}
455 template<typename T> __declspec(dllimport) void importedFuncTmplDecl();
importedFuncTmpl()456 template<typename T> __declspec(dllimport) inline void importedFuncTmpl() {}
457
458 // Import implicit instantiation of an imported function template.
459 // MSC-DAG: declare dllimport void @"\01??$importedFuncTmplDecl@UImplicitInst_Imported@@@@YAXXZ"()
460 // GNU-DAG: declare dllimport void @_Z20importedFuncTmplDeclI21ImplicitInst_ImportedEvv()
461 USE(importedFuncTmplDecl<ImplicitInst_Imported>)
462
463 // MSC-DAG: declare dllimport void @"\01??$importedFuncTmpl@UImplicitInst_Imported@@@@YAXXZ"()
464 // GNU-DAG: define linkonce_odr void @_Z16importedFuncTmplI21ImplicitInst_ImportedEvv()
465 // MO1-DAG: define available_externally dllimport void @"\01??$importedFuncTmpl@UImplicitInst_Imported@@@@YAXXZ"()
466 // GO1-DAG: define linkonce_odr void @_Z16importedFuncTmplI21ImplicitInst_ImportedEvv()
467 USE(importedFuncTmpl<ImplicitInst_Imported>)
468
469 // Import explicit instantiation declaration of an imported function template.
470 // MSC-DAG: declare dllimport void @"\01??$importedFuncTmpl@UExplicitDecl_Imported@@@@YAXXZ"()
471 // GNU-DAG: declare void @_Z16importedFuncTmplI21ExplicitDecl_ImportedEvv()
472 // MO1-DAG: define available_externally dllimport void @"\01??$importedFuncTmpl@UExplicitDecl_Imported@@@@YAXXZ"()
473 // GO1-DAG: define available_externally void @_Z16importedFuncTmplI21ExplicitDecl_ImportedEvv()
474 extern template void importedFuncTmpl<ExplicitDecl_Imported>();
475 USE(importedFuncTmpl<ExplicitDecl_Imported>)
476
477 // Import explicit instantiation definition of an imported function template.
478 // MSC-DAG: declare dllimport void @"\01??$importedFuncTmpl@UExplicitInst_Imported@@@@YAXXZ"()
479 // GNU-DAG: define weak_odr void @_Z16importedFuncTmplI21ExplicitInst_ImportedEvv()
480 // MO1-DAG: define available_externally dllimport void @"\01??$importedFuncTmpl@UExplicitInst_Imported@@@@YAXXZ"()
481 // GO1-DAG: define weak_odr void @_Z16importedFuncTmplI21ExplicitInst_ImportedEvv()
482 template void importedFuncTmpl<ExplicitInst_Imported>();
483 USE(importedFuncTmpl<ExplicitInst_Imported>)
484
485
486 // Import specialization of an imported function template.
487 // MSC-DAG: declare dllimport void @"\01??$importedFuncTmplDecl@UExplicitSpec_Imported@@@@YAXXZ"()
488 // GNU-DAG: declare dllimport void @_Z20importedFuncTmplDeclI21ExplicitSpec_ImportedEvv()
489 template<> __declspec(dllimport) void importedFuncTmplDecl<ExplicitSpec_Imported>();
USE(importedFuncTmplDecl<ExplicitSpec_Imported>)490 USE(importedFuncTmplDecl<ExplicitSpec_Imported>)
491
492 // MSC-DAG-FIXME: declare dllimport void @"\01??$importedFuncTmplDecl@UExplicitSpec_Def_Imported@@@@YAXXZ"()
493 // MO1-DAG-FIXME: define available_externally dllimport void @"\01??$importedFuncTmplDecl@UExplicitSpec_Def_Imported@@@@YAXXZ"()
494 #ifdef MSABI
495 //template<> __declspec(dllimport) void importedFuncTmplDecl<ExplicitSpec_Def_Imported>() {}
496 //USE(importedFuncTmplDecl<ExplicitSpec_Def_Imported>)
497 #endif
498
499 // MSC-DAG: declare dllimport void @"\01??$importedFuncTmplDecl@UExplicitSpec_InlineDef_Imported@@@@YAXXZ"()
500 // GNU-DAG: define linkonce_odr void @_Z20importedFuncTmplDeclI31ExplicitSpec_InlineDef_ImportedEvv()
501 // MO1-DAG: define available_externally dllimport void @"\01??$importedFuncTmplDecl@UExplicitSpec_InlineDef_Imported@@@@YAXXZ"()
502 // GO1-DAG: define linkonce_odr void @_Z20importedFuncTmplDeclI31ExplicitSpec_InlineDef_ImportedEvv()
503 template<> __declspec(dllimport) inline void importedFuncTmplDecl<ExplicitSpec_InlineDef_Imported>() {}
504 USE(importedFuncTmplDecl<ExplicitSpec_InlineDef_Imported>)
505
506
507 // MSC-DAG: declare dllimport void @"\01??$importedFuncTmpl@UExplicitSpec_Imported@@@@YAXXZ"()
508 // GNU-DAG: declare dllimport void @_Z16importedFuncTmplI21ExplicitSpec_ImportedEvv()
509 template<> __declspec(dllimport) void importedFuncTmpl<ExplicitSpec_Imported>();
USE(importedFuncTmpl<ExplicitSpec_Imported>)510 USE(importedFuncTmpl<ExplicitSpec_Imported>)
511
512 // MSC-DAG-FIXME: declare dllimport void @"\01??$importedFuncTmpl@UExplicitSpec_Def_Imported@@@@YAXXZ"()
513 // MO1-DAG-FIXME: define available_externally dllimport void @"\01??$importedFuncTmpl@UExplicitSpec_Def_Imported@@@@YAXXZ"()
514 #ifdef MSABI
515 //template<> __declspec(dllimport) void importedFuncTmpl<ExplicitSpec_Def_Imported>() {}
516 //USE(importedFuncTmpl<ExplicitSpec_Def_Imported>)
517 #endif
518
519 // MSC-DAG: declare dllimport void @"\01??$importedFuncTmpl@UExplicitSpec_InlineDef_Imported@@@@YAXXZ"()
520 // GNU-DAG: define linkonce_odr void @_Z16importedFuncTmplI31ExplicitSpec_InlineDef_ImportedEvv()
521 // MO1-DAG: define available_externally dllimport void @"\01??$importedFuncTmpl@UExplicitSpec_InlineDef_Imported@@@@YAXXZ"()
522 // GO1-DAG: define linkonce_odr void @_Z16importedFuncTmplI31ExplicitSpec_InlineDef_ImportedEvv()
523 template<> __declspec(dllimport) inline void importedFuncTmpl<ExplicitSpec_InlineDef_Imported>() {}
USE(importedFuncTmpl<ExplicitSpec_InlineDef_Imported>)524 USE(importedFuncTmpl<ExplicitSpec_InlineDef_Imported>)
525
526
527 // Not importing specialization of an imported function template without
528 // explicit dllimport.
529 // MSC-DAG: define void @"\01??$importedFuncTmpl@UExplicitSpec_NotImported@@@@YAXXZ"()
530 // GNU-DAG: define void @_Z16importedFuncTmplI24ExplicitSpec_NotImportedEvv()
531 template<> void importedFuncTmpl<ExplicitSpec_NotImported>() {}
532 USE(importedFuncTmpl<ExplicitSpec_NotImported>)
533
534
535 // Import explicit instantiation declaration of a non-imported function template.
536 // MSC-DAG: declare dllimport void @"\01??$funcTmpl@UExplicitDecl_Imported@@@@YAXXZ"()
537 // MSC-DAG: declare dllimport void @"\01??$inlineFuncTmpl@UExplicitDecl_Imported@@@@YAXXZ"()
538 // GNU-DAG: declare dllimport void @_Z8funcTmplI21ExplicitDecl_ImportedEvv()
539 // GNU-DAG: declare void @_Z14inlineFuncTmplI21ExplicitDecl_ImportedEvv()
540 // MO1-DAG: define available_externally dllimport void @"\01??$inlineFuncTmpl@UExplicitDecl_Imported@@@@YAXXZ"()
541 // GO1-DAG: define available_externally void @_Z14inlineFuncTmplI21ExplicitDecl_ImportedEvv()
542 extern template __declspec(dllimport) void funcTmpl<ExplicitDecl_Imported>();
543 extern template __declspec(dllimport) void inlineFuncTmpl<ExplicitDecl_Imported>();
544 USE(funcTmpl<ExplicitDecl_Imported>)
545 USE(inlineFuncTmpl<ExplicitDecl_Imported>)
546
547
548 // Import explicit instantiation definition of a non-imported function template.
549 // MSC-DAG: declare dllimport void @"\01??$funcTmpl@UExplicitInst_Imported@@@@YAXXZ"()
550 // MSC-DAG: declare dllimport void @"\01??$inlineFuncTmpl@UExplicitInst_Imported@@@@YAXXZ"()
551 // GNU-DAG: declare dllimport void @_Z8funcTmplI21ExplicitInst_ImportedEvv()
552 // GNU-DAG: define weak_odr void @_Z14inlineFuncTmplI21ExplicitInst_ImportedEvv()
553 // MO1-DAG: define available_externally dllimport void @"\01??$funcTmpl@UExplicitInst_Imported@@@@YAXXZ"()
554 // MO1-DAG: define available_externally dllimport void @"\01??$inlineFuncTmpl@UExplicitInst_Imported@@@@YAXXZ"()
555 // GO1-DAG: define available_externally dllimport void @_Z8funcTmplI21ExplicitInst_ImportedEvv()
556 // GO1-DAG: define weak_odr void @_Z14inlineFuncTmplI21ExplicitInst_ImportedEvv()
557 template __declspec(dllimport) void funcTmpl<ExplicitInst_Imported>();
558 template __declspec(dllimport) void inlineFuncTmpl<ExplicitInst_Imported>();
559 USE(funcTmpl<ExplicitInst_Imported>)
560 USE(inlineFuncTmpl<ExplicitInst_Imported>)
561
562
563 // Import specialization of a non-imported function template.
564 // MSC-DAG: declare dllimport void @"\01??$funcTmpl@UExplicitSpec_Imported@@@@YAXXZ"()
565 // GNU-DAG: declare dllimport void @_Z8funcTmplI21ExplicitSpec_ImportedEvv()
566 template<> __declspec(dllimport) void funcTmpl<ExplicitSpec_Imported>();
USE(funcTmpl<ExplicitSpec_Imported>)567 USE(funcTmpl<ExplicitSpec_Imported>)
568
569 // MSC-DAG-FIXME: declare dllimport void @"\01??$funcTmpl@UExplicitSpec_Def_Imported@@@@YAXXZ"()
570 // MO1-DAG-FIXME: define available_externally dllimport void @"\01??$funcTmpl@UExplicitSpec_Def_Imported@@@@YAXXZ"()
571 #ifdef MSABI
572 //template<> __declspec(dllimport) void funcTmpl<ExplicitSpec_Def_Imported>() {}
573 //USE(funcTmpl<ExplicitSpec_Def_Imported>)
574 #endif
575
576 // MSC-DAG: declare dllimport void @"\01??$funcTmpl@UExplicitSpec_InlineDef_Imported@@@@YAXXZ"()
577 // GNU-DAG: define linkonce_odr void @_Z8funcTmplI31ExplicitSpec_InlineDef_ImportedEvv()
578 // MO1-DAG: define available_externally dllimport void @"\01??$funcTmpl@UExplicitSpec_InlineDef_Imported@@@@YAXXZ"()
579 // GO1-DAG: define linkonce_odr void @_Z8funcTmplI31ExplicitSpec_InlineDef_ImportedEvv()
580 template<> __declspec(dllimport) inline void funcTmpl<ExplicitSpec_InlineDef_Imported>() {}
581 USE(funcTmpl<ExplicitSpec_InlineDef_Imported>)
582
583
584
585 //===----------------------------------------------------------------------===//
586 // Classes
587 //===----------------------------------------------------------------------===//
588
589 struct __declspec(dllimport) T {
aT590 void a() {}
591 // MO1-DAG: define available_externally dllimport x86_thiscallcc void @"\01?a@T@@QAEXXZ"
592
593 static int b;
594 // MO1-DAG: @"\01?b@T@@2HA" = external dllimport global i32
595
596 T& operator=(T&) = default;
597 // MO1-DAG: define available_externally dllimport x86_thiscallcc dereferenceable({{[0-9]+}}) %struct.T* @"\01??4T@@QAEAAU0@AAU0@@Z"
598
599 T& operator=(T&&) = default;
600 // Note: Don't mark inline move operators dllimport because current MSVC versions don't export them.
601 // M18-DAG: define linkonce_odr x86_thiscallcc dereferenceable({{[0-9]+}}) %struct.T* @"\01??4T@@QAEAAU0@$$QAU0@@Z"
602 // M19-DAG: define available_externally dllimport x86_thiscallcc dereferenceable({{[0-9]+}}) %struct.T* @"\01??4T@@QAEAAU0@$$QAU0@@Z"
603 };
604 USEMEMFUNC(T, a)
605 USEVAR(T::b)
606 USECOPYASSIGN(T)
607 USEMOVEASSIGN(T)
608
fooU609 template <typename T> struct __declspec(dllimport) U { void foo() {} };
610 // MO1-DAG: define available_externally dllimport x86_thiscallcc void @"\01?foo@?$U@H@@QAEXXZ"
611 struct __declspec(dllimport) V : public U<int> { };
612 USEMEMFUNC(V, foo)
613
fooW614 struct __declspec(dllimport) W { virtual void foo() {} };
615 USECLASS(W)
616 // vftable:
617 // MO1-DAG: @"\01??_7W@@6B@" = available_externally dllimport unnamed_addr constant [1 x i8*] [i8* bitcast (void (%struct.W*)* @"\01?foo@W@@UAEXXZ" to i8*)]
618 // GO1-DAG: @_ZTV1W = available_externally dllimport unnamed_addr constant [3 x i8*] [i8* null, i8* null, i8* bitcast (void (%struct.W*)* @_ZN1W3fooEv to i8*)]
619
620 struct __declspec(dllimport) KeyFuncClass {
KeyFuncClassKeyFuncClass621 constexpr KeyFuncClass() {}
622 virtual void foo();
623 };
624 extern constexpr KeyFuncClass keyFuncClassVar = {};
625 // G32-DAG: @_ZTV12KeyFuncClass = external dllimport unnamed_addr constant [3 x i8*]
626
627 struct __declspec(dllimport) X : public virtual W {};
628 USECLASS(X)
629 // vbtable:
630 // MO1-DAG: @"\01??_8X@@7B@" = available_externally dllimport unnamed_addr constant [2 x i32] [i32 0, i32 4]
631
632 struct __declspec(dllimport) Y {
633 int x;
634 };
635
~ZZ636 struct __declspec(dllimport) Z { virtual ~Z() {} };
637 USECLASS(Z)
638 // User-defined dtor:
639 // MO1-DAG: define available_externally dllimport x86_thiscallcc void @"\01??1Z@@UAE@XZ"
640
641 namespace DontUseDtorAlias {
642 struct __declspec(dllimport) A { ~A(); };
643 struct __declspec(dllimport) B : A { ~B(); };
~A()644 inline A::~A() { }
~B()645 inline B::~B() { }
646 // Emit a real definition of B's constructor; don't alias it to A's.
647 // MO1-DAG: available_externally dllimport x86_thiscallcc void @"\01??1B@DontUseDtorAlias@@QAE@XZ"
648 USECLASS(B)
649 }
650
651 namespace Vtordisp {
652 // Don't dllimport the vtordisp.
653 // MO1-DAG: define linkonce_odr x86_thiscallcc void @"\01?f@?$C@D@Vtordisp@@$4PPPPPPPM@A@AEXXZ"
654
655 class Base {
f()656 virtual void f() {}
657 };
658 template <typename T>
659 class __declspec(dllimport) C : virtual public Base {
660 public:
C()661 C() {}
f()662 virtual void f() {}
663 };
664 template class C<char>;
665 }
666
667 namespace ClassTemplateStaticDef {
668 // Regular template static field:
669 template <typename T> struct __declspec(dllimport) S {
670 static int x;
671 };
672 template <typename T> int S<T>::x;
673 // MSC-DAG: @"\01?x@?$S@H@ClassTemplateStaticDef@@2HA" = available_externally dllimport global i32 0
f()674 int f() { return S<int>::x; }
675
676 // Partial class template specialization static field:
677 template <typename A> struct T;
678 template <typename A> struct __declspec(dllimport) T<A*> {
679 static int x;
680 };
681 template <typename A> int T<A*>::x;
682 // GNU-DAG: @_ZN22ClassTemplateStaticDef1TIPvE1xE = available_externally dllimport global i32 0
g()683 int g() { return T<void*>::x; }
684 }
685
686 namespace PR19933 {
687 // Don't dynamically initialize dllimport vars.
688 // MSC2-NOT: @llvm.global_ctors
689 // GNU2-NOT: @llvm.global_ctors
690
691 struct NonPOD { NonPOD(); };
692 template <typename T> struct A { static NonPOD x; };
693 template <typename T> NonPOD A<T>::x;
694 template struct __declspec(dllimport) A<int>;
695 // MSC-DAG: @"\01?x@?$A@H@PR19933@@2UNonPOD@2@A" = available_externally dllimport global %"struct.PR19933::NonPOD" zeroinitializer
696
697 int f();
698 template <typename T> struct B { static int x; };
699 template <typename T> int B<T>::x = f();
700 template struct __declspec(dllimport) B<int>;
701 // MSC-DAG: @"\01?x@?$B@H@PR19933@@2HA" = available_externally dllimport global i32 0
702
g()703 constexpr int g() { return 42; }
704 template <typename T> struct C { static int x; };
705 template <typename T> int C<T>::x = g();
706 template struct __declspec(dllimport) C<int>;
707 // MSC-DAG: @"\01?x@?$C@H@PR19933@@2HA" = available_externally dllimport global i32 42
708
709 template <int I> struct D { static int x, y; };
710 template <int I> int D<I>::x = I + 1;
711 template <int I> int D<I>::y = I + f();
712 template struct __declspec(dllimport) D<42>;
713 // MSC-DAG: @"\01?x@?$D@$0CK@@PR19933@@2HA" = available_externally dllimport global i32 43
714 // MSC-DAG: @"\01?y@?$D@$0CK@@PR19933@@2HA" = available_externally dllimport global i32 0
715 }
716
717 namespace PR21355 {
718 struct __declspec(dllimport) S {
719 virtual ~S();
720 };
~S()721 S::~S() {}
722
723 // S::~S is a key function, so we would ordinarily emit a strong definition for
724 // the vtable. However, S is imported, so the vtable should be too.
725
726 // GNU-DAG: @_ZTVN7PR213551SE = available_externally dllimport unnamed_addr constant [4 x i8*]
727 }
728
729 namespace PR21366 {
730 struct __declspec(dllimport) S {
731 void outOfLineMethod();
inlineMethodPR21366::S732 void inlineMethod() {}
733 inline void anotherInlineMethod();
734 void outOfClassInlineMethod();
735 };
anotherInlineMethod()736 void S::anotherInlineMethod() {}
outOfClassInlineMethod()737 inline void S::outOfClassInlineMethod() {}
738 }
739
740 // MS ignores DLL attributes on partial specializations.
741 template <typename T> struct PartiallySpecializedClassTemplate {};
742 template <typename T> struct __declspec(dllimport) PartiallySpecializedClassTemplate<T*> { void f(); };
743 USEMEMFUNC(PartiallySpecializedClassTemplate<void*>, f);
744 // M32-DAG: declare x86_thiscallcc void @"\01?f@?$PartiallySpecializedClassTemplate@PAX@@QAEXXZ"
745 // G32-DAG: declare dllimport x86_thiscallcc void @_ZN33PartiallySpecializedClassTemplateIPvE1fEv
746
747 // Attributes on explicit specializations are honored.
748 template <typename T> struct ExplicitlySpecializedClassTemplate {};
749 template <> struct __declspec(dllimport) ExplicitlySpecializedClassTemplate<void*> { void f(); };
750 USEMEMFUNC(ExplicitlySpecializedClassTemplate<void*>, f);
751 // M32-DAG: declare dllimport x86_thiscallcc void @"\01?f@?$ExplicitlySpecializedClassTemplate@PAX@@QAEXXZ"
752 // G32-DAG: declare dllimport x86_thiscallcc void @_ZN34ExplicitlySpecializedClassTemplateIPvE1fEv
753
754 // MS inherits DLL attributes to partial specializations.
755 template <typename T> struct __declspec(dllimport) PartiallySpecializedImportedClassTemplate {};
fPartiallySpecializedImportedClassTemplate756 template <typename T> struct PartiallySpecializedImportedClassTemplate<T*> { void f() {} };
757 USEMEMFUNC(PartiallySpecializedImportedClassTemplate<void*>, f);
758 // M32-DAG: {{declare|define available_externally}} dllimport x86_thiscallcc void @"\01?f@?$PartiallySpecializedImportedClassTemplate@PAX@@QAEXXZ"
759 // G32-DAG: define linkonce_odr x86_thiscallcc void @_ZN41PartiallySpecializedImportedClassTemplateIPvE1fEv
760
761 // Attributes on the instantiation take precedence over attributes on the template.
fExplicitlyInstantiatedWithDifferentAttr762 template <typename T> struct __declspec(dllexport) ExplicitlyInstantiatedWithDifferentAttr { void f() {} };
763 template struct __declspec(dllimport) ExplicitlyInstantiatedWithDifferentAttr<int>;
764 USEMEMFUNC(ExplicitlyInstantiatedWithDifferentAttr<int>, f);
765 // M32-DAG: {{declare|define available_externally}} dllimport x86_thiscallcc void @"\01?f@?$ExplicitlyInstantiatedWithDifferentAttr@H@@QAEXXZ"
766
fExplicitInstantiationDeclImportedDefTemplate767 template <typename T> struct ExplicitInstantiationDeclImportedDefTemplate { void f() {} ExplicitInstantiationDeclImportedDefTemplate() {}};
768 extern template struct ExplicitInstantiationDeclImportedDefTemplate<int>;
769 template struct __declspec(dllimport) ExplicitInstantiationDeclImportedDefTemplate<int>;
770 USECLASS(ExplicitInstantiationDeclImportedDefTemplate<int>);
771 USEMEMFUNC(ExplicitInstantiationDeclImportedDefTemplate<int>, f);
772 // M32-DAG: {{declare|define available_externally}} dllimport x86_thiscallcc void @"\01?f@?$ExplicitInstantiationDeclImportedDefTemplate@H@@QAEXXZ"
773 // M32-DAG: {{declare|define available_externally}} dllimport x86_thiscallcc %struct.ExplicitInstantiationDeclImportedDefTemplate* @"\01??0?$ExplicitInstantiationDeclImportedDefTemplate@H@@QAE@XZ"
774 // G32-DAG: define weak_odr x86_thiscallcc void @_ZN44ExplicitInstantiationDeclImportedDefTemplateIiE1fEv
775
ExplicitInstantiationDeclExportedDefImportedTemplateExplicitInstantiationDeclExportedDefImportedTemplate776 template <typename T> struct __declspec(dllimport) ExplicitInstantiationDeclExportedDefImportedTemplate { void f() {} ExplicitInstantiationDeclExportedDefImportedTemplate() {} };
777 extern template struct __declspec(dllimport) ExplicitInstantiationDeclExportedDefImportedTemplate <int>;
778 template struct __declspec(dllexport) ExplicitInstantiationDeclExportedDefImportedTemplate<int>;
779 USECLASS(ExplicitInstantiationDeclExportedDefImportedTemplate<int>);
780 USEMEMFUNC(ExplicitInstantiationDeclExportedDefImportedTemplate<int>, f);
781 // M32-DAG: {{declare|define available_externally}} dllimport x86_thiscallcc void @"\01?f@?$ExplicitInstantiationDeclExportedDefImportedTemplate@H@@QAEXXZ"
782 // M32-DAG: {{declare|define available_externally}} dllimport x86_thiscallcc %struct.ExplicitInstantiationDeclExportedDefImportedTemplate* @"\01??0?$ExplicitInstantiationDeclExportedDefImportedTemplate@H@@QAE@XZ"
783
fPR23770BaseTemplate784 template <typename T> struct PR23770BaseTemplate { void f() {} };
785 template <typename T> struct PR23770DerivedTemplate : PR23770BaseTemplate<int> {};
786 extern template struct PR23770DerivedTemplate<int>;
787 template struct __declspec(dllimport) PR23770DerivedTemplate<int>;
788 USEMEMFUNC(PR23770BaseTemplate<int>, f);
789 // M32-DAG: declare dllimport x86_thiscallcc void @"\01?f@?$PR23770BaseTemplate@H@@QAEXXZ"
790
791 //===----------------------------------------------------------------------===//
792 // Classes with template base classes
793 //===----------------------------------------------------------------------===//
794
funcClassTemplate795 template <typename T> struct ClassTemplate { void func() {} };
796 template <typename T> struct __declspec(dllexport) ExportedClassTemplate { void func(); };
func()797 template <typename T> void ExportedClassTemplate<T>::func() {}
798 template <typename T> struct __declspec(dllimport) ImportedClassTemplate { void func(); };
799
funcExplicitlySpecializedTemplate800 template <typename T> struct ExplicitlySpecializedTemplate { void func() {} };
funcExplicitlySpecializedTemplate801 template <> struct ExplicitlySpecializedTemplate<int> { void func() {} };
funcExplicitlyExportSpecializedTemplate802 template <typename T> struct ExplicitlyExportSpecializedTemplate { void func() {} };
803 template <> struct __declspec(dllexport) ExplicitlyExportSpecializedTemplate<int> { void func(); };
func()804 void ExplicitlyExportSpecializedTemplate<int>::func() {}
funcExplicitlyImportSpecializedTemplate805 template <typename T> struct ExplicitlyImportSpecializedTemplate { void func() {} };
806 template <> struct __declspec(dllimport) ExplicitlyImportSpecializedTemplate<int> { void func(); };
807
funcExplicitlyInstantiatedTemplate808 template <typename T> struct ExplicitlyInstantiatedTemplate { void func() {} };
809 template struct ExplicitlyInstantiatedTemplate<int>;
810 template <typename T> struct ExplicitlyExportInstantiatedTemplate { void func(); };
func()811 template <typename T> void ExplicitlyExportInstantiatedTemplate<T>::func() {}
812 template struct __declspec(dllexport) ExplicitlyExportInstantiatedTemplate<int>;
813 template <typename T> struct ExplicitlyImportInstantiatedTemplate { void func(); };
814 template struct __declspec(dllimport) ExplicitlyImportInstantiatedTemplate<int>;
815
816
817 // MS: ClassTemplate<int> gets imported.
818 struct __declspec(dllimport) DerivedFromTemplate : public ClassTemplate<int> {};
819 USEMEMFUNC(ClassTemplate<int>, func)
820 // M32-DAG: {{declare|define available_externally}} dllimport x86_thiscallcc void @"\01?func@?$ClassTemplate@H@@QAEXXZ"
821 // G32-DAG: define linkonce_odr x86_thiscallcc void @_ZN13ClassTemplateIiE4funcEv
822
823 // ImportedTemplate is explicitly imported.
824 struct __declspec(dllimport) DerivedFromImportedTemplate : public ImportedClassTemplate<int> {};
825 USEMEMFUNC(ImportedClassTemplate<int>, func)
826 // M32-DAG: declare dllimport x86_thiscallcc void @"\01?func@?$ImportedClassTemplate@H@@QAEXXZ"
827 // G32-DAG: declare dllimport x86_thiscallcc void @_ZN21ImportedClassTemplateIiE4funcEv
828
829 // ExportedTemplate is explicitly exported.
830 struct __declspec(dllimport) DerivedFromExportedTemplate : public ExportedClassTemplate<int> {};
831 USEMEMFUNC(ExportedClassTemplate<int>, func)
832 // M32-DAG: define weak_odr dllexport x86_thiscallcc void @"\01?func@?$ExportedClassTemplate@H@@QAEXXZ"
833 // G32-DAG: define weak_odr dllexport x86_thiscallcc void @_ZN21ExportedClassTemplateIiE4funcEv
834
835 // Base class already implicitly instantiated without attribute.
836 struct DerivedFromTemplateD : public ClassTemplate<double> {};
837 struct __declspec(dllimport) DerivedFromTemplateD2 : public ClassTemplate<double> {};
838 USEMEMFUNC(ClassTemplate<double>, func)
839 // M32-DAG: declare dllimport x86_thiscallcc void @"\01?func@?$ClassTemplate@N@@QAEXXZ"
840 // G32-DAG: define linkonce_odr x86_thiscallcc void @_ZN13ClassTemplateIdE4funcEv
841
842 // MS: Base class already instantiated with dfferent attribute.
843 struct __declspec(dllexport) DerivedFromTemplateB : public ClassTemplate<bool> {};
844 struct __declspec(dllimport) DerivedFromTemplateB2 : public ClassTemplate<bool> {};
845 USEMEMFUNC(ClassTemplate<bool>, func)
846 // M32-DAG: define weak_odr dllexport x86_thiscallcc void @"\01?func@?$ClassTemplate@_N@@QAEXXZ"
847 // G32-DAG: define linkonce_odr x86_thiscallcc void @_ZN13ClassTemplateIbE4funcEv
848
849 // Base class already specialized without dll attribute.
850 struct __declspec(dllimport) DerivedFromExplicitlySpecializedTemplate : public ExplicitlySpecializedTemplate<int> {};
851 USEMEMFUNC(ExplicitlySpecializedTemplate<int>, func)
852 // M32-DAG: define linkonce_odr x86_thiscallcc void @"\01?func@?$ExplicitlySpecializedTemplate@H@@QAEXXZ"
853 // G32-DAG: define linkonce_odr x86_thiscallcc void @_ZN29ExplicitlySpecializedTemplateIiE4funcEv
854
855 // Base class alredy specialized with export attribute.
856 struct __declspec(dllimport) DerivedFromExplicitlyExportSpecializedTemplate : public ExplicitlyExportSpecializedTemplate<int> {};
857 USEMEMFUNC(ExplicitlyExportSpecializedTemplate<int>, func)
858 // M32-DAG: define dllexport x86_thiscallcc void @"\01?func@?$ExplicitlyExportSpecializedTemplate@H@@QAEXXZ"
859 // G32-DAG: define dllexport x86_thiscallcc void @_ZN35ExplicitlyExportSpecializedTemplateIiE4funcEv
860
861 // Base class already specialized with import attribute.
862 struct __declspec(dllimport) DerivedFromExplicitlyImportSpecializedTemplate : public ExplicitlyImportSpecializedTemplate<int> {};
863 USEMEMFUNC(ExplicitlyImportSpecializedTemplate<int>, func)
864 // M32-DAG: declare dllimport x86_thiscallcc void @"\01?func@?$ExplicitlyImportSpecializedTemplate@H@@QAEXXZ"
865 // G32-DAG: declare dllimport x86_thiscallcc void @_ZN35ExplicitlyImportSpecializedTemplateIiE4funcEv
866
867 // Base class already instantiated without dll attribute.
868 struct __declspec(dllimport) DerivedFromExplicitlyInstantiatedTemplate : public ExplicitlyInstantiatedTemplate<int> {};
869 USEMEMFUNC(ExplicitlyInstantiatedTemplate<int>, func)
870 // M32-DAG: define weak_odr x86_thiscallcc void @"\01?func@?$ExplicitlyInstantiatedTemplate@H@@QAEXXZ"
871 // G32-DAG: define weak_odr x86_thiscallcc void @_ZN30ExplicitlyInstantiatedTemplateIiE4funcEv
872
873 // Base class already instantiated with export attribute.
874 struct __declspec(dllimport) DerivedFromExplicitlyExportInstantiatedTemplate : public ExplicitlyExportInstantiatedTemplate<int> {};
875 USEMEMFUNC(ExplicitlyExportInstantiatedTemplate<int>, func)
876 // M32-DAG: define weak_odr dllexport x86_thiscallcc void @"\01?func@?$ExplicitlyExportInstantiatedTemplate@H@@QAEXXZ"
877 // G32-DAG: define weak_odr dllexport x86_thiscallcc void @_ZN36ExplicitlyExportInstantiatedTemplateIiE4funcEv
878
879 // Base class already instantiated with import attribute.
880 struct __declspec(dllimport) DerivedFromExplicitlyImportInstantiatedTemplate : public ExplicitlyImportInstantiatedTemplate<int> {};
881 USEMEMFUNC(ExplicitlyImportInstantiatedTemplate<int>, func)
882 // M32-DAG: declare dllimport x86_thiscallcc void @"\01?func@?$ExplicitlyImportInstantiatedTemplate@H@@QAEXXZ"
883 // G32-DAG: declare dllimport x86_thiscallcc void @_ZN36ExplicitlyImportInstantiatedTemplateIiE4funcEv
884
885 // MS: A dll attribute propagates through multiple levels of instantiation.
funcTopClass886 template <typename T> struct TopClass { void func() {} };
887 template <typename T> struct MiddleClass : public TopClass<T> { };
888 struct __declspec(dllimport) BottomClass : public MiddleClass<int> { };
889 USEMEMFUNC(TopClass<int>, func)
890 // M32-DAG: {{declare|define available_externally}} dllimport x86_thiscallcc void @"\01?func@?$TopClass@H@@QAEXXZ"
891 // G32-DAG: define linkonce_odr x86_thiscallcc void @_ZN8TopClassIiE4funcEv
892
funcExplicitInstantiationDeclTemplateBase893 template <typename T> struct ExplicitInstantiationDeclTemplateBase { void func() {} };
894 extern template struct ExplicitInstantiationDeclTemplateBase<int>;
895 struct __declspec(dllimport) DerivedFromExplicitInstantiationDeclTemplateBase : public ExplicitInstantiationDeclTemplateBase<int> {};
896 template struct ExplicitInstantiationDeclTemplateBase<int>;
897 USEMEMFUNC(ExplicitInstantiationDeclTemplateBase<int>, func)
898 // M32-DAG: declare dllimport x86_thiscallcc void @"\01?func@?$ExplicitInstantiationDeclTemplateBase@H@@QAEXXZ"
899 // G32-DAG: define weak_odr x86_thiscallcc void @_ZN37ExplicitInstantiationDeclTemplateBaseIiE4funcEv
900
funcExplicitInstantiationDeclTemplateBase2901 template <typename T> struct ExplicitInstantiationDeclTemplateBase2 { void func() {} };
902 extern template struct ExplicitInstantiationDeclTemplateBase2<int>;
903 struct __declspec(dllimport) DerivedFromExplicitInstantiationDeclTemplateBase2 : public ExplicitInstantiationDeclTemplateBase2<int> {};
904 template struct __declspec(dllexport) ExplicitInstantiationDeclTemplateBase2<int>;
905 USEMEMFUNC(ExplicitInstantiationDeclTemplateBase2<int>, func)
906 // M32-DAG: declare dllimport x86_thiscallcc void @"\01?func@?$ExplicitInstantiationDeclTemplateBase2@H@@QAEXXZ"
907 // G32-DAG: define weak_odr x86_thiscallcc void @_ZN38ExplicitInstantiationDeclTemplateBase2IiE4funcEv
908