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; |
22 | USEVAR(ExternGlobalDecl) |
23 | |
24 | // dllimport implies a declaration. |
25 | // CHECK: @GlobalDecl = external dllimport global i32 |
26 | __declspec(dllimport) int GlobalDecl; |
27 | USEVAR(GlobalDecl) |
28 | |
29 | // Redeclarations |
30 | // CHECK: @GlobalRedecl1 = external dllimport global i32 |
31 | __declspec(dllimport) extern int GlobalRedecl1; |
32 | __declspec(dllimport) extern int GlobalRedecl1; |
33 | USEVAR(GlobalRedecl1) |
34 | |
35 | // CHECK: @GlobalRedecl2 = external dllimport global i32 |
36 | __declspec(dllimport) int GlobalRedecl2; |
37 | __declspec(dllimport) int GlobalRedecl2; |
38 | USEVAR(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 |
46 | USEVAR(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; |
52 | USEVAR(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; |
58 | USEVAR(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; |
64 | int 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 |
81 | void (*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) {} |
89 | USE(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) {} |
100 | USE(noinline) |
101 | USE(alwaysInline) |
102 | |
103 | // Redeclarations |
104 | // CHECK-DAG: declare dllimport void @redecl1() |
105 | __declspec(dllimport) void redecl1(void); |
106 | __declspec(dllimport) void redecl1(void); |
107 | USE(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); |
114 | USE(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 |
120 | USE(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); |
126 | USE(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); |
132 | USE(redecl5) |
133 | void redecl5(void); // dllimport ignored |
134 | |