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