blob: 8a478777eb7e9a0047ff8ebe9254350dd119deec [file] [log] [blame]
Daniel Dunbara5728872009-12-15 20:14:24 +00001// RUN: %clang_cc1 -fsyntax-only -verify %s
Douglas Gregord85bea22009-09-26 06:47:28 +00002// PR5057
John McCall4b6e90a2009-12-11 20:51:23 +00003namespace 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 }
Douglas Gregord85bea22009-09-26 06:47:28 +000014}
15
John McCall4b6e90a2009-12-11 20:51:23 +000016namespace test1 {
Douglas Gregor182ddf02009-09-28 00:08:27 +000017 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}
Douglas Gregord7e5bdb2009-10-09 21:11:42 +000027
28// PR4768
John McCall4b6e90a2009-12-11 20:51:23 +000029namespace 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 };
Douglas Gregord7e5bdb2009-10-09 21:11:42 +000037
John McCall4b6e90a2009-12-11 20:51:23 +000038 template<> struct X0<int> {
39 template<typename U> friend struct X0;
40 };
Douglas Gregord7e5bdb2009-10-09 21:11:42 +000041
John McCall4b6e90a2009-12-11 20:51:23 +000042 template<typename T> struct X1 {
43 template<typename U> friend void f2(U);
44 template<typename U> friend void f3(U);
45 };
Douglas Gregora735b202009-10-13 14:39:41 +000046
John McCall4b6e90a2009-12-11 20:51:23 +000047 template<typename U> void f2(U);
Douglas Gregora735b202009-10-13 14:39:41 +000048
John McCall4b6e90a2009-12-11 20:51:23 +000049 X1<int> x1i;
50 X0<int*> x0ip;
Douglas Gregora735b202009-10-13 14:39:41 +000051
John McCall4b6e90a2009-12-11 20:51:23 +000052 template<> void f2(int);
Douglas Gregora735b202009-10-13 14:39:41 +000053
John McCall4b6e90a2009-12-11 20:51:23 +000054 // 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);
Douglas Gregora735b202009-10-13 14:39:41 +000057
John McCall4b6e90a2009-12-11 20:51:23 +000058 template<> void f3(int);
59}
Douglas Gregore8c01bd2009-10-30 21:07:27 +000060
61// PR5332
John McCall4b6e90a2009-12-11 20:51:23 +000062namespace test3 {
63 template <typename T> class Foo {
64 template <typename U>
65 friend class Foo;
66 };
Douglas Gregore8c01bd2009-10-30 21:07:27 +000067
John McCall4b6e90a2009-12-11 20:51:23 +000068 Foo<int> foo;
Douglas Gregor259571e2009-10-30 22:42:42 +000069
John McCall4b6e90a2009-12-11 20:51:23 +000070 template<typename T, T Value> struct X2a;
Douglas Gregor259571e2009-10-30 22:42:42 +000071
John McCall4b6e90a2009-12-11 20:51:23 +000072 template<typename T, int Size> struct X2b;
Douglas Gregor259571e2009-10-30 22:42:42 +000073
John McCall4b6e90a2009-12-11 20:51:23 +000074 template<typename T>
75 class X3 {
76 template<typename U, U Value> friend struct X2a;
John McCall93ba8572010-03-25 06:39:04 +000077
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}}
John McCall4b6e90a2009-12-11 20:51:23 +000082 };
Douglas Gregor259571e2009-10-30 22:42:42 +000083
John McCall4b6e90a2009-12-11 20:51:23 +000084 X3<int> x3i; // okay
Douglas Gregor259571e2009-10-30 22:42:42 +000085
John McCall93ba8572010-03-25 06:39:04 +000086 X3<long> x3l; // expected-note {{in instantiation}}
John McCall4b6e90a2009-12-11 20:51:23 +000087}
John McCalle976ffe2009-12-14 23:19:40 +000088
89// PR5716
90namespace 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>&) {
Chandler Carruthb2b5cc02011-01-04 04:44:35 +000096 int a[sizeof(T) ? -1 : -1]; // expected-error {{array with a negative size}}
John McCalle976ffe2009-12-14 23:19:40 +000097 }
98
99 void f() {
100 f(A<int>()); // expected-note {{in instantiation of function template specialization}}
101 }
102}
John McCall65c49462009-12-18 11:25:59 +0000103
104namespace 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}
Douglas Gregor5d52e472010-01-16 18:09:52 +0000113
114// PR6022
115namespace 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
Douglas Gregord4598a22010-04-28 04:52:24 +0000130namespace 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}
Douglas Gregore7089b02010-05-03 23:29:10 +0000145
146namespace 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
178namespace 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}
Douglas Gregorb0ee93c2010-12-21 08:14:57 +0000210
211namespace 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}
Chandler Carruth0f4be742011-05-03 18:35:10 +0000219
220// Don't crash, and error on invalid friend type template.
221namespace 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}
Douglas Gregorba4ee9a2011-10-20 15:58:54 +0000227
228namespace PR10660 {
229 struct A {
230 template <> friend class B; // expected-error{{extraneous 'template<>' in declaration of class 'B'}}
231 };
232}
Douglas Gregor8b0fa522012-03-30 16:20:47 +0000233
234namespace 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;
239 };
240
241 template <class S> template <class U> class A<S>::B {
242 };
243
244 A<double>::B<double> ab;
245}
Richard Smithc93e0142012-04-20 07:12:26 +0000246
247namespace RedeclUnrelated {
248 struct S {
249 int packaged_task;
250 template<typename> class future {
251 template<typename> friend class packaged_task;
252 };
253 future<void> share;
254 };
255}
256
257namespace PR12557 {
258 template <typename>
259 struct Foo;
260
261 template <typename Foo_>
262 struct Bar {
263 typedef Foo_ Foo; // expected-note {{previous}}
264
265 template <typename> friend struct Foo; // expected-error {{redefinition of 'Foo' as different kind of symbol}}
266 };
267
268 Bar<int> b;
269}
Richard Smith6e21b162012-04-22 02:13:50 +0000270
271namespace PR12585 {
272 struct A { };
273 template<typename> struct B {
274 template<typename> friend class A::does_not_exist; // \
275 // expected-error {{friend declaration of 'does_not_exist' does not match any declaration in 'PR12585::A'}}
276 };
277
278 struct C {
279 template<typename> struct D;
280 };
281 template<typename> class E {
282 int n;
283 template<typename> friend struct C::D;
284 };
285 template<typename T> struct C::D {
286 int f() {
287 return E<int>().n;
288 }
289 };
290 int n = C::D<void*>().f();
291
292 struct F {
293 template<int> struct G;
294 };
295 template<typename T> struct H {
296 // FIXME: As with cases above, the note here is on an unhelpful declaration,
297 // and should point to the declaration of G within F.
298 template<T> friend struct F::G; // \
299 // expected-error {{different type 'char' in template redeclaration}} \
300 // expected-note {{previous}}
301 };
302 H<int> h1; // ok
303 H<char> h2; // expected-note {{instantiation}}
304}
John McCalle34db6b2013-03-14 05:13:41 +0000305
306// Ensure that we can still instantiate a friend function template
307// after the friend declaration is instantiated during the delayed
308// parsing of a member function, but before the friend function has
309// been parsed.
310namespace rdar12350696 {
311 template <class T> struct A {
312 void foo() {
313 A<int> a;
314 }
315 template <class U> friend void foo(const A<U> & a) {
316 int array[sizeof(T) == sizeof(U) ? -1 : 1]; // expected-error {{negative size}}
317 }
318 };
319
320 void test() {
321 A<int> b;
322 foo(b); // expected-note {{in instantiation}}
323 }
324}