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 | |