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 namespace test7 { 297 struct A { int x[3]; }; 298 struct B { B(int, int); } extern b; 299 struct C { C(B); }; 300 struct D { D(C); }; 301 struct E { E(std::initializer_list<int>); }; 302 struct F { F(E); }; 303 fA1(T t)304 template<class T> decltype(A{1,2},T()) fA1(T t) {} fA2(T t)305 template<class T> decltype(A({1,2}),T()) fA2(T t) {} fB1(T t)306 template<class T> decltype(B{1,2},T()) fB1(T t) {} fB2(T t)307 template<class T> decltype(B({1,2}),T()) fB2(T t) {} fC1(T t)308 template<class T> decltype(C{{1,2}},T()) fC1(T t) {} fC2(T t)309 template<class T> decltype(C({1,2}),T()) fC2(T t) {} fD1(T t)310 template<class T> decltype(D{b},T()) fD1(T t) {} D(b)311 template<class T> decltype(D(b),T()) fD2(T t) {} fE1(T t)312 template<class T> decltype(E{1,2},T()) fE1(T t) {} fE2(T t)313 template<class T> decltype(E({1,2}),T()) fE2(T t) {} fF1(T t)314 template<class T> decltype(F{{1,2}},T()) fF1(T t) {} fF2(T t)315 template<class T> decltype(F({1,2}),T()) fF2(T t) {} 316 main()317 int main() { 318 fA1(1); // CHECK-LABEL: define {{.*}} @_ZN5test73fA1IiEEDTcmtlNS_1AELi1ELi2EEcvT__EES2_ 319 fA2(1); // CHECK-LABEL: define {{.*}} @_ZN5test73fA2IiEEDTcmcvNS_1AEilLi1ELi2EEcvT__EES2_ 320 fB1(1); // CHECK-LABEL: define {{.*}} @_ZN5test73fB1IiEEDTcmtlNS_1BELi1ELi2EEcvT__EES2_ 321 fB2(1); // CHECK-LABEL: define {{.*}} @_ZN5test73fB2IiEEDTcmcvNS_1BEilLi1ELi2EEcvT__EES2_ 322 fC1(1); // CHECK-LABEL: define {{.*}} @_ZN5test73fC1IiEEDTcmtlNS_1CEilLi1ELi2EEEcvT__EES2_ 323 fC2(1); // CHECK-LABEL: define {{.*}} @_ZN5test73fC2IiEEDTcmcvNS_1CEilLi1ELi2EEcvT__EES2_ 324 fD1(1); // CHECK-LABEL: define {{.*}} @_ZN5test73fD1IiEEDTcmtlNS_1DEL_ZNS_1bEEEcvT__EES2_ 325 fD2(1); // CHECK-LABEL: define {{.*}} @_ZN5test73fD2IiEEDTcmcvNS_1DEL_ZNS_1bEEcvT__EES2_ 326 fE1(1); // CHECK-LABEL: define {{.*}} @_ZN5test73fE1IiEEDTcmtlNS_1EELi1ELi2EEcvT__EES2_ 327 fE2(1); // CHECK-LABEL: define {{.*}} @_ZN5test73fE2IiEEDTcmcvNS_1EEilLi1ELi2EEcvT__EES2_ 328 fF1(1); // CHECK-LABEL: define {{.*}} @_ZN5test73fF1IiEEDTcmtlNS_1FEilLi1ELi2EEEcvT__EES2_ 329 fF2(1); // CHECK-LABEL: define {{.*}} @_ZN5test73fF2IiEEDTcmcvNS_1FEilLi1ELi2EEcvT__EES2_ 330 } 331 } 332 333 334 namespace test8 { 335 template <class> 336 struct X { footest8::X337 template<typename T> T foo() const { return 0; } bartest8::X338 template <class T> auto bar() const -> decltype(foo<T>()) { return 0; } 339 }; 340 341 // CHECK-LABEL: define weak_odr i32 @_ZNK5test81XIiE3barIiEEDTcl3fooIT_EEEv 342 template int X<int>::bar<int>() const; 343 } 344