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
test_bin_op_overload(A<1> * a1,A<2> * a2,A<4> * a4,A<8> * a8)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
test_unary_op_overload(A<8> * a8)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 {
fooN7::Cond113 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
test_X0(X0<int> x,IntegralConstant<int,sizeof (int)> ic)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>
test_plus(const T * xp,const T & x,const T & y)140 T test_plus(const T* xp, const T& x, const T& y) {
141 x.operator+(y);
142 return xp->operator+(y);
143 }
144
test_test_plus(X x)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 {
fN9::B156 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:
~A()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>
f0N12::C191 static C *f0(T a0) {return new C((typename A<T>::t0) 1); }
192 };
193
f0(int ** a)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>
fPR7202::Y220 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>
f(T t)239 void f(T t) {
240 A(17) << t;
241 }
242
243 template void f(int);
244
245 }
246