Home | History | Annotate | Download | only in CodeGen
      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;
     22 USEVAR(ExternGlobalDecl)
     23 
     24 // dllimport implies a declaration.
     25 // CHECK: @GlobalDecl = external dllimport global i32
     26 __declspec(dllimport) int GlobalDecl;
     27 USEVAR(GlobalDecl)
     28 
     29 // Redeclarations
     30 // CHECK: @GlobalRedecl1 = external dllimport global i32
     31 __declspec(dllimport) extern int GlobalRedecl1;
     32 __declspec(dllimport) extern int GlobalRedecl1;
     33 USEVAR(GlobalRedecl1)
     34 
     35 // CHECK: @GlobalRedecl2 = external dllimport global i32
     36 __declspec(dllimport) int GlobalRedecl2;
     37 __declspec(dllimport) int GlobalRedecl2;
     38 USEVAR(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
     45 USEVAR(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;
     51 USEVAR(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;
     57 USEVAR(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;
     63 int 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
     80 void (*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) {}
     88 USE(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) {}
     99 USE(noinline)
    100 USE(alwaysInline)
    101 
    102 // Redeclarations
    103 // CHECK-DAG: declare dllimport void @redecl1()
    104 __declspec(dllimport) void redecl1(void);
    105 __declspec(dllimport) void redecl1(void);
    106 USE(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);
    113 USE(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
    119 USE(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);
    125 USE(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);
    131 USE(redecl5)
    132                       void redecl5(void); // dllimport ignored
    133