|  | // RUN: %clang_cc1 -triple i686-windows-msvc   -fms-extensions -emit-llvm -std=c11 -O0 -o - %s | FileCheck --check-prefix=CHECK --check-prefix=MS %s | 
|  | // 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 | 
|  | // RUN: %clang_cc1 -triple i686-windows-gnu    -fms-extensions -emit-llvm -std=c11 -O0 -o - %s | FileCheck --check-prefix=CHECK --check-prefix=GNU %s | 
|  | // 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 | 
|  | // RUN: %clang_cc1 -triple i686-windows-msvc   -fms-extensions -emit-llvm -std=c11 -O1 -o - %s | FileCheck --check-prefix=O1 --check-prefix=MO1 %s | 
|  | // RUN: %clang_cc1 -triple i686-windows-gnu    -fms-extensions -emit-llvm -std=c11 -O1 -o - %s | FileCheck --check-prefix=O1 --check-prefix=GO1 %s | 
|  |  | 
|  | #define JOIN2(x, y) x##y | 
|  | #define JOIN(x, y) JOIN2(x, y) | 
|  | #define USEVAR(var) int JOIN(use, __LINE__)() { return var; } | 
|  | #define USE(func) void JOIN(use, __LINE__)() { func(); } | 
|  |  | 
|  |  | 
|  |  | 
|  | //===----------------------------------------------------------------------===// | 
|  | // Globals | 
|  | //===----------------------------------------------------------------------===// | 
|  |  | 
|  | // Import declaration. | 
|  | // CHECK: @ExternGlobalDecl = external dllimport global i32 | 
|  | __declspec(dllimport) extern int ExternGlobalDecl; | 
|  | USEVAR(ExternGlobalDecl) | 
|  |  | 
|  | // dllimport implies a declaration. | 
|  | // CHECK: @GlobalDecl = external dllimport global i32 | 
|  | __declspec(dllimport) int GlobalDecl; | 
|  | USEVAR(GlobalDecl) | 
|  |  | 
|  | // Redeclarations | 
|  | // CHECK: @GlobalRedecl1 = external dllimport global i32 | 
|  | __declspec(dllimport) extern int GlobalRedecl1; | 
|  | __declspec(dllimport) extern int GlobalRedecl1; | 
|  | USEVAR(GlobalRedecl1) | 
|  |  | 
|  | // CHECK: @GlobalRedecl2 = external dllimport global i32 | 
|  | __declspec(dllimport) int GlobalRedecl2; | 
|  | __declspec(dllimport) int GlobalRedecl2; | 
|  | USEVAR(GlobalRedecl2) | 
|  |  | 
|  | // NB: MSVC issues a warning and makes GlobalRedecl3 dllexport. We follow GCC | 
|  | // and drop the dllimport with a warning. | 
|  | // CHECK: @GlobalRedecl3 = external dso_local global i32 | 
|  | __declspec(dllimport) extern int GlobalRedecl3; | 
|  | extern int GlobalRedecl3; // dllimport ignored | 
|  | USEVAR(GlobalRedecl3) | 
|  |  | 
|  | // Make sure this works even if the decl has been used before it's defined (PR20792). | 
|  | // MS: @GlobalRedecl4 = common dso_local dllexport global i32 | 
|  | // GNU: @GlobalRedecl4 = common dso_local global i32 | 
|  | __declspec(dllimport) extern int GlobalRedecl4; | 
|  | USEVAR(GlobalRedecl4) | 
|  | int GlobalRedecl4; // dllimport ignored | 
|  |  | 
|  | // FIXME: dllimport is dropped in the AST; this should be reflected in codegen (PR02803). | 
|  | // CHECK: @GlobalRedecl5 = external dllimport global i32 | 
|  | __declspec(dllimport) extern int GlobalRedecl5; | 
|  | USEVAR(GlobalRedecl5) | 
|  | extern int GlobalRedecl5; // dllimport ignored | 
|  |  | 
|  | // Redeclaration in local context. | 
|  | // CHECK: @GlobalRedecl6 = external dllimport global i32 | 
|  | __declspec(dllimport) int GlobalRedecl6; | 
|  | int functionScope() { | 
|  | extern int GlobalRedecl6; // still dllimport | 
|  | return GlobalRedecl6; | 
|  | } | 
|  |  | 
|  |  | 
|  |  | 
|  | //===----------------------------------------------------------------------===// | 
|  | // Functions | 
|  | //===----------------------------------------------------------------------===// | 
|  |  | 
|  | // Import function declaration. | 
|  | // CHECK-DAG: declare dllimport void @decl() | 
|  | __declspec(dllimport) void decl(void); | 
|  |  | 
|  | // Initialize use_decl with the address of the thunk. | 
|  | // CHECK-DAG: @use_decl = dso_local global void ()* @decl | 
|  | void (*use_decl)(void) = &decl; | 
|  |  | 
|  | // Import inline function. | 
|  | // MS-DAG: declare dllimport void @inlineFunc() | 
|  | // MO1-DAG: define available_externally dllimport void @inlineFunc() | 
|  | // GNU-DAG: declare dso_local void @inlineFunc() | 
|  | // GO1-DAG: define available_externally dso_local void @inlineFunc() | 
|  | __declspec(dllimport) inline void inlineFunc(void) {} | 
|  | USE(inlineFunc) | 
|  |  | 
|  | // inline attributes | 
|  | // MS-DAG: declare dllimport void @noinline() | 
|  | // MO1-DAG: define available_externally dllimport void @noinline() | 
|  | // GNU-DAG: declare dso_local void @noinline() | 
|  | // GO1-DAG: define available_externally dso_local void @noinline() | 
|  | // CHECK-NOT: @alwaysInline() | 
|  | // O1-NOT: @alwaysInline() | 
|  | __declspec(dllimport) __attribute__((noinline)) inline void noinline(void) {} | 
|  | __declspec(dllimport) __attribute__((always_inline)) inline void alwaysInline(void) {} | 
|  | USE(noinline) | 
|  | USE(alwaysInline) | 
|  |  | 
|  | // Redeclarations | 
|  | // CHECK-DAG: declare dllimport void @redecl1() | 
|  | __declspec(dllimport) void redecl1(void); | 
|  | __declspec(dllimport) void redecl1(void); | 
|  | USE(redecl1) | 
|  |  | 
|  | // NB: MSVC issues a warning and makes redecl2/redecl3 dllexport. We follow GCC | 
|  | // and drop the dllimport with a warning. | 
|  | // CHECK-DAG: declare dso_local void @redecl2() | 
|  | __declspec(dllimport) void redecl2(void); | 
|  | void redecl2(void); | 
|  | USE(redecl2) | 
|  |  | 
|  | // MS: define dso_local dllexport void @redecl3() | 
|  | // GNU: define dso_local void @redecl3() | 
|  | __declspec(dllimport) void redecl3(void); | 
|  | void redecl3(void) {} // dllimport ignored | 
|  | USE(redecl3) | 
|  |  | 
|  | // Make sure this works even if the decl is used before it's defined (PR20792). | 
|  | // MS: define dso_local dllexport void @redecl4() | 
|  | // GNU: define dso_local void @redecl4() | 
|  | __declspec(dllimport) void redecl4(void); | 
|  | USE(redecl4) | 
|  | void redecl4(void) {} // dllimport ignored | 
|  |  | 
|  | // FIXME: dllimport is dropped in the AST; this should be reflected in codegen (PR20803). | 
|  | // CHECK-DAG: declare dllimport | 
|  | __declspec(dllimport) void redecl5(void); | 
|  | USE(redecl5) | 
|  | void redecl5(void); // dllimport ignored |