1a5728872c7702ddd09537c95bc3cbd20e1f2fb09Daniel Dunbar// RUN: %clang_cc1 -fsyntax-only -verify %s
2d85bea2affdd59d83d1be7d24b97f436484c3625Douglas Gregor// PR5057
34b6e90a0dd98b13c2d3ac34ee3eae3954dbb87c6John McCallnamespace test0 {
44b6e90a0dd98b13c2d3ac34ee3eae3954dbb87c6John McCall  namespace std {
54b6e90a0dd98b13c2d3ac34ee3eae3954dbb87c6John McCall    class X {
64b6e90a0dd98b13c2d3ac34ee3eae3954dbb87c6John McCall    public:
74b6e90a0dd98b13c2d3ac34ee3eae3954dbb87c6John McCall      template<typename T> friend struct Y;
84b6e90a0dd98b13c2d3ac34ee3eae3954dbb87c6John McCall    };
94b6e90a0dd98b13c2d3ac34ee3eae3954dbb87c6John McCall  }
104b6e90a0dd98b13c2d3ac34ee3eae3954dbb87c6John McCall
114b6e90a0dd98b13c2d3ac34ee3eae3954dbb87c6John McCall  namespace std {
124b6e90a0dd98b13c2d3ac34ee3eae3954dbb87c6John McCall    template<typename T> struct Y {};
134b6e90a0dd98b13c2d3ac34ee3eae3954dbb87c6John McCall  }
14d85bea2affdd59d83d1be7d24b97f436484c3625Douglas Gregor}
15d85bea2affdd59d83d1be7d24b97f436484c3625Douglas Gregor
164b6e90a0dd98b13c2d3ac34ee3eae3954dbb87c6John McCallnamespace test1 {
17182ddf0e5dc5667e6683a58b483a2e52564f4303Douglas Gregor  template<typename T> void f1(T) { } // expected-note{{here}}
18182ddf0e5dc5667e6683a58b483a2e52564f4303Douglas Gregor
19182ddf0e5dc5667e6683a58b483a2e52564f4303Douglas Gregor  class X {
20182ddf0e5dc5667e6683a58b483a2e52564f4303Douglas Gregor    template<typename T> friend void f0(T);
21182ddf0e5dc5667e6683a58b483a2e52564f4303Douglas Gregor    template<typename T> friend void f1(T);
22182ddf0e5dc5667e6683a58b483a2e52564f4303Douglas Gregor  };
23182ddf0e5dc5667e6683a58b483a2e52564f4303Douglas Gregor
24182ddf0e5dc5667e6683a58b483a2e52564f4303Douglas Gregor  template<typename T> void f0(T) { }
25182ddf0e5dc5667e6683a58b483a2e52564f4303Douglas Gregor  template<typename T> void f1(T) { } // expected-error{{redefinition}}
26182ddf0e5dc5667e6683a58b483a2e52564f4303Douglas Gregor}
27d7e5bdb23c6ba2786cf94788c9af555e2c1276ceDouglas Gregor
28d7e5bdb23c6ba2786cf94788c9af555e2c1276ceDouglas Gregor// PR4768
294b6e90a0dd98b13c2d3ac34ee3eae3954dbb87c6John McCallnamespace test2 {
304b6e90a0dd98b13c2d3ac34ee3eae3954dbb87c6John McCall  template<typename T> struct X0 {
314b6e90a0dd98b13c2d3ac34ee3eae3954dbb87c6John McCall    template<typename U> friend struct X0;
324b6e90a0dd98b13c2d3ac34ee3eae3954dbb87c6John McCall  };
334b6e90a0dd98b13c2d3ac34ee3eae3954dbb87c6John McCall
344b6e90a0dd98b13c2d3ac34ee3eae3954dbb87c6John McCall  template<typename T> struct X0<T*> {
354b6e90a0dd98b13c2d3ac34ee3eae3954dbb87c6John McCall    template<typename U> friend struct X0;
364b6e90a0dd98b13c2d3ac34ee3eae3954dbb87c6John McCall  };
37d7e5bdb23c6ba2786cf94788c9af555e2c1276ceDouglas Gregor
384b6e90a0dd98b13c2d3ac34ee3eae3954dbb87c6John McCall  template<> struct X0<int> {
394b6e90a0dd98b13c2d3ac34ee3eae3954dbb87c6John McCall    template<typename U> friend struct X0;
404b6e90a0dd98b13c2d3ac34ee3eae3954dbb87c6John McCall  };
41a735b206fdb5c15767a45289e1ffb3b568f70f2bDouglas Gregor
424b6e90a0dd98b13c2d3ac34ee3eae3954dbb87c6John McCall  template<typename T> struct X1 {
434b6e90a0dd98b13c2d3ac34ee3eae3954dbb87c6John McCall    template<typename U> friend void f2(U);
444b6e90a0dd98b13c2d3ac34ee3eae3954dbb87c6John McCall    template<typename U> friend void f3(U);
454b6e90a0dd98b13c2d3ac34ee3eae3954dbb87c6John McCall  };
46a735b206fdb5c15767a45289e1ffb3b568f70f2bDouglas Gregor
474b6e90a0dd98b13c2d3ac34ee3eae3954dbb87c6John McCall  template<typename U> void f2(U);
48a735b206fdb5c15767a45289e1ffb3b568f70f2bDouglas Gregor
494b6e90a0dd98b13c2d3ac34ee3eae3954dbb87c6John McCall  X1<int> x1i;
504b6e90a0dd98b13c2d3ac34ee3eae3954dbb87c6John McCall  X0<int*> x0ip;
51a735b206fdb5c15767a45289e1ffb3b568f70f2bDouglas Gregor
524b6e90a0dd98b13c2d3ac34ee3eae3954dbb87c6John McCall  template<> void f2(int);
53a735b206fdb5c15767a45289e1ffb3b568f70f2bDouglas Gregor
544b6e90a0dd98b13c2d3ac34ee3eae3954dbb87c6John McCall  // FIXME: Should this declaration of f3 be required for the specialization of
554b6e90a0dd98b13c2d3ac34ee3eae3954dbb87c6John McCall  // f3<int> (further below) to work? GCC and EDG don't require it, we do...
564b6e90a0dd98b13c2d3ac34ee3eae3954dbb87c6John McCall  template<typename U> void f3(U);
57a735b206fdb5c15767a45289e1ffb3b568f70f2bDouglas Gregor
584b6e90a0dd98b13c2d3ac34ee3eae3954dbb87c6John McCall  template<> void f3(int);
594b6e90a0dd98b13c2d3ac34ee3eae3954dbb87c6John McCall}
60e8c01bdb56549adcecd71ce39160eea54b2c51c8Douglas Gregor
61e8c01bdb56549adcecd71ce39160eea54b2c51c8Douglas Gregor// PR5332
624b6e90a0dd98b13c2d3ac34ee3eae3954dbb87c6John McCallnamespace test3 {
634b6e90a0dd98b13c2d3ac34ee3eae3954dbb87c6John McCall  template <typename T> class Foo {
644b6e90a0dd98b13c2d3ac34ee3eae3954dbb87c6John McCall    template <typename U>
654b6e90a0dd98b13c2d3ac34ee3eae3954dbb87c6John McCall    friend class Foo;
664b6e90a0dd98b13c2d3ac34ee3eae3954dbb87c6John McCall  };
67259571e27e513cfaf691cc7447e09b31a47d5438Douglas Gregor
684b6e90a0dd98b13c2d3ac34ee3eae3954dbb87c6John McCall  Foo<int> foo;
69259571e27e513cfaf691cc7447e09b31a47d5438Douglas Gregor
704b6e90a0dd98b13c2d3ac34ee3eae3954dbb87c6John McCall  template<typename T, T Value> struct X2a;
71259571e27e513cfaf691cc7447e09b31a47d5438Douglas Gregor
724b6e90a0dd98b13c2d3ac34ee3eae3954dbb87c6John McCall  template<typename T, int Size> struct X2b;
73259571e27e513cfaf691cc7447e09b31a47d5438Douglas Gregor
744b6e90a0dd98b13c2d3ac34ee3eae3954dbb87c6John McCall  template<typename T>
754b6e90a0dd98b13c2d3ac34ee3eae3954dbb87c6John McCall  class X3 {
764b6e90a0dd98b13c2d3ac34ee3eae3954dbb87c6John McCall    template<typename U, U Value> friend struct X2a;
7793ba8579c341d5329175f1413cdc3b35a36592d2John McCall
7893ba8579c341d5329175f1413cdc3b35a36592d2John McCall    // FIXME: the redeclaration note ends up here because redeclaration
7993ba8579c341d5329175f1413cdc3b35a36592d2John McCall    // lookup ends up finding the friend target from X3<int>.
8093ba8579c341d5329175f1413cdc3b35a36592d2John McCall    template<typename U, T Value> friend struct X2b; // expected-error {{template non-type parameter has a different type 'long' in template redeclaration}} \
8193ba8579c341d5329175f1413cdc3b35a36592d2John McCall      // expected-note {{previous non-type template parameter with type 'int' is here}}
824b6e90a0dd98b13c2d3ac34ee3eae3954dbb87c6John McCall  };
83259571e27e513cfaf691cc7447e09b31a47d5438Douglas Gregor
844b6e90a0dd98b13c2d3ac34ee3eae3954dbb87c6John McCall  X3<int> x3i; // okay
85259571e27e513cfaf691cc7447e09b31a47d5438Douglas Gregor
8693ba8579c341d5329175f1413cdc3b35a36592d2John McCall  X3<long> x3l; // expected-note {{in instantiation}}
874b6e90a0dd98b13c2d3ac34ee3eae3954dbb87c6John McCall}
88e976ffe18ee60b81641423f42ff6feec2f5e3cb7John McCall
89e976ffe18ee60b81641423f42ff6feec2f5e3cb7John McCall// PR5716
90e976ffe18ee60b81641423f42ff6feec2f5e3cb7John McCallnamespace test4 {
91e976ffe18ee60b81641423f42ff6feec2f5e3cb7John McCall  template<typename> struct A {
92e976ffe18ee60b81641423f42ff6feec2f5e3cb7John McCall    template<typename T> friend void f(const A<T>&);
93e976ffe18ee60b81641423f42ff6feec2f5e3cb7John McCall  };
94e976ffe18ee60b81641423f42ff6feec2f5e3cb7John McCall
95e976ffe18ee60b81641423f42ff6feec2f5e3cb7John McCall  template<typename T> void f(const A<T>&) {
96b2b5cc0cf908d516a107d373db963f692449a8a8Chandler Carruth    int a[sizeof(T) ? -1 : -1]; // expected-error {{array with a negative size}}
97e976ffe18ee60b81641423f42ff6feec2f5e3cb7John McCall  }
98e976ffe18ee60b81641423f42ff6feec2f5e3cb7John McCall
99e976ffe18ee60b81641423f42ff6feec2f5e3cb7John McCall  void f() {
100e976ffe18ee60b81641423f42ff6feec2f5e3cb7John McCall    f(A<int>()); // expected-note {{in instantiation of function template specialization}}
101e976ffe18ee60b81641423f42ff6feec2f5e3cb7John McCall  }
102e976ffe18ee60b81641423f42ff6feec2f5e3cb7John McCall}
10365c49466278f3739ac879f961b94b2aff744beedJohn McCall
10465c49466278f3739ac879f961b94b2aff744beedJohn McCallnamespace test5 {
10565c49466278f3739ac879f961b94b2aff744beedJohn McCall  class outer {
10665c49466278f3739ac879f961b94b2aff744beedJohn McCall    class foo;
10765c49466278f3739ac879f961b94b2aff744beedJohn McCall    template <typename T> friend struct cache;
10865c49466278f3739ac879f961b94b2aff744beedJohn McCall  };
10965c49466278f3739ac879f961b94b2aff744beedJohn McCall  class outer::foo {
11065c49466278f3739ac879f961b94b2aff744beedJohn McCall    template <typename T> friend struct cache;
11165c49466278f3739ac879f961b94b2aff744beedJohn McCall  };
11265c49466278f3739ac879f961b94b2aff744beedJohn McCall}
1135d52e47ed6a4f920723ebec371594a3fe7878d7cDouglas Gregor
1145d52e47ed6a4f920723ebec371594a3fe7878d7cDouglas Gregor// PR6022
1155d52e47ed6a4f920723ebec371594a3fe7878d7cDouglas Gregornamespace PR6022 {
1165d52e47ed6a4f920723ebec371594a3fe7878d7cDouglas Gregor  template <class T1, class T2 , class T3  > class A;
1175d52e47ed6a4f920723ebec371594a3fe7878d7cDouglas Gregor
1185d52e47ed6a4f920723ebec371594a3fe7878d7cDouglas Gregor  namespace inner {
1195d52e47ed6a4f920723ebec371594a3fe7878d7cDouglas Gregor    template<class T1, class T2, class T3, class T>
1205d52e47ed6a4f920723ebec371594a3fe7878d7cDouglas Gregor    A<T1, T2, T3>& f0(A<T1, T2, T3>&, T);
1215d52e47ed6a4f920723ebec371594a3fe7878d7cDouglas Gregor  }
1225d52e47ed6a4f920723ebec371594a3fe7878d7cDouglas Gregor
1235d52e47ed6a4f920723ebec371594a3fe7878d7cDouglas Gregor  template<class T1, class T2, class T3>
1245d52e47ed6a4f920723ebec371594a3fe7878d7cDouglas Gregor  class A {
1255d52e47ed6a4f920723ebec371594a3fe7878d7cDouglas Gregor    template<class U1, class U2, class U3, class T>
1265d52e47ed6a4f920723ebec371594a3fe7878d7cDouglas Gregor    friend A<U1, U2, U3>& inner::f0(A<U1, U2, U3>&, T);
1275d52e47ed6a4f920723ebec371594a3fe7878d7cDouglas Gregor  };
1285d52e47ed6a4f920723ebec371594a3fe7878d7cDouglas Gregor}
1295d52e47ed6a4f920723ebec371594a3fe7878d7cDouglas Gregor
130d4598a2cc7576c06f69d3cf64d0e2c9783ddf529Douglas Gregornamespace FriendTemplateDefinition {
131d4598a2cc7576c06f69d3cf64d0e2c9783ddf529Douglas Gregor  template<unsigned > struct int_c { };
132d4598a2cc7576c06f69d3cf64d0e2c9783ddf529Douglas Gregor
133d4598a2cc7576c06f69d3cf64d0e2c9783ddf529Douglas Gregor  template<typename T>
134d4598a2cc7576c06f69d3cf64d0e2c9783ddf529Douglas Gregor  struct X {
135d4598a2cc7576c06f69d3cf64d0e2c9783ddf529Douglas Gregor    template<unsigned N>
136d4598a2cc7576c06f69d3cf64d0e2c9783ddf529Douglas Gregor    friend void f(X, int_c<N>) {
137d4598a2cc7576c06f69d3cf64d0e2c9783ddf529Douglas Gregor      int value = N;
138d4598a2cc7576c06f69d3cf64d0e2c9783ddf529Douglas Gregor    };
139d4598a2cc7576c06f69d3cf64d0e2c9783ddf529Douglas Gregor  };
140d4598a2cc7576c06f69d3cf64d0e2c9783ddf529Douglas Gregor
141d4598a2cc7576c06f69d3cf64d0e2c9783ddf529Douglas Gregor  void test_X(X<int> x, int_c<5> i5) {
142d4598a2cc7576c06f69d3cf64d0e2c9783ddf529Douglas Gregor    f(x, i5);
143d4598a2cc7576c06f69d3cf64d0e2c9783ddf529Douglas Gregor  }
144d4598a2cc7576c06f69d3cf64d0e2c9783ddf529Douglas Gregor}
145e7089b0c6ffe8a8854150b60df00fb544099f77dDouglas Gregor
146e7089b0c6ffe8a8854150b60df00fb544099f77dDouglas Gregornamespace PR7013a {
147e7089b0c6ffe8a8854150b60df00fb544099f77dDouglas Gregor  template<class > struct X0
148e7089b0c6ffe8a8854150b60df00fb544099f77dDouglas Gregor  {
149e7089b0c6ffe8a8854150b60df00fb544099f77dDouglas Gregor    typedef int type;
150e7089b0c6ffe8a8854150b60df00fb544099f77dDouglas Gregor  };
151e7089b0c6ffe8a8854150b60df00fb544099f77dDouglas Gregor  template<typename > struct X1
152e7089b0c6ffe8a8854150b60df00fb544099f77dDouglas Gregor  {
153e7089b0c6ffe8a8854150b60df00fb544099f77dDouglas Gregor  };
154e7089b0c6ffe8a8854150b60df00fb544099f77dDouglas Gregor  template<typename , typename T> struct X2
155e7089b0c6ffe8a8854150b60df00fb544099f77dDouglas Gregor  {
156e7089b0c6ffe8a8854150b60df00fb544099f77dDouglas Gregor    typename T::type e;
157e7089b0c6ffe8a8854150b60df00fb544099f77dDouglas Gregor  };
158e7089b0c6ffe8a8854150b60df00fb544099f77dDouglas Gregor  namespace N
159e7089b0c6ffe8a8854150b60df00fb544099f77dDouglas Gregor  {
160e7089b0c6ffe8a8854150b60df00fb544099f77dDouglas Gregor    template <typename = int, typename = X1<int> > struct X3
161e7089b0c6ffe8a8854150b60df00fb544099f77dDouglas Gregor    {
162e7089b0c6ffe8a8854150b60df00fb544099f77dDouglas Gregor      template <typename T1, typename T2, typename B> friend void op(X2<T1, T2>& , B);
163e7089b0c6ffe8a8854150b60df00fb544099f77dDouglas Gregor    };
164e7089b0c6ffe8a8854150b60df00fb544099f77dDouglas Gregor    template <typename Ch, typename Tr, typename B> void op(X2<Ch, Tr>& , B)
165e7089b0c6ffe8a8854150b60df00fb544099f77dDouglas Gregor    {
166e7089b0c6ffe8a8854150b60df00fb544099f77dDouglas Gregor      X2<int, Tr> s;
167e7089b0c6ffe8a8854150b60df00fb544099f77dDouglas Gregor    }
168e7089b0c6ffe8a8854150b60df00fb544099f77dDouglas Gregor  }
169e7089b0c6ffe8a8854150b60df00fb544099f77dDouglas Gregor  int n()
170e7089b0c6ffe8a8854150b60df00fb544099f77dDouglas Gregor  {
171e7089b0c6ffe8a8854150b60df00fb544099f77dDouglas Gregor    X2<int, X0<int> > ngs;
172e7089b0c6ffe8a8854150b60df00fb544099f77dDouglas Gregor    N::X3<> b;
173e7089b0c6ffe8a8854150b60df00fb544099f77dDouglas Gregor    op(ngs, b);
174e7089b0c6ffe8a8854150b60df00fb544099f77dDouglas Gregor    return 0;
175e7089b0c6ffe8a8854150b60df00fb544099f77dDouglas Gregor  }
176e7089b0c6ffe8a8854150b60df00fb544099f77dDouglas Gregor}
177e7089b0c6ffe8a8854150b60df00fb544099f77dDouglas Gregor
178e7089b0c6ffe8a8854150b60df00fb544099f77dDouglas Gregornamespace PR7013b {
179e7089b0c6ffe8a8854150b60df00fb544099f77dDouglas Gregor  template<class > struct X0
180e7089b0c6ffe8a8854150b60df00fb544099f77dDouglas Gregor  {
181e7089b0c6ffe8a8854150b60df00fb544099f77dDouglas Gregor    typedef int type;
182e7089b0c6ffe8a8854150b60df00fb544099f77dDouglas Gregor  };
183e7089b0c6ffe8a8854150b60df00fb544099f77dDouglas Gregor  template<typename > struct X1
184e7089b0c6ffe8a8854150b60df00fb544099f77dDouglas Gregor  {
185e7089b0c6ffe8a8854150b60df00fb544099f77dDouglas Gregor  };
186e7089b0c6ffe8a8854150b60df00fb544099f77dDouglas Gregor  template<typename , typename T> struct X2
187e7089b0c6ffe8a8854150b60df00fb544099f77dDouglas Gregor  {
188e7089b0c6ffe8a8854150b60df00fb544099f77dDouglas Gregor    typename T::type e;
189e7089b0c6ffe8a8854150b60df00fb544099f77dDouglas Gregor  };
190e7089b0c6ffe8a8854150b60df00fb544099f77dDouglas Gregor  namespace N
191e7089b0c6ffe8a8854150b60df00fb544099f77dDouglas Gregor  {
192e7089b0c6ffe8a8854150b60df00fb544099f77dDouglas Gregor    template <typename = X1<int> > struct X3
193e7089b0c6ffe8a8854150b60df00fb544099f77dDouglas Gregor    {
194e7089b0c6ffe8a8854150b60df00fb544099f77dDouglas Gregor      template <typename T1, typename T2, typename B> friend void op(X2<T1, T2>& , B);
195e7089b0c6ffe8a8854150b60df00fb544099f77dDouglas Gregor    };
196e7089b0c6ffe8a8854150b60df00fb544099f77dDouglas Gregor    template <typename Ch, typename Tr, typename B> void op(X2<Ch, Tr>& , B)
197e7089b0c6ffe8a8854150b60df00fb544099f77dDouglas Gregor    {
198e7089b0c6ffe8a8854150b60df00fb544099f77dDouglas Gregor      X2<int, Tr> s;
199e7089b0c6ffe8a8854150b60df00fb544099f77dDouglas Gregor    }
200e7089b0c6ffe8a8854150b60df00fb544099f77dDouglas Gregor  }
201e7089b0c6ffe8a8854150b60df00fb544099f77dDouglas Gregor  int n()
202e7089b0c6ffe8a8854150b60df00fb544099f77dDouglas Gregor  {
203e7089b0c6ffe8a8854150b60df00fb544099f77dDouglas Gregor    X2<int, X0<int> > ngs;
204e7089b0c6ffe8a8854150b60df00fb544099f77dDouglas Gregor    N::X3<> b;
205e7089b0c6ffe8a8854150b60df00fb544099f77dDouglas Gregor    op(ngs, b);
206e7089b0c6ffe8a8854150b60df00fb544099f77dDouglas Gregor    return 0;
207e7089b0c6ffe8a8854150b60df00fb544099f77dDouglas Gregor  }
208e7089b0c6ffe8a8854150b60df00fb544099f77dDouglas Gregor
209e7089b0c6ffe8a8854150b60df00fb544099f77dDouglas Gregor}
210b0ee93cf945744569b82b8a07361061f2963264aDouglas Gregor
211b0ee93cf945744569b82b8a07361061f2963264aDouglas Gregornamespace PR8649 {
212b0ee93cf945744569b82b8a07361061f2963264aDouglas Gregor  template<typename T, typename U, unsigned N>
213b0ee93cf945744569b82b8a07361061f2963264aDouglas Gregor  struct X {
214b0ee93cf945744569b82b8a07361061f2963264aDouglas Gregor    template<unsigned M> friend class X<T, U, M>; // expected-error{{partial specialization cannot be declared as a friend}}
215b0ee93cf945744569b82b8a07361061f2963264aDouglas Gregor  };
216b0ee93cf945744569b82b8a07361061f2963264aDouglas Gregor
217b0ee93cf945744569b82b8a07361061f2963264aDouglas Gregor  X<int, float, 7> x;
218b0ee93cf945744569b82b8a07361061f2963264aDouglas Gregor}
2190f4be74ff0273e505d383f89174ef539828424edChandler Carruth
2200f4be74ff0273e505d383f89174ef539828424edChandler Carruth// Don't crash, and error on invalid friend type template.
2210f4be74ff0273e505d383f89174ef539828424edChandler Carruthnamespace friend_type_template_no_tag {
2220f4be74ff0273e505d383f89174ef539828424edChandler Carruth  template <typename T> struct S {
2230f4be74ff0273e505d383f89174ef539828424edChandler Carruth    template <typename U> friend S<U>; // expected-error{{friend type templates must use an elaborated type}}
2240f4be74ff0273e505d383f89174ef539828424edChandler Carruth  };
2250f4be74ff0273e505d383f89174ef539828424edChandler Carruth  template struct S<int>;
2260f4be74ff0273e505d383f89174ef539828424edChandler Carruth}
227ba4ee9a9b6e4cffc12bb6b395a58b89c189bb07eDouglas Gregor
228ba4ee9a9b6e4cffc12bb6b395a58b89c189bb07eDouglas Gregornamespace PR10660 {
229ba4ee9a9b6e4cffc12bb6b395a58b89c189bb07eDouglas Gregor  struct A {
230ba4ee9a9b6e4cffc12bb6b395a58b89c189bb07eDouglas Gregor    template <> friend class B; // expected-error{{extraneous 'template<>' in declaration of class 'B'}}
231ba4ee9a9b6e4cffc12bb6b395a58b89c189bb07eDouglas Gregor  };
232ba4ee9a9b6e4cffc12bb6b395a58b89c189bb07eDouglas Gregor}
2338b0fa5241a0416fc50dfbb7e38f20e777f191848Douglas Gregor
2348b0fa5241a0416fc50dfbb7e38f20e777f191848Douglas Gregornamespace rdar11147355 {
235ce6426feda94ca716ee7743b71961850740eb08dRichard Smith  template <class T>
2368b0fa5241a0416fc50dfbb7e38f20e777f191848Douglas Gregor  struct A {
2378b0fa5241a0416fc50dfbb7e38f20e777f191848Douglas Gregor    template <class U> class B;
238ce6426feda94ca716ee7743b71961850740eb08dRichard Smith    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}}
239ce6426feda94ca716ee7743b71961850740eb08dRichard Smith  private:
240ce6426feda94ca716ee7743b71961850740eb08dRichard Smith    int n; // expected-note {{here}}
2418b0fa5241a0416fc50dfbb7e38f20e777f191848Douglas Gregor  };
242ce6426feda94ca716ee7743b71961850740eb08dRichard Smith
2438b0fa5241a0416fc50dfbb7e38f20e777f191848Douglas Gregor  template <class S> template <class U> class A<S>::B {
244ce6426feda94ca716ee7743b71961850740eb08dRichard Smith  public:
245ce6426feda94ca716ee7743b71961850740eb08dRichard Smith    // FIXME: This should be permitted.
246ce6426feda94ca716ee7743b71961850740eb08dRichard Smith    int f(A<S*> a) { return a.n; } // expected-error {{private}}
247ce6426feda94ca716ee7743b71961850740eb08dRichard Smith  };
248ce6426feda94ca716ee7743b71961850740eb08dRichard Smith
2498b0fa5241a0416fc50dfbb7e38f20e777f191848Douglas Gregor  A<double>::B<double>  ab;
250ce6426feda94ca716ee7743b71961850740eb08dRichard Smith  A<double*> a;
251ce6426feda94ca716ee7743b71961850740eb08dRichard Smith  int k = ab.f(a); // expected-note {{instantiation of}}
2528b0fa5241a0416fc50dfbb7e38f20e777f191848Douglas Gregor}
253c93e014cd43b08812370cfc8ef7bb7b92305f8fbRichard Smith
254c93e014cd43b08812370cfc8ef7bb7b92305f8fbRichard Smithnamespace RedeclUnrelated {
255c93e014cd43b08812370cfc8ef7bb7b92305f8fbRichard Smith  struct S {
256c93e014cd43b08812370cfc8ef7bb7b92305f8fbRichard Smith    int packaged_task;
257c93e014cd43b08812370cfc8ef7bb7b92305f8fbRichard Smith    template<typename> class future {
258c93e014cd43b08812370cfc8ef7bb7b92305f8fbRichard Smith      template<typename> friend class packaged_task;
259c93e014cd43b08812370cfc8ef7bb7b92305f8fbRichard Smith    };
260c93e014cd43b08812370cfc8ef7bb7b92305f8fbRichard Smith    future<void> share;
261c93e014cd43b08812370cfc8ef7bb7b92305f8fbRichard Smith  };
262c93e014cd43b08812370cfc8ef7bb7b92305f8fbRichard Smith}
263c93e014cd43b08812370cfc8ef7bb7b92305f8fbRichard Smith
264c93e014cd43b08812370cfc8ef7bb7b92305f8fbRichard Smithnamespace PR12557 {
265c93e014cd43b08812370cfc8ef7bb7b92305f8fbRichard Smith  template <typename>
266c93e014cd43b08812370cfc8ef7bb7b92305f8fbRichard Smith  struct Foo;
267c93e014cd43b08812370cfc8ef7bb7b92305f8fbRichard Smith
268c93e014cd43b08812370cfc8ef7bb7b92305f8fbRichard Smith  template <typename Foo_>
269c93e014cd43b08812370cfc8ef7bb7b92305f8fbRichard Smith  struct Bar {
270c93e014cd43b08812370cfc8ef7bb7b92305f8fbRichard Smith    typedef Foo_  Foo; // expected-note {{previous}}
271c93e014cd43b08812370cfc8ef7bb7b92305f8fbRichard Smith
272c93e014cd43b08812370cfc8ef7bb7b92305f8fbRichard Smith    template <typename> friend struct Foo; // expected-error {{redefinition of 'Foo' as different kind of symbol}}
273c93e014cd43b08812370cfc8ef7bb7b92305f8fbRichard Smith  };
274c93e014cd43b08812370cfc8ef7bb7b92305f8fbRichard Smith
275c93e014cd43b08812370cfc8ef7bb7b92305f8fbRichard Smith  Bar<int> b;
276c93e014cd43b08812370cfc8ef7bb7b92305f8fbRichard Smith}
2776e21b16ab226959341b85e16060fd81f71cee628Richard Smith
2786e21b16ab226959341b85e16060fd81f71cee628Richard Smithnamespace PR12585 {
2796e21b16ab226959341b85e16060fd81f71cee628Richard Smith  struct A { };
2806e21b16ab226959341b85e16060fd81f71cee628Richard Smith  template<typename> struct B {
2816e21b16ab226959341b85e16060fd81f71cee628Richard Smith    template<typename> friend class A::does_not_exist; // \
2826e21b16ab226959341b85e16060fd81f71cee628Richard Smith     // expected-error {{friend declaration of 'does_not_exist' does not match any declaration in 'PR12585::A'}}
2836e21b16ab226959341b85e16060fd81f71cee628Richard Smith  };
2846e21b16ab226959341b85e16060fd81f71cee628Richard Smith
2856e21b16ab226959341b85e16060fd81f71cee628Richard Smith  struct C {
2866e21b16ab226959341b85e16060fd81f71cee628Richard Smith    template<typename> struct D;
2876e21b16ab226959341b85e16060fd81f71cee628Richard Smith  };
2886e21b16ab226959341b85e16060fd81f71cee628Richard Smith  template<typename> class E {
2896e21b16ab226959341b85e16060fd81f71cee628Richard Smith    int n;
2906e21b16ab226959341b85e16060fd81f71cee628Richard Smith    template<typename> friend struct C::D;
2916e21b16ab226959341b85e16060fd81f71cee628Richard Smith  };
2926e21b16ab226959341b85e16060fd81f71cee628Richard Smith  template<typename T> struct C::D {
2936e21b16ab226959341b85e16060fd81f71cee628Richard Smith    int f() {
2946e21b16ab226959341b85e16060fd81f71cee628Richard Smith      return E<int>().n;
2956e21b16ab226959341b85e16060fd81f71cee628Richard Smith    }
2966e21b16ab226959341b85e16060fd81f71cee628Richard Smith  };
2976e21b16ab226959341b85e16060fd81f71cee628Richard Smith  int n = C::D<void*>().f();
2986e21b16ab226959341b85e16060fd81f71cee628Richard Smith
2996e21b16ab226959341b85e16060fd81f71cee628Richard Smith  struct F {
3006e21b16ab226959341b85e16060fd81f71cee628Richard Smith    template<int> struct G;
3016e21b16ab226959341b85e16060fd81f71cee628Richard Smith  };
3026e21b16ab226959341b85e16060fd81f71cee628Richard Smith  template<typename T> struct H {
3036e21b16ab226959341b85e16060fd81f71cee628Richard Smith    // FIXME: As with cases above, the note here is on an unhelpful declaration,
3046e21b16ab226959341b85e16060fd81f71cee628Richard Smith    // and should point to the declaration of G within F.
3056e21b16ab226959341b85e16060fd81f71cee628Richard Smith    template<T> friend struct F::G; // \
3066e21b16ab226959341b85e16060fd81f71cee628Richard Smith      // expected-error {{different type 'char' in template redeclaration}} \
3076e21b16ab226959341b85e16060fd81f71cee628Richard Smith      // expected-note {{previous}}
3086e21b16ab226959341b85e16060fd81f71cee628Richard Smith  };
3096e21b16ab226959341b85e16060fd81f71cee628Richard Smith  H<int> h1; // ok
3106e21b16ab226959341b85e16060fd81f71cee628Richard Smith  H<char> h2; // expected-note {{instantiation}}
3116e21b16ab226959341b85e16060fd81f71cee628Richard Smith}
312e34db6b3e772e9832e1f6de1f23457076ffbec88John McCall
313e34db6b3e772e9832e1f6de1f23457076ffbec88John McCall// Ensure that we can still instantiate a friend function template
314e34db6b3e772e9832e1f6de1f23457076ffbec88John McCall// after the friend declaration is instantiated during the delayed
315e34db6b3e772e9832e1f6de1f23457076ffbec88John McCall// parsing of a member function, but before the friend function has
316e34db6b3e772e9832e1f6de1f23457076ffbec88John McCall// been parsed.
317e34db6b3e772e9832e1f6de1f23457076ffbec88John McCallnamespace rdar12350696 {
318e34db6b3e772e9832e1f6de1f23457076ffbec88John McCall  template <class T> struct A {
319e34db6b3e772e9832e1f6de1f23457076ffbec88John McCall    void foo() {
320e34db6b3e772e9832e1f6de1f23457076ffbec88John McCall      A<int> a;
321e34db6b3e772e9832e1f6de1f23457076ffbec88John McCall    }
322e34db6b3e772e9832e1f6de1f23457076ffbec88John McCall    template <class U> friend void foo(const A<U> & a) {
323e34db6b3e772e9832e1f6de1f23457076ffbec88John McCall      int array[sizeof(T) == sizeof(U) ? -1 : 1]; // expected-error {{negative size}}
324e34db6b3e772e9832e1f6de1f23457076ffbec88John McCall    }
325e34db6b3e772e9832e1f6de1f23457076ffbec88John McCall  };
326e34db6b3e772e9832e1f6de1f23457076ffbec88John McCall
327e34db6b3e772e9832e1f6de1f23457076ffbec88John McCall  void test() {
328e34db6b3e772e9832e1f6de1f23457076ffbec88John McCall    A<int> b;
329e34db6b3e772e9832e1f6de1f23457076ffbec88John McCall    foo(b); // expected-note {{in instantiation}}
330e34db6b3e772e9832e1f6de1f23457076ffbec88John McCall  }
331e34db6b3e772e9832e1f6de1f23457076ffbec88John McCall}
332