Home | History | Annotate | Download | only in CodeGenCXX
      1 // RUN: %clang_cc1 %s -triple=i686-pc-win32 -fms-extensions -emit-llvm -o - | FileCheck %s
      2 
      3 int f();
      4 
      5 // CHECK: $"\01?x@selectany_init@@3HA" = comdat any
      6 // CHECK: $"\01?x@?$A@H@explicit_template_instantiation@@2HB" = comdat any
      7 // CHECK: $"\01?x@?$A@H@implicit_template_instantiation@@2HB" = comdat any
      8 
      9 namespace simple_init {
     10 #pragma init_seg(compiler)
     11 int x = f();
     12 // CHECK: @"\01?x@simple_init@@3HA" = global i32 0, align 4
     13 // CHECK: @__cxx_init_fn_ptr = private constant void ()* @"\01??__Ex@simple_init@@YAXXZ", section ".CRT$XCC"
     14 
     15 #pragma init_seg(lib)
     16 int y = f();
     17 // CHECK: @"\01?y@simple_init@@3HA" = global i32 0, align 4
     18 // CHECK: @__cxx_init_fn_ptr.1 = private constant void ()* @"\01??__Ey@simple_init@@YAXXZ", section ".CRT$XCL"
     19 
     20 #pragma init_seg(user)
     21 int z = f();
     22 // CHECK: @"\01?z@simple_init@@3HA" = global i32 0, align 4
     23 // No function pointer!  This one goes on @llvm.global_ctors.
     24 }
     25 
     26 #pragma init_seg(".asdf")
     27 
     28 namespace internal_init {
     29 namespace {
     30 int x = f();
     31 // CHECK: @"\01?x@?A@internal_init@@3HA" = internal global i32 0, align 4
     32 // CHECK: @__cxx_init_fn_ptr.2 = private constant void ()* @"\01??__Ex@?A@internal_init@@YAXXZ", section ".asdf"
     33 }
     34 }
     35 
     36 namespace selectany_init {
     37 int __declspec(selectany) x = f();
     38 // CHECK: @"\01?x@selectany_init@@3HA" = weak_odr global i32 0, comdat, align 4
     39 // CHECK: @__cxx_init_fn_ptr.3 = private constant void ()* @"\01??__Ex@selectany_init@@YAXXZ", section ".asdf", comdat($"\01?x@selectany_init@@3HA")
     40 }
     41 
     42 namespace explicit_template_instantiation {
     43 template <typename T> struct A { static const int x; };
     44 template <typename T> const int A<T>::x = f();
     45 template struct A<int>;
     46 // CHECK: @"\01?x@?$A@H@explicit_template_instantiation@@2HB" = weak_odr global i32 0, comdat, align 4
     47 // CHECK: @__cxx_init_fn_ptr.4 = private constant void ()* @"\01??__Ex@?$A@H@explicit_template_instantiation@@2HB@YAXXZ", section ".asdf", comdat($"\01?x@?$A@H@explicit_template_instantiation@@2HB")
     48 }
     49 
     50 namespace implicit_template_instantiation {
     51 template <typename T> struct A { static const int x; };
     52 template <typename T> const int A<T>::x = f();
     53 int g() { return A<int>::x; }
     54 // CHECK: @"\01?x@?$A@H@implicit_template_instantiation@@2HB" = linkonce_odr global i32 0, comdat, align 4
     55 // CHECK: @__cxx_init_fn_ptr.5 = private constant void ()* @"\01??__Ex@?$A@H@implicit_template_instantiation@@2HB@YAXXZ", section ".asdf", comdat($"\01?x@?$A@H@implicit_template_instantiation@@2HB")
     56 }
     57 
     58 // ... and here's where we emitted user level ctors.
     59 // CHECK: @llvm.global_ctors = appending global [1 x { i32, void ()*, i8* }]
     60 // CHECK: [{ i32, void ()*, i8* } { i32 65535, void ()* @_GLOBAL__sub_I_pragma_init_seg.cpp, i8* null }]
     61 
     62 // We have to mark everything used so we can survive globalopt, even through
     63 // LTO.  There's no way LLVM could really understand if data in the .asdf
     64 // section is really used or dead.
     65 //
     66 // CHECK: @llvm.used = appending global [6 x i8*]
     67 // CHECK: [i8* bitcast (void ()** @__cxx_init_fn_ptr to i8*),
     68 // CHECK: i8* bitcast (void ()** @__cxx_init_fn_ptr.1 to i8*),
     69 // CHECK: i8* bitcast (void ()** @__cxx_init_fn_ptr.2 to i8*),
     70 // CHECK: i8* bitcast (void ()** @__cxx_init_fn_ptr.3 to i8*),
     71 // CHECK: i8* bitcast (void ()** @__cxx_init_fn_ptr.4 to i8*),
     72 // CHECK: i8* bitcast (void ()** @__cxx_init_fn_ptr.5 to i8*)], section "llvm.metadata"
     73