1// RUN: %clang_cc1 -std=c++11 -emit-llvm %s -o - -triple=x86_64-apple-darwin9 | FileCheck %s 2 3template < bool condition, typename T = void > 4struct enable_if { typedef T type; }; 5 6template< typename T > 7struct enable_if< false, T > {}; 8 9// PR5876 10namespace Casts { 11 template< unsigned O > 12 void implicit(typename enable_if< O <= 4 >::type* = 0) { 13 } 14 15 template< unsigned O > 16 void cstyle(typename enable_if< O <= (unsigned)4 >::type* = 0) { 17 } 18 19 template< unsigned O > 20 void functional(typename enable_if< O <= unsigned(4) >::type* = 0) { 21 } 22 23 template< unsigned O > 24 void static_(typename enable_if< O <= static_cast<unsigned>(4) >::type* = 0) { 25 } 26 27 template< typename T > 28 void auto_(decltype(new auto(T()))) { 29 } 30 31 // FIXME: Test const_cast, reinterpret_cast, dynamic_cast, which are 32 // a bit harder to use in template arguments. 33 template <unsigned N> struct T {}; 34 35 template <int N> T<N> f() { return T<N>(); } 36 37 // CHECK: define weak_odr void @_ZN5Casts8implicitILj4EEEvPN9enable_ifIXleT_Li4EEvE4typeE 38 template void implicit<4>(void*); 39 // CHECK: define weak_odr void @_ZN5Casts6cstyleILj4EEEvPN9enable_ifIXleT_cvjLi4EEvE4typeE 40 template void cstyle<4>(void*); 41 // CHECK: define weak_odr void @_ZN5Casts10functionalILj4EEEvPN9enable_ifIXleT_cvjLi4EEvE4typeE 42 template void functional<4>(void*); 43 // CHECK: define weak_odr void @_ZN5Casts7static_ILj4EEEvPN9enable_ifIXleT_cvjLi4EEvE4typeE 44 template void static_<4>(void*); 45 46 // CHECK: define weak_odr void @_ZN5Casts1fILi6EEENS_1TIXT_EEEv 47 template T<6> f<6>(); 48 49 // CHECK: define weak_odr void @_ZN5Casts5auto_IiEEvDTnw_DapicvT__EEE( 50 template void auto_<int>(int*); 51} 52 53namespace test1 { 54 short foo(short); 55 int foo(int); 56 57 // CHECK: define linkonce_odr signext i16 @_ZN5test11aIsEEDTcl3foocvT__EEES1_( 58 template <class T> auto a(T t) -> decltype(foo(T())) { return foo(t); } 59 60 // CHECK: define linkonce_odr signext i16 @_ZN5test11bIsEEDTcp3foocvT__EEES1_( 61 template <class T> auto b(T t) -> decltype((foo)(T())) { return (foo)(t); } 62 63 void test(short s) { 64 a(s); 65 b(s); 66 } 67} 68 69namespace test2 { 70 template <class T> void a(T x, decltype(x()) y) {} 71 template <class T> auto b(T x) -> decltype(x()) { return x(); } 72 template <class T> void c(T x, void (*p)(decltype(x()))) {} 73 template <class T> void d(T x, auto (*p)() -> decltype(x())) {} 74 template <class T> void e(auto (*p)(T y) -> decltype(y())) {} 75 template <class T> void f(void (*p)(T x, decltype(x()) y)) {} 76 template <class T> void g(T x, decltype(x()) y) { 77 static decltype(x()) variable; 78 variable = 0; 79 } 80 template <class T> void h(T x, decltype((decltype(x())(*)()) 0) y) {} 81 template <class T> void i(decltype((auto (*)(T x) -> decltype(x())) 0) y) {} 82 83 float foo(); 84 void bar(float); 85 float baz(float(*)()); 86 void fred(float(*)(), float); 87 88 // CHECK: define void @_ZN5test211instantiateEv 89 void instantiate() { 90 // CHECK: call void @_ZN5test21aIPFfvEEEvT_DTclfL0p_EE( 91 a(foo, 0.0f); 92 // CHECK: call float @_ZN5test21bIPFfvEEEDTclfp_EET_( 93 (void) b(foo); 94 // CHECK: call void @_ZN5test21cIPFfvEEEvT_PFvDTclfL1p_EEE( 95 c(foo, bar); 96 // CHECK: call void @_ZN5test21dIPFfvEEEvT_PFDTclfL0p_EEvE( 97 d(foo, foo); 98 // CHECK: call void @_ZN5test21eIPFfvEEEvPFDTclfp_EET_E( 99 e(baz); 100 // CHECK: call void @_ZN5test21fIPFfvEEEvPFvT_DTclfL0p_EEE( 101 f(fred); 102 // CHECK: call void @_ZN5test21gIPFfvEEEvT_DTclfL0p_EE( 103 g(foo, 0.0f); 104 // CHECK: call void @_ZN5test21hIPFfvEEEvT_DTcvPFDTclfL0p_EEvELi0EE( 105 h(foo, foo); 106 // CHECK: call void @_ZN5test21iIPFfvEEEvDTcvPFDTclfp_EET_ELi0EE( 107 i<float(*)()>(baz); 108 } 109 110 // CHECK: store float {{.*}}, float* @_ZZN5test21gIPFfvEEEvT_DTclfL0p_EEE8variable, 111} 112 113namespace test3 { 114 template <class T, class U> void a(T x, U y, decltype(x.*y) z) {} 115 116 struct X { 117 int *member; 118 }; 119 120 // CHECK: define void @_ZN5test311instantiateEv 121 void instantiate() { 122 X x; 123 int *ip; 124 // CHECK: call void @_ZN5test31aINS_1XEMS1_PiEEvT_T0_DTdsfL0p_fL0p0_E 125 a(x, &X::member, ip); 126 } 127} 128