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