• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
myoperation(float f)84 int myoperation(float f) {
85   return (int) f;
86 }
87 
88 template <typename T>
89 class B {
90   template <typename U>
B()91   friend B<U>() {} // expected-error {{must use a qualified name when declaring a constructor as a friend}}
92 };
93