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 5struct Outer { 6 struct Inner { 7 int intfield; 8 }; 9}; 10 11struct Base { 12 void base_member(); 13 14 typedef int Int; 15 Int typedeffed_member(); 16}; 17 18struct Derived : public Base { 19}; 20 21int myglobal; 22 23void global_function(); 24extern "C" { 25 void global_c_function(); 26} 27 28class 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 80A::UndeclaredSoFar y; // expected-error {{no type named 'UndeclaredSoFar' in 'A'}} 81 82class PreDeclared; 83 84int myoperation(float f) { 85 return (int) f; 86} 87 88template <typename T> 89class 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