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 {
f1(T)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 
f0(T)24   template<typename T> void f0(T) { }
f1(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 
f(const A<T> &)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 
f()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>
f(X,int_c<N>)136     friend void f(X, int_c<N>) {
137       int value = N;
138     };
139   };
140 
test_X(X<int> x,int_c<5> i5)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     };
op(X2<Ch,Tr> &,B)164     template <typename Ch, typename Tr, typename B> void op(X2<Ch, Tr>& , B)
165     {
166       X2<int, Tr> s;
167     }
168   }
n()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     };
op(X2<Ch,Tr> &,B)196     template <typename Ch, typename Tr, typename B> void op(X2<Ch, Tr>& , B)
197     {
198       X2<int, Tr> s;
199     }
200   }
n()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.
f(A<S * > a)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 {
fPR12585::C::D293     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 {
foordar12350696::A319     void foo() {
320       A<int> a;
321     }
foo(const A<U> & a)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 
test()327   void test() {
328     A<int> b;
329     foo(b); // expected-note {{in instantiation}}
330   }
331 }
332