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;
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 // CHECK: @GlobalRedecl3 = external global i32
43 __declspec(dllimport) extern int GlobalRedecl3;
44                       extern int GlobalRedecl3; // dllimport ignored
45 USEVAR(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 USE(decl)
57 
58 // Import inline function.
59 // CHECK-DAG: declare dllimport void @inlineFunc()
60 // O1-DAG: define available_externally dllimport void @inlineFunc()
61 __declspec(dllimport) inline void inlineFunc(void) {}
62 USE(inlineFunc)
63 
64 // inline attributes
65 // CHECK-DAG: declare dllimport void @noinline()
66 // O1-DAG: define available_externally dllimport void @noinline()
67 // CHECK-NOT: @alwaysInline()
68 // O1-NOT: @alwaysInline()
69 __declspec(dllimport) __attribute__((noinline)) inline void noinline(void) {}
70 __declspec(dllimport) __attribute__((always_inline)) inline void alwaysInline(void) {}
71 USE(noinline)
72 USE(alwaysInline)
73 
74 // Redeclarations
75 // CHECK-DAG: declare dllimport void @redecl1()
76 __declspec(dllimport) void redecl1(void);
77 __declspec(dllimport) void redecl1(void);
78 USE(redecl1)
79 
80 // NB: MSVC issues a warning and makes redecl2/redecl3 dllexport. We follow GCC
81 // and drop the dllimport with a warning.
82 // CHECK-DAG: declare void @redecl2()
83 __declspec(dllimport) void redecl2(void);
84                       void redecl2(void);
85 USE(redecl2)
86 
87 // CHECK-DAG: define void @redecl3()
88 __declspec(dllimport) void redecl3(void);
89                       void redecl3(void) {} // dllimport ignored
90 USE(redecl3)
91