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; functionScope()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 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() inlineFunc(void)88__declspec(dllimport) inline void inlineFunc(void) {} USE(inlineFunc)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) {} alwaysInline(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); 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); USE(redecl4)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); 132 USE(redecl5) 133 void redecl5(void); // dllimport ignored 134