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