// RUN: %clang_cc1 -fsyntax-only -verify %s -std=c++14 friend class A; // expected-error {{'friend' used outside of class}} void f() { friend class A; } // expected-error {{'friend' used outside of class}} class C { friend class A; }; class D { void f() { friend class A; } }; // expected-error {{'friend' used outside of class}} // PR5760 namespace test0 { namespace ns { void f(int); } struct A { friend void ns::f(int a); }; } // Test derived from LLVM's Registry.h namespace test1 { template <class T> struct Outer { void foo(T); struct Inner { friend void Outer::foo(T); }; }; void test() { (void) Outer<int>::Inner(); } } // PR5476 namespace test2 { namespace foo { void Func(int x); } class Bar { friend void ::test2::foo::Func(int x); }; } // PR5134 namespace test3 { class Foo { friend const int getInt(int inInt = 0) {} }; } namespace test4 { class T4A { friend class T4B; public: T4A(class T4B *); protected: T4B *mB; // error here }; class T4B {}; } namespace rdar8529993 { struct A { ~A(); }; struct B : A { template<int> friend A::~A(); // expected-error {{destructor cannot be declared as a template}} }; } // PR7915 namespace test5 { struct A; struct A1 { friend void A(); }; struct B { friend void B(); }; } // PR8479 namespace test6_1 { class A { public: private: friend class vectorA; A() {} }; class vectorA { public: vectorA(int i, const A& t = A()) {} }; void f() { vectorA v(1); } } namespace test6_2 { template<class T> class vector { public: vector(int i, const T& t = T()) {} }; class A { public: private: friend class vector<A>; A() {} }; void f() { vector<A> v(1); } } namespace test6_3 { template<class T> class vector { public: vector(int i) {} void f(const T& t = T()) {} }; class A { public: private: friend void vector<A>::f(const A&); A() {} }; void f() { vector<A> v(1); v.f(); } } namespace test7 { extern "C" { class X { friend int test7_f() { return 42; } }; } } // PR15485 namespace test8 { namespace ns1 { namespace ns2 { template<class T> void f(T t); // expected-note {{target of using declaration}} } using ns2::f; // expected-note {{using declaration}} } struct A { void f(); }; // expected-note 2{{target of using declaration}} struct B : public A { using A::f; }; // expected-note {{using declaration}} template<typename T> struct C : A { using A::f; }; // expected-note {{using declaration}} struct X { template<class T> friend void ns1::f(T t); // expected-error {{cannot befriend target of using declaration}} friend void B::f(); // expected-error {{cannot befriend target of using declaration}} friend void C<int>::f(); // expected-error {{cannot befriend target of using declaration}} }; } // PR16423 namespace test9 { class C { }; struct A { friend void C::f(int, int, int) {} // expected-error {{no function named 'f' with type 'void (int, int, int)' was found in the specified scope}} }; } namespace test10 { struct X {}; extern void f10_a(); extern void f10_a(X); struct A { friend void f10_a(); friend void f10_b(); friend void f10_c(); friend void f10_d(); friend void f10_a(X); friend void f10_b(X); friend void f10_c(X); friend void f10_d(X); }; extern void f10_b(); extern void f10_b(X); struct B { friend void f10_a(); friend void f10_b(); friend void f10_c(); friend void f10_d(); friend void f10_a(X); friend void f10_b(X); friend void f10_c(X); friend void f10_d(X); }; extern void f10_c(); extern void f10_c(X); // FIXME: Give a better diagnostic for the case where a function exists but is // not visible. void g(X x) { f10_a(); f10_b(); f10_c(); f10_d(); // expected-error {{undeclared identifier}} ::test10::f10_a(); ::test10::f10_b(); ::test10::f10_c(); ::test10::f10_d(); // expected-error {{no member named 'f10_d'}} f10_a(x); f10_b(x); f10_c(x); f10_d(x); // PR16597: expected-error {{undeclared identifier}} ::test10::f10_a(x); ::test10::f10_b(x); ::test10::f10_c(x); ::test10::f10_d(x); // expected-error {{no type named 'f10_d'}} } struct Y : X { friend void f10_d(); friend void f10_d(X); }; struct Z { operator X(); friend void f10_d(); friend void f10_d(X); }; void g(X x, Y y, Z z) { f10_d(); // expected-error {{undeclared identifier}} ::test10::f10_d(); // expected-error {{no member named 'f10_d'}} // f10_d is visible to ADL in the second and third cases. f10_d(x); // expected-error {{undeclared identifier}} f10_d(y); f10_d(z); // No ADL here. ::test10::f10_d(x); // expected-error {{no type named 'f10_d'}} ::test10::f10_d(y); // expected-error {{no type named 'f10_d'}} ::test10::f10_d(z); // expected-error {{no type named 'f10_d'}} } void local_externs(X x, Y y) { extern void f10_d(); extern void f10_d(X); f10_d(); f10_d(x); // FIXME: This lookup should fail, because the local extern declaration // should suppress ADL. f10_d(y); { int f10_d; f10_d(); // expected-error {{not a function}} f10_d(x); // expected-error {{not a function}} f10_d(y); // expected-error {{not a function}} } } void i(X x, Y y) { f10_d(); // expected-error {{undeclared identifier}} f10_d(x); // expected-error {{undeclared identifier}} f10_d(y); } struct C { friend void f10_d(); friend void f10_d(X); }; void j(X x, Y y) { f10_d(); // expected-error {{undeclared identifier}} f10_d(x); // expected-error {{undeclared identifier}} f10_d(y); } extern void f10_d(); extern void f10_d(X); void k(X x, Y y, Z z) { // All OK now. f10_d(); f10_d(x); ::test10::f10_d(); ::test10::f10_d(x); ::test10::f10_d(y); ::test10::f10_d(z); } } namespace test11 { class __attribute__((visibility("hidden"))) B; class A { friend class __attribute__((visibility("hidden"), noreturn)) B; // expected-warning {{'noreturn' attribute only applies to functions and methods}} }; } namespace pr21851 { // PR21851 was a problem where we assumed that when the friend function redecl // lookup found a C++ method, it would necessarily have a qualifier. Below we // have some test cases where unqualified lookup finds C++ methods without using // qualifiers. Unfortunately, we can't exercise the case of an access check // failure because nested classes always have access to the members of outer // classes. void friend_own_method() { class A { void m() {} friend void m(); }; } void friend_enclosing_method() { class A; class C { int p; friend class A; }; class A { void enclosing_friend() { (void)b->p; (void)c->p; } class B { void b(A *a) { (void)a->c->p; } int p; friend void enclosing_friend(); }; B *b; C *c; }; } static auto friend_file_func() { extern void file_scope_friend(); class A { int p; friend void file_scope_friend(); }; return A(); } void file_scope_friend() { auto a = friend_file_func(); (void)a.p; } } template<typename T> struct X_pr6954 { operator int(); friend void f_pr6954(int x); }; int array0_pr6954[sizeof(X_pr6954<int>)]; int array1_pr6954[sizeof(X_pr6954<float>)]; void g_pr6954() { f_pr6954(5); // expected-error{{undeclared identifier 'f_pr6954'}} } namespace tag_redecl { namespace N { struct X *p; namespace { class K { friend struct X; }; } } namespace N { struct X; X *q = p; } }