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