Home | History | Annotate | Download | only in class.friend
      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