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. 10namespace 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. 21namespace 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. 32namespace 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. 48namespace 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. 64namespace 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. 75namespace 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. 88namespace 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. 104namespace 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