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 
98 
99 //===----------------------------------------------------------------------===//
100 // Variable templates
101 //===----------------------------------------------------------------------===//
102 
103 // Import declaration.
104 // MSC-DAG: @"\01??$ExternVarTmplDecl@UImplicitInst_Imported@@@@3HA" = external dllimport global i32
105 // GNU-DAG: @_Z17ExternVarTmplDeclI21ImplicitInst_ImportedE          = external dllimport global i32
106 template<typename T> __declspec(dllimport) extern int ExternVarTmplDecl;
107 USEVAR(ExternVarTmplDecl<ImplicitInst_Imported>)
108 
109 // dllimport implies a declaration.
110 // MSC-DAG: @"\01??$VarTmplDecl@UImplicitInst_Imported@@@@3HA" = external dllimport global i32
111 // GNU-DAG: @_Z11VarTmplDeclI21ImplicitInst_ImportedE          = external dllimport global i32
112 template<typename T> __declspec(dllimport) int VarTmplDecl;
113 USEVAR(VarTmplDecl<ImplicitInst_Imported>)
114 
115 // Redeclarations
116 // MSC-DAG: @"\01??$VarTmplRedecl1@UImplicitInst_Imported@@@@3HA" = external dllimport global i32
117 // GNU-DAG: @_Z14VarTmplRedecl1I21ImplicitInst_ImportedE          = external dllimport global i32
118 template<typename T> __declspec(dllimport) extern int VarTmplRedecl1;
119 template<typename T> __declspec(dllimport) extern int VarTmplRedecl1;
120 USEVAR(VarTmplRedecl1<ImplicitInst_Imported>)
121 
122 // MSC-DAG: @"\01??$VarTmplRedecl2@UImplicitInst_Imported@@@@3HA" = external dllimport global i32
123 // GNU-DAG: @_Z14VarTmplRedecl2I21ImplicitInst_ImportedE          = external dllimport global i32
124 template<typename T> __declspec(dllimport) int VarTmplRedecl2;
125 template<typename T> __declspec(dllimport) int VarTmplRedecl2;
126 USEVAR(VarTmplRedecl2<ImplicitInst_Imported>)
127 
128 // MSC-DAG: @"\01??$VarTmplRedecl3@UImplicitInst_Imported@@@@3HA" = external global i32
129 // GNU-DAG: @_Z14VarTmplRedecl3I21ImplicitInst_ImportedE          = external global i32
130 template<typename T> __declspec(dllimport) extern int VarTmplRedecl3;
131 template<typename T>                       extern int VarTmplRedecl3; // dllimport ignored
132 USEVAR(VarTmplRedecl3<ImplicitInst_Imported>)
133 
134 
135 // MSC-DAG: @"\01??$ExternalVarTmpl@UImplicitInst_Imported@@@ns@@3HA" = external dllimport global i32
136 // GNU-DAG: @_ZN2ns15ExternalVarTmplI21ImplicitInst_ImportedEE        = external dllimport global i32
137 namespace ns { template<typename T> __declspec(dllimport) int ExternalVarTmpl; }
138 USEVAR(ns::ExternalVarTmpl<ImplicitInst_Imported>)
139 
140 
141 template<typename T> int VarTmpl;
142 template<typename T> __declspec(dllimport) int ImportedVarTmpl;
143 
144 // Import implicit instantiation of an imported variable template.
145 // MSC-DAG: @"\01??$ImportedVarTmpl@UImplicitInst_Imported@@@@3HA" = external dllimport global i32
146 // GNU-DAG: @_Z15ImportedVarTmplI21ImplicitInst_ImportedE          = external dllimport global i32
147 USEVAR(ImportedVarTmpl<ImplicitInst_Imported>)
148 
149 // Import explicit instantiation declaration of an imported variable template.
150 // MSC-DAG: @"\01??$ImportedVarTmpl@UExplicitDecl_Imported@@@@3HA" = external dllimport global i32
151 // GNU-DAG: @_Z15ImportedVarTmplI21ExplicitDecl_ImportedE          = external dllimport global i32
152 extern template int ImportedVarTmpl<ExplicitDecl_Imported>;
153 USEVAR(ImportedVarTmpl<ExplicitDecl_Imported>)
154 
155 // An explicit instantiation definition of an imported variable template cannot
156 // be imported because the template must be defined which is illegal.
157 
158 // Import specialization of an imported variable template.
159 // MSC-DAG: @"\01??$ImportedVarTmpl@UExplicitSpec_Imported@@@@3HA" = external dllimport global i32
160 // GNU-DAG: @_Z15ImportedVarTmplI21ExplicitSpec_ImportedE          = external dllimport global i32
161 template<> __declspec(dllimport) int ImportedVarTmpl<ExplicitSpec_Imported>;
162 USEVAR(ImportedVarTmpl<ExplicitSpec_Imported>)
163 
164 // Not importing specialization of an imported variable template without
165 // explicit dllimport.
166 // MSC-DAG: @"\01??$ImportedVarTmpl@UExplicitSpec_NotImported@@@@3HA" = global i32 0, align 4
167 // GNU-DAG: @_Z15ImportedVarTmplI24ExplicitSpec_NotImportedE          = global i32 0, align 4
168 template<> int ImportedVarTmpl<ExplicitSpec_NotImported>;
169 USEVAR(ImportedVarTmpl<ExplicitSpec_NotImported>)
170 
171 // Import explicit instantiation declaration of a non-imported variable template.
172 // MSC-DAG: @"\01??$VarTmpl@UExplicitDecl_Imported@@@@3HA" = external dllimport global i32
173 // GNU-DAG: @_Z7VarTmplI21ExplicitDecl_ImportedE           = external dllimport global i32
174 extern template __declspec(dllimport) int VarTmpl<ExplicitDecl_Imported>;
175 USEVAR(VarTmpl<ExplicitDecl_Imported>)
176 
177 // Import explicit instantiation definition of a non-imported variable template.
178 // MSC-DAG: @"\01??$VarTmpl@UExplicitInst_Imported@@@@3HA" = external dllimport global i32
179 // GNU-DAG: @_Z7VarTmplI21ExplicitInst_ImportedE           = external dllimport global i32
180 template __declspec(dllimport) int VarTmpl<ExplicitInst_Imported>;
181 USEVAR(VarTmpl<ExplicitInst_Imported>)
182 
183 // Import specialization of a non-imported variable template.
184 // MSC-DAG: @"\01??$VarTmpl@UExplicitSpec_Imported@@@@3HA" = external dllimport global i32
185 // GNU-DAG: @_Z7VarTmplI21ExplicitSpec_ImportedE           = external dllimport global i32
186 template<> __declspec(dllimport) int VarTmpl<ExplicitSpec_Imported>;
187 USEVAR(VarTmpl<ExplicitSpec_Imported>)
188 
189 
190 
191 //===----------------------------------------------------------------------===//
192 // Functions
193 //===----------------------------------------------------------------------===//
194 
195 // Import function declaration.
196 // MSC-DAG: declare dllimport void @"\01?decl@@YAXXZ"()
197 // GNU-DAG: declare dllimport void @_Z4declv()
198 __declspec(dllimport) void decl();
199 USE(decl)
200 
201 // extern "C"
202 // MSC-DAG: declare dllimport void @externC()
203 // GNU-DAG: declare dllimport void @externC()
204 extern "C" __declspec(dllimport) void externC();
205 USE(externC)
206 
207 // Import inline function.
208 // MSC-DAG: declare dllimport void @"\01?inlineFunc@@YAXXZ"()
209 // GNU-DAG: declare dllimport void @_Z10inlineFuncv()
210 // MO1-DAG: define available_externally dllimport void @"\01?inlineFunc@@YAXXZ"()
211 // GO1-DAG: define available_externally dllimport void @_Z10inlineFuncv()
212 __declspec(dllimport) inline void inlineFunc() {}
213 USE(inlineFunc)
214 
215 // MSC-DAG: declare dllimport void @"\01?inlineDecl@@YAXXZ"()
216 // GNU-DAG: declare dllimport void @_Z10inlineDeclv()
217 // MO1-DAG: define available_externally dllimport void @"\01?inlineDecl@@YAXXZ"()
218 // GO1-DAG: define available_externally dllimport void @_Z10inlineDeclv()
219 __declspec(dllimport) inline void inlineDecl();
220                              void inlineDecl() {}
221 USE(inlineDecl)
222 
223 // MSC-DAG: declare dllimport void @"\01?inlineDef@@YAXXZ"()
224 // GNU-DAG: declare dllimport void @_Z9inlineDefv()
225 // MO1-DAG: define available_externally dllimport void @"\01?inlineDef@@YAXXZ"()
226 // GO1-DAG: define available_externally dllimport void @_Z9inlineDefv()
227 __declspec(dllimport) void inlineDef();
228                inline void inlineDef() {}
229 USE(inlineDef)
230 
231 // inline attributes
232 // MSC-DAG: declare dllimport void @"\01?noinline@@YAXXZ"()
233 // GNU-DAG: declare dllimport void @_Z8noinlinev()
234 __declspec(dllimport) __attribute__((noinline)) inline void noinline() {}
235 USE(noinline)
236 
237 // MSC2-NOT: @"\01?alwaysInline@@YAXXZ"()
238 // GNU2-NOT: @_Z12alwaysInlinev()
239 __declspec(dllimport) __attribute__((always_inline)) inline void alwaysInline() {}
240 USE(alwaysInline)
241 
242 // Redeclarations
243 // MSC-DAG: declare dllimport void @"\01?redecl1@@YAXXZ"()
244 // GNU-DAG: declare dllimport void @_Z7redecl1v()
245 __declspec(dllimport) void redecl1();
246 __declspec(dllimport) void redecl1();
247 USE(redecl1)
248 
249 // NB: MSC issues a warning and makes redecl2/redecl3 dllexport. We follow GCC
250 // and drop the dllimport with a warning.
251 // MSC-DAG: declare void @"\01?redecl2@@YAXXZ"()
252 // GNU-DAG: declare void @_Z7redecl2v()
253 __declspec(dllimport) void redecl2();
254                       void redecl2();
255 USE(redecl2)
256 
257 // MSC-DAG: define void @"\01?redecl3@@YAXXZ"()
258 // GNU-DAG: define void @_Z7redecl3v()
259 __declspec(dllimport) void redecl3();
260                       void redecl3() {} // dllimport ignored
261 USE(redecl3)
262 
263 
264 // Friend functions
265 // MSC-DAG: declare dllimport void @"\01?friend1@@YAXXZ"()
266 // GNU-DAG: declare dllimport void @_Z7friend1v()
267 // MSC-DAG: declare           void @"\01?friend2@@YAXXZ"()
268 // GNU-DAG: declare           void @_Z7friend2v()
269 // MSC-DAG: define            void @"\01?friend3@@YAXXZ"()
270 // GNU-DAG: define            void @_Z7friend3v()
271 struct FuncFriend {
272   friend __declspec(dllimport) void friend1();
273   friend __declspec(dllimport) void friend2();
274   friend __declspec(dllimport) void friend3();
275 };
276 __declspec(dllimport) void friend1();
277                       void friend2(); // dllimport ignored
278                       void friend3() {} // dllimport ignored
279 USE(friend1)
280 USE(friend2)
281 USE(friend3)
282 
283 // Implicit declarations can be redeclared with dllimport.
284 // MSC-DAG: declare dllimport noalias i8* @"\01??2@{{YAPAXI|YAPEAX_K}}@Z"(
285 // GNU-DAG: declare dllimport noalias i8* @_Znw{{[yj]}}(
286 __declspec(dllimport) void* operator new(__SIZE_TYPE__ n);
287 void UNIQ(use)() { ::operator new(42); }
288 
289 // MSC-DAG: declare dllimport void @"\01?externalFunc@ns@@YAXXZ"()
290 // GNU-DAG: declare dllimport void @_ZN2ns12externalFuncEv()
291 namespace ns { __declspec(dllimport) void externalFunc(); }
292 USE(ns::externalFunc)
293 
294 
295 
296 //===----------------------------------------------------------------------===//
297 // Function templates
298 //===----------------------------------------------------------------------===//
299 
300 // Import function template declaration.
301 // MSC-DAG: declare dllimport void @"\01??$funcTmplDecl@UImplicitInst_Imported@@@@YAXXZ"()
302 // GNU-DAG: declare dllimport void @_Z12funcTmplDeclI21ImplicitInst_ImportedEvv()
303 template<typename T> __declspec(dllimport) void funcTmplDecl();
304 USE(funcTmplDecl<ImplicitInst_Imported>)
305 
306 // Function template definitions cannot be imported.
307 
308 // Import inline function template.
309 // MSC-DAG: declare dllimport void @"\01??$inlineFuncTmpl1@UImplicitInst_Imported@@@@YAXXZ"()
310 // GNU-DAG: declare dllimport void @_Z15inlineFuncTmpl1I21ImplicitInst_ImportedEvv()
311 // MO1-DAG: define available_externally dllimport void @"\01??$inlineFuncTmpl1@UImplicitInst_Imported@@@@YAXXZ"()
312 // GO1-DAG: define available_externally dllimport void @_Z15inlineFuncTmpl1I21ImplicitInst_ImportedEvv()
313 template<typename T> __declspec(dllimport) inline void inlineFuncTmpl1() {}
314 USE(inlineFuncTmpl1<ImplicitInst_Imported>)
315 
316 // MSC-DAG: declare dllimport void @"\01??$inlineFuncTmpl2@UImplicitInst_Imported@@@@YAXXZ"()
317 // GNU-DAG: declare dllimport void @_Z15inlineFuncTmpl2I21ImplicitInst_ImportedEvv()
318 // MO1-DAG: define available_externally dllimport void @"\01??$inlineFuncTmpl2@UImplicitInst_Imported@@@@YAXXZ"()
319 // GO1-DAG: define available_externally dllimport void @_Z15inlineFuncTmpl2I21ImplicitInst_ImportedEvv()
320 template<typename T> inline void __attribute__((dllimport)) inlineFuncTmpl2() {}
321 USE(inlineFuncTmpl2<ImplicitInst_Imported>)
322 
323 // MSC-DAG: declare dllimport void @"\01??$inlineFuncTmplDecl@UImplicitInst_Imported@@@@YAXXZ"()
324 // GNU-DAG: declare dllimport void @_Z18inlineFuncTmplDeclI21ImplicitInst_ImportedEvv()
325 // MO1-DAG: define available_externally dllimport void @"\01??$inlineFuncTmplDecl@UImplicitInst_Imported@@@@YAXXZ"()
326 // GO1-DAG: define available_externally dllimport void @_Z18inlineFuncTmplDeclI21ImplicitInst_ImportedEvv()
327 template<typename T> __declspec(dllimport) inline void inlineFuncTmplDecl();
328 template<typename T>                              void inlineFuncTmplDecl() {}
329 USE(inlineFuncTmplDecl<ImplicitInst_Imported>)
330 
331 // MSC-DAG: declare dllimport void @"\01??$inlineFuncTmplDef@UImplicitInst_Imported@@@@YAXXZ"()
332 // GNU-DAG: declare dllimport void @_Z17inlineFuncTmplDefI21ImplicitInst_ImportedEvv()
333 // MO1-DAG: define available_externally dllimport void @"\01??$inlineFuncTmplDef@UImplicitInst_Imported@@@@YAXXZ"()
334 // GO1-DAG: define available_externally dllimport void @_Z17inlineFuncTmplDefI21ImplicitInst_ImportedEvv()
335 template<typename T> __declspec(dllimport) void inlineFuncTmplDef();
336 template<typename T>                inline void inlineFuncTmplDef() {}
337 USE(inlineFuncTmplDef<ImplicitInst_Imported>)
338 
339 
340 // Redeclarations
341 // MSC-DAG: declare dllimport void @"\01??$funcTmplRedecl1@UImplicitInst_Imported@@@@YAXXZ"()
342 // GNU-DAG: declare dllimport void @_Z15funcTmplRedecl1I21ImplicitInst_ImportedEvv()
343 template<typename T> __declspec(dllimport) void funcTmplRedecl1();
344 template<typename T> __declspec(dllimport) void funcTmplRedecl1();
345 USE(funcTmplRedecl1<ImplicitInst_Imported>)
346 
347 // MSC-DAG: declare void @"\01??$funcTmplRedecl2@UImplicitInst_NotImported@@@@YAXXZ"()
348 // GNU-DAG: declare void @_Z15funcTmplRedecl2I24ImplicitInst_NotImportedEvv()
349 template<typename T> __declspec(dllimport) void funcTmplRedecl2();
350 template<typename T>                       void funcTmplRedecl2(); // dllimport ignored
351 USE(funcTmplRedecl2<ImplicitInst_NotImported>)
352 
353 // MSC-DAG: define linkonce_odr void @"\01??$funcTmplRedecl3@UImplicitInst_NotImported@@@@YAXXZ"()
354 // GNU-DAG: define linkonce_odr void @_Z15funcTmplRedecl3I24ImplicitInst_NotImportedEvv()
355 template<typename T> __declspec(dllimport) void funcTmplRedecl3();
356 template<typename T>                       void funcTmplRedecl3() {} // dllimport ignored
357 USE(funcTmplRedecl3<ImplicitInst_NotImported>)
358 
359 
360 // Function template friends
361 // MSC-DAG: declare dllimport   void @"\01??$funcTmplFriend1@UImplicitInst_Imported@@@@YAXXZ"()
362 // GNU-DAG: declare dllimport   void @_Z15funcTmplFriend1I21ImplicitInst_ImportedEvv()
363 // MSC-DAG: declare             void @"\01??$funcTmplFriend2@UImplicitInst_NotImported@@@@YAXXZ"()
364 // GNU-DAG: declare             void @_Z15funcTmplFriend2I24ImplicitInst_NotImportedEvv()
365 // MSC-DAG: define linkonce_odr void @"\01??$funcTmplFriend3@UImplicitInst_NotImported@@@@YAXXZ"()
366 // GNU-DAG: define linkonce_odr void @_Z15funcTmplFriend3I24ImplicitInst_NotImportedEvv()
367 // MSC-DAG: declare dllimport   void @"\01??$funcTmplFriend4@UImplicitInst_Imported@@@@YAXXZ"()
368 // GNU-DAG: declare dllimport   void @_Z15funcTmplFriend4I21ImplicitInst_ImportedEvv()
369 struct FuncTmplFriend {
370   template<typename T> friend __declspec(dllimport) void funcTmplFriend1();
371   template<typename T> friend __declspec(dllimport) void funcTmplFriend2();
372   template<typename T> friend __declspec(dllimport) void funcTmplFriend3();
373   template<typename T> friend __declspec(dllimport) inline void funcTmplFriend4();
374 };
375 template<typename T> __declspec(dllimport) void funcTmplFriend1();
376 template<typename T>                       void funcTmplFriend2(); // dllimport ignored
377 template<typename T>                       void funcTmplFriend3() {} // dllimport ignored
378 template<typename T>                       inline void funcTmplFriend4() {}
379 USE(funcTmplFriend1<ImplicitInst_Imported>)
380 USE(funcTmplFriend2<ImplicitInst_NotImported>)
381 USE(funcTmplFriend3<ImplicitInst_NotImported>)
382 USE(funcTmplFriend4<ImplicitInst_Imported>)
383 
384 // MSC-DAG: declare dllimport void @"\01??$externalFuncTmpl@UImplicitInst_Imported@@@ns@@YAXXZ"()
385 // GNU-DAG: declare dllimport void @_ZN2ns16externalFuncTmplI21ImplicitInst_ImportedEEvv()
386 namespace ns { template<typename T> __declspec(dllimport) void externalFuncTmpl(); }
387 USE(ns::externalFuncTmpl<ImplicitInst_Imported>)
388 
389 
390 template<typename T> void funcTmpl() {}
391 template<typename T> inline void inlineFuncTmpl() {}
392 template<typename T> __declspec(dllimport) void importedFuncTmplDecl();
393 template<typename T> __declspec(dllimport) inline void importedFuncTmpl() {}
394 
395 // Import implicit instantiation of an imported function template.
396 // MSC-DAG: declare dllimport void @"\01??$importedFuncTmplDecl@UImplicitInst_Imported@@@@YAXXZ"()
397 // GNU-DAG: declare dllimport void @_Z20importedFuncTmplDeclI21ImplicitInst_ImportedEvv()
398 USE(importedFuncTmplDecl<ImplicitInst_Imported>)
399 
400 // MSC-DAG: declare dllimport void @"\01??$importedFuncTmpl@UImplicitInst_Imported@@@@YAXXZ"()
401 // GNU-DAG: declare dllimport void @_Z16importedFuncTmplI21ImplicitInst_ImportedEvv()
402 // MO1-DAG: define available_externally dllimport void @"\01??$importedFuncTmpl@UImplicitInst_Imported@@@@YAXXZ"()
403 // GO1-DAG: define available_externally dllimport void @_Z16importedFuncTmplI21ImplicitInst_ImportedEvv()
404 USE(importedFuncTmpl<ImplicitInst_Imported>)
405 
406 // Import explicit instantiation declaration of an imported function template.
407 // MSC-DAG: declare dllimport void @"\01??$importedFuncTmpl@UExplicitDecl_Imported@@@@YAXXZ"()
408 // GNU-DAG: declare dllimport void @_Z16importedFuncTmplI21ExplicitDecl_ImportedEvv()
409 // MO1-DAG: define available_externally dllimport void @"\01??$importedFuncTmpl@UExplicitDecl_Imported@@@@YAXXZ"()
410 // GO1-DAG: define available_externally dllimport void @_Z16importedFuncTmplI21ExplicitDecl_ImportedEvv()
411 extern template void importedFuncTmpl<ExplicitDecl_Imported>();
412 USE(importedFuncTmpl<ExplicitDecl_Imported>)
413 
414 // Import explicit instantiation definition of an imported function template.
415 // MSC-DAG: declare dllimport void @"\01??$importedFuncTmpl@UExplicitInst_Imported@@@@YAXXZ"()
416 // GNU-DAG: declare dllimport void @_Z16importedFuncTmplI21ExplicitInst_ImportedEvv()
417 // MO1-DAG: define available_externally dllimport void @"\01??$importedFuncTmpl@UExplicitInst_Imported@@@@YAXXZ"()
418 // GO1-DAG: define available_externally dllimport void @_Z16importedFuncTmplI21ExplicitInst_ImportedEvv()
419 template void importedFuncTmpl<ExplicitInst_Imported>();
420 USE(importedFuncTmpl<ExplicitInst_Imported>)
421 
422 
423 // Import specialization of an imported function template.
424 // MSC-DAG: declare dllimport void @"\01??$importedFuncTmplDecl@UExplicitSpec_Imported@@@@YAXXZ"()
425 // GNU-DAG: declare dllimport void @_Z20importedFuncTmplDeclI21ExplicitSpec_ImportedEvv()
426 template<> __declspec(dllimport) void importedFuncTmplDecl<ExplicitSpec_Imported>();
427 USE(importedFuncTmplDecl<ExplicitSpec_Imported>)
428 
429 // MSC-DAG-FIXME: declare dllimport void @"\01??$importedFuncTmplDecl@UExplicitSpec_Def_Imported@@@@YAXXZ"()
430 // MO1-DAG-FIXME: define available_externally dllimport void @"\01??$importedFuncTmplDecl@UExplicitSpec_Def_Imported@@@@YAXXZ"()
431 #ifdef MSABI
432 //template<> __declspec(dllimport) void importedFuncTmplDecl<ExplicitSpec_Def_Imported>() {}
433 //USE(importedFuncTmplDecl<ExplicitSpec_Def_Imported>)
434 #endif
435 
436 // MSC-DAG: declare dllimport void @"\01??$importedFuncTmplDecl@UExplicitSpec_InlineDef_Imported@@@@YAXXZ"()
437 // GNU-DAG: declare dllimport void @_Z20importedFuncTmplDeclI31ExplicitSpec_InlineDef_ImportedEvv()
438 // MO1-DAG: define available_externally dllimport void @"\01??$importedFuncTmplDecl@UExplicitSpec_InlineDef_Imported@@@@YAXXZ"()
439 // GO1-DAG: define available_externally dllimport void @_Z20importedFuncTmplDeclI31ExplicitSpec_InlineDef_ImportedEvv()
440 template<> __declspec(dllimport) inline void importedFuncTmplDecl<ExplicitSpec_InlineDef_Imported>() {}
441 USE(importedFuncTmplDecl<ExplicitSpec_InlineDef_Imported>)
442 
443 
444 // MSC-DAG: declare dllimport void @"\01??$importedFuncTmpl@UExplicitSpec_Imported@@@@YAXXZ"()
445 // GNU-DAG: declare dllimport void @_Z16importedFuncTmplI21ExplicitSpec_ImportedEvv()
446 template<> __declspec(dllimport) void importedFuncTmpl<ExplicitSpec_Imported>();
447 USE(importedFuncTmpl<ExplicitSpec_Imported>)
448 
449 // MSC-DAG-FIXME: declare dllimport void @"\01??$importedFuncTmpl@UExplicitSpec_Def_Imported@@@@YAXXZ"()
450 // MO1-DAG-FIXME: define available_externally dllimport void @"\01??$importedFuncTmpl@UExplicitSpec_Def_Imported@@@@YAXXZ"()
451 #ifdef MSABI
452 //template<> __declspec(dllimport) void importedFuncTmpl<ExplicitSpec_Def_Imported>() {}
453 //USE(importedFuncTmpl<ExplicitSpec_Def_Imported>)
454 #endif
455 
456 // MSC-DAG: declare dllimport void @"\01??$importedFuncTmpl@UExplicitSpec_InlineDef_Imported@@@@YAXXZ"()
457 // GNU-DAG: declare dllimport void @_Z16importedFuncTmplI31ExplicitSpec_InlineDef_ImportedEvv()
458 // MO1-DAG: define available_externally dllimport void @"\01??$importedFuncTmpl@UExplicitSpec_InlineDef_Imported@@@@YAXXZ"()
459 // GO1-DAG: define available_externally dllimport void @_Z16importedFuncTmplI31ExplicitSpec_InlineDef_ImportedEvv()
460 template<> __declspec(dllimport) inline void importedFuncTmpl<ExplicitSpec_InlineDef_Imported>() {}
461 USE(importedFuncTmpl<ExplicitSpec_InlineDef_Imported>)
462 
463 
464 // Not importing specialization of an imported function template without
465 // explicit dllimport.
466 // MSC-DAG: define void @"\01??$importedFuncTmpl@UExplicitSpec_NotImported@@@@YAXXZ"()
467 // GNU-DAG: define void @_Z16importedFuncTmplI24ExplicitSpec_NotImportedEvv()
468 template<> void importedFuncTmpl<ExplicitSpec_NotImported>() {}
469 USE(importedFuncTmpl<ExplicitSpec_NotImported>)
470 
471 
472 // Import explicit instantiation declaration of a non-imported function template.
473 // MSC-DAG: declare dllimport void @"\01??$funcTmpl@UExplicitDecl_Imported@@@@YAXXZ"()
474 // MSC-DAG: declare dllimport void @"\01??$inlineFuncTmpl@UExplicitDecl_Imported@@@@YAXXZ"()
475 // GNU-DAG: declare dllimport void @_Z8funcTmplI21ExplicitDecl_ImportedEvv()
476 // GNU-DAG: declare dllimport void @_Z14inlineFuncTmplI21ExplicitDecl_ImportedEvv()
477 // MO1-DAG: define available_externally dllimport void @"\01??$inlineFuncTmpl@UExplicitDecl_Imported@@@@YAXXZ"()
478 // GO1-DAG: define available_externally dllimport void @_Z14inlineFuncTmplI21ExplicitDecl_ImportedEvv()
479 extern template __declspec(dllimport) void funcTmpl<ExplicitDecl_Imported>();
480 extern template __declspec(dllimport) void inlineFuncTmpl<ExplicitDecl_Imported>();
481 USE(funcTmpl<ExplicitDecl_Imported>)
482 USE(inlineFuncTmpl<ExplicitDecl_Imported>)
483 
484 
485 // Import explicit instantiation definition of a non-imported function template.
486 // MSC-DAG: declare dllimport void @"\01??$funcTmpl@UExplicitInst_Imported@@@@YAXXZ"()
487 // MSC-DAG: declare dllimport void @"\01??$inlineFuncTmpl@UExplicitInst_Imported@@@@YAXXZ"()
488 // GNU-DAG: declare dllimport void @_Z8funcTmplI21ExplicitInst_ImportedEvv()
489 // GNU-DAG: declare dllimport void @_Z14inlineFuncTmplI21ExplicitInst_ImportedEvv()
490 // MO1-DAG: define available_externally dllimport void @"\01??$funcTmpl@UExplicitInst_Imported@@@@YAXXZ"()
491 // MO1-DAG: define available_externally dllimport void @"\01??$inlineFuncTmpl@UExplicitInst_Imported@@@@YAXXZ"()
492 // GO1-DAG: define available_externally dllimport void @_Z8funcTmplI21ExplicitInst_ImportedEvv()
493 // GO1-DAG: define available_externally dllimport void @_Z14inlineFuncTmplI21ExplicitInst_ImportedEvv()
494 template __declspec(dllimport) void funcTmpl<ExplicitInst_Imported>();
495 template __declspec(dllimport) void inlineFuncTmpl<ExplicitInst_Imported>();
496 USE(funcTmpl<ExplicitInst_Imported>)
497 USE(inlineFuncTmpl<ExplicitInst_Imported>)
498 
499 
500 // Import specialization of a non-imported function template.
501 // MSC-DAG: declare dllimport void @"\01??$funcTmpl@UExplicitSpec_Imported@@@@YAXXZ"()
502 // GNU-DAG: declare dllimport void @_Z8funcTmplI21ExplicitSpec_ImportedEvv()
503 template<> __declspec(dllimport) void funcTmpl<ExplicitSpec_Imported>();
504 USE(funcTmpl<ExplicitSpec_Imported>)
505 
506 // MSC-DAG-FIXME: declare dllimport void @"\01??$funcTmpl@UExplicitSpec_Def_Imported@@@@YAXXZ"()
507 // MO1-DAG-FIXME: define available_externally dllimport void @"\01??$funcTmpl@UExplicitSpec_Def_Imported@@@@YAXXZ"()
508 #ifdef MSABI
509 //template<> __declspec(dllimport) void funcTmpl<ExplicitSpec_Def_Imported>() {}
510 //USE(funcTmpl<ExplicitSpec_Def_Imported>)
511 #endif
512 
513 // MSC-DAG: declare dllimport void @"\01??$funcTmpl@UExplicitSpec_InlineDef_Imported@@@@YAXXZ"()
514 // GNU-DAG: declare dllimport void @_Z8funcTmplI31ExplicitSpec_InlineDef_ImportedEvv()
515 // MO1-DAG: define available_externally dllimport void @"\01??$funcTmpl@UExplicitSpec_InlineDef_Imported@@@@YAXXZ"()
516 // GO1-DAG: define available_externally dllimport void @_Z8funcTmplI31ExplicitSpec_InlineDef_ImportedEvv()
517 template<> __declspec(dllimport) inline void funcTmpl<ExplicitSpec_InlineDef_Imported>() {}
518 USE(funcTmpl<ExplicitSpec_InlineDef_Imported>)
519 
520 
521 
522 //===----------------------------------------------------------------------===//
523 // Classes
524 //===----------------------------------------------------------------------===//
525 
526 struct __declspec(dllimport) T {
527   void a() {}
528   // MO1-DAG: define available_externally dllimport x86_thiscallcc void @"\01?a@T@@QAEXXZ"
529 
530   static int b;
531   // MO1-DAG: @"\01?b@T@@2HA" = external dllimport global i32
532 
533   T& operator=(T&) = default;
534   // MO1-DAG: define available_externally dllimport x86_thiscallcc nonnull %struct.T* @"\01??4T@@QAEAAU0@AAU0@@Z"
535 
536   T& operator=(T&&) = default;
537   // Note: Don't mark inline move operators dllimport because current MSVC versions don't export them.
538   // MO1-DAG: define linkonce_odr x86_thiscallcc nonnull %struct.T* @"\01??4T@@QAEAAU0@$$QAU0@@Z"
539 };
540 USEMEMFUNC(T, a)
541 USEVAR(T::b)
542 USECOPYASSIGN(T)
543 USEMOVEASSIGN(T)
544 
545 template <typename T> struct __declspec(dllimport) U { void foo() {} };
546 // MO1-DAG: define available_externally dllimport x86_thiscallcc void @"\01?foo@?$U@H@@QAEXXZ"
547 struct __declspec(dllimport) V : public U<int> { };
548 USEMEMFUNC(V, foo)
549 
550 struct __declspec(dllimport) W { virtual void foo() {} };
551 USECLASS(W)
552 // vftable:
553 // 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*)]
554 // GO1-DAG: @_ZTV1W = available_externally dllimport unnamed_addr constant [3 x i8*] [i8* null, i8* null, i8* bitcast (void (%struct.W*)* @_ZN1W3fooEv to i8*)]
555 
556 struct __declspec(dllimport) KeyFuncClass {
557   constexpr KeyFuncClass() {}
558   virtual void foo();
559 };
560 constexpr KeyFuncClass keyFuncClassVar;
561 // G32-DAG: @_ZTV12KeyFuncClass = external dllimport unnamed_addr constant [3 x i8*]
562 
563 struct __declspec(dllimport) X : public virtual W {};
564 USECLASS(X)
565 // vbtable:
566 // MO1-DAG: @"\01??_8X@@7B@" = available_externally dllimport unnamed_addr constant [2 x i32] [i32 0, i32 4]
567 
568 struct __declspec(dllimport) Y {
569   int x;
570 };
571 
572 struct __declspec(dllimport) Z { virtual ~Z() {} };
573 USECLASS(Z)
574 // User-defined dtor:
575 // MO1-DAG: define available_externally dllimport x86_thiscallcc void @"\01??1Z@@UAE@XZ"
576 
577 namespace DontUseDtorAlias {
578   struct __declspec(dllimport) A { ~A(); };
579   struct __declspec(dllimport) B : A { ~B(); };
580   inline A::~A() { }
581   inline B::~B() { }
582   // Emit a real definition of B's constructor; don't alias it to A's.
583   // MO1-DAG: available_externally dllimport x86_thiscallcc void @"\01??1B@DontUseDtorAlias@@QAE@XZ"
584   USECLASS(B)
585 }
586 
587 namespace Vtordisp {
588   // Don't dllimport the vtordisp.
589   // MO1-DAG: define linkonce_odr x86_thiscallcc void @"\01?f@?$C@D@Vtordisp@@$4PPPPPPPM@A@AEXXZ"
590 
591   class Base {
592     virtual void f() {}
593   };
594   template <typename T>
595   class __declspec(dllimport) C : virtual public Base {
596   public:
597     C() {}
598     virtual void f() {}
599   };
600   template class C<char>;
601 }
602 
603 namespace ClassTemplateStaticDef {
604   // Regular template static field:
605   template <typename T> struct __declspec(dllimport) S {
606     static int x;
607   };
608   template <typename T> int S<T>::x;
609   // MSC-DAG: @"\01?x@?$S@H@ClassTemplateStaticDef@@2HA" = available_externally dllimport global i32 0
610   int f() { return S<int>::x; }
611 
612   // Partial class template specialization static field:
613   template <typename A> struct T;
614   template <typename A> struct __declspec(dllimport) T<A*> {
615     static int x;
616   };
617   template <typename A> int T<A*>::x;
618   // M32-DAG: @"\01?x@?$T@PAX@ClassTemplateStaticDef@@2HA" = available_externally dllimport global i32 0
619   int g() { return T<void*>::x; }
620 }
621 
622 namespace PR19933 {
623 // Don't dynamically initialize dllimport vars.
624 // MSC2-NOT: @llvm.global_ctors
625 // GNU2-NOT: @llvm.global_ctors
626 
627   struct NonPOD { NonPOD(); };
628   template <typename T> struct A { static NonPOD x; };
629   template <typename T> NonPOD A<T>::x;
630   template struct __declspec(dllimport) A<int>;
631   // MSC-DAG: @"\01?x@?$A@H@PR19933@@2UNonPOD@2@A" = available_externally dllimport global %"struct.PR19933::NonPOD" zeroinitializer
632 
633   int f();
634   template <typename T> struct B { static int x; };
635   template <typename T> int B<T>::x = f();
636   template struct __declspec(dllimport) B<int>;
637   // MSC-DAG: @"\01?x@?$B@H@PR19933@@2HA" = available_externally dllimport global i32 0
638 
639   constexpr int g() { return 42; }
640   template <typename T> struct C { static int x; };
641   template <typename T> int C<T>::x = g();
642   template struct __declspec(dllimport) C<int>;
643   // MSC-DAG: @"\01?x@?$C@H@PR19933@@2HA" = available_externally dllimport global i32 42
644 
645   template <int I> struct D { static int x, y; };
646   template <int I> int D<I>::x = I + 1;
647   template <int I> int D<I>::y = I + f();
648   template struct __declspec(dllimport) D<42>;
649   // MSC-DAG: @"\01?x@?$D@$0CK@@PR19933@@2HA" = available_externally dllimport global i32 43
650   // MSC-DAG: @"\01?y@?$D@$0CK@@PR19933@@2HA" = available_externally dllimport global i32 0
651 }
652