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