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