// RUN: %clang_cc1 -fsyntax-only -verify %s // PR5057 namespace test0 { namespace std { class X { public: template<typename T> friend struct Y; }; } namespace std { template<typename T> struct Y {}; } } namespace test1 { template<typename T> void f1(T) { } // expected-note{{here}} class X { template<typename T> friend void f0(T); template<typename T> friend void f1(T); }; template<typename T> void f0(T) { } template<typename T> void f1(T) { } // expected-error{{redefinition}} } // PR4768 namespace test2 { template<typename T> struct X0 { template<typename U> friend struct X0; }; template<typename T> struct X0<T*> { template<typename U> friend struct X0; }; template<> struct X0<int> { template<typename U> friend struct X0; }; template<typename T> struct X1 { template<typename U> friend void f2(U); template<typename U> friend void f3(U); }; template<typename U> void f2(U); X1<int> x1i; X0<int*> x0ip; template<> void f2(int); // FIXME: Should this declaration of f3 be required for the specialization of // f3<int> (further below) to work? GCC and EDG don't require it, we do... template<typename U> void f3(U); template<> void f3(int); } // PR5332 namespace test3 { template <typename T> class Foo { template <typename U> friend class Foo; }; Foo<int> foo; template<typename T, T Value> struct X2a; template<typename T, int Size> struct X2b; template<typename T> class X3 { template<typename U, U Value> friend struct X2a; // FIXME: the redeclaration note ends up here because redeclaration // lookup ends up finding the friend target from X3<int>. template<typename U, T Value> friend struct X2b; // expected-error {{template non-type parameter has a different type 'long' in template redeclaration}} \ // expected-note {{previous non-type template parameter with type 'int' is here}} }; X3<int> x3i; // okay X3<long> x3l; // expected-note {{in instantiation}} } // PR5716 namespace test4 { template<typename> struct A { template<typename T> friend void f(const A<T>&); }; template<typename T> void f(const A<T>&) { int a[sizeof(T) ? -1 : -1]; // expected-error {{array with a negative size}} } void f() { f(A<int>()); // expected-note {{in instantiation of function template specialization}} } } namespace test5 { class outer { class foo; template <typename T> friend struct cache; }; class outer::foo { template <typename T> friend struct cache; }; } // PR6022 namespace PR6022 { template <class T1, class T2 , class T3 > class A; namespace inner { template<class T1, class T2, class T3, class T> A<T1, T2, T3>& f0(A<T1, T2, T3>&, T); } template<class T1, class T2, class T3> class A { template<class U1, class U2, class U3, class T> friend A<U1, U2, U3>& inner::f0(A<U1, U2, U3>&, T); }; } namespace FriendTemplateDefinition { template<unsigned > struct int_c { }; template<typename T> struct X { template<unsigned N> friend void f(X, int_c<N>) { int value = N; }; }; void test_X(X<int> x, int_c<5> i5) { f(x, i5); } } namespace PR7013a { template<class > struct X0 { typedef int type; }; template<typename > struct X1 { }; template<typename , typename T> struct X2 { typename T::type e; }; namespace N { template <typename = int, typename = X1<int> > struct X3 { template <typename T1, typename T2, typename B> friend void op(X2<T1, T2>& , B); }; template <typename Ch, typename Tr, typename B> void op(X2<Ch, Tr>& , B) { X2<int, Tr> s; } } int n() { X2<int, X0<int> > ngs; N::X3<> b; op(ngs, b); return 0; } } namespace PR7013b { template<class > struct X0 { typedef int type; }; template<typename > struct X1 { }; template<typename , typename T> struct X2 { typename T::type e; }; namespace N { template <typename = X1<int> > struct X3 { template <typename T1, typename T2, typename B> friend void op(X2<T1, T2>& , B); }; template <typename Ch, typename Tr, typename B> void op(X2<Ch, Tr>& , B) { X2<int, Tr> s; } } int n() { X2<int, X0<int> > ngs; N::X3<> b; op(ngs, b); return 0; } } namespace PR8649 { template<typename T, typename U, unsigned N> struct X { template<unsigned M> friend class X<T, U, M>; // expected-error{{partial specialization cannot be declared as a friend}} }; X<int, float, 7> x; } // Don't crash, and error on invalid friend type template. namespace friend_type_template_no_tag { template <typename T> struct S { template <typename U> friend S<U>; // expected-error{{friend type templates must use an elaborated type}} }; template struct S<int>; } namespace PR10660 { struct A { template <> friend class B; // expected-error{{extraneous 'template<>' in declaration of class 'B'}} }; } namespace rdar11147355 { template <class T> struct A { template <class U> class B; 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}} private: int n; // expected-note {{here}} }; template <class S> template <class U> class A<S>::B { public: // FIXME: This should be permitted. int f(A<S*> a) { return a.n; } // expected-error {{private}} }; A<double>::B<double> ab; A<double*> a; int k = ab.f(a); // expected-note {{instantiation of}} } namespace RedeclUnrelated { struct S { int packaged_task; template<typename> class future { template<typename> friend class packaged_task; }; future<void> share; }; } namespace PR12557 { template <typename> struct Foo; template <typename Foo_> struct Bar { typedef Foo_ Foo; // expected-note {{previous}} template <typename> friend struct Foo; // expected-error {{redefinition of 'Foo' as different kind of symbol}} }; Bar<int> b; } namespace PR12585 { struct A { }; template<typename> struct B { template<typename> friend class A::does_not_exist; // \ // expected-error {{friend declaration of 'does_not_exist' does not match any declaration in 'PR12585::A'}} }; struct C { template<typename> struct D; }; template<typename> class E { int n; template<typename> friend struct C::D; }; template<typename T> struct C::D { int f() { return E<int>().n; } }; int n = C::D<void*>().f(); struct F { template<int> struct G; }; template<typename T> struct H { // FIXME: As with cases above, the note here is on an unhelpful declaration, // and should point to the declaration of G within F. template<T> friend struct F::G; // \ // expected-error {{different type 'char' in template redeclaration}} \ // expected-note {{previous}} }; H<int> h1; // ok H<char> h2; // expected-note {{instantiation}} } // Ensure that we can still instantiate a friend function template // after the friend declaration is instantiated during the delayed // parsing of a member function, but before the friend function has // been parsed. namespace rdar12350696 { template <class T> struct A { void foo() { A<int> a; } template <class U> friend void foo(const A<U> & a) { int array[sizeof(T) == sizeof(U) ? -1 : 1]; // expected-error {{negative size}} } }; void test() { A<int> b; foo(b); // expected-note {{in instantiation}} } }