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; 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// Make sure this works even if the decl has been used before it's defined (PR20792). 48// MS: @GlobalRedecl4 = common dllexport global i32 49// GNU: @GlobalRedecl4 = common global i32 50__declspec(dllimport) extern int GlobalRedecl4; 51USEVAR(GlobalRedecl4) 52 int GlobalRedecl4; // dllimport ignored 53 54// FIXME: dllimport is dropped in the AST; this should be reflected in codegen (PR02803). 55// CHECK: @GlobalRedecl5 = external dllimport global i32 56__declspec(dllimport) extern int GlobalRedecl5; 57USEVAR(GlobalRedecl5) 58 extern int GlobalRedecl5; // dllimport ignored 59 60// Redeclaration in local context. 61// CHECK: @GlobalRedecl6 = external dllimport global i32 62__declspec(dllimport) int GlobalRedecl6; 63int functionScope() { 64 extern int GlobalRedecl6; // still dllimport 65 return GlobalRedecl6; 66} 67 68 69 70//===----------------------------------------------------------------------===// 71// Functions 72//===----------------------------------------------------------------------===// 73 74// Import function declaration. 75// CHECK-DAG: declare dllimport void @decl() 76__declspec(dllimport) void decl(void); 77 78// Initialize use_decl with the address of the thunk. 79// CHECK-DAG: @use_decl = global void ()* @decl 80void (*use_decl)(void) = &decl; 81 82// Import inline function. 83// MS-DAG: declare dllimport void @inlineFunc() 84// MO1-DAG: define available_externally dllimport void @inlineFunc() 85// GNU-DAG: declare void @inlineFunc() 86// GO1-DAG: define available_externally void @inlineFunc() 87__declspec(dllimport) inline void inlineFunc(void) {} 88USE(inlineFunc) 89 90// inline attributes 91// MS-DAG: declare dllimport void @noinline() 92// MO1-DAG: define available_externally dllimport void @noinline() 93// GNU-DAG: declare void @noinline() 94// GO1-DAG: define available_externally void @noinline() 95// CHECK-NOT: @alwaysInline() 96// O1-NOT: @alwaysInline() 97__declspec(dllimport) __attribute__((noinline)) inline void noinline(void) {} 98__declspec(dllimport) __attribute__((always_inline)) inline void alwaysInline(void) {} 99USE(noinline) 100USE(alwaysInline) 101 102// Redeclarations 103// CHECK-DAG: declare dllimport void @redecl1() 104__declspec(dllimport) void redecl1(void); 105__declspec(dllimport) void redecl1(void); 106USE(redecl1) 107 108// NB: MSVC issues a warning and makes redecl2/redecl3 dllexport. We follow GCC 109// and drop the dllimport with a warning. 110// CHECK-DAG: declare void @redecl2() 111__declspec(dllimport) void redecl2(void); 112 void redecl2(void); 113USE(redecl2) 114 115// MS: define dllexport void @redecl3() 116// GNU: define void @redecl3() 117__declspec(dllimport) void redecl3(void); 118 void redecl3(void) {} // dllimport ignored 119USE(redecl3) 120 121// Make sure this works even if the decl is used before it's defined (PR20792). 122// MS: define dllexport void @redecl4() 123// GNU: define void @redecl4() 124__declspec(dllimport) void redecl4(void); 125USE(redecl4) 126 void redecl4(void) {} // dllimport ignored 127 128// FIXME: dllimport is dropped in the AST; this should be reflected in codegen (PR20803). 129// CHECK-DAG: declare dllimport 130__declspec(dllimport) void redecl5(void); 131USE(redecl5) 132 void redecl5(void); // dllimport ignored 133