friend-template.cpp revision ce6426feda94ca716ee7743b71961850740eb08d
1// RUN: %clang_cc1 -fsyntax-only -verify %s
2// PR5057
3namespace 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
16namespace 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
29namespace 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
62namespace 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
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>&) {
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
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}
113
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
130namespace 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
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}
210
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}
219
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}
227
228namespace PR10660 {
229  struct A {
230    template <> friend class B; // expected-error{{extraneous 'template<>' in declaration of class 'B'}}
231  };
232}
233
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; // 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
254namespace 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
264namespace 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
278namespace 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.
317namespace 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