Home | History | Annotate | Download | only in class.friend
      1 // RUN: %clang_cc1 -fsyntax-only -verify %s
      2 
      3 struct Outer {
      4   struct Inner {
      5     int intfield;
      6   };
      7 };
      8 
      9 struct Base {
     10   void base_member();
     11 
     12   typedef int Int;
     13   Int typedeffed_member();
     14 };
     15 
     16 struct Derived : public Base {
     17 };
     18 
     19 int myglobal;
     20 
     21 void global_function();
     22 extern "C" {
     23   void global_c_function();
     24 }
     25 
     26 class A {
     27   class AInner {
     28   };
     29 
     30   friend class PreDeclared;
     31   friend class Outer::Inner;
     32   friend int Outer::Inner::intfield; // expected-error {{friends can only be classes or functions}}
     33   friend int Outer::Inner::missing_field; //expected-error {{friends can only be classes or functions}}
     34   friend int myoperation(float); // okay
     35   friend int myglobal;   // expected-error {{friends can only be classes or functions}}
     36 
     37   friend void global_function();
     38   friend void global_c_function();
     39 
     40   friend class UndeclaredSoFar;
     41   UndeclaredSoFar x; // expected-error {{unknown type name 'UndeclaredSoFar'}}
     42 
     43   void a_member();
     44   friend void A::a_member(); // expected-error {{friends cannot be members of the declaring class}}
     45   friend void a_member(); // okay (because we ignore class scopes when looking up friends)
     46   friend class A::AInner; // this is okay as an extension
     47   friend class AInner; // okay, refers to ::AInner
     48 
     49   friend void Derived::missing_member(); // expected-error {{no function named 'missing_member' with type 'void ()' was found in the specified scope}}
     50 
     51   friend void Derived::base_member(); // expected-error {{no function named 'base_member' with type 'void ()' was found in the specified scope}}
     52 
     53   friend int Base::typedeffed_member(); // okay: should look through typedef
     54 
     55   // These test that the friend is properly not being treated as a
     56   // member function.
     57   friend A operator|(const A& l, const A& r); // okay
     58   friend A operator|(const A& r); // expected-error {{overloaded 'operator|' must be a binary operator (has 1 parameter)}}
     59 
     60   friend operator bool() const; // expected-error {{must use a qualified name when declaring a conversion operator as a friend}} \
     61        // expected-error{{non-member function cannot have 'const' qualifier}}
     62 
     63   typedef void ftypedef();
     64   friend ftypedef typedeffed_function; // okay (because it's not declared as a member)
     65 
     66   class facet;
     67   friend class facet;  // should not assert
     68   class facet {};
     69 };
     70 
     71 A::UndeclaredSoFar y; // expected-error {{no type named 'UndeclaredSoFar' in 'A'}}
     72 
     73 class PreDeclared;
     74 
     75 int myoperation(float f) {
     76   return (int) f;
     77 }
     78