15f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer// RUN: %clang_cc1 -std=c++11 -emit-llvm %s -o - -triple=x86_64-apple-darwin9 | FileCheck %s
25f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
35f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencernamespace std {
45f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  typedef decltype(sizeof(int)) size_t;
50bc735ffcfb223c0186419547abaa5c84482663eChris Lattner
60bc735ffcfb223c0186419547abaa5c84482663eChris Lattner  // libc++'s implementation
75f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  template <class _E>
85f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  class initializer_list
95f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  {
105f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    const _E* __begin_;
115f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    size_t    __size_;
125f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
135f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    initializer_list(const _E* __b, size_t __s)
145f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer      : __begin_(__b),
15bdc601b196c48d4cd56a5ceb45d41ae4e87371abKen Dyck        __size_(__s)
161abee64ad71519ea9d91f1fe76441b9cdb75b6c0Dmitri Gribenko    {}
178d3ba23f2d9e6c87794d059412a0808c9cbacb25Dmitri Gribenko
188d3ba23f2d9e6c87794d059412a0808c9cbacb25Dmitri Gribenko  public:
198d3ba23f2d9e6c87794d059412a0808c9cbacb25Dmitri Gribenko    typedef _E        value_type;
2049aa7ff1245abd03e6e998e01302df31e4c6f8f6Argyrios Kyrtzidis    typedef const _E& reference;
21980e508ca70d6de75d2abfd96b4681fc98bb2698Steve Naroff    typedef const _E& const_reference;
22aaba5e346dffdbad5d1c42765a89e4a7afb0da67Douglas Gregor    typedef size_t    size_type;
23b17166c8077cd900cca83a895c43b30ea6660598Argyrios Kyrtzidis
24e91593ef084479340582b2ba177b44be50a717b7Daniel Dunbar    typedef const _E* iterator;
25ea1471e0e967548c596a71469702f8846dbaf3c0John McCall    typedef const _E* const_iterator;
262cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor
277b90340c9c7d07aef4e301e72b5e8a30d5f4f0c8Argyrios Kyrtzidis    initializer_list() : __begin_(nullptr), __size_(0) {}
2819cc4abea06a9b49e0e16a50d335c064cd723572Anders Carlsson
2914110477887e3dc168ffc6c191e72d705051f99ePeter Collingbourne    size_t    size()  const {return __size_;}
301b63e4f732dbc73d90abf886b4d21f8e3a165f6dChris Lattner    const _E* begin() const {return __begin_;}
31a9376d470ccb0eac74fe09a6b2a18a890f1d17c4Chris Lattner    const _E* end()   const {return __begin_ + __size_;}
325f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  };
33f5942a44880be26878592eb052b737579349411eBenjamin Kramer}
3485f9bceab1542aafff012d4d28e998f4ba16e362Anders Carlsson
356fe7c8aa8c7546743ecd0ac0138c2cf5d8155386Nate Begemantemplate < bool condition, typename T = void >
36f5942a44880be26878592eb052b737579349411eBenjamin Kramerstruct enable_if { typedef T type; };
370c8cd1ac55720276ad41fa7b4f8785bead5afd32Ted Kremenek
38071cc7deffad608165b1ddd5263e8bf181861520Charles Davistemplate< typename T >
392636197098e02fd7c90f9496056b8ab886dcbff0Argyrios Kyrtzidisstruct enable_if< false, T > {};
4029445a0542d128cd7ee587ee52229670b9b54a12Anders Carlsson
415f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer// PR5876
425f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencernamespace Casts {
431827403a7138946305c0058f262e02b595cf882fDouglas Gregor  template< unsigned O >
441827403a7138946305c0058f262e02b595cf882fDouglas Gregor  void implicit(typename enable_if< O <= 4 >::type* = 0) {
45225843186e3972ce798d3de00f86da9008b15a0eDouglas Gregor  }
46225843186e3972ce798d3de00f86da9008b15a0eDouglas Gregor
47ffe37fdda5b4b4f162a45155c30d9f60ce110c12Sean Hunt  template< unsigned O >
48ffe37fdda5b4b4f162a45155c30d9f60ce110c12Sean Hunt  void cstyle(typename enable_if< O <= (unsigned)4 >::type* = 0) {
49a376d10acfacf19d6dfa41069f7929739a18dd7aDouglas Gregor  }
50a376d10acfacf19d6dfa41069f7929739a18dd7aDouglas Gregor
51ffe37fdda5b4b4f162a45155c30d9f60ce110c12Sean Hunt  template< unsigned O >
52ffe37fdda5b4b4f162a45155c30d9f60ce110c12Sean Hunt  void functional(typename enable_if< O <= unsigned(4) >::type* = 0) {
534923aa25eb39d64106a5817c02d560a3aecf8b2cDouglas Gregor  }
544923aa25eb39d64106a5817c02d560a3aecf8b2cDouglas Gregor
554923aa25eb39d64106a5817c02d560a3aecf8b2cDouglas Gregor  template< unsigned O >
565f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  void static_(typename enable_if< O <= static_cast<unsigned>(4) >::type* = 0) {
57aa4a99b4a62615db243f7a5c433169f2fc704420Anton Korobeynikov  }
585f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
595f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  template< typename T >
60a5ef44ff5d93a3be6ca67782828157a71894cf0cDmitri Gribenko  void auto_(decltype(new auto(T()))) {
61aa0cd85838f2a024e589ea4e8c2094130065af21Dmitri Gribenko  }
62aa0cd85838f2a024e589ea4e8c2094130065af21Dmitri Gribenko
63aa0cd85838f2a024e589ea4e8c2094130065af21Dmitri Gribenko  template< typename T >
64aa0cd85838f2a024e589ea4e8c2094130065af21Dmitri Gribenko  void scalar_(decltype(T(), int())) {
65aa0cd85838f2a024e589ea4e8c2094130065af21Dmitri Gribenko  }
66aa0cd85838f2a024e589ea4e8c2094130065af21Dmitri Gribenko
67aa0cd85838f2a024e589ea4e8c2094130065af21Dmitri Gribenko  // FIXME: Test const_cast, reinterpret_cast, dynamic_cast, which are
68c3fee3539fd00a6ce21dc1f574baf76686640072Dmitri Gribenko  // a bit harder to use in template arguments.
69c3fee3539fd00a6ce21dc1f574baf76686640072Dmitri Gribenko  template <unsigned N> struct T {};
70c3fee3539fd00a6ce21dc1f574baf76686640072Dmitri Gribenko
71c3fee3539fd00a6ce21dc1f574baf76686640072Dmitri Gribenko  template <int N> T<N> f() { return T<N>(); }
72aa0cd85838f2a024e589ea4e8c2094130065af21Dmitri Gribenko
73aa0cd85838f2a024e589ea4e8c2094130065af21Dmitri Gribenko  // CHECK-LABEL: define weak_odr void @_ZN5Casts8implicitILj4EEEvPN9enable_ifIXleT_Li4EEvE4typeE
74aa0cd85838f2a024e589ea4e8c2094130065af21Dmitri Gribenko  template void implicit<4>(void*);
75aa0cd85838f2a024e589ea4e8c2094130065af21Dmitri Gribenko  // CHECK-LABEL: define weak_odr void @_ZN5Casts6cstyleILj4EEEvPN9enable_ifIXleT_cvjLi4EEvE4typeE
7696b098674908eaa59a9128f3305cda6fbbdad563Dmitri Gribenko  template void cstyle<4>(void*);
7796b098674908eaa59a9128f3305cda6fbbdad563Dmitri Gribenko  // CHECK-LABEL: define weak_odr void @_ZN5Casts10functionalILj4EEEvPN9enable_ifIXleT_cvjLi4EEvE4typeE
7896b098674908eaa59a9128f3305cda6fbbdad563Dmitri Gribenko  template void functional<4>(void*);
7996b098674908eaa59a9128f3305cda6fbbdad563Dmitri Gribenko  // CHECK-LABEL: define weak_odr void @_ZN5Casts7static_ILj4EEEvPN9enable_ifIXleT_cvjLi4EEvE4typeE
8096b098674908eaa59a9128f3305cda6fbbdad563Dmitri Gribenko  template void static_<4>(void*);
8196b098674908eaa59a9128f3305cda6fbbdad563Dmitri Gribenko
8296b098674908eaa59a9128f3305cda6fbbdad563Dmitri Gribenko  // CHECK-LABEL: define weak_odr void @_ZN5Casts1fILi6EEENS_1TIXT_EEEv
83811c820257746b1799b790b6adc7804f44154011Dmitri Gribenko  template T<6> f<6>();
84aa0cd85838f2a024e589ea4e8c2094130065af21Dmitri Gribenko
85aa0cd85838f2a024e589ea4e8c2094130065af21Dmitri Gribenko  // CHECK-LABEL: define weak_odr void @_ZN5Casts5auto_IiEEvDTnw_DapicvT__EEE(
86aa0cd85838f2a024e589ea4e8c2094130065af21Dmitri Gribenko  template void auto_<int>(int*);
87aa0cd85838f2a024e589ea4e8c2094130065af21Dmitri Gribenko
88aa0cd85838f2a024e589ea4e8c2094130065af21Dmitri Gribenko  // CHECK-LABEL: define weak_odr void @_ZN5Casts7scalar_IiEEvDTcmcvT__Ecvi_EE(
89abd56c816e9164b17bb3e7154a511b0c9896ffdbDmitri Gribenko  template void scalar_<int>(int);
90abd56c816e9164b17bb3e7154a511b0c9896ffdbDmitri Gribenko}
91abd56c816e9164b17bb3e7154a511b0c9896ffdbDmitri Gribenko
92abd56c816e9164b17bb3e7154a511b0c9896ffdbDmitri Gribenkonamespace test1 {
93abd56c816e9164b17bb3e7154a511b0c9896ffdbDmitri Gribenko  short foo(short);
94abd56c816e9164b17bb3e7154a511b0c9896ffdbDmitri Gribenko  int foo(int);
95abd56c816e9164b17bb3e7154a511b0c9896ffdbDmitri Gribenko
96abd56c816e9164b17bb3e7154a511b0c9896ffdbDmitri Gribenko  // CHECK-LABEL: define linkonce_odr signext i16 @_ZN5test11aIsEEDTcl3foocvT__EEES1_(
9796b098674908eaa59a9128f3305cda6fbbdad563Dmitri Gribenko  template <class T> auto a(T t) -> decltype(foo(T())) { return foo(t); }
98c27bc80a98b9558513b50956c930eedc9e461ae0Dmitri Gribenko
99c27bc80a98b9558513b50956c930eedc9e461ae0Dmitri Gribenko  // CHECK-LABEL: define linkonce_odr signext i16 @_ZN5test11bIsEEDTcp3foocvT__EEES1_(
100abd56c816e9164b17bb3e7154a511b0c9896ffdbDmitri Gribenko  template <class T> auto b(T t) -> decltype((foo)(T())) { return (foo)(t); }
101abd56c816e9164b17bb3e7154a511b0c9896ffdbDmitri Gribenko
102abd56c816e9164b17bb3e7154a511b0c9896ffdbDmitri Gribenko  void test(short s) {
103abd56c816e9164b17bb3e7154a511b0c9896ffdbDmitri Gribenko    a(s);
104aa0cd85838f2a024e589ea4e8c2094130065af21Dmitri Gribenko    b(s);
105aa0cd85838f2a024e589ea4e8c2094130065af21Dmitri Gribenko  }
106aa0cd85838f2a024e589ea4e8c2094130065af21Dmitri Gribenko}
107aa0cd85838f2a024e589ea4e8c2094130065af21Dmitri Gribenko
108aa0cd85838f2a024e589ea4e8c2094130065af21Dmitri Gribenkonamespace test2 {
109aa0cd85838f2a024e589ea4e8c2094130065af21Dmitri Gribenko  template <class T> void a(T x, decltype(x()) y) {}
110a444f1856459130bd3a1bb8995331c9e367db04fDmitri Gribenko  template <class T> auto b(T x) -> decltype(x()) { return x(); }
111a444f1856459130bd3a1bb8995331c9e367db04fDmitri Gribenko  template <class T> void c(T x, void (*p)(decltype(x()))) {}
112a444f1856459130bd3a1bb8995331c9e367db04fDmitri Gribenko  template <class T> void d(T x, auto (*p)() -> decltype(x())) {}
113a444f1856459130bd3a1bb8995331c9e367db04fDmitri Gribenko  template <class T> void e(auto (*p)(T y) -> decltype(y())) {}
114a444f1856459130bd3a1bb8995331c9e367db04fDmitri Gribenko  template <class T> void f(void (*p)(T x, decltype(x()) y)) {}
115a444f1856459130bd3a1bb8995331c9e367db04fDmitri Gribenko  template <class T> void g(T x, decltype(x()) y) {
116a444f1856459130bd3a1bb8995331c9e367db04fDmitri Gribenko    static decltype(x()) variable;
117a444f1856459130bd3a1bb8995331c9e367db04fDmitri Gribenko    variable = 0;
118a444f1856459130bd3a1bb8995331c9e367db04fDmitri Gribenko  }
119a444f1856459130bd3a1bb8995331c9e367db04fDmitri Gribenko  template <class T> void h(T x, decltype((decltype(x())(*)()) 0) y) {}
120a444f1856459130bd3a1bb8995331c9e367db04fDmitri Gribenko  template <class T> void i(decltype((auto (*)(T x) -> decltype(x())) 0) y) {}
121a444f1856459130bd3a1bb8995331c9e367db04fDmitri Gribenko
122a444f1856459130bd3a1bb8995331c9e367db04fDmitri Gribenko  float foo();
123a444f1856459130bd3a1bb8995331c9e367db04fDmitri Gribenko  void bar(float);
124a444f1856459130bd3a1bb8995331c9e367db04fDmitri Gribenko  float baz(float(*)());
125a444f1856459130bd3a1bb8995331c9e367db04fDmitri Gribenko  void fred(float(*)(), float);
126a444f1856459130bd3a1bb8995331c9e367db04fDmitri Gribenko
127a444f1856459130bd3a1bb8995331c9e367db04fDmitri Gribenko  // CHECK-LABEL: define void @_ZN5test211instantiateEv
128a444f1856459130bd3a1bb8995331c9e367db04fDmitri Gribenko  void instantiate() {
129a444f1856459130bd3a1bb8995331c9e367db04fDmitri Gribenko    // CHECK: call void @_ZN5test21aIPFfvEEEvT_DTclfL0p_EE(
130a444f1856459130bd3a1bb8995331c9e367db04fDmitri Gribenko    a(foo, 0.0f);
131a444f1856459130bd3a1bb8995331c9e367db04fDmitri Gribenko    // CHECK: call float @_ZN5test21bIPFfvEEEDTclfp_EET_(
132a444f1856459130bd3a1bb8995331c9e367db04fDmitri Gribenko    (void) b(foo);
133a444f1856459130bd3a1bb8995331c9e367db04fDmitri Gribenko    // CHECK: call void @_ZN5test21cIPFfvEEEvT_PFvDTclfL1p_EEE(
134aa0cd85838f2a024e589ea4e8c2094130065af21Dmitri Gribenko    c(foo, bar);
135aa0cd85838f2a024e589ea4e8c2094130065af21Dmitri Gribenko    // CHECK: call void @_ZN5test21dIPFfvEEEvT_PFDTclfL0p_EEvE(
136aa0cd85838f2a024e589ea4e8c2094130065af21Dmitri Gribenko    d(foo, foo);
137aa0cd85838f2a024e589ea4e8c2094130065af21Dmitri Gribenko    // CHECK: call void @_ZN5test21eIPFfvEEEvPFDTclfp_EET_E(
138aa0cd85838f2a024e589ea4e8c2094130065af21Dmitri Gribenko    e(baz);
139aa0cd85838f2a024e589ea4e8c2094130065af21Dmitri Gribenko    // CHECK: call void @_ZN5test21fIPFfvEEEvPFvT_DTclfL0p_EEE(
140aa0cd85838f2a024e589ea4e8c2094130065af21Dmitri Gribenko    f(fred);
141811c820257746b1799b790b6adc7804f44154011Dmitri Gribenko    // CHECK: call void @_ZN5test21gIPFfvEEEvT_DTclfL0p_EE(
1429c00676f2393335dc60c61faf944d4f8f622fac6Dmitri Gribenko    g(foo, 0.0f);
143aa0cd85838f2a024e589ea4e8c2094130065af21Dmitri Gribenko    // CHECK: call void @_ZN5test21hIPFfvEEEvT_DTcvPFDTclfL0p_EEvELi0EE(
144811c820257746b1799b790b6adc7804f44154011Dmitri Gribenko    h(foo, foo);
145aa0cd85838f2a024e589ea4e8c2094130065af21Dmitri Gribenko    // CHECK: call void @_ZN5test21iIPFfvEEEvDTcvPFDTclfp_EET_ELi0EE(
146aa0cd85838f2a024e589ea4e8c2094130065af21Dmitri Gribenko    i<float(*)()>(baz);
147aa0cd85838f2a024e589ea4e8c2094130065af21Dmitri Gribenko  }
148aa0cd85838f2a024e589ea4e8c2094130065af21Dmitri Gribenko
149aa0cd85838f2a024e589ea4e8c2094130065af21Dmitri Gribenko  // CHECK: store float {{.*}}, float* @_ZZN5test21gIPFfvEEEvT_DTclfL0p_EEE8variable,
150aa0cd85838f2a024e589ea4e8c2094130065af21Dmitri Gribenko}
151811c820257746b1799b790b6adc7804f44154011Dmitri Gribenko
152aa0cd85838f2a024e589ea4e8c2094130065af21Dmitri Gribenkonamespace test3 {
153aa0cd85838f2a024e589ea4e8c2094130065af21Dmitri Gribenko  template <class T, class U> void a(T x, U y, decltype(x.*y) z) {}
154aa0cd85838f2a024e589ea4e8c2094130065af21Dmitri Gribenko
155aa0cd85838f2a024e589ea4e8c2094130065af21Dmitri Gribenko  struct X {
156aa0cd85838f2a024e589ea4e8c2094130065af21Dmitri Gribenko    int *member;
157aa0cd85838f2a024e589ea4e8c2094130065af21Dmitri Gribenko  };
158aa0cd85838f2a024e589ea4e8c2094130065af21Dmitri Gribenko
159aa0cd85838f2a024e589ea4e8c2094130065af21Dmitri Gribenko  // CHECK-LABEL: define void @_ZN5test311instantiateEv
160aa0cd85838f2a024e589ea4e8c2094130065af21Dmitri Gribenko  void instantiate() {
161aa0cd85838f2a024e589ea4e8c2094130065af21Dmitri Gribenko    X x;
162811c820257746b1799b790b6adc7804f44154011Dmitri Gribenko    int *ip;
163aa0cd85838f2a024e589ea4e8c2094130065af21Dmitri Gribenko    // CHECK: call void @_ZN5test31aINS_1XEMS1_PiEEvT_T0_DTdsfL0p_fL0p0_E
164aa0cd85838f2a024e589ea4e8c2094130065af21Dmitri Gribenko    a(x, &X::member, ip);
165aa0cd85838f2a024e589ea4e8c2094130065af21Dmitri Gribenko  }
166aa0cd85838f2a024e589ea4e8c2094130065af21Dmitri Gribenko}
167811c820257746b1799b790b6adc7804f44154011Dmitri Gribenko
168aa0cd85838f2a024e589ea4e8c2094130065af21Dmitri Gribenkonamespace test4 {
169aa0cd85838f2a024e589ea4e8c2094130065af21Dmitri Gribenko  struct X {
170aa0cd85838f2a024e589ea4e8c2094130065af21Dmitri Gribenko    X(int);
171aa0cd85838f2a024e589ea4e8c2094130065af21Dmitri Gribenko  };
172aa0cd85838f2a024e589ea4e8c2094130065af21Dmitri Gribenko
173aa0cd85838f2a024e589ea4e8c2094130065af21Dmitri Gribenko  template <typename T>
174aa0cd85838f2a024e589ea4e8c2094130065af21Dmitri Gribenko  void tf1(decltype(new T(1)) p)
175aa0cd85838f2a024e589ea4e8c2094130065af21Dmitri Gribenko  {}
176aa0cd85838f2a024e589ea4e8c2094130065af21Dmitri Gribenko
177aa0cd85838f2a024e589ea4e8c2094130065af21Dmitri Gribenko  template <typename T>
178aa0cd85838f2a024e589ea4e8c2094130065af21Dmitri Gribenko  void tf2(decltype(new T({1})) p)
179aa0cd85838f2a024e589ea4e8c2094130065af21Dmitri Gribenko  {}
180aa0cd85838f2a024e589ea4e8c2094130065af21Dmitri Gribenko
181aa0cd85838f2a024e589ea4e8c2094130065af21Dmitri Gribenko  template <typename T>
182aa0cd85838f2a024e589ea4e8c2094130065af21Dmitri Gribenko  void tf3(decltype(new T{1}) p)
183aa0cd85838f2a024e589ea4e8c2094130065af21Dmitri Gribenko  {}
184aa0cd85838f2a024e589ea4e8c2094130065af21Dmitri Gribenko
1858bdb58a7835a9a90dd9b9791fccf269cbc1dcef3Dmitri Gribenko  // CHECK: void @_ZN5test43tf1INS_1XEEEvDTnw_T_piLi1EEE
1868bdb58a7835a9a90dd9b9791fccf269cbc1dcef3Dmitri Gribenko  template void tf1<X>(X*);
187abd56c816e9164b17bb3e7154a511b0c9896ffdbDmitri Gribenko
188aa0cd85838f2a024e589ea4e8c2094130065af21Dmitri Gribenko  // CHECK: void @_ZN5test43tf2INS_1XEEEvDTnw_T_piilLi1EEEE
189aa0cd85838f2a024e589ea4e8c2094130065af21Dmitri Gribenko  template void tf2<X>(X*);
190811c820257746b1799b790b6adc7804f44154011Dmitri Gribenko
191aa0cd85838f2a024e589ea4e8c2094130065af21Dmitri Gribenko  // CHECK: void @_ZN5test43tf3INS_1XEEEvDTnw_T_ilLi1EEE
192aa0cd85838f2a024e589ea4e8c2094130065af21Dmitri Gribenko  template void tf3<X>(X*);
193aa0cd85838f2a024e589ea4e8c2094130065af21Dmitri Gribenko
194aa0cd85838f2a024e589ea4e8c2094130065af21Dmitri Gribenko}
195aa0cd85838f2a024e589ea4e8c2094130065af21Dmitri Gribenko
1968d3ba23f2d9e6c87794d059412a0808c9cbacb25Dmitri Gribenkonamespace test5 {
197aa0cd85838f2a024e589ea4e8c2094130065af21Dmitri Gribenko  template <typename T> void a(decltype(noexcept(T()))) {}
1988d3ba23f2d9e6c87794d059412a0808c9cbacb25Dmitri Gribenko  template void a<int>(decltype(noexcept(int())));
1998d3ba23f2d9e6c87794d059412a0808c9cbacb25Dmitri Gribenko  // CHECK: void @_ZN5test51aIiEEvDTnxcvT__EE(
2008d3ba23f2d9e6c87794d059412a0808c9cbacb25Dmitri Gribenko}
2018d3ba23f2d9e6c87794d059412a0808c9cbacb25Dmitri Gribenko