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