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 
fT1(T t)317   template<class T> decltype(T{}) fT1(T t) {}
T()318   template<class T> decltype(T()) fT2(T t) {}
fT3(T t)319   template<class T> decltype(T{1}) fT3(T t) {}
fT4(T t)320   template<class T> decltype(T(1)) fT4(T t) {}
fT5(T t)321   template<class T> decltype(T{1,2}) fT5(T t) {}
fT6(T t)322   template<class T> decltype(T(1,2)) fT6(T t) {}
fT7(T t)323   template<class T> decltype(T{{}}) fT7(T t) {}
fT8(T t)324   template<class T> decltype(T({})) fT8(T t) {}
fT9(T t)325   template<class T> decltype(T{{1}}) fT9(T t) {}
fTA(T t)326   template<class T> decltype(T({1})) fTA(T t) {}
fTB(T t)327   template<class T> decltype(T{{1,2}}) fTB(T t) {}
fTC(T t)328   template<class T> decltype(T({1,2})) fTC(T t) {}
329 
main()330   int main() {
331     fA1(1); // CHECK-LABEL: define {{.*}} @_ZN5test73fA1IiEEDTcmtlNS_1AELi1ELi2EEcvT__EES2_
332     fA2(1); // CHECK-LABEL: define {{.*}} @_ZN5test73fA2IiEEDTcmcvNS_1AEilLi1ELi2EEcvT__EES2_
333     fB1(1); // CHECK-LABEL: define {{.*}} @_ZN5test73fB1IiEEDTcmtlNS_1BELi1ELi2EEcvT__EES2_
334     fB2(1); // CHECK-LABEL: define {{.*}} @_ZN5test73fB2IiEEDTcmcvNS_1BEilLi1ELi2EEcvT__EES2_
335     fC1(1); // CHECK-LABEL: define {{.*}} @_ZN5test73fC1IiEEDTcmtlNS_1CEilLi1ELi2EEEcvT__EES2_
336     fC2(1); // CHECK-LABEL: define {{.*}} @_ZN5test73fC2IiEEDTcmcvNS_1CEilLi1ELi2EEcvT__EES2_
337     fD1(1); // CHECK-LABEL: define {{.*}} @_ZN5test73fD1IiEEDTcmtlNS_1DEL_ZNS_1bEEEcvT__EES2_
338     fD2(1); // CHECK-LABEL: define {{.*}} @_ZN5test73fD2IiEEDTcmcvNS_1DEL_ZNS_1bEEcvT__EES2_
339     fE1(1); // CHECK-LABEL: define {{.*}} @_ZN5test73fE1IiEEDTcmtlNS_1EELi1ELi2EEcvT__EES2_
340     fE2(1); // CHECK-LABEL: define {{.*}} @_ZN5test73fE2IiEEDTcmcvNS_1EEilLi1ELi2EEcvT__EES2_
341     fF1(1); // CHECK-LABEL: define {{.*}} @_ZN5test73fF1IiEEDTcmtlNS_1FEilLi1ELi2EEEcvT__EES2_
342     fF2(1); // CHECK-LABEL: define {{.*}} @_ZN5test73fF2IiEEDTcmcvNS_1FEilLi1ELi2EEcvT__EES2_
343     fT1(1); // CHECK-LABEL: define {{.*}} @_ZN5test73fT1IiEEDTtlT_EES1_(
344     fT2(1); // CHECK-LABEL: define {{.*}} @_ZN5test73fT2IiEEDTcvT__EES1_(
345     fT3(1); // CHECK-LABEL: define {{.*}} @_ZN5test73fT3IiEEDTtlT_Li1EEES1_(
346     fT4(1); // CHECK-LABEL: define {{.*}} @_ZN5test73fT4IiEEDTcvT_Li1EES1_(
347     fT5(b); // CHECK-LABEL: define {{.*}} @_ZN5test73fT5INS_1BEEEDTtlT_Li1ELi2EEES2_(
348     fT6(b); // CHECK-LABEL: define {{.*}} @_ZN5test73fT6INS_1BEEEDTcvT__Li1ELi2EEES2_(
349     fT7(A{}); // CHECK-LABEL: define {{.*}} @_ZN5test73fT7INS_1AEEEDTtlT_ilEEES2_(
350     fT8(A{}); // CHECK-LABEL: define {{.*}} @_ZN5test73fT8INS_1AEEEDTcvT_ilEES2_(
351     fT9(A{}); // CHECK-LABEL: define {{.*}} @_ZN5test73fT9INS_1AEEEDTtlT_ilLi1EEEES2_(
352     fTA(A{}); // CHECK-LABEL: define {{.*}} @_ZN5test73fTAINS_1AEEEDTcvT_ilLi1EEES2_(
353     fTB<C>(b); // CHECK-LABEL: define {{.*}} @_ZN5test73fTBINS_1CEEEDTtlT_ilLi1ELi2EEEES2_(
354     fTC<C>(b); // CHECK-LABEL: define {{.*}} @_ZN5test73fTCINS_1CEEEDTcvT_ilLi1ELi2EEES2_(
355   }
356 }
357 
358 
359 namespace test8 {
360   template <class>
361   struct X {
footest8::X362     template<typename T> T foo() const { return 0; }
bartest8::X363     template <class T> auto bar() const -> decltype(foo<T>()) { return 0; }
364   };
365 
366   // CHECK-LABEL: define weak_odr i32 @_ZNK5test81XIiE3barIiEEDTcl3fooIT_EEEv
367   template int X<int>::bar<int>() const;
368 }
369 
370 namespace designated_init {
371   struct A { struct B { int b[5][5]; } a; };
372   // CHECK-LABEL: define {{.*}} @_ZN15designated_init1fINS_1AEEEvDTtlT_di1adi1bdxLi3EdXLi1ELi4ELi9EEE(
f(decltype(T{.a.b[3][1 ... 4] = 9})x)373   template<typename T> void f(decltype(T{.a.b[3][1 ... 4] = 9}) x) {}
use_f(A a)374   void use_f(A a) { f<A>(a); }
375 }
376 
377 namespace null {
378   template <decltype(nullptr) P>
cpp_nullptr(typename enable_if<P==nullptr>::type * =0)379   void cpp_nullptr(typename enable_if<P == nullptr>::type* = 0) {
380   }
381 
382   template <void *P>
gnu_null(typename enable_if<P==__null>::type * =0)383   void gnu_null(typename enable_if<P == __null>::type* = 0) {
384   }
385 
386   // CHECK-LABEL: define {{.*}} @_ZN4null11cpp_nullptrILDn0EEEvPN9enable_ifIXeqT_LDnEEvE4typeE
387   template void cpp_nullptr<nullptr>(void *);
388 
389   // CHECK-LABEL: define {{.*}} @_ZN4null8gnu_nullILPv0EEEvPN9enable_ifIXeqT_Ll0EEvE4typeE
390   template void gnu_null<nullptr>(void *);
391 }
392