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 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
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
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();
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();
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();
237                inline void 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() {}
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();
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
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);
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 
318 
319 //===----------------------------------------------------------------------===//
320 // Function templates
321 //===----------------------------------------------------------------------===//
322 
323 // Import function template declaration.
324 // MSC-DAG: declare dllimport void @"\01??$funcTmplDecl@UImplicitInst_Imported@@@@YAXXZ"()
325 // GNU-DAG: declare dllimport void @_Z12funcTmplDeclI21ImplicitInst_ImportedEvv()
326 template<typename T> __declspec(dllimport) void funcTmplDecl();
327 USE(funcTmplDecl<ImplicitInst_Imported>)
328 
329 // Function template definitions cannot be imported.
330 
331 // Import inline function template.
332 // MSC-DAG: declare dllimport void @"\01??$inlineFuncTmpl1@UImplicitInst_Imported@@@@YAXXZ"()
333 // GNU-DAG: define linkonce_odr void @_Z15inlineFuncTmpl1I21ImplicitInst_ImportedEvv()
334 // MO1-DAG: define available_externally dllimport void @"\01??$inlineFuncTmpl1@UImplicitInst_Imported@@@@YAXXZ"()
335 // GO1-DAG: define linkonce_odr void @_Z15inlineFuncTmpl1I21ImplicitInst_ImportedEvv()
336 template<typename T> __declspec(dllimport) inline void inlineFuncTmpl1() {}
337 USE(inlineFuncTmpl1<ImplicitInst_Imported>)
338 
339 // MSC-DAG: declare dllimport void @"\01??$inlineFuncTmpl2@UImplicitInst_Imported@@@@YAXXZ"()
340 // GNU-DAG: define linkonce_odr void @_Z15inlineFuncTmpl2I21ImplicitInst_ImportedEvv()
341 // MO1-DAG: define available_externally dllimport void @"\01??$inlineFuncTmpl2@UImplicitInst_Imported@@@@YAXXZ"()
342 // GO1-DAG: define linkonce_odr void @_Z15inlineFuncTmpl2I21ImplicitInst_ImportedEvv()
343 template<typename T> inline void __attribute__((dllimport)) inlineFuncTmpl2() {}
344 USE(inlineFuncTmpl2<ImplicitInst_Imported>)
345 
346 // MSC-DAG: declare dllimport void @"\01??$inlineFuncTmplDecl@UImplicitInst_Imported@@@@YAXXZ"()
347 // GNU-DAG: define linkonce_odr void @_Z18inlineFuncTmplDeclI21ImplicitInst_ImportedEvv()
348 // MO1-DAG: define available_externally dllimport void @"\01??$inlineFuncTmplDecl@UImplicitInst_Imported@@@@YAXXZ"()
349 // GO1-DAG: define linkonce_odr void @_Z18inlineFuncTmplDeclI21ImplicitInst_ImportedEvv()
350 template<typename T> __declspec(dllimport) inline void inlineFuncTmplDecl();
351 template<typename T>                              void inlineFuncTmplDecl() {}
352 USE(inlineFuncTmplDecl<ImplicitInst_Imported>)
353 
354 // MSC-DAG: declare dllimport void @"\01??$inlineFuncTmplDef@UImplicitInst_Imported@@@@YAXXZ"()
355 // GNU-DAG: define linkonce_odr void @_Z17inlineFuncTmplDefI21ImplicitInst_ImportedEvv()
356 // MO1-DAG: define available_externally dllimport void @"\01??$inlineFuncTmplDef@UImplicitInst_Imported@@@@YAXXZ"()
357 // GO1-DAG: define linkonce_odr void @_Z17inlineFuncTmplDefI21ImplicitInst_ImportedEvv()
358 template<typename T> __declspec(dllimport) void inlineFuncTmplDef();
359 template<typename T>                inline void inlineFuncTmplDef() {}
360 USE(inlineFuncTmplDef<ImplicitInst_Imported>)
361 
362 
363 // Redeclarations
364 // MSC-DAG: declare dllimport void @"\01??$funcTmplRedecl1@UImplicitInst_Imported@@@@YAXXZ"()
365 // GNU-DAG: declare dllimport void @_Z15funcTmplRedecl1I21ImplicitInst_ImportedEvv()
366 template<typename T> __declspec(dllimport) void funcTmplRedecl1();
367 template<typename T> __declspec(dllimport) void funcTmplRedecl1();
368 USE(funcTmplRedecl1<ImplicitInst_Imported>)
369 
370 // MSC-DAG: declare void @"\01??$funcTmplRedecl2@UImplicitInst_NotImported@@@@YAXXZ"()
371 // GNU-DAG: declare void @_Z15funcTmplRedecl2I24ImplicitInst_NotImportedEvv()
372 template<typename T> __declspec(dllimport) void funcTmplRedecl2();
373 template<typename T>                       void funcTmplRedecl2(); // dllimport ignored
374 USE(funcTmplRedecl2<ImplicitInst_NotImported>)
375 
376 // MSC-DAG: define linkonce_odr void @"\01??$funcTmplRedecl3@UImplicitInst_NotImported@@@@YAXXZ"()
377 // GNU-DAG: define linkonce_odr void @_Z15funcTmplRedecl3I24ImplicitInst_NotImportedEvv()
378 template<typename T> __declspec(dllimport) void funcTmplRedecl3();
379 template<typename T>                       void funcTmplRedecl3() {} // dllimport ignored
380 USE(funcTmplRedecl3<ImplicitInst_NotImported>)
381 
382 
383 // Function template friends
384 // MSC-DAG: declare dllimport   void @"\01??$funcTmplFriend1@UImplicitInst_Imported@@@@YAXXZ"()
385 // GNU-DAG: declare dllimport   void @_Z15funcTmplFriend1I21ImplicitInst_ImportedEvv()
386 // MSC-DAG: declare             void @"\01??$funcTmplFriend2@UImplicitInst_NotImported@@@@YAXXZ"()
387 // GNU-DAG: declare             void @_Z15funcTmplFriend2I24ImplicitInst_NotImportedEvv()
388 // MSC-DAG: define linkonce_odr void @"\01??$funcTmplFriend3@UImplicitInst_NotImported@@@@YAXXZ"()
389 // GNU-DAG: define linkonce_odr void @_Z15funcTmplFriend3I24ImplicitInst_NotImportedEvv()
390 // MSC-DAG: declare dllimport   void @"\01??$funcTmplFriend4@UImplicitInst_Imported@@@@YAXXZ"()
391 // GNU-DAG: define linkonce_odr void @_Z15funcTmplFriend4I21ImplicitInst_ImportedEvv()
392 struct FuncTmplFriend {
393   template<typename T> friend __declspec(dllimport) void funcTmplFriend1();
394   template<typename T> friend __declspec(dllimport) void funcTmplFriend2();
395   template<typename T> friend __declspec(dllimport) void funcTmplFriend3();
396   template<typename T> friend __declspec(dllimport) inline void funcTmplFriend4();
397 };
398 template<typename T> __declspec(dllimport) void funcTmplFriend1();
399 template<typename T>                       void funcTmplFriend2(); // dllimport ignored
400 template<typename T>                       void funcTmplFriend3() {} // dllimport ignored
401 template<typename T>                       inline void funcTmplFriend4() {}
402 USE(funcTmplFriend1<ImplicitInst_Imported>)
403 USE(funcTmplFriend2<ImplicitInst_NotImported>)
404 USE(funcTmplFriend3<ImplicitInst_NotImported>)
405 USE(funcTmplFriend4<ImplicitInst_Imported>)
406 
407 // MSC-DAG: declare dllimport void @"\01??$externalFuncTmpl@UImplicitInst_Imported@@@ns@@YAXXZ"()
408 // GNU-DAG: declare dllimport void @_ZN2ns16externalFuncTmplI21ImplicitInst_ImportedEEvv()
409 namespace ns { template<typename T> __declspec(dllimport) void externalFuncTmpl(); }
410 USE(ns::externalFuncTmpl<ImplicitInst_Imported>)
411 
412 
413 template<typename T> void funcTmpl() {}
414 template<typename T> inline void inlineFuncTmpl() {}
415 template<typename T> __declspec(dllimport) void importedFuncTmplDecl();
416 template<typename T> __declspec(dllimport) inline void importedFuncTmpl() {}
417 
418 // Import implicit instantiation of an imported function template.
419 // MSC-DAG: declare dllimport void @"\01??$importedFuncTmplDecl@UImplicitInst_Imported@@@@YAXXZ"()
420 // GNU-DAG: declare dllimport void @_Z20importedFuncTmplDeclI21ImplicitInst_ImportedEvv()
421 USE(importedFuncTmplDecl<ImplicitInst_Imported>)
422 
423 // MSC-DAG: declare dllimport void @"\01??$importedFuncTmpl@UImplicitInst_Imported@@@@YAXXZ"()
424 // GNU-DAG: define linkonce_odr void @_Z16importedFuncTmplI21ImplicitInst_ImportedEvv()
425 // MO1-DAG: define available_externally dllimport void @"\01??$importedFuncTmpl@UImplicitInst_Imported@@@@YAXXZ"()
426 // GO1-DAG: define linkonce_odr void @_Z16importedFuncTmplI21ImplicitInst_ImportedEvv()
427 USE(importedFuncTmpl<ImplicitInst_Imported>)
428 
429 // Import explicit instantiation declaration of an imported function template.
430 // MSC-DAG: declare dllimport void @"\01??$importedFuncTmpl@UExplicitDecl_Imported@@@@YAXXZ"()
431 // GNU-DAG: declare void @_Z16importedFuncTmplI21ExplicitDecl_ImportedEvv()
432 // MO1-DAG: define available_externally dllimport void @"\01??$importedFuncTmpl@UExplicitDecl_Imported@@@@YAXXZ"()
433 // GO1-DAG: define available_externally void @_Z16importedFuncTmplI21ExplicitDecl_ImportedEvv()
434 extern template void importedFuncTmpl<ExplicitDecl_Imported>();
435 USE(importedFuncTmpl<ExplicitDecl_Imported>)
436 
437 // Import explicit instantiation definition of an imported function template.
438 // MSC-DAG: declare dllimport void @"\01??$importedFuncTmpl@UExplicitInst_Imported@@@@YAXXZ"()
439 // GNU-DAG: define weak_odr void @_Z16importedFuncTmplI21ExplicitInst_ImportedEvv()
440 // MO1-DAG: define available_externally dllimport void @"\01??$importedFuncTmpl@UExplicitInst_Imported@@@@YAXXZ"()
441 // GO1-DAG: define weak_odr void @_Z16importedFuncTmplI21ExplicitInst_ImportedEvv()
442 template void importedFuncTmpl<ExplicitInst_Imported>();
443 USE(importedFuncTmpl<ExplicitInst_Imported>)
444 
445 
446 // Import specialization of an imported function template.
447 // MSC-DAG: declare dllimport void @"\01??$importedFuncTmplDecl@UExplicitSpec_Imported@@@@YAXXZ"()
448 // GNU-DAG: declare dllimport void @_Z20importedFuncTmplDeclI21ExplicitSpec_ImportedEvv()
449 template<> __declspec(dllimport) void importedFuncTmplDecl<ExplicitSpec_Imported>();
450 USE(importedFuncTmplDecl<ExplicitSpec_Imported>)
451 
452 // MSC-DAG-FIXME: declare dllimport void @"\01??$importedFuncTmplDecl@UExplicitSpec_Def_Imported@@@@YAXXZ"()
453 // MO1-DAG-FIXME: define available_externally dllimport void @"\01??$importedFuncTmplDecl@UExplicitSpec_Def_Imported@@@@YAXXZ"()
454 #ifdef MSABI
455 //template<> __declspec(dllimport) void importedFuncTmplDecl<ExplicitSpec_Def_Imported>() {}
456 //USE(importedFuncTmplDecl<ExplicitSpec_Def_Imported>)
457 #endif
458 
459 // MSC-DAG: declare dllimport void @"\01??$importedFuncTmplDecl@UExplicitSpec_InlineDef_Imported@@@@YAXXZ"()
460 // GNU-DAG: define linkonce_odr void @_Z20importedFuncTmplDeclI31ExplicitSpec_InlineDef_ImportedEvv()
461 // MO1-DAG: define available_externally dllimport void @"\01??$importedFuncTmplDecl@UExplicitSpec_InlineDef_Imported@@@@YAXXZ"()
462 // GO1-DAG: define linkonce_odr void @_Z20importedFuncTmplDeclI31ExplicitSpec_InlineDef_ImportedEvv()
463 template<> __declspec(dllimport) inline void importedFuncTmplDecl<ExplicitSpec_InlineDef_Imported>() {}
464 USE(importedFuncTmplDecl<ExplicitSpec_InlineDef_Imported>)
465 
466 
467 // MSC-DAG: declare dllimport void @"\01??$importedFuncTmpl@UExplicitSpec_Imported@@@@YAXXZ"()
468 // GNU-DAG: declare dllimport void @_Z16importedFuncTmplI21ExplicitSpec_ImportedEvv()
469 template<> __declspec(dllimport) void importedFuncTmpl<ExplicitSpec_Imported>();
470 USE(importedFuncTmpl<ExplicitSpec_Imported>)
471 
472 // MSC-DAG-FIXME: declare dllimport void @"\01??$importedFuncTmpl@UExplicitSpec_Def_Imported@@@@YAXXZ"()
473 // MO1-DAG-FIXME: define available_externally dllimport void @"\01??$importedFuncTmpl@UExplicitSpec_Def_Imported@@@@YAXXZ"()
474 #ifdef MSABI
475 //template<> __declspec(dllimport) void importedFuncTmpl<ExplicitSpec_Def_Imported>() {}
476 //USE(importedFuncTmpl<ExplicitSpec_Def_Imported>)
477 #endif
478 
479 // MSC-DAG: declare dllimport void @"\01??$importedFuncTmpl@UExplicitSpec_InlineDef_Imported@@@@YAXXZ"()
480 // GNU-DAG: define linkonce_odr void @_Z16importedFuncTmplI31ExplicitSpec_InlineDef_ImportedEvv()
481 // MO1-DAG: define available_externally dllimport void @"\01??$importedFuncTmpl@UExplicitSpec_InlineDef_Imported@@@@YAXXZ"()
482 // GO1-DAG: define linkonce_odr void @_Z16importedFuncTmplI31ExplicitSpec_InlineDef_ImportedEvv()
483 template<> __declspec(dllimport) inline void importedFuncTmpl<ExplicitSpec_InlineDef_Imported>() {}
484 USE(importedFuncTmpl<ExplicitSpec_InlineDef_Imported>)
485 
486 
487 // Not importing specialization of an imported function template without
488 // explicit dllimport.
489 // MSC-DAG: define void @"\01??$importedFuncTmpl@UExplicitSpec_NotImported@@@@YAXXZ"()
490 // GNU-DAG: define void @_Z16importedFuncTmplI24ExplicitSpec_NotImportedEvv()
491 template<> void importedFuncTmpl<ExplicitSpec_NotImported>() {}
492 USE(importedFuncTmpl<ExplicitSpec_NotImported>)
493 
494 
495 // Import explicit instantiation declaration of a non-imported function template.
496 // MSC-DAG: declare dllimport void @"\01??$funcTmpl@UExplicitDecl_Imported@@@@YAXXZ"()
497 // MSC-DAG: declare dllimport void @"\01??$inlineFuncTmpl@UExplicitDecl_Imported@@@@YAXXZ"()
498 // GNU-DAG: declare dllimport void @_Z8funcTmplI21ExplicitDecl_ImportedEvv()
499 // GNU-DAG: declare void @_Z14inlineFuncTmplI21ExplicitDecl_ImportedEvv()
500 // MO1-DAG: define available_externally dllimport void @"\01??$inlineFuncTmpl@UExplicitDecl_Imported@@@@YAXXZ"()
501 // GO1-DAG: define available_externally void @_Z14inlineFuncTmplI21ExplicitDecl_ImportedEvv()
502 extern template __declspec(dllimport) void funcTmpl<ExplicitDecl_Imported>();
503 extern template __declspec(dllimport) void inlineFuncTmpl<ExplicitDecl_Imported>();
504 USE(funcTmpl<ExplicitDecl_Imported>)
505 USE(inlineFuncTmpl<ExplicitDecl_Imported>)
506 
507 
508 // Import explicit instantiation definition of a non-imported function template.
509 // MSC-DAG: declare dllimport void @"\01??$funcTmpl@UExplicitInst_Imported@@@@YAXXZ"()
510 // MSC-DAG: declare dllimport void @"\01??$inlineFuncTmpl@UExplicitInst_Imported@@@@YAXXZ"()
511 // GNU-DAG: declare dllimport void @_Z8funcTmplI21ExplicitInst_ImportedEvv()
512 // GNU-DAG: define weak_odr void @_Z14inlineFuncTmplI21ExplicitInst_ImportedEvv()
513 // MO1-DAG: define available_externally dllimport void @"\01??$funcTmpl@UExplicitInst_Imported@@@@YAXXZ"()
514 // MO1-DAG: define available_externally dllimport void @"\01??$inlineFuncTmpl@UExplicitInst_Imported@@@@YAXXZ"()
515 // GO1-DAG: define available_externally dllimport void @_Z8funcTmplI21ExplicitInst_ImportedEvv()
516 // GO1-DAG: define weak_odr void @_Z14inlineFuncTmplI21ExplicitInst_ImportedEvv()
517 template __declspec(dllimport) void funcTmpl<ExplicitInst_Imported>();
518 template __declspec(dllimport) void inlineFuncTmpl<ExplicitInst_Imported>();
519 USE(funcTmpl<ExplicitInst_Imported>)
520 USE(inlineFuncTmpl<ExplicitInst_Imported>)
521 
522 
523 // Import specialization of a non-imported function template.
524 // MSC-DAG: declare dllimport void @"\01??$funcTmpl@UExplicitSpec_Imported@@@@YAXXZ"()
525 // GNU-DAG: declare dllimport void @_Z8funcTmplI21ExplicitSpec_ImportedEvv()
526 template<> __declspec(dllimport) void funcTmpl<ExplicitSpec_Imported>();
527 USE(funcTmpl<ExplicitSpec_Imported>)
528 
529 // MSC-DAG-FIXME: declare dllimport void @"\01??$funcTmpl@UExplicitSpec_Def_Imported@@@@YAXXZ"()
530 // MO1-DAG-FIXME: define available_externally dllimport void @"\01??$funcTmpl@UExplicitSpec_Def_Imported@@@@YAXXZ"()
531 #ifdef MSABI
532 //template<> __declspec(dllimport) void funcTmpl<ExplicitSpec_Def_Imported>() {}
533 //USE(funcTmpl<ExplicitSpec_Def_Imported>)
534 #endif
535 
536 // MSC-DAG: declare dllimport void @"\01??$funcTmpl@UExplicitSpec_InlineDef_Imported@@@@YAXXZ"()
537 // GNU-DAG: define linkonce_odr void @_Z8funcTmplI31ExplicitSpec_InlineDef_ImportedEvv()
538 // MO1-DAG: define available_externally dllimport void @"\01??$funcTmpl@UExplicitSpec_InlineDef_Imported@@@@YAXXZ"()
539 // GO1-DAG: define linkonce_odr void @_Z8funcTmplI31ExplicitSpec_InlineDef_ImportedEvv()
540 template<> __declspec(dllimport) inline void funcTmpl<ExplicitSpec_InlineDef_Imported>() {}
541 USE(funcTmpl<ExplicitSpec_InlineDef_Imported>)
542 
543 
544 
545 //===----------------------------------------------------------------------===//
546 // Classes
547 //===----------------------------------------------------------------------===//
548 
549 struct __declspec(dllimport) T {
550   void a() {}
551   // MO1-DAG: define available_externally dllimport x86_thiscallcc void @"\01?a@T@@QAEXXZ"
552 
553   static int b;
554   // MO1-DAG: @"\01?b@T@@2HA" = external dllimport global i32
555 
556   T& operator=(T&) = default;
557   // MO1-DAG: define available_externally dllimport x86_thiscallcc dereferenceable({{[0-9]+}}) %struct.T* @"\01??4T@@QAEAAU0@AAU0@@Z"
558 
559   T& operator=(T&&) = default;
560   // Note: Don't mark inline move operators dllimport because current MSVC versions don't export them.
561   // M18-DAG: define linkonce_odr x86_thiscallcc dereferenceable({{[0-9]+}}) %struct.T* @"\01??4T@@QAEAAU0@$$QAU0@@Z"
562   // M19-DAG: define available_externally dllimport x86_thiscallcc dereferenceable({{[0-9]+}}) %struct.T* @"\01??4T@@QAEAAU0@$$QAU0@@Z"
563 };
564 USEMEMFUNC(T, a)
565 USEVAR(T::b)
566 USECOPYASSIGN(T)
567 USEMOVEASSIGN(T)
568 
569 template <typename T> struct __declspec(dllimport) U { void foo() {} };
570 // MO1-DAG: define available_externally dllimport x86_thiscallcc void @"\01?foo@?$U@H@@QAEXXZ"
571 struct __declspec(dllimport) V : public U<int> { };
572 USEMEMFUNC(V, foo)
573 
574 struct __declspec(dllimport) W { virtual void foo() {} };
575 USECLASS(W)
576 // vftable:
577 // 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*)]
578 // GO1-DAG: @_ZTV1W = available_externally dllimport unnamed_addr constant [3 x i8*] [i8* null, i8* null, i8* bitcast (void (%struct.W*)* @_ZN1W3fooEv to i8*)]
579 
580 struct __declspec(dllimport) KeyFuncClass {
581   constexpr KeyFuncClass() {}
582   virtual void foo();
583 };
584 constexpr KeyFuncClass keyFuncClassVar;
585 // G32-DAG: @_ZTV12KeyFuncClass = external dllimport unnamed_addr constant [3 x i8*]
586 
587 struct __declspec(dllimport) X : public virtual W {};
588 USECLASS(X)
589 // vbtable:
590 // MO1-DAG: @"\01??_8X@@7B@" = available_externally dllimport unnamed_addr constant [2 x i32] [i32 0, i32 4]
591 
592 struct __declspec(dllimport) Y {
593   int x;
594 };
595 
596 struct __declspec(dllimport) Z { virtual ~Z() {} };
597 USECLASS(Z)
598 // User-defined dtor:
599 // MO1-DAG: define available_externally dllimport x86_thiscallcc void @"\01??1Z@@UAE@XZ"
600 
601 namespace DontUseDtorAlias {
602   struct __declspec(dllimport) A { ~A(); };
603   struct __declspec(dllimport) B : A { ~B(); };
604   inline A::~A() { }
605   inline B::~B() { }
606   // Emit a real definition of B's constructor; don't alias it to A's.
607   // MO1-DAG: available_externally dllimport x86_thiscallcc void @"\01??1B@DontUseDtorAlias@@QAE@XZ"
608   USECLASS(B)
609 }
610 
611 namespace Vtordisp {
612   // Don't dllimport the vtordisp.
613   // MO1-DAG: define linkonce_odr x86_thiscallcc void @"\01?f@?$C@D@Vtordisp@@$4PPPPPPPM@A@AEXXZ"
614 
615   class Base {
616     virtual void f() {}
617   };
618   template <typename T>
619   class __declspec(dllimport) C : virtual public Base {
620   public:
621     C() {}
622     virtual void f() {}
623   };
624   template class C<char>;
625 }
626 
627 namespace ClassTemplateStaticDef {
628   // Regular template static field:
629   template <typename T> struct __declspec(dllimport) S {
630     static int x;
631   };
632   template <typename T> int S<T>::x;
633   // MSC-DAG: @"\01?x@?$S@H@ClassTemplateStaticDef@@2HA" = available_externally dllimport global i32 0
634   int f() { return S<int>::x; }
635 
636   // Partial class template specialization static field:
637   template <typename A> struct T;
638   template <typename A> struct __declspec(dllimport) T<A*> {
639     static int x;
640   };
641   template <typename A> int T<A*>::x;
642   // GNU-DAG: @_ZN22ClassTemplateStaticDef1TIPvE1xE = available_externally dllimport global i32 0
643   int g() { return T<void*>::x; }
644 }
645 
646 namespace PR19933 {
647 // Don't dynamically initialize dllimport vars.
648 // MSC2-NOT: @llvm.global_ctors
649 // GNU2-NOT: @llvm.global_ctors
650 
651   struct NonPOD { NonPOD(); };
652   template <typename T> struct A { static NonPOD x; };
653   template <typename T> NonPOD A<T>::x;
654   template struct __declspec(dllimport) A<int>;
655   // MSC-DAG: @"\01?x@?$A@H@PR19933@@2UNonPOD@2@A" = available_externally dllimport global %"struct.PR19933::NonPOD" zeroinitializer
656 
657   int f();
658   template <typename T> struct B { static int x; };
659   template <typename T> int B<T>::x = f();
660   template struct __declspec(dllimport) B<int>;
661   // MSC-DAG: @"\01?x@?$B@H@PR19933@@2HA" = available_externally dllimport global i32 0
662 
663   constexpr int g() { return 42; }
664   template <typename T> struct C { static int x; };
665   template <typename T> int C<T>::x = g();
666   template struct __declspec(dllimport) C<int>;
667   // MSC-DAG: @"\01?x@?$C@H@PR19933@@2HA" = available_externally dllimport global i32 42
668 
669   template <int I> struct D { static int x, y; };
670   template <int I> int D<I>::x = I + 1;
671   template <int I> int D<I>::y = I + f();
672   template struct __declspec(dllimport) D<42>;
673   // MSC-DAG: @"\01?x@?$D@$0CK@@PR19933@@2HA" = available_externally dllimport global i32 43
674   // MSC-DAG: @"\01?y@?$D@$0CK@@PR19933@@2HA" = available_externally dllimport global i32 0
675 }
676 
677 namespace PR21355 {
678   struct __declspec(dllimport) S {
679     virtual ~S();
680   };
681   S::~S() {}
682 
683   // S::~S is a key function, so we would ordinarily emit a strong definition for
684   // the vtable. However, S is imported, so the vtable should be too.
685 
686   // GNU-DAG: @_ZTVN7PR213551SE = available_externally dllimport unnamed_addr constant [4 x i8*]
687 }
688 
689 namespace PR21366 {
690   struct __declspec(dllimport) S {
691     void outOfLineMethod();
692     void inlineMethod() {}
693     inline void anotherInlineMethod();
694     void outOfClassInlineMethod();
695   };
696   void S::anotherInlineMethod() {}
697   inline void S::outOfClassInlineMethod() {}
698 }
699 
700 // MS ignores DLL attributes on partial specializations.
701 template <typename T> struct PartiallySpecializedClassTemplate {};
702 template <typename T> struct __declspec(dllimport) PartiallySpecializedClassTemplate<T*> { void f(); };
703 USEMEMFUNC(PartiallySpecializedClassTemplate<void*>, f);
704 // M32-DAG: declare x86_thiscallcc void @"\01?f@?$PartiallySpecializedClassTemplate@PAX@@QAEXXZ"
705 // G32-DAG: declare dllimport x86_thiscallcc void @_ZN33PartiallySpecializedClassTemplateIPvE1fEv
706 
707 // Attributes on explicit specializations are honored.
708 template <typename T> struct ExplicitlySpecializedClassTemplate {};
709 template <> struct __declspec(dllimport) ExplicitlySpecializedClassTemplate<void*> { void f(); };
710 USEMEMFUNC(ExplicitlySpecializedClassTemplate<void*>, f);
711 // M32-DAG: declare dllimport x86_thiscallcc void @"\01?f@?$ExplicitlySpecializedClassTemplate@PAX@@QAEXXZ"
712 // G32-DAG: declare dllimport x86_thiscallcc void @_ZN34ExplicitlySpecializedClassTemplateIPvE1fEv
713 
714 // MS inherits DLL attributes to partial specializations.
715 template <typename T> struct __declspec(dllimport) PartiallySpecializedImportedClassTemplate {};
716 template <typename T> struct PartiallySpecializedImportedClassTemplate<T*> { void f() {} };
717 USEMEMFUNC(PartiallySpecializedImportedClassTemplate<void*>, f);
718 // M32-DAG: {{declare|define available_externally}} dllimport x86_thiscallcc void @"\01?f@?$PartiallySpecializedImportedClassTemplate@PAX@@QAEXXZ"
719 // G32-DAG: define linkonce_odr x86_thiscallcc void @_ZN41PartiallySpecializedImportedClassTemplateIPvE1fEv
720 
721 // Attributes on the instantiation take precedence over attributes on the template.
722 template <typename T> struct __declspec(dllexport) ExplicitlyInstantiatedWithDifferentAttr { void f() {} };
723 template struct __declspec(dllimport) ExplicitlyInstantiatedWithDifferentAttr<int>;
724 USEMEMFUNC(ExplicitlyInstantiatedWithDifferentAttr<int>, f);
725 // M32-DAG: {{declare|define available_externally}} dllimport x86_thiscallcc void @"\01?f@?$ExplicitlyInstantiatedWithDifferentAttr@H@@QAEXXZ"
726 
727 template <typename T> struct ExplicitInstantiationDeclImportedDefTemplate { void f() {} ExplicitInstantiationDeclImportedDefTemplate() {}};
728 extern template struct ExplicitInstantiationDeclImportedDefTemplate<int>;
729 template struct __declspec(dllimport) ExplicitInstantiationDeclImportedDefTemplate<int>;
730 USECLASS(ExplicitInstantiationDeclImportedDefTemplate<int>);
731 USEMEMFUNC(ExplicitInstantiationDeclImportedDefTemplate<int>, f);
732 // M32-DAG: {{declare|define available_externally}} dllimport x86_thiscallcc void @"\01?f@?$ExplicitInstantiationDeclImportedDefTemplate@H@@QAEXXZ"
733 // M32-DAG: {{declare|define available_externally}} dllimport x86_thiscallcc %struct.ExplicitInstantiationDeclImportedDefTemplate* @"\01??0?$ExplicitInstantiationDeclImportedDefTemplate@H@@QAE@XZ"
734 // G32-DAG: define weak_odr x86_thiscallcc void @_ZN44ExplicitInstantiationDeclImportedDefTemplateIiE1fEv
735 
736 template <typename T> struct __declspec(dllimport) ExplicitInstantiationDeclExportedDefImportedTemplate { void f() {} ExplicitInstantiationDeclExportedDefImportedTemplate() {} };
737 extern template struct __declspec(dllimport) ExplicitInstantiationDeclExportedDefImportedTemplate <int>;
738 template struct __declspec(dllexport) ExplicitInstantiationDeclExportedDefImportedTemplate<int>;
739 USECLASS(ExplicitInstantiationDeclExportedDefImportedTemplate<int>);
740 USEMEMFUNC(ExplicitInstantiationDeclExportedDefImportedTemplate<int>, f);
741 // M32-DAG: {{declare|define available_externally}} dllimport x86_thiscallcc void @"\01?f@?$ExplicitInstantiationDeclExportedDefImportedTemplate@H@@QAEXXZ"
742 // M32-DAG: {{declare|define available_externally}} dllimport x86_thiscallcc %struct.ExplicitInstantiationDeclExportedDefImportedTemplate* @"\01??0?$ExplicitInstantiationDeclExportedDefImportedTemplate@H@@QAE@XZ"
743 
744 template <typename T> struct PR23770BaseTemplate { void f() {} };
745 template <typename T> struct PR23770DerivedTemplate : PR23770BaseTemplate<int> {};
746 extern template struct PR23770DerivedTemplate<int>;
747 template struct __declspec(dllimport) PR23770DerivedTemplate<int>;
748 USEMEMFUNC(PR23770BaseTemplate<int>, f);
749 // M32-DAG: declare dllimport x86_thiscallcc void @"\01?f@?$PR23770BaseTemplate@H@@QAEXXZ"
750 
751 //===----------------------------------------------------------------------===//
752 // Classes with template base classes
753 //===----------------------------------------------------------------------===//
754 
755 template <typename T> struct ClassTemplate { void func() {} };
756 template <typename T> struct __declspec(dllexport) ExportedClassTemplate { void func(); };
757 template <typename T> void ExportedClassTemplate<T>::func() {}
758 template <typename T> struct __declspec(dllimport) ImportedClassTemplate { void func(); };
759 
760 template <typename T> struct ExplicitlySpecializedTemplate { void func() {} };
761 template <> struct ExplicitlySpecializedTemplate<int> { void func() {} };
762 template <typename T> struct ExplicitlyExportSpecializedTemplate { void func() {} };
763 template <> struct __declspec(dllexport) ExplicitlyExportSpecializedTemplate<int> { void func(); };
764 void ExplicitlyExportSpecializedTemplate<int>::func() {}
765 template <typename T> struct ExplicitlyImportSpecializedTemplate { void func() {} };
766 template <> struct __declspec(dllimport) ExplicitlyImportSpecializedTemplate<int> { void func(); };
767 
768 template <typename T> struct ExplicitlyInstantiatedTemplate { void func() {} };
769 template struct ExplicitlyInstantiatedTemplate<int>;
770 template <typename T> struct ExplicitlyExportInstantiatedTemplate { void func(); };
771 template <typename T> void ExplicitlyExportInstantiatedTemplate<T>::func() {}
772 template struct __declspec(dllexport) ExplicitlyExportInstantiatedTemplate<int>;
773 template <typename T> struct ExplicitlyImportInstantiatedTemplate { void func(); };
774 template struct __declspec(dllimport) ExplicitlyImportInstantiatedTemplate<int>;
775 
776 
777 // MS: ClassTemplate<int> gets imported.
778 struct __declspec(dllimport) DerivedFromTemplate : public ClassTemplate<int> {};
779 USEMEMFUNC(ClassTemplate<int>, func)
780 // M32-DAG: {{declare|define available_externally}} dllimport x86_thiscallcc void @"\01?func@?$ClassTemplate@H@@QAEXXZ"
781 // G32-DAG: define linkonce_odr x86_thiscallcc void @_ZN13ClassTemplateIiE4funcEv
782 
783 // ImportedTemplate is explicitly imported.
784 struct __declspec(dllimport) DerivedFromImportedTemplate : public ImportedClassTemplate<int> {};
785 USEMEMFUNC(ImportedClassTemplate<int>, func)
786 // M32-DAG: declare dllimport x86_thiscallcc void @"\01?func@?$ImportedClassTemplate@H@@QAEXXZ"
787 // G32-DAG: declare dllimport x86_thiscallcc void @_ZN21ImportedClassTemplateIiE4funcEv
788 
789 // ExportedTemplate is explicitly exported.
790 struct __declspec(dllimport) DerivedFromExportedTemplate : public ExportedClassTemplate<int> {};
791 USEMEMFUNC(ExportedClassTemplate<int>, func)
792 // M32-DAG: define weak_odr dllexport x86_thiscallcc void @"\01?func@?$ExportedClassTemplate@H@@QAEXXZ"
793 // G32-DAG: define weak_odr dllexport x86_thiscallcc void @_ZN21ExportedClassTemplateIiE4funcEv
794 
795 // Base class already implicitly instantiated without attribute.
796 struct DerivedFromTemplateD : public ClassTemplate<double> {};
797 struct __declspec(dllimport) DerivedFromTemplateD2 : public ClassTemplate<double> {};
798 USEMEMFUNC(ClassTemplate<double>, func)
799 // M32-DAG: declare dllimport x86_thiscallcc void @"\01?func@?$ClassTemplate@N@@QAEXXZ"
800 // G32-DAG: define linkonce_odr x86_thiscallcc void @_ZN13ClassTemplateIdE4funcEv
801 
802 // MS: Base class already instantiated with dfferent attribute.
803 struct __declspec(dllexport) DerivedFromTemplateB : public ClassTemplate<bool> {};
804 struct __declspec(dllimport) DerivedFromTemplateB2 : public ClassTemplate<bool> {};
805 USEMEMFUNC(ClassTemplate<bool>, func)
806 // M32-DAG: define weak_odr dllexport x86_thiscallcc void @"\01?func@?$ClassTemplate@_N@@QAEXXZ"
807 // G32-DAG: define linkonce_odr x86_thiscallcc void @_ZN13ClassTemplateIbE4funcEv
808 
809 // Base class already specialized without dll attribute.
810 struct __declspec(dllimport) DerivedFromExplicitlySpecializedTemplate : public ExplicitlySpecializedTemplate<int> {};
811 USEMEMFUNC(ExplicitlySpecializedTemplate<int>, func)
812 // M32-DAG: define linkonce_odr x86_thiscallcc void @"\01?func@?$ExplicitlySpecializedTemplate@H@@QAEXXZ"
813 // G32-DAG: define linkonce_odr x86_thiscallcc void @_ZN29ExplicitlySpecializedTemplateIiE4funcEv
814 
815 // Base class alredy specialized with export attribute.
816 struct __declspec(dllimport) DerivedFromExplicitlyExportSpecializedTemplate : public ExplicitlyExportSpecializedTemplate<int> {};
817 USEMEMFUNC(ExplicitlyExportSpecializedTemplate<int>, func)
818 // M32-DAG: define dllexport x86_thiscallcc void @"\01?func@?$ExplicitlyExportSpecializedTemplate@H@@QAEXXZ"
819 // G32-DAG: define dllexport x86_thiscallcc void @_ZN35ExplicitlyExportSpecializedTemplateIiE4funcEv
820 
821 // Base class already specialized with import attribute.
822 struct __declspec(dllimport) DerivedFromExplicitlyImportSpecializedTemplate : public ExplicitlyImportSpecializedTemplate<int> {};
823 USEMEMFUNC(ExplicitlyImportSpecializedTemplate<int>, func)
824 // M32-DAG: declare dllimport x86_thiscallcc void @"\01?func@?$ExplicitlyImportSpecializedTemplate@H@@QAEXXZ"
825 // G32-DAG: declare dllimport x86_thiscallcc void @_ZN35ExplicitlyImportSpecializedTemplateIiE4funcEv
826 
827 // Base class already instantiated without dll attribute.
828 struct __declspec(dllimport) DerivedFromExplicitlyInstantiatedTemplate : public ExplicitlyInstantiatedTemplate<int> {};
829 USEMEMFUNC(ExplicitlyInstantiatedTemplate<int>, func)
830 // M32-DAG: define weak_odr x86_thiscallcc void @"\01?func@?$ExplicitlyInstantiatedTemplate@H@@QAEXXZ"
831 // G32-DAG: define weak_odr x86_thiscallcc void @_ZN30ExplicitlyInstantiatedTemplateIiE4funcEv
832 
833 // Base class already instantiated with export attribute.
834 struct __declspec(dllimport) DerivedFromExplicitlyExportInstantiatedTemplate : public ExplicitlyExportInstantiatedTemplate<int> {};
835 USEMEMFUNC(ExplicitlyExportInstantiatedTemplate<int>, func)
836 // M32-DAG: define weak_odr dllexport x86_thiscallcc void @"\01?func@?$ExplicitlyExportInstantiatedTemplate@H@@QAEXXZ"
837 // G32-DAG: define weak_odr dllexport x86_thiscallcc void @_ZN36ExplicitlyExportInstantiatedTemplateIiE4funcEv
838 
839 // Base class already instantiated with import attribute.
840 struct __declspec(dllimport) DerivedFromExplicitlyImportInstantiatedTemplate : public ExplicitlyImportInstantiatedTemplate<int> {};
841 USEMEMFUNC(ExplicitlyImportInstantiatedTemplate<int>, func)
842 // M32-DAG: declare dllimport x86_thiscallcc void @"\01?func@?$ExplicitlyImportInstantiatedTemplate@H@@QAEXXZ"
843 // G32-DAG: declare dllimport x86_thiscallcc void @_ZN36ExplicitlyImportInstantiatedTemplateIiE4funcEv
844 
845 // MS: A dll attribute propagates through multiple levels of instantiation.
846 template <typename T> struct TopClass { void func() {} };
847 template <typename T> struct MiddleClass : public TopClass<T> { };
848 struct __declspec(dllimport) BottomClass : public MiddleClass<int> { };
849 USEMEMFUNC(TopClass<int>, func)
850 // M32-DAG: {{declare|define available_externally}} dllimport x86_thiscallcc void @"\01?func@?$TopClass@H@@QAEXXZ"
851 // G32-DAG: define linkonce_odr x86_thiscallcc void @_ZN8TopClassIiE4funcEv
852 
853 template <typename T> struct ExplicitInstantiationDeclTemplateBase { void func() {} };
854 extern template struct ExplicitInstantiationDeclTemplateBase<int>;
855 struct __declspec(dllimport) DerivedFromExplicitInstantiationDeclTemplateBase : public ExplicitInstantiationDeclTemplateBase<int> {};
856 template struct ExplicitInstantiationDeclTemplateBase<int>;
857 USEMEMFUNC(ExplicitInstantiationDeclTemplateBase<int>, func)
858 // M32-DAG: declare dllimport x86_thiscallcc void @"\01?func@?$ExplicitInstantiationDeclTemplateBase@H@@QAEXXZ"
859 // G32-DAG: define weak_odr x86_thiscallcc void @_ZN37ExplicitInstantiationDeclTemplateBaseIiE4funcEv
860 
861 template <typename T> struct ExplicitInstantiationDeclTemplateBase2 { void func() {} };
862 extern template struct ExplicitInstantiationDeclTemplateBase2<int>;
863 struct __declspec(dllimport) DerivedFromExplicitInstantiationDeclTemplateBase2 : public ExplicitInstantiationDeclTemplateBase2<int> {};
864 template struct __declspec(dllexport) ExplicitInstantiationDeclTemplateBase2<int>;
865 USEMEMFUNC(ExplicitInstantiationDeclTemplateBase2<int>, func)
866 // M32-DAG: declare dllimport x86_thiscallcc void @"\01?func@?$ExplicitInstantiationDeclTemplateBase2@H@@QAEXXZ"
867 // G32-DAG: define weak_odr x86_thiscallcc void @_ZN38ExplicitInstantiationDeclTemplateBase2IiE4funcEv
868