reference, declarationdefinition
definition → references, declarations, derived classes, virtual overrides
reference to multiple definitions → definitions
unreferenced
    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-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

#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.
// 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 = 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