1// RUN: %clang_cc1 -fsyntax-only %s
2typedef char one_byte;
3typedef char (&two_bytes)[2];
4typedef char (&four_bytes)[4];
5typedef char (&eight_bytes)[8];
6
7template<int N> struct A { };
8
9namespace N1 {
10  struct X { };
11}
12
13namespace N2 {
14  struct Y { };
15
16  two_bytes operator+(Y, Y);
17}
18
19namespace N3 {
20  struct Z { };
21
22  eight_bytes operator+(Z, Z);
23}
24
25namespace N4 {
26  one_byte operator+(N1::X, N2::Y);
27
28  template<typename T, typename U>
29  struct BinOpOverload {
30    typedef A<sizeof(T() + U())> type;
31  };
32}
33
34namespace N1 {
35  four_bytes operator+(X, X);
36}
37
38namespace N3 {
39  eight_bytes operator+(Z, Z); // redeclaration
40}
41
42void test_bin_op_overload(A<1> *a1, A<2> *a2, A<4> *a4, A<8> *a8) {
43  typedef N4::BinOpOverload<N1::X, N2::Y>::type XY;
44  XY *xy = a1;
45  typedef N4::BinOpOverload<N1::X, N1::X>::type XX;
46  XX *xx = a4;
47  typedef N4::BinOpOverload<N2::Y, N2::Y>::type YY;
48  YY *yy = a2;
49  typedef N4::BinOpOverload<N3::Z, N3::Z>::type ZZ;
50  ZZ *zz = a8;
51}
52
53namespace N3 {
54  eight_bytes operator-(::N3::Z);
55}
56
57namespace N4 {
58  template<typename T>
59  struct UnaryOpOverload {
60    typedef A<sizeof(-T())> type;
61  };
62}
63
64void test_unary_op_overload(A<8> *a8) {
65  typedef N4::UnaryOpOverload<N3::Z>::type UZ;
66  UZ *uz = a8;
67}
68
69/*
70namespace N5 {
71  template<int I>
72  struct Lookup {
73    enum { val = I, more = val + 1 };
74  };
75
76  template<bool B>
77  struct Cond {
78    enum Junk { is = B ? Lookup<B>::more : Lookup<Lookup<B+1>::more>::val };
79  };
80
81  enum { resultT = Cond<true>::is,
82         resultF = Cond<false>::is };
83}
84*/
85
86namespace N6 {
87  // non-typedependent
88  template<int I>
89  struct Lookup {};
90
91  template<bool B, typename T, typename E>
92  struct Cond {
93    typedef Lookup<B ? sizeof(T) : sizeof(E)> True;
94    typedef Lookup<!B ? sizeof(T) : sizeof(E)> False;
95  };
96
97  typedef Cond<true, int, char>::True True;
98  typedef Cond<true, int, char>::False False;
99
100  // check that we have the right types
101  Lookup<1> const &L1(False());
102  Lookup<sizeof(int)> const &L2(True());
103}
104
105
106namespace N7 {
107  // type dependent
108  template<int I>
109  struct Lookup {};
110
111  template<bool B, typename T, typename E>
112  struct Cond {
113    T foo() { return B ? T() : E(); }
114    typedef Lookup<sizeof(B ? T() : E())> Type;
115  };
116
117  //Cond<true, int*, double> C; // Errors
118  //int V(C.foo()); // Errors
119  //typedef Cond<true, int*, double>::Type Type; // Errors
120  typedef Cond<true, int, double>::Type Type;
121}
122
123template<typename T, unsigned long N> struct IntegralConstant { };
124
125template<typename T>
126struct X0 {
127  void f(T x, IntegralConstant<T, sizeof(x)>);
128};
129
130void test_X0(X0<int> x, IntegralConstant<int, sizeof(int)> ic) {
131  x.f(5,ic);
132}
133
134namespace N8 {
135  struct X {
136    X operator+(const X&) const;
137  };
138
139  template<typename T>
140  T test_plus(const T* xp, const T& x, const T& y) {
141    x.operator+(y);
142    return xp->operator+(y);
143  }
144
145  void test_test_plus(X x) {
146    test_plus(&x, x, x);
147  }
148}
149
150namespace N9 {
151  struct A {
152    bool operator==(int value);
153  };
154
155  template<typename T> struct B {
156    bool f(A a) {
157      return a == 1;
158    }
159  };
160
161  template struct B<int>;
162}
163
164namespace N10 {
165  template <typename T>
166  class A {
167    struct X { };
168
169  public:
170    ~A() {
171      f(reinterpret_cast<X *>(0), reinterpret_cast<X *>(0));
172    }
173
174  private:
175    void f(X *);
176    void f(X *, X *);
177  };
178
179  template class A<int>;
180}
181
182namespace N12 {
183  // PR5224
184  template<typename T>
185  struct A { typedef int t0; };
186
187  struct C  {
188    C(int);
189
190    template<typename T>
191    static C *f0(T a0) {return new C((typename A<T>::t0) 1);   }
192  };
193
194  void f0(int **a) { C::f0(a); }
195}
196
197namespace PR7202 {
198  template<typename U, typename T>
199  struct meta {
200    typedef T type;
201  };
202
203  struct X {
204    struct dummy;
205
206    template<typename T>
207    X(T, typename meta<T, dummy*>::type = 0);
208
209    template<typename T, typename A>
210    X(T, A);
211  };
212
213  template<typename T>
214  struct Z { };
215
216  template<typename T> Z<T> g(T);
217
218  struct Y {
219    template<typename T>
220    void f(T t) {
221      new X(g(*this));
222    }
223  };
224
225  template void Y::f(int);
226}
227
228namespace N13 {
229  class A{
230    A(const A&);
231
232  public:
233    ~A();
234    A(int);
235    template<typename T> A &operator<<(const T&);
236  };
237
238  template<typename T>
239  void f(T t) {
240    A(17) << t;
241  }
242
243  template void f(int);
244
245}
246