Clang Project

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