1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133
|
// 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 -fno-inline -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-inline -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__)(void) { return var; }
#define USE(func) void JOIN(use, __LINE__)(void) { 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.
// MS: @GlobalRedecl3 = external dso_local global i32
// GNU: @GlobalRedecl3 = external 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 = dso_local dllexport global i32
// GNU: @GlobalRedecl4 = 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(void) {
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 ptr @decl
void (*use_decl)(void) = &decl;
// Import inline function.
// MS-DAG: declare dllimport void @inlineFunc()
// MO1-DAG: declare dllimport void @inlineFunc()
// GNU-DAG: declare dso_local void @inlineFunc()
// GO1-DAG: declare dso_local void @inlineFunc()
__declspec(dllimport) inline void inlineFunc(void) {}
USE(inlineFunc)
// inline attributes
// MS-DAG: declare dllimport void @noinline()
// MO1-DAG: declare dllimport void @noinline()
// GNU-DAG: declare dso_local void @noinline()
// GO1-DAG: declare 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
|