dllimport.cpp revision ef8225444452a1486bd721f3285301fe84643b00
1ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com// 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
2ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com// 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
3ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com// 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
4ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com// 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
5ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com// RUN: %clang_cc1 -triple i686-windows-msvc   -fno-rtti -emit-llvm -std=c++1y -O1 -o - %s -DMSABI | FileCheck --check-prefix=MO1 %s
6ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com// RUN: %clang_cc1 -triple i686-windows-gnu    -fno-rtti -emit-llvm -std=c++1y -O1 -o - %s         | FileCheck --check-prefix=GO1 %s
7ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com
8ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com// CHECK-NOT doesn't play nice with CHECK-DAG, so use separate run lines.
98a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com// RUN: %clang_cc1 -triple i686-windows-msvc   -fno-rtti -emit-llvm -std=c++1y -O0 -o - %s -DMSABI | FileCheck --check-prefix=MSC2 %s
108a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com// RUN: %clang_cc1 -triple i686-windows-gnu    -fno-rtti -emit-llvm -std=c++1y -O0 -o - %s         | FileCheck --check-prefix=GNU2 %s
118a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
128a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com// Helper structs to make templates more expressive.
138a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comstruct ImplicitInst_Imported {};
148a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comstruct ImplicitInst_NotImported {};
15a5572e5bb2a2bbeeb59de0741c2527869d365a0ccommit-bot@chromium.orgstruct ExplicitDecl_Imported {};
168a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comstruct ExplicitInst_Imported {};
178a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comstruct ExplicitSpec_Imported {};
188a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comstruct ExplicitSpec_Def_Imported {};
199c9005a347e9996f357bd79591bd34f74f8bbc66commit-bot@chromium.orgstruct ExplicitSpec_InlineDef_Imported {};
209c9005a347e9996f357bd79591bd34f74f8bbc66commit-bot@chromium.orgstruct ExplicitSpec_NotImported {};
218a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
228a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#define JOIN2(x, y) x##y
23b6e161937bc890f0aa12ac5e27415d4d260ea6e0junov@chromium.org#define JOIN(x, y) JOIN2(x, y)
2476f9e938df0b5826fd4c80b854ceafaf385cfbe1robertphillips@google.com#define UNIQ(name) JOIN(name, __LINE__)
258a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#define USEVARTYPE(type, var) type UNIQ(use)() { return var; }
2687fcd950198a16211b3988610beebb5ca5bcf323commit-bot@chromium.org#define USEVAR(var) USEVARTYPE(int, var)
2787fcd950198a16211b3988610beebb5ca5bcf323commit-bot@chromium.org#define USE(func) void UNIQ(use)() { func(); }
288a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#define USEMEMFUNC(class, func) void (class::*UNIQ(use)())() { return &class::func; }
29ff21c2e0ae23da0f4742b47d4d37969a2a18bd99skia.committer@gmail.com#define USECLASS(class) void UNIQ(USE)() { class x; }
300f10f7bf1fb43ca6346dc220a076773b1f19a367commit-bot@chromium.org#define USECOPYASSIGN(class) class& (class::*UNIQ(use)())(class&) { return &class::operator=; }
31ba28d03e94dc221d6a803bf2a84a420b9159255cdjsollen@google.com#define USEMOVEASSIGN(class) class& (class::*UNIQ(use)())(class&&) { return &class::operator=; }
328a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
339de5b514d38c5b36066bcdc14fba2f7e5196d372dandov//===----------------------------------------------------------------------===//
349de5b514d38c5b36066bcdc14fba2f7e5196d372dandov// Globals
359de5b514d38c5b36066bcdc14fba2f7e5196d372dandov//===----------------------------------------------------------------------===//
36e197cbf9a3e66bab926bc5e51962752dad5221a0bsalomon@google.com
3787fcd950198a16211b3988610beebb5ca5bcf323commit-bot@chromium.org// Import declaration.
3887fcd950198a16211b3988610beebb5ca5bcf323commit-bot@chromium.org// MSC-DAG: @"\01?ExternGlobalDecl@@3HA" = external dllimport global i32
3987fcd950198a16211b3988610beebb5ca5bcf323commit-bot@chromium.org// GNU-DAG: @ExternGlobalDecl            = external dllimport global i32
4087fcd950198a16211b3988610beebb5ca5bcf323commit-bot@chromium.org__declspec(dllimport) extern int ExternGlobalDecl;
41e901b6de3ef8dea842008a08fc81e92fb1478d61commit-bot@chromium.orgUSEVAR(ExternGlobalDecl)
4287fcd950198a16211b3988610beebb5ca5bcf323commit-bot@chromium.org
4387fcd950198a16211b3988610beebb5ca5bcf323commit-bot@chromium.org// dllimport implies a declaration.
4487fcd950198a16211b3988610beebb5ca5bcf323commit-bot@chromium.org// MSC-DAG: @"\01?GlobalDecl@@3HA" = external dllimport global i32
4587fcd950198a16211b3988610beebb5ca5bcf323commit-bot@chromium.org// GNU-DAG: @GlobalDecl            = external dllimport global i32
4687fcd950198a16211b3988610beebb5ca5bcf323commit-bot@chromium.org__declspec(dllimport) int GlobalDecl;
4787fcd950198a16211b3988610beebb5ca5bcf323commit-bot@chromium.orgUSEVAR(GlobalDecl)
4887fcd950198a16211b3988610beebb5ca5bcf323commit-bot@chromium.org
4987fcd950198a16211b3988610beebb5ca5bcf323commit-bot@chromium.org// Redeclarations
5087fcd950198a16211b3988610beebb5ca5bcf323commit-bot@chromium.org// MSC-DAG: @"\01?GlobalRedecl1@@3HA" = external dllimport global i32
5187fcd950198a16211b3988610beebb5ca5bcf323commit-bot@chromium.org// GNU-DAG: @GlobalRedecl1            = external dllimport global i32
5287fcd950198a16211b3988610beebb5ca5bcf323commit-bot@chromium.org__declspec(dllimport) extern int GlobalRedecl1;
5387fcd950198a16211b3988610beebb5ca5bcf323commit-bot@chromium.org__declspec(dllimport) extern int GlobalRedecl1;
5487fcd950198a16211b3988610beebb5ca5bcf323commit-bot@chromium.orgUSEVAR(GlobalRedecl1)
5587fcd950198a16211b3988610beebb5ca5bcf323commit-bot@chromium.org
5687fcd950198a16211b3988610beebb5ca5bcf323commit-bot@chromium.org// MSC-DAG: @"\01?GlobalRedecl2a@@3HA" = external dllimport global i32
578a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com// GNU-DAG: @GlobalRedecl2a            = external dllimport global i32
588b0e8ac5f582de80356019406e2975079bf0829dcommit-bot@chromium.org__declspec(dllimport) int GlobalRedecl2a;
598b0e8ac5f582de80356019406e2975079bf0829dcommit-bot@chromium.org__declspec(dllimport) int GlobalRedecl2a;
60ce56d965069c1649afe14319cb239e6ad670682acommit-bot@chromium.orgUSEVAR(GlobalRedecl2a)
618a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
6287fcd950198a16211b3988610beebb5ca5bcf323commit-bot@chromium.org// M32-DAG: @"\01?GlobalRedecl2b@@3PAHA"   = external dllimport global i32*
6387fcd950198a16211b3988610beebb5ca5bcf323commit-bot@chromium.org// M64-DAG: @"\01?GlobalRedecl2b@@3PEAHEA" = external dllimport global i32*
648a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com// GNU-DAG: @GlobalRedecl2b                = external dllimport global i32*
657c2f27d788fff9dbf66a6d52753e47f786a313c0reed@google.comint *__attribute__((dllimport)) GlobalRedecl2b;
668a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comint *__attribute__((dllimport)) GlobalRedecl2b;
678a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comUSEVARTYPE(int*, GlobalRedecl2b)
688a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
6987fcd950198a16211b3988610beebb5ca5bcf323commit-bot@chromium.org// MSC-DAG: @"\01?GlobalRedecl2c@@3HA" = external dllimport global i32
7087fcd950198a16211b3988610beebb5ca5bcf323commit-bot@chromium.org// GNU-DAG: @GlobalRedecl2c            = external dllimport global i32
7187fcd950198a16211b3988610beebb5ca5bcf323commit-bot@chromium.orgint GlobalRedecl2c __attribute__((dllimport));
7287fcd950198a16211b3988610beebb5ca5bcf323commit-bot@chromium.orgint GlobalRedecl2c __attribute__((dllimport));
7387fcd950198a16211b3988610beebb5ca5bcf323commit-bot@chromium.orgUSEVAR(GlobalRedecl2c)
7480116dcf1e1baf9817ae42d0aca51f7eabaa2880commit-bot@chromium.org
75a5572e5bb2a2bbeeb59de0741c2527869d365a0ccommit-bot@chromium.org// NB: MSC issues a warning and makes GlobalRedecl3 dllexport. We follow GCC
76a5572e5bb2a2bbeeb59de0741c2527869d365a0ccommit-bot@chromium.org// and drop the dllimport with a warning.
77a5572e5bb2a2bbeeb59de0741c2527869d365a0ccommit-bot@chromium.org// MSC-DAG: @"\01?GlobalRedecl3@@3HA" = external global i32
78a5572e5bb2a2bbeeb59de0741c2527869d365a0ccommit-bot@chromium.org// GNU-DAG: @GlobalRedecl3            = external global i32
799c9005a347e9996f357bd79591bd34f74f8bbc66commit-bot@chromium.org__declspec(dllimport) extern int GlobalRedecl3;
80a5572e5bb2a2bbeeb59de0741c2527869d365a0ccommit-bot@chromium.org                      extern int GlobalRedecl3; // dllimport ignored
818a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comUSEVAR(GlobalRedecl3)
82
83// MSC-DAG: @"\01?ExternalGlobal@ns@@3HA" = external dllimport global i32
84// GNU-DAG: @_ZN2ns14ExternalGlobalE      = external dllimport global i32
85namespace ns { __declspec(dllimport) int ExternalGlobal; }
86USEVAR(ns::ExternalGlobal)
87
88int 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
91inline int __declspec(dllimport) inlineStaticLocalsFunc() {
92  static int x = f();
93  return x++;
94};
95USE(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
100int *initializationFunc() {
101  static int *const arr[] = {&ExternGlobalDecl};
102  return arr[0];
103}
104USE(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
114template<typename T> __declspec(dllimport) extern int ExternVarTmplDecl;
115USEVAR(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
120template<typename T> __declspec(dllimport) int VarTmplDecl;
121USEVAR(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
126template<typename T> __declspec(dllimport) extern int VarTmplRedecl1;
127template<typename T> __declspec(dllimport) extern int VarTmplRedecl1;
128USEVAR(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
132template<typename T> __declspec(dllimport) int VarTmplRedecl2;
133template<typename T> __declspec(dllimport) int VarTmplRedecl2;
134USEVAR(VarTmplRedecl2<ImplicitInst_Imported>)
135
136// MSC-DAG: @"\01??$VarTmplRedecl3@UImplicitInst_Imported@@@@3HA" = external global i32
137// GNU-DAG: @_Z14VarTmplRedecl3I21ImplicitInst_ImportedE          = external global i32
138template<typename T> __declspec(dllimport) extern int VarTmplRedecl3;
139template<typename T>                       extern int VarTmplRedecl3; // dllimport ignored
140USEVAR(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
145namespace ns { template<typename T> __declspec(dllimport) int ExternalVarTmpl; }
146USEVAR(ns::ExternalVarTmpl<ImplicitInst_Imported>)
147
148
149template<typename T> int VarTmpl;
150template<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
155USEVAR(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
160extern template int ImportedVarTmpl<ExplicitDecl_Imported>;
161USEVAR(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
169template<> __declspec(dllimport) int ImportedVarTmpl<ExplicitSpec_Imported>;
170USEVAR(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
176template<> int ImportedVarTmpl<ExplicitSpec_NotImported>;
177USEVAR(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
182extern template __declspec(dllimport) int VarTmpl<ExplicitDecl_Imported>;
183USEVAR(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
188template __declspec(dllimport) int VarTmpl<ExplicitInst_Imported>;
189USEVAR(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
194template<> __declspec(dllimport) int VarTmpl<ExplicitSpec_Imported>;
195USEVAR(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();
207USE(decl)
208
209// extern "C"
210// MSC-DAG: declare dllimport void @externC()
211// GNU-DAG: declare dllimport void @externC()
212extern "C" __declspec(dllimport) void externC();
213USE(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() {}
221USE(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() {}
229USE(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() {}
237USE(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() {}
243USE(noinline)
244
245// MSC2-NOT: @"\01?alwaysInline@@YAXXZ"()
246// GNU2-NOT: @_Z12alwaysInlinev()
247__declspec(dllimport) __attribute__((always_inline)) inline void alwaysInline() {}
248USE(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();
255USE(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();
263USE(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
269USE(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()
279struct 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
287USE(friend1)
288USE(friend2)
289USE(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);
295void UNIQ(use)() { ::operator new(42); }
296
297// MSC-DAG: declare dllimport void @"\01?externalFunc@ns@@YAXXZ"()
298// GNU-DAG: declare dllimport void @_ZN2ns12externalFuncEv()
299namespace ns { __declspec(dllimport) void externalFunc(); }
300USE(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()
311template<typename T> __declspec(dllimport) void funcTmplDecl();
312USE(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()
321template<typename T> __declspec(dllimport) inline void inlineFuncTmpl1() {}
322USE(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()
328template<typename T> inline void __attribute__((dllimport)) inlineFuncTmpl2() {}
329USE(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()
335template<typename T> __declspec(dllimport) inline void inlineFuncTmplDecl();
336template<typename T>                              void inlineFuncTmplDecl() {}
337USE(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()
343template<typename T> __declspec(dllimport) void inlineFuncTmplDef();
344template<typename T>                inline void inlineFuncTmplDef() {}
345USE(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()
351template<typename T> __declspec(dllimport) void funcTmplRedecl1();
352template<typename T> __declspec(dllimport) void funcTmplRedecl1();
353USE(funcTmplRedecl1<ImplicitInst_Imported>)
354
355// MSC-DAG: declare void @"\01??$funcTmplRedecl2@UImplicitInst_NotImported@@@@YAXXZ"()
356// GNU-DAG: declare void @_Z15funcTmplRedecl2I24ImplicitInst_NotImportedEvv()
357template<typename T> __declspec(dllimport) void funcTmplRedecl2();
358template<typename T>                       void funcTmplRedecl2(); // dllimport ignored
359USE(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()
363template<typename T> __declspec(dllimport) void funcTmplRedecl3();
364template<typename T>                       void funcTmplRedecl3() {} // dllimport ignored
365USE(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()
377struct 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};
383template<typename T> __declspec(dllimport) void funcTmplFriend1();
384template<typename T>                       void funcTmplFriend2(); // dllimport ignored
385template<typename T>                       void funcTmplFriend3() {} // dllimport ignored
386template<typename T>                       inline void funcTmplFriend4() {}
387USE(funcTmplFriend1<ImplicitInst_Imported>)
388USE(funcTmplFriend2<ImplicitInst_NotImported>)
389USE(funcTmplFriend3<ImplicitInst_NotImported>)
390USE(funcTmplFriend4<ImplicitInst_Imported>)
391
392// MSC-DAG: declare dllimport void @"\01??$externalFuncTmpl@UImplicitInst_Imported@@@ns@@YAXXZ"()
393// GNU-DAG: declare dllimport void @_ZN2ns16externalFuncTmplI21ImplicitInst_ImportedEEvv()
394namespace ns { template<typename T> __declspec(dllimport) void externalFuncTmpl(); }
395USE(ns::externalFuncTmpl<ImplicitInst_Imported>)
396
397
398template<typename T> void funcTmpl() {}
399template<typename T> inline void inlineFuncTmpl() {}
400template<typename T> __declspec(dllimport) void importedFuncTmplDecl();
401template<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()
406USE(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()
412USE(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()
419extern template void importedFuncTmpl<ExplicitDecl_Imported>();
420USE(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()
427template void importedFuncTmpl<ExplicitInst_Imported>();
428USE(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()
434template<> __declspec(dllimport) void importedFuncTmplDecl<ExplicitSpec_Imported>();
435USE(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()
448template<> __declspec(dllimport) inline void importedFuncTmplDecl<ExplicitSpec_InlineDef_Imported>() {}
449USE(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()
454template<> __declspec(dllimport) void importedFuncTmpl<ExplicitSpec_Imported>();
455USE(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()
468template<> __declspec(dllimport) inline void importedFuncTmpl<ExplicitSpec_InlineDef_Imported>() {}
469USE(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()
476template<> void importedFuncTmpl<ExplicitSpec_NotImported>() {}
477USE(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()
487extern template __declspec(dllimport) void funcTmpl<ExplicitDecl_Imported>();
488extern template __declspec(dllimport) void inlineFuncTmpl<ExplicitDecl_Imported>();
489USE(funcTmpl<ExplicitDecl_Imported>)
490USE(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()
502template __declspec(dllimport) void funcTmpl<ExplicitInst_Imported>();
503template __declspec(dllimport) void inlineFuncTmpl<ExplicitInst_Imported>();
504USE(funcTmpl<ExplicitInst_Imported>)
505USE(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()
511template<> __declspec(dllimport) void funcTmpl<ExplicitSpec_Imported>();
512USE(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()
525template<> __declspec(dllimport) inline void funcTmpl<ExplicitSpec_InlineDef_Imported>() {}
526USE(funcTmpl<ExplicitSpec_InlineDef_Imported>)
527
528
529
530//===----------------------------------------------------------------------===//
531// Classes
532//===----------------------------------------------------------------------===//
533
534struct __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};
548USEMEMFUNC(T, a)
549USEVAR(T::b)
550USECOPYASSIGN(T)
551USEMOVEASSIGN(T)
552
553template <typename T> struct __declspec(dllimport) U { void foo() {} };
554// MO1-DAG: define available_externally dllimport x86_thiscallcc void @"\01?foo@?$U@H@@QAEXXZ"
555struct __declspec(dllimport) V : public U<int> { };
556USEMEMFUNC(V, foo)
557
558struct __declspec(dllimport) W { virtual void foo() {} };
559USECLASS(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
564struct __declspec(dllimport) KeyFuncClass {
565  constexpr KeyFuncClass() {}
566  virtual void foo();
567};
568constexpr KeyFuncClass keyFuncClassVar;
569// G32-DAG: @_ZTV12KeyFuncClass = external dllimport unnamed_addr constant [3 x i8*]
570
571struct __declspec(dllimport) X : public virtual W {};
572USECLASS(X)
573// vbtable:
574// MO1-DAG: @"\01??_8X@@7B@" = available_externally dllimport unnamed_addr constant [2 x i32] [i32 0, i32 4]
575
576struct __declspec(dllimport) Y {
577  int x;
578};
579
580struct __declspec(dllimport) Z { virtual ~Z() {} };
581USECLASS(Z)
582// User-defined dtor:
583// MO1-DAG: define available_externally dllimport x86_thiscallcc void @"\01??1Z@@UAE@XZ"
584
585namespace 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
595namespace 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
611namespace 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
630namespace 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.
662template <typename T> struct PartiallySpecializedClassTemplate {};
663template <typename T> struct __declspec(dllimport) PartiallySpecializedClassTemplate<T*> { void f() {} };
664USEMEMFUNC(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
668template <typename T> struct ExplicitlySpecializedClassTemplate {};
669template <> struct __declspec(dllimport) ExplicitlySpecializedClassTemplate<void*> { void f() {} };
670USEMEMFUNC(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
678template <typename T> struct ClassTemplate { void func() {} };
679template <typename T> struct __declspec(dllexport) ExportedClassTemplate { void func() {} };
680template <typename T> struct __declspec(dllimport) ImportedClassTemplate { void func() {} };
681
682template <typename T> struct ExplicitlySpecializedTemplate { void func() {} };
683template <> struct ExplicitlySpecializedTemplate<int> { void func() {} };
684template <typename T> struct ExplicitlyExportSpecializedTemplate { void func() {} };
685template <> struct __declspec(dllexport) ExplicitlyExportSpecializedTemplate<int> { void func() {} };
686template <typename T> struct ExplicitlyImportSpecializedTemplate { void func() {} };
687template <> struct __declspec(dllimport) ExplicitlyImportSpecializedTemplate<int> { void func() {} };
688
689template <typename T> struct ExplicitlyInstantiatedTemplate { void func() {} };
690template struct ExplicitlyInstantiatedTemplate<int>;
691template <typename T> struct ExplicitlyExportInstantiatedTemplate { void func() {} };
692template struct __declspec(dllexport) ExplicitlyExportInstantiatedTemplate<int>;
693template <typename T> struct ExplicitlyImportInstantiatedTemplate { void func() {} };
694template struct __declspec(dllimport) ExplicitlyImportInstantiatedTemplate<int>;
695
696
697// MS: ClassTemplate<int> gets imported.
698struct __declspec(dllimport) DerivedFromTemplate : public ClassTemplate<int> {};
699USEMEMFUNC(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.
704struct __declspec(dllimport) DerivedFromImportedTemplate : public ImportedClassTemplate<int> {};
705USEMEMFUNC(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.
710struct __declspec(dllimport) DerivedFromExportedTemplate : public ExportedClassTemplate<int> {};
711USEMEMFUNC(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.
716struct DerivedFromTemplateD : public ClassTemplate<double> {};
717struct __declspec(dllimport) DerivedFromTemplateD2 : public ClassTemplate<double> {};
718USEMEMFUNC(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.
723struct __declspec(dllexport) DerivedFromTemplateB : public ClassTemplate<bool> {};
724struct __declspec(dllimport) DerivedFromTemplateB2 : public ClassTemplate<bool> {};
725USEMEMFUNC(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.
730struct __declspec(dllimport) DerivedFromExplicitlySpecializedTemplate : public ExplicitlySpecializedTemplate<int> {};
731USEMEMFUNC(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.
736struct __declspec(dllimport) DerivedFromExplicitlyExportSpecializedTemplate : public ExplicitlyExportSpecializedTemplate<int> {};
737USEMEMFUNC(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.
742struct __declspec(dllimport) DerivedFromExplicitlyImportSpecializedTemplate : public ExplicitlyImportSpecializedTemplate<int> {};
743USEMEMFUNC(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.
748struct __declspec(dllimport) DerivedFromExplicitlyInstantiatedTemplate : public ExplicitlyInstantiatedTemplate<int> {};
749USEMEMFUNC(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.
754struct __declspec(dllimport) DerivedFromExplicitlyExportInstantiatedTemplate : public ExplicitlyExportInstantiatedTemplate<int> {};
755USEMEMFUNC(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.
760struct __declspec(dllimport) DerivedFromExplicitlyImportInstantiatedTemplate : public ExplicitlyImportInstantiatedTemplate<int> {};
761USEMEMFUNC(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.
766template <typename T> struct TopClass { void func() {} };
767template <typename T> struct MiddleClass : public TopClass<T> { };
768struct __declspec(dllimport) BottomClas : public MiddleClass<int> { };
769USEMEMFUNC(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