1 // RUN: %clang_cc1 -fsyntax-only %s
2 typedef char one_byte;
3 typedef char (&two_bytes)[2];
4 typedef char (&four_bytes)[4];
5 typedef char (&eight_bytes)[8];
6 
7 template<int N> struct A { };
8 
9 namespace N1 {
10   struct X { };
11 }
12 
13 namespace N2 {
14   struct Y { };
15 
16   two_bytes operator+(Y, Y);
17 }
18 
19 namespace N3 {
20   struct Z { };
21 
22   eight_bytes operator+(Z, Z);
23 }
24 
25 namespace 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 
34 namespace N1 {
35   four_bytes operator+(X, X);
36 }
37 
38 namespace N3 {
39   eight_bytes operator+(Z, Z); // redeclaration
40 }
41 
42 void 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 
53 namespace N3 {
54   eight_bytes operator-(::N3::Z);
55 }
56 
57 namespace N4 {
58   template<typename T>
59   struct UnaryOpOverload {
60     typedef A<sizeof(-T())> type;
61   };
62 }
63 
64 void test_unary_op_overload(A<8> *a8) {
65   typedef N4::UnaryOpOverload<N3::Z>::type UZ;
66   UZ *uz = a8;
67 }
68 
69 /*
70 namespace 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 
86 namespace 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 
106 namespace 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 
123 template<typename T, unsigned long N> struct IntegralConstant { };
124 
125 template<typename T>
126 struct X0 {
127   void f(T x, IntegralConstant<T, sizeof(x)>);
128 };
129 
130 void test_X0(X0<int> x, IntegralConstant<int, sizeof(int)> ic) {
131   x.f(5,ic);
132 }
133 
134 namespace 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 
150 namespace 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 
164 namespace 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 
182 namespace 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 
197 namespace 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 
228 namespace 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