1*67e74705SXin Li // RUN: %clang_cc1 -std=c++11 -emit-llvm %s -o - -triple=x86_64-apple-darwin9 | FileCheck %s 2*67e74705SXin Li 3*67e74705SXin Li namespace std { 4*67e74705SXin Li typedef decltype(sizeof(int)) size_t; 5*67e74705SXin Li 6*67e74705SXin Li // libc++'s implementation 7*67e74705SXin Li template <class _E> 8*67e74705SXin Li class initializer_list 9*67e74705SXin Li { 10*67e74705SXin Li const _E* __begin_; 11*67e74705SXin Li size_t __size_; 12*67e74705SXin Li initializer_list(const _E * __b,size_t __s)13*67e74705SXin Li initializer_list(const _E* __b, size_t __s) 14*67e74705SXin Li : __begin_(__b), 15*67e74705SXin Li __size_(__s) 16*67e74705SXin Li {} 17*67e74705SXin Li 18*67e74705SXin Li public: 19*67e74705SXin Li typedef _E value_type; 20*67e74705SXin Li typedef const _E& reference; 21*67e74705SXin Li typedef const _E& const_reference; 22*67e74705SXin Li typedef size_t size_type; 23*67e74705SXin Li 24*67e74705SXin Li typedef const _E* iterator; 25*67e74705SXin Li typedef const _E* const_iterator; 26*67e74705SXin Li initializer_list()27*67e74705SXin Li initializer_list() : __begin_(nullptr), __size_(0) {} 28*67e74705SXin Li size() const29*67e74705SXin Li size_t size() const {return __size_;} begin() const30*67e74705SXin Li const _E* begin() const {return __begin_;} end() const31*67e74705SXin Li const _E* end() const {return __begin_ + __size_;} 32*67e74705SXin Li }; 33*67e74705SXin Li } 34*67e74705SXin Li 35*67e74705SXin Li template < bool condition, typename T = void > 36*67e74705SXin Li struct enable_if { typedef T type; }; 37*67e74705SXin Li 38*67e74705SXin Li template< typename T > 39*67e74705SXin Li struct enable_if< false, T > {}; 40*67e74705SXin Li 41*67e74705SXin Li // PR5876 42*67e74705SXin Li namespace Casts { 43*67e74705SXin Li template< unsigned O > implicit(typename enable_if<O<=4>::type * =0)44*67e74705SXin Li void implicit(typename enable_if< O <= 4 >::type* = 0) { 45*67e74705SXin Li } 46*67e74705SXin Li 47*67e74705SXin Li template< unsigned O > cstyle(typename enable_if<O<=(unsigned)4>::type * =0)48*67e74705SXin Li void cstyle(typename enable_if< O <= (unsigned)4 >::type* = 0) { 49*67e74705SXin Li } 50*67e74705SXin Li 51*67e74705SXin Li template< unsigned O > functional(typename enable_if<O<=unsigned (4)>::type * =0)52*67e74705SXin Li void functional(typename enable_if< O <= unsigned(4) >::type* = 0) { 53*67e74705SXin Li } 54*67e74705SXin Li 55*67e74705SXin Li template< unsigned O > static_(typename enable_if<O<=static_cast<unsigned> (4)>::type * =0)56*67e74705SXin Li void static_(typename enable_if< O <= static_cast<unsigned>(4) >::type* = 0) { 57*67e74705SXin Li } 58*67e74705SXin Li 59*67e74705SXin Li template <unsigned O, typename T> reinterpret_(typename enable_if<O<=sizeof (reinterpret_cast<T * > (0))>::type * =0)60*67e74705SXin Li void reinterpret_(typename enable_if<O <= sizeof(reinterpret_cast<T *>(0))>::type * = 0) { 61*67e74705SXin Li } 62*67e74705SXin Li 63*67e74705SXin Li template <typename T, T *p> const_(typename enable_if<0<=sizeof (const_cast<T * > (p))>::type * =0)64*67e74705SXin Li void const_(typename enable_if<0 <= sizeof(const_cast<T *>(p))>::type * = 0) { 65*67e74705SXin Li } 66*67e74705SXin Li 67*67e74705SXin Li template <typename T, T *p> dynamic_(typename enable_if<0<=sizeof (dynamic_cast<T * > (p))>::type * =0)68*67e74705SXin Li void dynamic_(typename enable_if<0 <= sizeof(dynamic_cast<T *>(p))>::type * = 0) { 69*67e74705SXin Li } 70*67e74705SXin Li 71*67e74705SXin Li template< typename T > auto_(decltype(new auto (T ())) )72*67e74705SXin Li void auto_(decltype(new auto(T()))) { 73*67e74705SXin Li } 74*67e74705SXin Li 75*67e74705SXin Li template< typename T > scalar_(decltype(T (),int ()) )76*67e74705SXin Li void scalar_(decltype(T(), int())) { 77*67e74705SXin Li } 78*67e74705SXin Li 79*67e74705SXin Li template <unsigned N> struct T {}; 80*67e74705SXin Li f()81*67e74705SXin Li template <int N> T<N> f() { return T<N>(); } 82*67e74705SXin Li 83*67e74705SXin Li extern int i; 84*67e74705SXin Li extern struct S {} s; 85*67e74705SXin Li 86*67e74705SXin Li // CHECK-LABEL: define weak_odr void @_ZN5Casts8implicitILj4EEEvPN9enable_ifIXleT_Li4EEvE4typeE 87*67e74705SXin Li template void implicit<4>(void*); 88*67e74705SXin Li // CHECK-LABEL: define weak_odr void @_ZN5Casts6cstyleILj4EEEvPN9enable_ifIXleT_cvjLi4EEvE4typeE 89*67e74705SXin Li template void cstyle<4>(void*); 90*67e74705SXin Li // CHECK-LABEL: define weak_odr void @_ZN5Casts10functionalILj4EEEvPN9enable_ifIXleT_cvjLi4EEvE4typeE 91*67e74705SXin Li template void functional<4>(void*); 92*67e74705SXin Li // CHECK-LABEL: define weak_odr void @_ZN5Casts7static_ILj4EEEvPN9enable_ifIXleT_scjLi4EEvE4typeE 93*67e74705SXin Li template void static_<4>(void*); 94*67e74705SXin Li // CHECK-LABEL: define weak_odr void @_ZN5Casts12reinterpret_ILj4EiEEvPN9enable_ifIXleT_szrcPT0_Li0EEvE4typeE 95*67e74705SXin Li template void reinterpret_<4, int>(void*); 96*67e74705SXin Li // CHECK-LABEL: define weak_odr void @_ZN5Casts6const_IiXadL_ZNS_1iEEEEEvPN9enable_ifIXleLi0EszccPT_T0_EvE4typeE 97*67e74705SXin Li template void const_<int, &i>(void*); 98*67e74705SXin Li // CHECK-LABEL: define weak_odr void @_ZN5Casts8dynamic_INS_1SEXadL_ZNS_1sEEEEEvPN9enable_ifIXleLi0EszdcPT_T0_EvE4typeE 99*67e74705SXin Li template void dynamic_<struct S, &s>(void*); 100*67e74705SXin Li 101*67e74705SXin Li // CHECK-LABEL: define weak_odr void @_ZN5Casts1fILi6EEENS_1TIXT_EEEv 102*67e74705SXin Li template T<6> f<6>(); 103*67e74705SXin Li 104*67e74705SXin Li // CHECK-LABEL: define weak_odr void @_ZN5Casts5auto_IiEEvDTnw_DapicvT__EEE( 105*67e74705SXin Li template void auto_<int>(int*); 106*67e74705SXin Li 107*67e74705SXin Li // CHECK-LABEL: define weak_odr void @_ZN5Casts7scalar_IiEEvDTcmcvT__Ecvi_EE( 108*67e74705SXin Li template void scalar_<int>(int); 109*67e74705SXin Li } 110*67e74705SXin Li 111*67e74705SXin Li namespace test1 { 112*67e74705SXin Li short foo(short); 113*67e74705SXin Li int foo(int); 114*67e74705SXin Li 115*67e74705SXin Li // CHECK-LABEL: define linkonce_odr signext i16 @_ZN5test11aIsEEDTcl3foocvT__EEES1_( a(T t)116*67e74705SXin Li template <class T> auto a(T t) -> decltype(foo(T())) { return foo(t); } 117*67e74705SXin Li 118*67e74705SXin Li // CHECK-LABEL: define linkonce_odr signext i16 @_ZN5test11bIsEEDTcp3foocvT__EEES1_( b(T t)119*67e74705SXin Li template <class T> auto b(T t) -> decltype((foo)(T())) { return (foo)(t); } 120*67e74705SXin Li test(short s)121*67e74705SXin Li void test(short s) { 122*67e74705SXin Li a(s); 123*67e74705SXin Li b(s); 124*67e74705SXin Li } 125*67e74705SXin Li } 126*67e74705SXin Li 127*67e74705SXin Li namespace test2 { a(T x,decltype(x ()) y)128*67e74705SXin Li template <class T> void a(T x, decltype(x()) y) {} b(T x)129*67e74705SXin Li template <class T> auto b(T x) -> decltype(x()) { return x(); } c(T x,void (* p)(decltype(x ()) ))130*67e74705SXin Li template <class T> void c(T x, void (*p)(decltype(x()))) {} 131*67e74705SXin Li template <class T> void d(T x, auto (*p)() -> decltype(x())) {} 132*67e74705SXin Li template <class T> void e(auto (*p)(T y) -> decltype(y())) {} f(void (* p)(T x,decltype(x ()) y))133*67e74705SXin Li template <class T> void f(void (*p)(T x, decltype(x()) y)) {} g(T x,decltype(x ()) y)134*67e74705SXin Li template <class T> void g(T x, decltype(x()) y) { 135*67e74705SXin Li static decltype(x()) variable; 136*67e74705SXin Li variable = 0; 137*67e74705SXin Li } 138*67e74705SXin Li template <class T> void h(T x, decltype((decltype(x())(*)()) 0) y) {} 139*67e74705SXin Li template <class T> void i(decltype((auto (*)(T x) -> decltype(x())) 0) y) {} 140*67e74705SXin Li 141*67e74705SXin Li float foo(); 142*67e74705SXin Li void bar(float); 143*67e74705SXin Li float baz(float(*)()); 144*67e74705SXin Li void fred(float(*)(), float); 145*67e74705SXin Li 146*67e74705SXin Li // CHECK-LABEL: define void @_ZN5test211instantiateEv instantiate()147*67e74705SXin Li void instantiate() { 148*67e74705SXin Li // CHECK: call void @_ZN5test21aIPFfvEEEvT_DTclfL0p_EE( 149*67e74705SXin Li a(foo, 0.0f); 150*67e74705SXin Li // CHECK: call float @_ZN5test21bIPFfvEEEDTclfp_EET_( 151*67e74705SXin Li (void) b(foo); 152*67e74705SXin Li // CHECK: call void @_ZN5test21cIPFfvEEEvT_PFvDTclfL1p_EEE( 153*67e74705SXin Li c(foo, bar); 154*67e74705SXin Li // CHECK: call void @_ZN5test21dIPFfvEEEvT_PFDTclfL0p_EEvE( 155*67e74705SXin Li d(foo, foo); 156*67e74705SXin Li // CHECK: call void @_ZN5test21eIPFfvEEEvPFDTclfp_EET_E( 157*67e74705SXin Li e(baz); 158*67e74705SXin Li // CHECK: call void @_ZN5test21fIPFfvEEEvPFvT_DTclfL0p_EEE( 159*67e74705SXin Li f(fred); 160*67e74705SXin Li // CHECK: call void @_ZN5test21gIPFfvEEEvT_DTclfL0p_EE( 161*67e74705SXin Li g(foo, 0.0f); 162*67e74705SXin Li // CHECK: call void @_ZN5test21hIPFfvEEEvT_DTcvPFDTclfL0p_EEvELi0EE( 163*67e74705SXin Li h(foo, foo); 164*67e74705SXin Li // CHECK: call void @_ZN5test21iIPFfvEEEvDTcvPFDTclfp_EET_ELi0EE( 165*67e74705SXin Li i<float(*)()>(baz); 166*67e74705SXin Li } 167*67e74705SXin Li 168*67e74705SXin Li // CHECK: store float {{.*}}, float* @_ZZN5test21gIPFfvEEEvT_DTclfL0p_EEE8variable, 169*67e74705SXin Li } 170*67e74705SXin Li 171*67e74705SXin Li namespace test3 { 172*67e74705SXin Li template <class T, class U> void a(T x, U y, decltype(x.*y) z) {} 173*67e74705SXin Li 174*67e74705SXin Li struct X { 175*67e74705SXin Li int *member; 176*67e74705SXin Li }; 177*67e74705SXin Li 178*67e74705SXin Li // CHECK-LABEL: define void @_ZN5test311instantiateEv instantiate()179*67e74705SXin Li void instantiate() { 180*67e74705SXin Li X x; 181*67e74705SXin Li int *ip; 182*67e74705SXin Li // CHECK: call void @_ZN5test31aINS_1XEMS1_PiEEvT_T0_DTdsfL0p_fL0p0_E 183*67e74705SXin Li a(x, &X::member, ip); 184*67e74705SXin Li } 185*67e74705SXin Li } 186*67e74705SXin Li 187*67e74705SXin Li namespace test4 { 188*67e74705SXin Li struct X { 189*67e74705SXin Li X(int); 190*67e74705SXin Li }; 191*67e74705SXin Li 192*67e74705SXin Li template <typename T> 193*67e74705SXin Li void tf1(decltype(new T(1)) p) 194*67e74705SXin Li {} 195*67e74705SXin Li 196*67e74705SXin Li template <typename T> 197*67e74705SXin Li void tf2(decltype(new T({1})) p) 198*67e74705SXin Li {} 199*67e74705SXin Li 200*67e74705SXin Li template <typename T> tf3(decltype(new T{1}) p)201*67e74705SXin Li void tf3(decltype(new T{1}) p) 202*67e74705SXin Li {} 203*67e74705SXin Li 204*67e74705SXin Li // CHECK: void @_ZN5test43tf1INS_1XEEEvDTnw_T_piLi1EEE 205*67e74705SXin Li template void tf1<X>(X*); 206*67e74705SXin Li 207*67e74705SXin Li // CHECK: void @_ZN5test43tf2INS_1XEEEvDTnw_T_piilLi1EEEE 208*67e74705SXin Li template void tf2<X>(X*); 209*67e74705SXin Li 210*67e74705SXin Li // CHECK: void @_ZN5test43tf3INS_1XEEEvDTnw_T_ilLi1EEE 211*67e74705SXin Li template void tf3<X>(X*); 212*67e74705SXin Li 213*67e74705SXin Li } 214*67e74705SXin Li 215*67e74705SXin Li namespace test5 { a(decltype(noexcept (T ())) )216*67e74705SXin Li template <typename T> void a(decltype(noexcept(T()))) {} 217*67e74705SXin Li template void a<int>(decltype(noexcept(int()))); 218*67e74705SXin Li // CHECK: void @_ZN5test51aIiEEvDTnxcvT__EE( 219*67e74705SXin Li } 220*67e74705SXin Li 221*67e74705SXin Li namespace test6 { 222*67e74705SXin Li struct X { 223*67e74705SXin Li int i; 224*67e74705SXin Li }; 225*67e74705SXin Li 226*67e74705SXin Li struct Y { 227*67e74705SXin Li union { 228*67e74705SXin Li int i; 229*67e74705SXin Li }; 230*67e74705SXin Li }; 231*67e74705SXin Li 232*67e74705SXin Li struct Z { 233*67e74705SXin Li union { 234*67e74705SXin Li X ua; 235*67e74705SXin Li Y ub; 236*67e74705SXin Li }; 237*67e74705SXin Li 238*67e74705SXin Li struct { 239*67e74705SXin Li X s; 240*67e74705SXin Li }; 241*67e74705SXin Li 242*67e74705SXin Li union { 243*67e74705SXin Li union { 244*67e74705SXin Li struct { 245*67e74705SXin Li struct { 246*67e74705SXin Li X uuss; 247*67e74705SXin Li }; 248*67e74705SXin Li }; 249*67e74705SXin Li }; 250*67e74705SXin Li }; 251*67e74705SXin Li }; 252*67e74705SXin Li 253*67e74705SXin Li Z z, *zp; 254*67e74705SXin Li 255*67e74705SXin Li template<typename T> 256*67e74705SXin Li void f1(decltype(T(z.ua.i))) {} 257*67e74705SXin Li template void f1<int>(int); 258*67e74705SXin Li // CHECK-LABEL: define weak_odr void @_ZN5test62f1IiEEvDTcvT_dtdtL_ZNS_1zEE2ua1iE 259*67e74705SXin Li 260*67e74705SXin Li template<typename T> 261*67e74705SXin Li void f2(decltype(T(z.ub.i))) {} 262*67e74705SXin Li template void f2<int>(int); 263*67e74705SXin Li // CHECK-LABEL: define weak_odr void @_ZN5test62f2IiEEvDTcvT_dtdtL_ZNS_1zEE2ub1iE 264*67e74705SXin Li 265*67e74705SXin Li template<typename T> 266*67e74705SXin Li void f3(decltype(T(z.s.i))) {} 267*67e74705SXin Li template void f3<int>(int); 268*67e74705SXin Li // CHECK-LABEL: define weak_odr void @_ZN5test62f3IiEEvDTcvT_dtdtL_ZNS_1zEE1s1iE 269*67e74705SXin Li 270*67e74705SXin Li template<typename T> 271*67e74705SXin Li void f4(decltype(T(z.uuss.i))) {} 272*67e74705SXin Li template void f4<int>(int); 273*67e74705SXin Li // CHECK-LABEL: define weak_odr void @_ZN5test62f4IiEEvDTcvT_dtdtL_ZNS_1zEE4uuss1iE 274*67e74705SXin Li 275*67e74705SXin Li template<typename T> 276*67e74705SXin Li void f5(decltype(T(zp->ua.i))) {} 277*67e74705SXin Li template void f5<int>(int); 278*67e74705SXin Li // CHECK-LABEL: define weak_odr void @_ZN5test62f5IiEEvDTcvT_dtptL_ZNS_2zpEE2ua1iE 279*67e74705SXin Li 280*67e74705SXin Li template<typename T> 281*67e74705SXin Li void f6(decltype(T(zp->ub.i))) {} 282*67e74705SXin Li template void f6<int>(int); 283*67e74705SXin Li // CHECK-LABEL: define weak_odr void @_ZN5test62f6IiEEvDTcvT_dtptL_ZNS_2zpEE2ub1iE 284*67e74705SXin Li 285*67e74705SXin Li template<typename T> 286*67e74705SXin Li void f7(decltype(T(zp->s.i))) {} 287*67e74705SXin Li template void f7<int>(int); 288*67e74705SXin Li // CHECK-LABEL: define weak_odr void @_ZN5test62f7IiEEvDTcvT_dtptL_ZNS_2zpEE1s1iE 289*67e74705SXin Li 290*67e74705SXin Li template<typename T> 291*67e74705SXin Li void f8(decltype(T(zp->uuss.i))) {} 292*67e74705SXin Li template void f8<int>(int); 293*67e74705SXin Li // CHECK-LABEL: define weak_odr void @_ZN5test62f8IiEEvDTcvT_dtptL_ZNS_2zpEE4uuss1iE 294*67e74705SXin Li } 295*67e74705SXin Li 296*67e74705SXin Li namespace test7 { 297*67e74705SXin Li struct A { int x[3]; }; 298*67e74705SXin Li struct B { B(int, int); } extern b; 299*67e74705SXin Li struct C { C(B); }; 300*67e74705SXin Li struct D { D(C); }; 301*67e74705SXin Li struct E { E(std::initializer_list<int>); }; 302*67e74705SXin Li struct F { F(E); }; 303*67e74705SXin Li fA1(T t)304*67e74705SXin Li template<class T> decltype(A{1,2},T()) fA1(T t) {} fA2(T t)305*67e74705SXin Li template<class T> decltype(A({1,2}),T()) fA2(T t) {} fB1(T t)306*67e74705SXin Li template<class T> decltype(B{1,2},T()) fB1(T t) {} fB2(T t)307*67e74705SXin Li template<class T> decltype(B({1,2}),T()) fB2(T t) {} fC1(T t)308*67e74705SXin Li template<class T> decltype(C{{1,2}},T()) fC1(T t) {} fC2(T t)309*67e74705SXin Li template<class T> decltype(C({1,2}),T()) fC2(T t) {} fD1(T t)310*67e74705SXin Li template<class T> decltype(D{b},T()) fD1(T t) {} D(b)311*67e74705SXin Li template<class T> decltype(D(b),T()) fD2(T t) {} fE1(T t)312*67e74705SXin Li template<class T> decltype(E{1,2},T()) fE1(T t) {} fE2(T t)313*67e74705SXin Li template<class T> decltype(E({1,2}),T()) fE2(T t) {} fF1(T t)314*67e74705SXin Li template<class T> decltype(F{{1,2}},T()) fF1(T t) {} fF2(T t)315*67e74705SXin Li template<class T> decltype(F({1,2}),T()) fF2(T t) {} 316*67e74705SXin Li main()317*67e74705SXin Li int main() { 318*67e74705SXin Li fA1(1); // CHECK-LABEL: define {{.*}} @_ZN5test73fA1IiEEDTcmtlNS_1AELi1ELi2EEcvT__EES2_ 319*67e74705SXin Li fA2(1); // CHECK-LABEL: define {{.*}} @_ZN5test73fA2IiEEDTcmcvNS_1AEilLi1ELi2EEcvT__EES2_ 320*67e74705SXin Li fB1(1); // CHECK-LABEL: define {{.*}} @_ZN5test73fB1IiEEDTcmtlNS_1BELi1ELi2EEcvT__EES2_ 321*67e74705SXin Li fB2(1); // CHECK-LABEL: define {{.*}} @_ZN5test73fB2IiEEDTcmcvNS_1BEilLi1ELi2EEcvT__EES2_ 322*67e74705SXin Li fC1(1); // CHECK-LABEL: define {{.*}} @_ZN5test73fC1IiEEDTcmtlNS_1CEilLi1ELi2EEEcvT__EES2_ 323*67e74705SXin Li fC2(1); // CHECK-LABEL: define {{.*}} @_ZN5test73fC2IiEEDTcmcvNS_1CEilLi1ELi2EEcvT__EES2_ 324*67e74705SXin Li fD1(1); // CHECK-LABEL: define {{.*}} @_ZN5test73fD1IiEEDTcmtlNS_1DEL_ZNS_1bEEEcvT__EES2_ 325*67e74705SXin Li fD2(1); // CHECK-LABEL: define {{.*}} @_ZN5test73fD2IiEEDTcmcvNS_1DEL_ZNS_1bEEcvT__EES2_ 326*67e74705SXin Li fE1(1); // CHECK-LABEL: define {{.*}} @_ZN5test73fE1IiEEDTcmtlNS_1EELi1ELi2EEcvT__EES2_ 327*67e74705SXin Li fE2(1); // CHECK-LABEL: define {{.*}} @_ZN5test73fE2IiEEDTcmcvNS_1EEilLi1ELi2EEcvT__EES2_ 328*67e74705SXin Li fF1(1); // CHECK-LABEL: define {{.*}} @_ZN5test73fF1IiEEDTcmtlNS_1FEilLi1ELi2EEEcvT__EES2_ 329*67e74705SXin Li fF2(1); // CHECK-LABEL: define {{.*}} @_ZN5test73fF2IiEEDTcmcvNS_1FEilLi1ELi2EEcvT__EES2_ 330*67e74705SXin Li } 331*67e74705SXin Li } 332*67e74705SXin Li 333*67e74705SXin Li 334*67e74705SXin Li namespace test8 { 335*67e74705SXin Li template <class> 336*67e74705SXin Li struct X { footest8::X337*67e74705SXin Li template<typename T> T foo() const { return 0; } bartest8::X338*67e74705SXin Li template <class T> auto bar() const -> decltype(foo<T>()) { return 0; } 339*67e74705SXin Li }; 340*67e74705SXin Li 341*67e74705SXin Li // CHECK-LABEL: define weak_odr i32 @_ZNK5test81XIiE3barIiEEDTcl3fooIT_EEEv 342*67e74705SXin Li template int X<int>::bar<int>() const; 343*67e74705SXin Li } 344