xref: /aosp_15_r20/external/clang/test/CodeGen/dllimport.c (revision 67e74705e28f6214e480b399dd47ea732279e315)
1*67e74705SXin Li // RUN: %clang_cc1 -triple i686-windows-msvc   -fms-extensions -emit-llvm -std=c11 -O0 -o - %s | FileCheck --check-prefix=CHECK --check-prefix=MS %s
2*67e74705SXin Li // RUN: %clang_cc1 -triple x86_64-windows-msvc -fms-extensions -emit-llvm -std=c11 -O0 -o - %s | FileCheck --check-prefix=CHECK --check-prefix=MS %s
3*67e74705SXin Li // RUN: %clang_cc1 -triple i686-windows-gnu    -fms-extensions -emit-llvm -std=c11 -O0 -o - %s | FileCheck --check-prefix=CHECK --check-prefix=GNU %s
4*67e74705SXin Li // RUN: %clang_cc1 -triple x86_64-windows-gnu  -fms-extensions -emit-llvm -std=c11 -O0 -o - %s | FileCheck --check-prefix=CHECK --check-prefix=GNU %s
5*67e74705SXin Li // RUN: %clang_cc1 -triple i686-windows-msvc   -fms-extensions -emit-llvm -std=c11 -O1 -o - %s | FileCheck --check-prefix=O1 --check-prefix=MO1 %s
6*67e74705SXin Li // RUN: %clang_cc1 -triple i686-windows-gnu    -fms-extensions -emit-llvm -std=c11 -O1 -o - %s | FileCheck --check-prefix=O1 --check-prefix=GO1 %s
7*67e74705SXin Li 
8*67e74705SXin Li #define JOIN2(x, y) x##y
9*67e74705SXin Li #define JOIN(x, y) JOIN2(x, y)
10*67e74705SXin Li #define USEVAR(var) int JOIN(use, __LINE__)() { return var; }
11*67e74705SXin Li #define USE(func) void JOIN(use, __LINE__)() { func(); }
12*67e74705SXin Li 
13*67e74705SXin Li 
14*67e74705SXin Li 
15*67e74705SXin Li //===----------------------------------------------------------------------===//
16*67e74705SXin Li // Globals
17*67e74705SXin Li //===----------------------------------------------------------------------===//
18*67e74705SXin Li 
19*67e74705SXin Li // Import declaration.
20*67e74705SXin Li // CHECK: @ExternGlobalDecl = external dllimport global i32
21*67e74705SXin Li __declspec(dllimport) extern int ExternGlobalDecl;
22*67e74705SXin Li USEVAR(ExternGlobalDecl)
23*67e74705SXin Li 
24*67e74705SXin Li // dllimport implies a declaration.
25*67e74705SXin Li // CHECK: @GlobalDecl = external dllimport global i32
26*67e74705SXin Li __declspec(dllimport) int GlobalDecl;
27*67e74705SXin Li USEVAR(GlobalDecl)
28*67e74705SXin Li 
29*67e74705SXin Li // Redeclarations
30*67e74705SXin Li // CHECK: @GlobalRedecl1 = external dllimport global i32
31*67e74705SXin Li __declspec(dllimport) extern int GlobalRedecl1;
32*67e74705SXin Li __declspec(dllimport) extern int GlobalRedecl1;
33*67e74705SXin Li USEVAR(GlobalRedecl1)
34*67e74705SXin Li 
35*67e74705SXin Li // CHECK: @GlobalRedecl2 = external dllimport global i32
36*67e74705SXin Li __declspec(dllimport) int GlobalRedecl2;
37*67e74705SXin Li __declspec(dllimport) int GlobalRedecl2;
38*67e74705SXin Li USEVAR(GlobalRedecl2)
39*67e74705SXin Li 
40*67e74705SXin Li // NB: MSVC issues a warning and makes GlobalRedecl3 dllexport. We follow GCC
41*67e74705SXin Li // and drop the dllimport with a warning.
42*67e74705SXin Li // CHECK: @GlobalRedecl3 = external global i32
43*67e74705SXin Li __declspec(dllimport) extern int GlobalRedecl3;
44*67e74705SXin Li                       extern int GlobalRedecl3; // dllimport ignored
45*67e74705SXin Li USEVAR(GlobalRedecl3)
46*67e74705SXin Li 
47*67e74705SXin Li // Make sure this works even if the decl has been used before it's defined (PR20792).
48*67e74705SXin Li // MS: @GlobalRedecl4 = common dllexport global i32
49*67e74705SXin Li // GNU: @GlobalRedecl4 = common global i32
50*67e74705SXin Li __declspec(dllimport) extern int GlobalRedecl4;
51*67e74705SXin Li USEVAR(GlobalRedecl4)
52*67e74705SXin Li                       int GlobalRedecl4; // dllimport ignored
53*67e74705SXin Li 
54*67e74705SXin Li // FIXME: dllimport is dropped in the AST; this should be reflected in codegen (PR02803).
55*67e74705SXin Li // CHECK: @GlobalRedecl5 = external dllimport global i32
56*67e74705SXin Li __declspec(dllimport) extern int GlobalRedecl5;
57*67e74705SXin Li USEVAR(GlobalRedecl5)
58*67e74705SXin Li                       extern int GlobalRedecl5; // dllimport ignored
59*67e74705SXin Li 
60*67e74705SXin Li // Redeclaration in local context.
61*67e74705SXin Li // CHECK: @GlobalRedecl6 = external dllimport global i32
62*67e74705SXin Li __declspec(dllimport) int GlobalRedecl6;
functionScope()63*67e74705SXin Li int functionScope() {
64*67e74705SXin Li   extern int GlobalRedecl6; // still dllimport
65*67e74705SXin Li   return GlobalRedecl6;
66*67e74705SXin Li }
67*67e74705SXin Li 
68*67e74705SXin Li 
69*67e74705SXin Li 
70*67e74705SXin Li //===----------------------------------------------------------------------===//
71*67e74705SXin Li // Functions
72*67e74705SXin Li //===----------------------------------------------------------------------===//
73*67e74705SXin Li 
74*67e74705SXin Li // Import function declaration.
75*67e74705SXin Li // CHECK-DAG: declare dllimport void @decl()
76*67e74705SXin Li __declspec(dllimport) void decl(void);
77*67e74705SXin Li 
78*67e74705SXin Li // Initialize use_decl with the address of the thunk.
79*67e74705SXin Li // CHECK-DAG: @use_decl = global void ()* @decl
80*67e74705SXin Li void (*use_decl)(void) = &decl;
81*67e74705SXin Li 
82*67e74705SXin Li // Import inline function.
83*67e74705SXin Li // MS-DAG: declare dllimport void @inlineFunc()
84*67e74705SXin Li // MO1-DAG: define available_externally dllimport void @inlineFunc()
85*67e74705SXin Li // GNU-DAG: declare void @inlineFunc()
86*67e74705SXin Li // GO1-DAG: define available_externally void @inlineFunc()
inlineFunc(void)87*67e74705SXin Li __declspec(dllimport) inline void inlineFunc(void) {}
USE(inlineFunc)88*67e74705SXin Li USE(inlineFunc)
89*67e74705SXin Li 
90*67e74705SXin Li // inline attributes
91*67e74705SXin Li // MS-DAG: declare dllimport void @noinline()
92*67e74705SXin Li // MO1-DAG: define available_externally dllimport void @noinline()
93*67e74705SXin Li // GNU-DAG: declare void @noinline()
94*67e74705SXin Li // GO1-DAG: define available_externally void @noinline()
95*67e74705SXin Li // CHECK-NOT: @alwaysInline()
96*67e74705SXin Li // O1-NOT: @alwaysInline()
97*67e74705SXin Li __declspec(dllimport) __attribute__((noinline)) inline void noinline(void) {}
alwaysInline(void)98*67e74705SXin Li __declspec(dllimport) __attribute__((always_inline)) inline void alwaysInline(void) {}
99*67e74705SXin Li USE(noinline)
100*67e74705SXin Li USE(alwaysInline)
101*67e74705SXin Li 
102*67e74705SXin Li // Redeclarations
103*67e74705SXin Li // CHECK-DAG: declare dllimport void @redecl1()
104*67e74705SXin Li __declspec(dllimport) void redecl1(void);
105*67e74705SXin Li __declspec(dllimport) void redecl1(void);
106*67e74705SXin Li USE(redecl1)
107*67e74705SXin Li 
108*67e74705SXin Li // NB: MSVC issues a warning and makes redecl2/redecl3 dllexport. We follow GCC
109*67e74705SXin Li // and drop the dllimport with a warning.
110*67e74705SXin Li // CHECK-DAG: declare void @redecl2()
111*67e74705SXin Li __declspec(dllimport) void redecl2(void);
112*67e74705SXin Li                       void redecl2(void);
113*67e74705SXin Li USE(redecl2)
114*67e74705SXin Li 
115*67e74705SXin Li // MS: define dllexport void @redecl3()
116*67e74705SXin Li // GNU: define void @redecl3()
117*67e74705SXin Li __declspec(dllimport) void redecl3(void);
redecl3(void)118*67e74705SXin Li                       void redecl3(void) {} // dllimport ignored
119*67e74705SXin Li USE(redecl3)
120*67e74705SXin Li 
121*67e74705SXin Li // Make sure this works even if the decl is used before it's defined (PR20792).
122*67e74705SXin Li // MS: define dllexport void @redecl4()
123*67e74705SXin Li // GNU: define void @redecl4()
124*67e74705SXin Li __declspec(dllimport) void redecl4(void);
USE(redecl4)125*67e74705SXin Li USE(redecl4)
126*67e74705SXin Li                       void redecl4(void) {} // dllimport ignored
127*67e74705SXin Li 
128*67e74705SXin Li // FIXME: dllimport is dropped in the AST; this should be reflected in codegen (PR20803).
129*67e74705SXin Li // CHECK-DAG: declare dllimport
130*67e74705SXin Li __declspec(dllimport) void redecl5(void);
131*67e74705SXin Li USE(redecl5)
132*67e74705SXin Li                       void redecl5(void); // dllimport ignored
133