2015-05-27 03:44:52 +08:00
|
|
|
// 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
|
2019-06-05 11:17:11 +08:00
|
|
|
// RUN: %clang_cc1 -triple i686-windows-msvc -fms-extensions -emit-llvm -std=c11 -O1 -fno-experimental-new-pass-manager -o - %s | FileCheck --check-prefix=O1 --check-prefix=MO1 %s
|
|
|
|
// RUN: %clang_cc1 -triple i686-windows-gnu -fms-extensions -emit-llvm -std=c11 -O1 -fno-experimental-new-pass-manager -o - %s | FileCheck --check-prefix=O1 --check-prefix=GO1 %s
|
2014-05-25 18:34:16 +08:00
|
|
|
|
|
|
|
#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.
|
2018-08-30 01:26:58 +08:00
|
|
|
// MS: @GlobalRedecl3 = external dso_local global i32
|
|
|
|
// GNU: @GlobalRedecl3 = external global i32
|
2014-05-25 18:34:16 +08:00
|
|
|
__declspec(dllimport) extern int GlobalRedecl3;
|
|
|
|
extern int GlobalRedecl3; // dllimport ignored
|
|
|
|
USEVAR(GlobalRedecl3)
|
|
|
|
|
2014-08-29 08:16:06 +08:00
|
|
|
// Make sure this works even if the decl has been used before it's defined (PR20792).
|
2020-03-10 03:25:24 +08:00
|
|
|
// MS: @GlobalRedecl4 = dso_local dllexport global i32
|
|
|
|
// GNU: @GlobalRedecl4 = dso_local global i32
|
2014-08-29 08:16:06 +08:00
|
|
|
__declspec(dllimport) extern int GlobalRedecl4;
|
|
|
|
USEVAR(GlobalRedecl4)
|
|
|
|
int GlobalRedecl4; // dllimport ignored
|
|
|
|
|
2014-08-30 01:36:11 +08:00
|
|
|
// 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
|
2014-08-29 08:16:06 +08:00
|
|
|
|
2014-08-01 03:29:39 +08:00
|
|
|
// Redeclaration in local context.
|
2014-08-30 01:36:11 +08:00
|
|
|
// CHECK: @GlobalRedecl6 = external dllimport global i32
|
|
|
|
__declspec(dllimport) int GlobalRedecl6;
|
2014-08-01 03:29:39 +08:00
|
|
|
int functionScope() {
|
2014-08-30 01:36:11 +08:00
|
|
|
extern int GlobalRedecl6; // still dllimport
|
|
|
|
return GlobalRedecl6;
|
2014-08-01 03:29:39 +08:00
|
|
|
}
|
|
|
|
|
2014-05-25 18:34:16 +08:00
|
|
|
|
|
|
|
|
|
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
// Functions
|
|
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
|
|
|
|
// Import function declaration.
|
|
|
|
// CHECK-DAG: declare dllimport void @decl()
|
|
|
|
__declspec(dllimport) void decl(void);
|
2014-06-25 16:15:07 +08:00
|
|
|
|
|
|
|
// Initialize use_decl with the address of the thunk.
|
2018-02-24 03:30:48 +08:00
|
|
|
// CHECK-DAG: @use_decl = dso_local global void ()* @decl
|
2014-06-25 16:15:07 +08:00
|
|
|
void (*use_decl)(void) = &decl;
|
2014-05-25 18:34:16 +08:00
|
|
|
|
|
|
|
// Import inline function.
|
2014-11-03 22:24:45 +08:00
|
|
|
// MS-DAG: declare dllimport void @inlineFunc()
|
|
|
|
// MO1-DAG: define available_externally dllimport void @inlineFunc()
|
2018-02-24 03:30:48 +08:00
|
|
|
// GNU-DAG: declare dso_local void @inlineFunc()
|
|
|
|
// GO1-DAG: define available_externally dso_local void @inlineFunc()
|
2014-05-25 18:34:16 +08:00
|
|
|
__declspec(dllimport) inline void inlineFunc(void) {}
|
|
|
|
USE(inlineFunc)
|
|
|
|
|
|
|
|
// inline attributes
|
2014-11-03 22:24:45 +08:00
|
|
|
// MS-DAG: declare dllimport void @noinline()
|
|
|
|
// MO1-DAG: define available_externally dllimport void @noinline()
|
2018-02-24 03:30:48 +08:00
|
|
|
// GNU-DAG: declare dso_local void @noinline()
|
|
|
|
// GO1-DAG: define available_externally dso_local void @noinline()
|
2014-05-25 18:34:16 +08:00
|
|
|
// 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.
|
2018-02-24 03:30:48 +08:00
|
|
|
// CHECK-DAG: declare dso_local void @redecl2()
|
2014-05-25 18:34:16 +08:00
|
|
|
__declspec(dllimport) void redecl2(void);
|
|
|
|
void redecl2(void);
|
|
|
|
USE(redecl2)
|
|
|
|
|
2018-02-24 03:30:48 +08:00
|
|
|
// MS: define dso_local dllexport void @redecl3()
|
|
|
|
// GNU: define dso_local void @redecl3()
|
2014-05-25 18:34:16 +08:00
|
|
|
__declspec(dllimport) void redecl3(void);
|
|
|
|
void redecl3(void) {} // dllimport ignored
|
|
|
|
USE(redecl3)
|
2014-08-29 08:16:06 +08:00
|
|
|
|
|
|
|
// Make sure this works even if the decl is used before it's defined (PR20792).
|
2018-02-24 03:30:48 +08:00
|
|
|
// MS: define dso_local dllexport void @redecl4()
|
|
|
|
// GNU: define dso_local void @redecl4()
|
2014-08-29 08:16:06 +08:00
|
|
|
__declspec(dllimport) void redecl4(void);
|
|
|
|
USE(redecl4)
|
|
|
|
void redecl4(void) {} // dllimport ignored
|
2014-08-30 01:36:11 +08:00
|
|
|
|
|
|
|
// 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
|