1// RUN: %clang_cc1 -triple i686-windows-msvc   -emit-llvm -std=c11 -O0 -o - %s | FileCheck %s
2// RUN: %clang_cc1 -triple x86_64-windows-msvc -emit-llvm -std=c11 -O0 -o - %s | FileCheck %s
3// RUN: %clang_cc1 -triple i686-windows-gnu    -emit-llvm -std=c11 -O0 -o - %s | FileCheck %s
4// RUN: %clang_cc1 -triple x86_64-windows-gnu  -emit-llvm -std=c11 -O0 -o - %s | FileCheck %s
5// RUN: %clang_cc1 -triple i686-windows-msvc   -emit-llvm -std=c11 -O1 -o - %s | FileCheck --check-prefix=O1 %s
6// RUN: %clang_cc1 -triple i686-windows-gnu    -emit-llvm -std=c11 -O1 -o - %s | FileCheck --check-prefix=O1 %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// CHECK: @GlobalRedecl3 = external global i32
43__declspec(dllimport) extern int GlobalRedecl3;
44                      extern int GlobalRedecl3; // dllimport ignored
45USEVAR(GlobalRedecl3)
46
47
48
49//===----------------------------------------------------------------------===//
50// Functions
51//===----------------------------------------------------------------------===//
52
53// Import function declaration.
54// CHECK-DAG: declare dllimport void @decl()
55__declspec(dllimport) void decl(void);
56
57// Initialize use_decl with the address of the thunk.
58// CHECK-DAG: @use_decl = global void ()* @decl
59void (*use_decl)(void) = &decl;
60
61// Import inline function.
62// CHECK-DAG: declare dllimport void @inlineFunc()
63// O1-DAG: define available_externally dllimport void @inlineFunc()
64__declspec(dllimport) inline void inlineFunc(void) {}
65USE(inlineFunc)
66
67// inline attributes
68// CHECK-DAG: declare dllimport void @noinline()
69// O1-DAG: define available_externally dllimport void @noinline()
70// CHECK-NOT: @alwaysInline()
71// O1-NOT: @alwaysInline()
72__declspec(dllimport) __attribute__((noinline)) inline void noinline(void) {}
73__declspec(dllimport) __attribute__((always_inline)) inline void alwaysInline(void) {}
74USE(noinline)
75USE(alwaysInline)
76
77// Redeclarations
78// CHECK-DAG: declare dllimport void @redecl1()
79__declspec(dllimport) void redecl1(void);
80__declspec(dllimport) void redecl1(void);
81USE(redecl1)
82
83// NB: MSVC issues a warning and makes redecl2/redecl3 dllexport. We follow GCC
84// and drop the dllimport with a warning.
85// CHECK-DAG: declare void @redecl2()
86__declspec(dllimport) void redecl2(void);
87                      void redecl2(void);
88USE(redecl2)
89
90// CHECK-DAG: define void @redecl3()
91__declspec(dllimport) void redecl3(void);
92                      void redecl3(void) {} // dllimport ignored
93USE(redecl3)
94