1*67e74705SXin Li // RUN: %clang_cc1 %s -std=c++1y -triple=x86_64-pc-linux -emit-llvm -o - | FileCheck --check-prefix=ELF --check-prefix=ALL %s 2*67e74705SXin Li // RUN: %clang_cc1 %s -std=c++1y -triple=x86_64-apple-darwin -emit-llvm -o - | FileCheck --check-prefix=MACHO --check-prefix=ALL %s 3*67e74705SXin Li 4*67e74705SXin Li // ALL: ; ModuleID 5*67e74705SXin Li 6*67e74705SXin Li extern "C" int foo(); 7*67e74705SXin Li 8*67e74705SXin Li template<typename T> struct A { static int a; }; 9*67e74705SXin Li template<typename T> int A<T>::a = foo(); 10*67e74705SXin Li 11*67e74705SXin Li // ALLK-NOT: @_ZN1AIcE1aE 12*67e74705SXin Li template<> int A<char>::a; 13*67e74705SXin Li 14*67e74705SXin Li // ALL: @_ZN1AIbE1aE = global i32 10 15*67e74705SXin Li template<> int A<bool>::a = 10; 16*67e74705SXin Li 17*67e74705SXin Li // ALL: @llvm.global_ctors = appending global [8 x { i32, void ()*, i8* }] 18*67e74705SXin Li 19*67e74705SXin Li // ELF: [{ i32, void ()*, i8* } { i32 65535, void ()* @[[unordered1:[^,]*]], i8* bitcast (i32* @_ZN1AIsE1aE to i8*) }, 20*67e74705SXin Li // MACHO: [{ i32, void ()*, i8* } { i32 65535, void ()* @[[unordered1:[^,]*]], i8* null }, 21*67e74705SXin Li 22*67e74705SXin Li // ELF: { i32, void ()*, i8* } { i32 65535, void ()* @[[unordered2:[^,]*]], i8* bitcast (i16* @_Z1xIsE to i8*) }, 23*67e74705SXin Li // MACHO: { i32, void ()*, i8* } { i32 65535, void ()* @[[unordered2:[^,]*]], i8* null }, 24*67e74705SXin Li 25*67e74705SXin Li // ELF: { i32, void ()*, i8* } { i32 65535, void ()* @[[unordered3:[^,]*]], i8* bitcast (i32* @_ZN2ns1aIiE1iE to i8*) }, 26*67e74705SXin Li // MACHO: { i32, void ()*, i8* } { i32 65535, void ()* @[[unordered3:[^,]*]], i8* null }, 27*67e74705SXin Li 28*67e74705SXin Li // ELF: { i32, void ()*, i8* } { i32 65535, void ()* @[[unordered4:[^,]*]], i8* bitcast (i32* @_ZN2ns1b1iIiEE to i8*) }, 29*67e74705SXin Li // MACHO: { i32, void ()*, i8* } { i32 65535, void ()* @[[unordered4:[^,]*]], i8* null }, 30*67e74705SXin Li 31*67e74705SXin Li // ELF: { i32, void ()*, i8* } { i32 65535, void ()* @[[unordered5:[^,]*]], i8* bitcast (i32* @_ZN1AIvE1aE to i8*) }, 32*67e74705SXin Li // MACHO: { i32, void ()*, i8* } { i32 65535, void ()* @[[unordered5:[^,]*]], i8* null }, 33*67e74705SXin Li 34*67e74705SXin Li // ELF: { i32, void ()*, i8* } { i32 65535, void ()* @[[unordered6:[^,]*]], i8* @_Z1xIcE }, 35*67e74705SXin Li // MACHO: { i32, void ()*, i8* } { i32 65535, void ()* @[[unordered6:[^,]*]], i8* null }, 36*67e74705SXin Li 37*67e74705SXin Li // ALL: { i32, void ()*, i8* } { i32 65535, void ()* @[[unordered7:[^,]*]], i8* null }, 38*67e74705SXin Li 39*67e74705SXin Li // ALL: { i32, void ()*, i8* } { i32 65535, void ()* @_GLOBAL__sub_I_static_member_variable_explicit_specialization.cpp, i8* null }] 40*67e74705SXin Li 41*67e74705SXin Li template int A<short>::a; // Unordered 42*67e74705SXin Li int b = foo(); 43*67e74705SXin Li int c = foo(); 44*67e74705SXin Li int d = A<void>::a; // Unordered 45*67e74705SXin Li 46*67e74705SXin Li // An explicit specialization is ordered, and goes in __GLOBAL_sub_I_static_member_variable_explicit_specialization.cpp. 47*67e74705SXin Li template<> struct A<int> { static int a; }; 48*67e74705SXin Li int A<int>::a = foo(); 49*67e74705SXin Li 50*67e74705SXin Li template<typename T> struct S { static T x; static T y; }; 51*67e74705SXin Li template<> int S<int>::x = foo(); 52*67e74705SXin Li template<> int S<int>::y = S<int>::x; 53*67e74705SXin Li 54*67e74705SXin Li template<typename T> T x = foo(); 55*67e74705SXin Li template short x<short>; // Unordered 56*67e74705SXin Li template<> int x<int> = foo(); 57*67e74705SXin Li int e = x<char>; // Unordered 58*67e74705SXin Li 59*67e74705SXin Li namespace ns { 60*67e74705SXin Li template <typename T> struct a { 61*67e74705SXin Li static int i; 62*67e74705SXin Li }; 63*67e74705SXin Li template<typename T> int a<T>::i = foo(); 64*67e74705SXin Li template struct a<int>; 65*67e74705SXin Li 66*67e74705SXin Li struct b { 67*67e74705SXin Li template <typename T> static T i; 68*67e74705SXin Li }; 69*67e74705SXin Li template<typename T> T b::i = foo(); 70*67e74705SXin Li template int b::i<int>; 71*67e74705SXin Li } 72*67e74705SXin Li 73*67e74705SXin Li namespace { 74*67e74705SXin Li template<typename T> struct Internal { static int a; }; 75*67e74705SXin Li template<typename T> int Internal<T>::a = foo(); 76*67e74705SXin Li } 77*67e74705SXin Li int *use_internal_a = &Internal<int>::a; 78*67e74705SXin Li 79*67e74705SXin Li // ALL: define internal void @[[unordered1]]( 80*67e74705SXin Li // ALL: call i32 @foo() 81*67e74705SXin Li // ALL: store {{.*}} @_ZN1AIsE1aE 82*67e74705SXin Li // ALL: ret 83*67e74705SXin Li 84*67e74705SXin Li // ALL: define internal void @[[unordered2]]( 85*67e74705SXin Li // ALL: call i32 @foo() 86*67e74705SXin Li // ALL: store {{.*}} @_Z1xIsE 87*67e74705SXin Li // ALL: ret 88*67e74705SXin Li 89*67e74705SXin Li // ALL: define internal void @[[unordered3]]( 90*67e74705SXin Li // ALL: call i32 @foo() 91*67e74705SXin Li // ALL: store {{.*}} @_ZN2ns1aIiE1iE 92*67e74705SXin Li // ALL: ret 93*67e74705SXin Li 94*67e74705SXin Li // ALL: define internal void @[[unordered4]]( 95*67e74705SXin Li // ALL: call i32 @foo() 96*67e74705SXin Li // ALL: store {{.*}} @_ZN2ns1b1iIiEE 97*67e74705SXin Li // ALL: ret 98*67e74705SXin Li 99*67e74705SXin Li // ALL: define internal void @[[unordered5]]( 100*67e74705SXin Li // ALL: call i32 @foo() 101*67e74705SXin Li // ALL: store {{.*}} @_ZN1AIvE1aE 102*67e74705SXin Li // ALL: ret 103*67e74705SXin Li 104*67e74705SXin Li // ALL: define internal void @[[unordered6]]( 105*67e74705SXin Li // ALL: call i32 @foo() 106*67e74705SXin Li // ALL: store {{.*}} @_Z1xIcE 107*67e74705SXin Li // ALL: ret 108*67e74705SXin Li 109*67e74705SXin Li // ALL: define internal void @[[unordered7]]( 110*67e74705SXin Li // ALL: call i32 @foo() 111*67e74705SXin Li // ALL: store {{.*}} @_ZN12_GLOBAL__N_18InternalIiE1aE 112*67e74705SXin Li // ALL: ret 113*67e74705SXin Li 114*67e74705SXin Li // ALL: define internal void @_GLOBAL__sub_I_static_member_variable_explicit_specialization.cpp() 115*67e74705SXin Li // We call unique stubs for every ordered dynamic initializer in the TU. 116*67e74705SXin Li // ALL: call 117*67e74705SXin Li // ALL: call 118*67e74705SXin Li // ALL: call 119*67e74705SXin Li // ALL: call 120*67e74705SXin Li // ALL: call 121*67e74705SXin Li // ALL: call 122*67e74705SXin Li // ALL: call 123*67e74705SXin Li // ALL: call 124*67e74705SXin Li // ALL-NOT: call 125*67e74705SXin Li // ALL: ret 126