reference, declarationdefinition
definition → references, declarations, derived classes, virtual overrides
reference to multiple definitions → definitions
unreferenced
    1
    2
    3
    4
    5
    6
    7
    8
    9
   10
   11
   12
   13
   14
   15
   16
   17
   18
   19
   20
   21
   22
   23
   24
   25
   26
   27
   28
   29
   30
   31
   32
   33
   34
   35
   36
   37
   38
   39
   40
   41
   42
   43
   44
   45
   46
   47
   48
   49
   50
   51
   52
   53
   54
   55
   56
   57
   58
   59
   60
   61
   62
   63
   64
   65
   66
   67
   68
   69
   70
   71
   72
   73
   74
   75
   76
   77
   78
   79
   80
   81
   82
   83
   84
   85
   86
   87
   88
   89
   90
   91
   92
// RUN: %clang_cc1 -fsyntax-only -verify %s
// RUN: %clang_cc1 -fsyntax-only -verify -std=c++98 %s
// RUN: %clang_cc1 -fsyntax-only -verify -std=c++11 %s

struct Outer {
  struct Inner {
    int intfield;
  };
};

struct Base {
  void base_member();
  
  typedef int Int;
  Int typedeffed_member();
};

struct Derived : public Base {
};

int myglobal;

void global_function();
extern "C" {
  void global_c_function();
}

class A {
  class AInner {
  };

  friend class PreDeclared;
  friend class Outer::Inner;
  friend int Outer::Inner::intfield; // expected-error {{friends can only be classes or functions}}
  friend int Outer::Inner::missing_field; //expected-error {{friends can only be classes or functions}}
  friend int myoperation(float); // okay
  friend int myglobal;   // expected-error {{friends can only be classes or functions}}

  friend void global_function();
  friend void global_c_function();

  friend class UndeclaredSoFar;
  UndeclaredSoFar x; // expected-error {{unknown type name 'UndeclaredSoFar'}}

  void a_member();
  friend void A::a_member();
#if __cplusplus <= 199711L
  // expected-error@-2 {{friends cannot be members of the declaring class}}
#endif
  friend void a_member(); // okay (because we ignore class scopes when looking up friends)
  friend class A::AInner; // this is okay as an extension
  friend class AInner; // okay, refers to ::AInner

  friend void Derived::missing_member(); // expected-error {{friend declaration of 'missing_member' does not match any declaration in 'Derived'}}

  friend void Derived::base_member(); // expected-error {{friend declaration of 'base_member' does not match any declaration in 'Derived'}}

  friend int Base::typedeffed_member(); // okay: should look through typedef

  // These test that the friend is properly not being treated as a
  // member function.
  friend A operator|(const A& l, const A& r); // okay
  friend A operator|(const A& r); // expected-error {{overloaded 'operator|' must be a binary operator (has 1 parameter)}}

  friend operator bool() const; // expected-error {{must use a qualified name when declaring a conversion operator as a friend}} \
       // expected-error{{non-member function cannot have 'const' qualifier}}

  typedef void ftypedef();
  friend ftypedef typedeffed_function; // okay (because it's not declared as a member)

  class facet;
  friend class facet;  // should not assert
  class facet {};

  friend int Unknown::thing(); // expected-error {{use of undeclared identifier}}
  friend int friendfunc(), Unknown::thing(); // expected-error {{use of undeclared identifier}}
  friend int friendfunc(), Unknown::thing() : 4; // expected-error {{use of undeclared identifier}}
};

A::UndeclaredSoFar y; // expected-error {{no type named 'UndeclaredSoFar' in 'A'}}

class PreDeclared;

int myoperation(float f) {
  return (int) f;
}

template <typename T>
class B {
  template <typename U>
  friend B<U>() {} // expected-error {{must use a qualified name when declaring a constructor as a friend}}
};