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