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
   93
   94
   95
   96
   97
   98
   99
  100
  101
  102
  103
  104
  105
  106
  107
  108
  109
  110
  111
  112
  113
  114
  115
  116
  117
  118
  119
  120
  121
  122
  123
  124
  125
  126
  127
  128
  129
  130
  131
  132
  133
  134
  135
  136
  137
  138
  139
  140
  141
  142
  143
  144
  145
  146
  147
  148
  149
  150
  151
  152
  153
  154
  155
  156
  157
  158
  159
  160
  161
  162
  163
  164
  165
  166
  167
  168
  169
  170
  171
  172
  173
  174
  175
  176
  177
  178
  179
  180
  181
  182
  183
  184
  185
  186
  187
  188
  189
  190
  191
  192
// RUN: %clang_cc1 -fsyntax-only -verify %s

// C++0x [class.access]p6:
//   All access controls in [class.access] affect the ability to
//   access a class member name from a particular scope. For purposes
//   of access control, the base-specifiers of a class and the
//   definitions of class members that appear outside of the class
//   definition are considered to be within the scope of that
//   class. In particular, access controls apply as usual to member
//   names accessed as part of a function return type, even though it
//   is not possible to determine the access privileges of that use
//   without first parsing the rest of the function
//   declarator. Similarly, access control for implicit calls to the
//   constructors, the conversion functions, or the destructor called
//   to create and destroy a static data member is performed as if
//   these calls appeared in the scope of the member's class.

struct Public {}; struct Protected {}; struct Private {};

namespace test0 {
  class A {
    typedef int type; // expected-note {{declared private here}}
    type foo();
  };

  A::type foo() { } // expected-error {{'type' is a private member}}
  A::type A::foo() { }
}

// conversion decls
namespace test1 {
  class A {
  public:
    A();
    operator Public ();
    A(Public);
  protected:
    operator Protected (); // expected-note {{declared protected here}}
    A(Protected); // expected-note {{declared protected here}}
  private:
    operator Private (); // expected-note {{declared private here}}
    A(Private); // expected-note {{declared private here}}
  };

  void test() {
    A a;
    Public pub = a;
    Protected prot = a; // expected-error {{'operator Protected' is a protected member}}
    Private priv = a; // expected-error {{'operator Private' is a private member}}
    A apub = pub;
    A aprot = prot; // expected-error {{protected constructor}}
    A apriv = priv; // expected-error {{private constructor}}
  }
}

// PR6967
namespace test2 {
  class A {
  public:
    template <class T> static void set(T &t, typename T::type v) {
      t.value = v;
    }
    template <class T> static typename T::type get(const T &t) {
      return t.value;
    }
  };

  class B {
    friend class A;

  private:
    typedef int type;
    type value;
  };

  int test() {
    B b;
    A::set(b, 0);
    return A::get(b);
  }
}

namespace test3 {
  class Green {}; class Blue {};

  // We have to wrap this in a class because a partial specialization
  // isn't actually in the context of the template.
  struct Outer {
    template <class T, class Nat> class A {
    };
  };

  template <class T> class Outer::A<T, typename T::nature> {
  public:
    static void foo(); // expected-note {{'Outer::A<B, Green>::foo' declared here}}
  };

  class B {
  private: typedef Green nature;
    friend class Outer;
  };

  void test() {
    Outer::A<B, Green>::foo();
    Outer::A<B, Blue>::foo(); // expected-error {{no member named 'foo' in 'test3::Outer::A<test3::B, test3::Blue>'; did you mean 'Outer::A<B, Green>::foo'?}}
  }
}

namespace test4 {
  template <class T> class A {
  private: typedef int type;
    template <class U> friend void foo(U &, typename U::type);
  };

  template <class U> void foo(U &, typename U::type) {}
  
  void test() {
    A<int> a;
    foo(a, 0);
  }
}

// PR7644
namespace test5 {
  class A {
    enum Enum { E0, E1, E2 }; // expected-note 4 {{declared private here}}
    template <Enum> void foo();
    template <Enum> class bar;
  };

  template <A::Enum en> void A::foo() {}
  template <A::Enum en> class A::bar {};

  template <A::Enum en> void foo() {} // expected-error {{'Enum' is a private member of 'test5::A'}}
  template <A::Enum en> class bar {}; // expected-error {{'Enum' is a private member of 'test5::A'}}

  class B {
    template <A::Enum en> void foo() {} // expected-error {{'Enum' is a private member of 'test5::A'}}
    template <A::Enum en> class bar {}; // expected-error {{'Enum' is a private member of 'test5::A'}}
  };
}

namespace test6 {
  class A {
  public: class public_inner {};
  protected: class protected_inner {};
  private: class private_inner {}; // expected-note {{declared private here}}
  };

  class B : A {
    public_inner a;
    protected_inner b;
    private_inner c; // expected-error {{'private_inner' is a private member of 'test6::A'}}
  };
}

// PR9229
namespace test7 {
  void foo(int arg[1]);
  class A {
    void check();
  };
  class B {
    friend class A;
    A ins;
  };
  void A::check() {
    void foo(int arg[__builtin_offsetof(B, ins)]);
  }
}

// rdar://problem/10155256
namespace test8 {
  class A {
    typedef void* (A::*UnspecifiedBoolType)() const;
    operator UnspecifiedBoolType() const; // expected-note {{implicitly declared private here}}
  };

  void test(A &a) {
    if (a) return; // expected-error-re {{'operator void *(test8::A::*)(){{( __attribute__\(\(thiscall\)\))?}} const' is a private member of 'test8::A'}}
  }
}

namespace test9 {
  class A {
    operator char*() const; // expected-note {{implicitly declared private here}}
  };

  void test(A &a) {
    delete a; // expected-error {{'operator char *' is a private member of 'test9::A'}}
  }
}