1 // RUN: %clang_cc1 -fsyntax-only -verify %s
7 template<typename T
> friend struct Y
;
12 template<typename T
> struct Y
{};
17 template<typename T
> void f1(T
) { } // expected-note{{here}}
20 template<typename T
> friend void f0(T
);
21 template<typename T
> friend void f1(T
);
24 template<typename T
> void f0(T
) { }
25 template<typename T
> void f1(T
) { } // expected-error{{redefinition}}
30 template<typename T
> struct X0
{
31 template<typename U
> friend struct X0
;
34 template<typename T
> struct X0
<T
*> {
35 template<typename U
> friend struct X0
;
38 template<> struct X0
<int> {
39 template<typename U
> friend struct X0
;
42 template<typename T
> struct X1
{
43 template<typename U
> friend void f2(U
);
44 template<typename U
> friend void f3(U
);
47 template<typename U
> void f2(U
);
52 template<> void f2(int);
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
);
58 template<> void f3(int);
63 template <typename T
> class Foo
{
70 template<typename T
, T Value
> struct X2a
;
72 template<typename T
, int Size
> struct X2b
;
76 template<typename U
, U Value
> friend struct X2a
;
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}}
86 X3
<long> x3l
; // expected-note {{in instantiation}}
91 template<typename
> struct A
{
92 template<typename T
> friend void 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}}
100 f(A
<int>()); // expected-note {{in instantiation of function template specialization}}
107 template <typename T
> friend struct cache
;
110 template <typename T
> friend struct cache
;
116 template <class T1
, class T2
, class T3
> class A
;
119 template<class T1
, class T2
, class T3
, class T
>
120 A
<T1
, T2
, T3
>& f0(A
<T1
, T2
, T3
>&, T
);
123 template<class T1
, class T2
, class T3
>
125 template<class U1
, class U2
, class U3
, class T
>
126 friend A
<U1
, U2
, U3
>& inner::f0(A
<U1
, U2
, U3
>&, T
);
130 namespace FriendTemplateDefinition
{
131 template<unsigned > struct int_c
{ };
136 friend void f(X
, int_c
<N
>) {
141 void test_X(X
<int> x
, int_c
<5> i5
) {
147 template<class > struct X0
151 template<typename
> struct X1
154 template<typename
, typename T
> struct X2
160 template <typename
= int, typename
= X1
<int> > struct X3
162 template <typename T1
, typename T2
, typename B
> friend void op(X2
<T1
, T2
>& , B
);
164 template <typename Ch
, typename Tr
, typename B
> void op(X2
<Ch
, Tr
>& , B
)
171 X2
<int, X0
<int> > ngs
;
179 template<class > struct X0
183 template<typename
> struct X1
186 template<typename
, typename T
> struct X2
192 template <typename
= X1
<int> > struct X3
194 template <typename T1
, typename T2
, typename B
> friend void op(X2
<T1
, T2
>& , B
);
196 template <typename Ch
, typename Tr
, typename B
> void op(X2
<Ch
, Tr
>& , B
)
203 X2
<int, X0
<int> > ngs
;
212 template<typename T
, typename U
, unsigned N
>
214 template<unsigned M
> friend class X
<T
, U
, M
>; // expected-error{{partial specialization cannot be declared as a friend}}
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}}
225 template struct S
<int>;
230 template <> friend class B
; // expected-error{{extraneous 'template<>' in declaration of class 'B'}}
234 namespace rdar11147355
{
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}}
240 int n
; // expected-note {{here}}
243 template <class S
> template <class U
> class A
<S
>::B
{
245 // FIXME: This should be permitted.
246 int f(A
<S
*> a
) { return a
.n
; } // expected-error {{private}}
249 A
<double>::B
<double> ab
;
251 int k
= ab
.f(a
); // expected-note {{instantiation of}}
254 namespace RedeclUnrelated
{
257 template<typename
> class future
{
258 template<typename
> friend class packaged_task
;
268 template <typename Foo_
>
270 typedef Foo_ Foo
; // expected-note {{previous}}
272 template <typename
> friend struct Foo
; // expected-error {{redefinition of 'Foo' as different kind of symbol}}
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'}}
286 template<typename
> struct D
;
288 template<typename
> class E
{
290 template<typename
> friend struct C::D
;
292 template<typename T
> struct C::D
{
297 int n
= C::D
<void*>().f();
300 template<int> struct G
;
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}}
310 H
<char> h2
; // expected-note {{instantiation}}
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
317 namespace rdar12350696
{
318 template <class T
> struct 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}}
329 foo(b
); // expected-note {{in instantiation}}
333 namespace StackUseAfterScope
{
334 template <typename T
> class Bar
{};
336 // Make sure this doesn't crash.
337 template <> friend class Bar
<int>; // expected-error {{template specialization declaration cannot be a friend}}