1 | // RUN: %clang_cc1 -fsyntax-only -verify %s |
2 | // PR5057 |
3 | namespace test0 { |
4 | namespace std { |
5 | class X { |
6 | public: |
7 | template<typename T> friend struct Y; |
8 | }; |
9 | } |
10 | |
11 | namespace std { |
12 | template<typename T> struct Y {}; |
13 | } |
14 | } |
15 | |
16 | namespace test1 { |
17 | template<typename T> void f1(T) { } // expected-note{{here}} |
18 | |
19 | class X { |
20 | template<typename T> friend void f0(T); |
21 | template<typename T> friend void f1(T); |
22 | }; |
23 | |
24 | template<typename T> void f0(T) { } |
25 | template<typename T> void f1(T) { } // expected-error{{redefinition}} |
26 | } |
27 | |
28 | // PR4768 |
29 | namespace test2 { |
30 | template<typename T> struct X0 { |
31 | template<typename U> friend struct X0; |
32 | }; |
33 | |
34 | template<typename T> struct X0<T*> { |
35 | template<typename U> friend struct X0; |
36 | }; |
37 | |
38 | template<> struct X0<int> { |
39 | template<typename U> friend struct X0; |
40 | }; |
41 | |
42 | template<typename T> struct X1 { |
43 | template<typename U> friend void f2(U); |
44 | template<typename U> friend void f3(U); |
45 | }; |
46 | |
47 | template<typename U> void f2(U); |
48 | |
49 | X1<int> x1i; |
50 | X0<int*> x0ip; |
51 | |
52 | template<> void f2(int); |
53 | |
54 | // FIXME: Should this declaration of f3 be required for the specialization of |
55 | // f3<int> (further below) to work? GCC and EDG don't require it, we do... |
56 | template<typename U> void f3(U); |
57 | |
58 | template<> void f3(int); |
59 | } |
60 | |
61 | // PR5332 |
62 | namespace test3 { |
63 | template <typename T> class Foo { |
64 | template <typename U> |
65 | friend class Foo; |
66 | }; |
67 | |
68 | Foo<int> foo; |
69 | |
70 | template<typename T, T Value> struct X2a; |
71 | |
72 | template<typename T, int Size> struct X2b; |
73 | |
74 | template<typename T> |
75 | class X3 { |
76 | template<typename U, U Value> friend struct X2a; |
77 | |
78 | // FIXME: the redeclaration note ends up here because redeclaration |
79 | // lookup ends up finding the friend target from X3<int>. |
80 | template<typename U, T Value> friend struct X2b; // expected-error {{template non-type parameter has a different type 'long' in template redeclaration}} \ |
81 | // expected-note {{previous non-type template parameter with type 'int' is here}} |
82 | }; |
83 | |
84 | X3<int> x3i; // okay |
85 | |
86 | X3<long> x3l; // expected-note {{in instantiation}} |
87 | } |
88 | |
89 | // PR5716 |
90 | namespace test4 { |
91 | template<typename> struct A { |
92 | template<typename T> friend void f(const A<T>&); |
93 | }; |
94 | |
95 | template<typename T> void f(const A<T>&) { |
96 | int a[sizeof(T) ? -1 : -1]; // expected-error {{array with a negative size}} |
97 | } |
98 | |
99 | void f() { |
100 | f(A<int>()); // expected-note {{in instantiation of function template specialization}} |
101 | } |
102 | } |
103 | |
104 | namespace test5 { |
105 | class outer { |
106 | class foo; |
107 | template <typename T> friend struct cache; |
108 | }; |
109 | class outer::foo { |
110 | template <typename T> friend struct cache; |
111 | }; |
112 | } |
113 | |
114 | // PR6022 |
115 | namespace PR6022 { |
116 | template <class T1, class T2 , class T3 > class A; |
117 | |
118 | namespace inner { |
119 | template<class T1, class T2, class T3, class T> |
120 | A<T1, T2, T3>& f0(A<T1, T2, T3>&, T); |
121 | } |
122 | |
123 | template<class T1, class T2, class T3> |
124 | class A { |
125 | template<class U1, class U2, class U3, class T> |
126 | friend A<U1, U2, U3>& inner::f0(A<U1, U2, U3>&, T); |
127 | }; |
128 | } |
129 | |
130 | namespace FriendTemplateDefinition { |
131 | template<unsigned > struct int_c { }; |
132 | |
133 | template<typename T> |
134 | struct X { |
135 | template<unsigned N> |
136 | friend void f(X, int_c<N>) { |
137 | int value = N; |
138 | }; |
139 | }; |
140 | |
141 | void test_X(X<int> x, int_c<5> i5) { |
142 | f(x, i5); |
143 | } |
144 | } |
145 | |
146 | namespace PR7013a { |
147 | template<class > struct X0 |
148 | { |
149 | typedef int type; |
150 | }; |
151 | template<typename > struct X1 |
152 | { |
153 | }; |
154 | template<typename , typename T> struct X2 |
155 | { |
156 | typename T::type e; |
157 | }; |
158 | namespace N |
159 | { |
160 | template <typename = int, typename = X1<int> > struct X3 |
161 | { |
162 | template <typename T1, typename T2, typename B> friend void op(X2<T1, T2>& , B); |
163 | }; |
164 | template <typename Ch, typename Tr, typename B> void op(X2<Ch, Tr>& , B) |
165 | { |
166 | X2<int, Tr> s; |
167 | } |
168 | } |
169 | int n() |
170 | { |
171 | X2<int, X0<int> > ngs; |
172 | N::X3<> b; |
173 | op(ngs, b); |
174 | return 0; |
175 | } |
176 | } |
177 | |
178 | namespace PR7013b { |
179 | template<class > struct X0 |
180 | { |
181 | typedef int type; |
182 | }; |
183 | template<typename > struct X1 |
184 | { |
185 | }; |
186 | template<typename , typename T> struct X2 |
187 | { |
188 | typename T::type e; |
189 | }; |
190 | namespace N |
191 | { |
192 | template <typename = X1<int> > struct X3 |
193 | { |
194 | template <typename T1, typename T2, typename B> friend void op(X2<T1, T2>& , B); |
195 | }; |
196 | template <typename Ch, typename Tr, typename B> void op(X2<Ch, Tr>& , B) |
197 | { |
198 | X2<int, Tr> s; |
199 | } |
200 | } |
201 | int n() |
202 | { |
203 | X2<int, X0<int> > ngs; |
204 | N::X3<> b; |
205 | op(ngs, b); |
206 | return 0; |
207 | } |
208 | |
209 | } |
210 | |
211 | namespace PR8649 { |
212 | template<typename T, typename U, unsigned N> |
213 | struct X { |
214 | template<unsigned M> friend class X<T, U, M>; // expected-error{{partial specialization cannot be declared as a friend}} |
215 | }; |
216 | |
217 | X<int, float, 7> x; |
218 | } |
219 | |
220 | // Don't crash, and error on invalid friend type template. |
221 | namespace friend_type_template_no_tag { |
222 | template <typename T> struct S { |
223 | template <typename U> friend S<U>; // expected-error{{friend type templates must use an elaborated type}} |
224 | }; |
225 | template struct S<int>; |
226 | } |
227 | |
228 | namespace PR10660 { |
229 | struct A { |
230 | template <> friend class B; // expected-error{{extraneous 'template<>' in declaration of class 'B'}} |
231 | }; |
232 | } |
233 | |
234 | namespace rdar11147355 { |
235 | template <class T> |
236 | struct A { |
237 | template <class U> class B; |
238 | template <class S> template <class U> friend class A<S>::B; // expected-warning {{dependent nested name specifier 'A<S>::' for friend template declaration is not supported; ignoring this friend declaration}} |
239 | private: |
240 | int n; // expected-note {{here}} |
241 | }; |
242 | |
243 | template <class S> template <class U> class A<S>::B { |
244 | public: |
245 | // FIXME: This should be permitted. |
246 | int f(A<S*> a) { return a.n; } // expected-error {{private}} |
247 | }; |
248 | |
249 | A<double>::B<double> ab; |
250 | A<double*> a; |
251 | int k = ab.f(a); // expected-note {{instantiation of}} |
252 | } |
253 | |
254 | namespace RedeclUnrelated { |
255 | struct S { |
256 | int packaged_task; |
257 | template<typename> class future { |
258 | template<typename> friend class packaged_task; |
259 | }; |
260 | future<void> share; |
261 | }; |
262 | } |
263 | |
264 | namespace PR12557 { |
265 | template <typename> |
266 | struct Foo; |
267 | |
268 | template <typename Foo_> |
269 | struct Bar { |
270 | typedef Foo_ Foo; // expected-note {{previous}} |
271 | |
272 | template <typename> friend struct Foo; // expected-error {{redefinition of 'Foo' as different kind of symbol}} |
273 | }; |
274 | |
275 | Bar<int> b; |
276 | } |
277 | |
278 | namespace PR12585 { |
279 | struct A { }; |
280 | template<typename> struct B { |
281 | template<typename> friend class A::does_not_exist; // \ |
282 | // expected-error {{friend declaration of 'does_not_exist' does not match any declaration in 'PR12585::A'}} |
283 | }; |
284 | |
285 | struct C { |
286 | template<typename> struct D; |
287 | }; |
288 | template<typename> class E { |
289 | int n; |
290 | template<typename> friend struct C::D; |
291 | }; |
292 | template<typename T> struct C::D { |
293 | int f() { |
294 | return E<int>().n; |
295 | } |
296 | }; |
297 | int n = C::D<void*>().f(); |
298 | |
299 | struct F { |
300 | template<int> struct G; |
301 | }; |
302 | template<typename T> struct H { |
303 | // FIXME: As with cases above, the note here is on an unhelpful declaration, |
304 | // and should point to the declaration of G within F. |
305 | template<T> friend struct F::G; // \ |
306 | // expected-error {{different type 'char' in template redeclaration}} \ |
307 | // expected-note {{previous}} |
308 | }; |
309 | H<int> h1; // ok |
310 | H<char> h2; // expected-note {{instantiation}} |
311 | } |
312 | |
313 | // Ensure that we can still instantiate a friend function template |
314 | // after the friend declaration is instantiated during the delayed |
315 | // parsing of a member function, but before the friend function has |
316 | // been parsed. |
317 | namespace rdar12350696 { |
318 | template <class T> struct A { |
319 | void foo() { |
320 | A<int> a; |
321 | } |
322 | template <class U> friend void foo(const A<U> & a) { |
323 | int array[sizeof(T) == sizeof(U) ? -1 : 1]; // expected-error {{negative size}} |
324 | } |
325 | }; |
326 | |
327 | void test() { |
328 | A<int> b; |
329 | foo(b); // expected-note {{in instantiation}} |
330 | } |
331 | } |
332 | |