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