friend-template.cpp revision 259571e27e513cfaf691cc7447e09b31a47d5438
1182ddf0e5dc5667e6683a58b483a2e52564f4303Douglas Gregor// RUN: clang-cc -fsyntax-only -verify %s
2d85bea2affdd59d83d1be7d24b97f436484c3625Douglas Gregor
3d85bea2affdd59d83d1be7d24b97f436484c3625Douglas Gregor// PR5057
4d85bea2affdd59d83d1be7d24b97f436484c3625Douglas Gregornamespace std {
5d85bea2affdd59d83d1be7d24b97f436484c3625Douglas Gregor  class X {
6d85bea2affdd59d83d1be7d24b97f436484c3625Douglas Gregor  public:
7d85bea2affdd59d83d1be7d24b97f436484c3625Douglas Gregor    template<typename T>
8d85bea2affdd59d83d1be7d24b97f436484c3625Douglas Gregor    friend struct Y;
9d85bea2affdd59d83d1be7d24b97f436484c3625Douglas Gregor  };
10d85bea2affdd59d83d1be7d24b97f436484c3625Douglas Gregor}
11d85bea2affdd59d83d1be7d24b97f436484c3625Douglas Gregor
12d85bea2affdd59d83d1be7d24b97f436484c3625Douglas Gregornamespace std {
13d85bea2affdd59d83d1be7d24b97f436484c3625Douglas Gregor  template<typename T>
14d85bea2affdd59d83d1be7d24b97f436484c3625Douglas Gregor  struct Y
15d85bea2affdd59d83d1be7d24b97f436484c3625Douglas Gregor  {
16d85bea2affdd59d83d1be7d24b97f436484c3625Douglas Gregor  };
17d85bea2affdd59d83d1be7d24b97f436484c3625Douglas Gregor}
18182ddf0e5dc5667e6683a58b483a2e52564f4303Douglas Gregor
19182ddf0e5dc5667e6683a58b483a2e52564f4303Douglas Gregor
20182ddf0e5dc5667e6683a58b483a2e52564f4303Douglas Gregornamespace N {
21182ddf0e5dc5667e6683a58b483a2e52564f4303Douglas Gregor  template<typename T> void f1(T) { } // expected-note{{here}}
22182ddf0e5dc5667e6683a58b483a2e52564f4303Douglas Gregor
23182ddf0e5dc5667e6683a58b483a2e52564f4303Douglas Gregor  class X {
24182ddf0e5dc5667e6683a58b483a2e52564f4303Douglas Gregor    template<typename T> friend void f0(T);
25182ddf0e5dc5667e6683a58b483a2e52564f4303Douglas Gregor    template<typename T> friend void f1(T);
26182ddf0e5dc5667e6683a58b483a2e52564f4303Douglas Gregor  };
27182ddf0e5dc5667e6683a58b483a2e52564f4303Douglas Gregor
28182ddf0e5dc5667e6683a58b483a2e52564f4303Douglas Gregor  template<typename T> void f0(T) { }
29182ddf0e5dc5667e6683a58b483a2e52564f4303Douglas Gregor  template<typename T> void f1(T) { } // expected-error{{redefinition}}
30182ddf0e5dc5667e6683a58b483a2e52564f4303Douglas Gregor}
31d7e5bdb23c6ba2786cf94788c9af555e2c1276ceDouglas Gregor
32d7e5bdb23c6ba2786cf94788c9af555e2c1276ceDouglas Gregor// PR4768
33d7e5bdb23c6ba2786cf94788c9af555e2c1276ceDouglas Gregortemplate<typename T>
34d7e5bdb23c6ba2786cf94788c9af555e2c1276ceDouglas Gregorstruct X0 {
35d7e5bdb23c6ba2786cf94788c9af555e2c1276ceDouglas Gregor  template<typename U> friend struct X0;
36d7e5bdb23c6ba2786cf94788c9af555e2c1276ceDouglas Gregor};
37d7e5bdb23c6ba2786cf94788c9af555e2c1276ceDouglas Gregor
38d7e5bdb23c6ba2786cf94788c9af555e2c1276ceDouglas Gregortemplate<typename T>
39d7e5bdb23c6ba2786cf94788c9af555e2c1276ceDouglas Gregorstruct X0<T*> {
40d7e5bdb23c6ba2786cf94788c9af555e2c1276ceDouglas Gregor  template<typename U> friend struct X0;
41d7e5bdb23c6ba2786cf94788c9af555e2c1276ceDouglas Gregor};
42d7e5bdb23c6ba2786cf94788c9af555e2c1276ceDouglas Gregor
43d7e5bdb23c6ba2786cf94788c9af555e2c1276ceDouglas Gregortemplate<>
44d7e5bdb23c6ba2786cf94788c9af555e2c1276ceDouglas Gregorstruct X0<int> {
45d7e5bdb23c6ba2786cf94788c9af555e2c1276ceDouglas Gregor  template<typename U> friend struct X0;
46d7e5bdb23c6ba2786cf94788c9af555e2c1276ceDouglas Gregor};
47a735b206fdb5c15767a45289e1ffb3b568f70f2bDouglas Gregor
48a735b206fdb5c15767a45289e1ffb3b568f70f2bDouglas Gregortemplate<typename T>
49a735b206fdb5c15767a45289e1ffb3b568f70f2bDouglas Gregorstruct X1 {
50a735b206fdb5c15767a45289e1ffb3b568f70f2bDouglas Gregor  template<typename U> friend void f2(U);
51a735b206fdb5c15767a45289e1ffb3b568f70f2bDouglas Gregor  template<typename U> friend void f3(U);
52a735b206fdb5c15767a45289e1ffb3b568f70f2bDouglas Gregor};
53a735b206fdb5c15767a45289e1ffb3b568f70f2bDouglas Gregor
54a735b206fdb5c15767a45289e1ffb3b568f70f2bDouglas Gregortemplate<typename U> void f2(U);
55a735b206fdb5c15767a45289e1ffb3b568f70f2bDouglas Gregor
56a735b206fdb5c15767a45289e1ffb3b568f70f2bDouglas GregorX1<int> x1i;
57e8c01bdb56549adcecd71ce39160eea54b2c51c8Douglas GregorX0<int*> x0ip;
58a735b206fdb5c15767a45289e1ffb3b568f70f2bDouglas Gregor
59a735b206fdb5c15767a45289e1ffb3b568f70f2bDouglas Gregortemplate<> void f2(int);
60a735b206fdb5c15767a45289e1ffb3b568f70f2bDouglas Gregor
61a735b206fdb5c15767a45289e1ffb3b568f70f2bDouglas Gregor// FIXME: Should this declaration of f3 be required for the specialization of
62a735b206fdb5c15767a45289e1ffb3b568f70f2bDouglas Gregor// f3<int> (further below) to work? GCC and EDG don't require it, we do...
63a735b206fdb5c15767a45289e1ffb3b568f70f2bDouglas Gregortemplate<typename U> void f3(U);
64a735b206fdb5c15767a45289e1ffb3b568f70f2bDouglas Gregor
65a735b206fdb5c15767a45289e1ffb3b568f70f2bDouglas Gregortemplate<> void f3(int);
66e8c01bdb56549adcecd71ce39160eea54b2c51c8Douglas Gregor
67e8c01bdb56549adcecd71ce39160eea54b2c51c8Douglas Gregor// PR5332
68e8c01bdb56549adcecd71ce39160eea54b2c51c8Douglas Gregortemplate <typename T>
69e8c01bdb56549adcecd71ce39160eea54b2c51c8Douglas Gregorclass Foo {
70e8c01bdb56549adcecd71ce39160eea54b2c51c8Douglas Gregor  template <typename U>
71e8c01bdb56549adcecd71ce39160eea54b2c51c8Douglas Gregor  friend class Foo;
72e8c01bdb56549adcecd71ce39160eea54b2c51c8Douglas Gregor};
73e8c01bdb56549adcecd71ce39160eea54b2c51c8Douglas Gregor
74e8c01bdb56549adcecd71ce39160eea54b2c51c8Douglas GregorFoo<int> foo;
75259571e27e513cfaf691cc7447e09b31a47d5438Douglas Gregor
76259571e27e513cfaf691cc7447e09b31a47d5438Douglas Gregortemplate<typename T, T Value>
77259571e27e513cfaf691cc7447e09b31a47d5438Douglas Gregorstruct X2a;
78259571e27e513cfaf691cc7447e09b31a47d5438Douglas Gregor
79259571e27e513cfaf691cc7447e09b31a47d5438Douglas Gregortemplate<typename T, int Size>
80259571e27e513cfaf691cc7447e09b31a47d5438Douglas Gregorstruct X2b;
81259571e27e513cfaf691cc7447e09b31a47d5438Douglas Gregor
82259571e27e513cfaf691cc7447e09b31a47d5438Douglas Gregortemplate<typename T>
83259571e27e513cfaf691cc7447e09b31a47d5438Douglas Gregorclass X3 {
84259571e27e513cfaf691cc7447e09b31a47d5438Douglas Gregor  template<typename U, U Value>
85259571e27e513cfaf691cc7447e09b31a47d5438Douglas Gregor  friend struct X2a;
86259571e27e513cfaf691cc7447e09b31a47d5438Douglas Gregor
87259571e27e513cfaf691cc7447e09b31a47d5438Douglas Gregor  template<typename U, T Value>
88259571e27e513cfaf691cc7447e09b31a47d5438Douglas Gregor  friend struct X2b;
89259571e27e513cfaf691cc7447e09b31a47d5438Douglas Gregor};
90259571e27e513cfaf691cc7447e09b31a47d5438Douglas Gregor
91259571e27e513cfaf691cc7447e09b31a47d5438Douglas GregorX3<int> x3i; // okay
92259571e27e513cfaf691cc7447e09b31a47d5438Douglas Gregor
93259571e27e513cfaf691cc7447e09b31a47d5438Douglas GregorX3<long> x3l; // FIXME: should cause an instantiation-time failure
94