• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1  // RUN: %clang_cc1 -fsyntax-only -verify %s
2  
3  // C++98 [class.friend]p7:
4  // C++11 [class.friend]p9:
5  //   A name nominated by a friend declaration shall be accessible in
6  //   the scope of the class containing the friend declaration.
7  
8  // PR12328
9  // Simple, non-templated case.
10  namespace test0 {
11    class X {
12      void f(); // expected-note {{implicitly declared private here}}
13    };
14  
15    class Y {
16      friend void X::f(); // expected-error {{friend function 'f' is a private member of 'test0::X'}}
17    };
18  }
19  
20  // Templated but non-dependent.
21  namespace test1 {
22    class X {
23      void f(); // expected-note {{implicitly declared private here}}
24    };
25  
26    template <class T> class Y {
27      friend void X::f(); // expected-error {{friend function 'f' is a private member of 'test1::X'}}
28    };
29  }
30  
31  // Dependent but instantiated at the right type.
32  namespace test2 {
33    template <class T> class Y;
34  
35    class X {
36      void f();
37      friend class Y<int>;
38    };
39  
40    template <class T> class Y {
41      friend void X::f();
42    };
43  
44    template class Y<int>;
45  }
46  
47  // Dependent and instantiated at the wrong type.
48  namespace test3 {
49    template <class T> class Y;
50  
51    class X {
52      void f(); // expected-note {{implicitly declared private here}}
53      friend class Y<int>;
54    };
55  
56    template <class T> class Y {
57      friend void X::f(); // expected-error {{friend function 'f' is a private member of 'test3::X'}}
58    };
59  
60    template class Y<float>; // expected-note {{in instantiation}}
61  }
62  
63  // Dependent because dependently-scoped.
64  namespace test4 {
65    template <class T> class X {
66      void f();
67    };
68  
69    template <class T> class Y {
70      friend void X<T>::f();
71    };
72  }
73  
74  // Dependently-scoped, no friends.
75  namespace test5 {
76    template <class T> class X {
77      void f(); // expected-note {{implicitly declared private here}}
78    };
79  
80    template <class T> class Y {
81      friend void X<T>::f(); // expected-error {{friend function 'f' is a private member of 'test5::X<int>'}}
82    };
83  
84    template class Y<int>; // expected-note {{in instantiation}}
85  }
86  
87  // Dependently-scoped, wrong friend.
88  namespace test6 {
89    template <class T> class Y;
90  
91    template <class T> class X {
92      void f(); // expected-note {{implicitly declared private here}}
93      friend class Y<float>;
94    };
95  
96    template <class T> class Y {
97      friend void X<T>::f(); // expected-error {{friend function 'f' is a private member of 'test6::X<int>'}}
98    };
99  
100    template class Y<int>; // expected-note {{in instantiation}}
101  }
102  
103  // Dependently-scoped, right friend.
104  namespace test7 {
105    template <class T> class Y;
106  
107    template <class T> class X {
108      void f();
109      friend class Y<int>;
110    };
111  
112    template <class T> class Y {
113      friend void X<T>::f();
114    };
115  
116    template class Y<int>;
117  }
118