1// RUN: %clang_cc1 -fsyntax-only -verify %s
2
3// C++0x [class.access.base]p1(a):
4//   If a class is declared to be a base class for another class using
5//   the public access specifier, the public members of the base class
6//   are accessible as public members of the derived class and protected
7//   members of the base class are accessible as protected members of
8//   the derived class.
9namespace test0 {
10  class Base {
11  public: int pub; static int spub;
12  protected: int prot; static int sprot; // expected-note 4 {{declared protected here}}
13  private: int priv; static int spriv; // expected-note 8 {{declared private here}}
14  };
15
16  class Test : public Base {
17    void test() {
18      pub++;
19      spub++;
20      prot++;
21      sprot++;
22      priv++; // expected-error {{private member}}
23      spriv++; // expected-error {{private member}}
24
25      Base::pub++;
26      Base::spub++;
27      Base::prot++;
28      Base::sprot++;
29      Base::priv++; // expected-error {{private member}}
30      Base::spriv++; // expected-error {{private member}}
31    }
32  };
33
34  void test(Test *t) {
35    t->pub++;
36    t->spub++;
37    t->prot++; // expected-error {{protected member}}
38    t->sprot++; // expected-error {{protected member}}
39    t->priv++; // expected-error {{private member}}
40    t->spriv++; // expected-error {{private member}}
41
42    t->Base::pub++;
43    t->Base::spub++;
44    t->Base::prot++; // expected-error {{protected member}}
45    t->Base::sprot++; // expected-error {{protected member}}
46    t->Base::priv++; // expected-error {{private member}}
47    t->Base::spriv++; // expected-error {{private member}}
48  }
49}
50
51// C++0x [class.access.base]p1(b):
52//   If a class is declared to be a base class for another class using
53//   the protected access specifier, the public and protected members
54//   of the base class are accessible as protected members of the
55//   derived class.
56namespace test1 {
57  class Base { // expected-note 6{{member is declared here}}
58  public:
59    int pub; // expected-note{{member is declared here}}
60    static int spub; // expected-note{{member is declared here}}
61  protected: int prot; static int sprot; // expected-note 4 {{declared protected here}}
62  private: int priv; static int spriv; // expected-note 8 {{declared private here}}
63  };
64
65  class Test : protected Base { // expected-note 6 {{declared protected here}} expected-note 8 {{constrained by protected inheritance here}}
66    void test() {
67      pub++;
68      spub++;
69      prot++;
70      sprot++;
71      priv++; // expected-error {{private member}}
72      spriv++; // expected-error {{private member}}
73
74      Base::pub++;
75      Base::spub++;
76      Base::prot++;
77      Base::sprot++;
78      Base::priv++; // expected-error {{private member}}
79      Base::spriv++; // expected-error {{private member}}
80    }
81  };
82
83  void test(Test *t) {
84    t->pub++; // expected-error {{protected member}} expected-error {{protected base class}}
85    t->spub++; // expected-error {{protected member}}
86    t->prot++; // expected-error {{protected member}} expected-error {{protected base class}}
87    t->sprot++; // expected-error {{protected member}}
88    t->priv++; // expected-error {{private member}} expected-error {{protected base class}}
89    t->spriv++; // expected-error {{private member}}
90
91    // Two possible errors here: one for Base, one for the member
92    t->Base::pub++; // expected-error {{protected member}} expected-error {{protected base class}}
93    t->Base::spub++; // expected-error {{protected member}}
94    t->Base::prot++; // expected-error 2 {{protected member}} expected-error {{protected base class}}
95    t->Base::sprot++; // expected-error 2 {{protected member}}
96    t->Base::priv++; // expected-error {{protected member}} expected-error {{private member}} expected-error {{protected base class}}
97    t->Base::spriv++; // expected-error {{protected member}} expected-error {{private member}}
98  }
99}
100
101// C++0x [class.access.base]p1(b):
102//   If a class is declared to be a base class for another class using
103//   the private access specifier, the public and protected members of
104//   the base class are accessible as private members of the derived
105//   class.
106namespace test2 {
107  class Base { // expected-note 6{{member is declared here}}
108  public:
109    int pub; // expected-note{{member is declared here}}
110    static int spub; // expected-note{{member is declared here}}
111  protected:
112    int prot; // expected-note {{declared protected here}} \
113    // expected-note{{member is declared here}}
114    static int sprot; // expected-note {{declared protected here}} \
115    // expected-note{{member is declared here}}
116  private:
117    int priv; // expected-note 4 {{declared private here}}
118    static int spriv; // expected-note 4 {{declared private here}}
119  };
120
121  class Test : private Base { // expected-note 6 {{declared private here}} \
122                              // expected-note 10 {{constrained by private inheritance here}}
123    void test() {
124      pub++;
125      spub++;
126      prot++;
127      sprot++;
128      priv++; // expected-error {{private member}}
129      spriv++; // expected-error {{private member}}
130
131      Base::pub++;
132      Base::spub++;
133      Base::prot++;
134      Base::sprot++;
135      Base::priv++; // expected-error {{private member}}
136      Base::spriv++; // expected-error {{private member}}
137    }
138  };
139
140  void test(Test *t) {
141    t->pub++; // expected-error {{private member}} expected-error {{private base class}}
142    t->spub++; // expected-error {{private member}}
143    t->prot++; // expected-error {{private member}} expected-error {{private base class}}
144    t->sprot++; // expected-error {{private member}}
145    t->priv++; // expected-error {{private member}} expected-error {{private base class}}
146    t->spriv++; // expected-error {{private member}}
147
148    t->Base::pub++; // expected-error {{private member}} expected-error {{private base class}}
149    t->Base::spub++; // expected-error {{private member}}
150    t->Base::prot++; // expected-error {{protected member}} expected-error {{private member}} expected-error {{private base class}}
151    t->Base::sprot++; // expected-error {{protected member}} expected-error {{private member}}
152    t->Base::priv++; // expected-error 2 {{private member}} expected-error {{private base class}}
153    t->Base::spriv++; // expected-error 2 {{private member}}
154  }
155}
156
157namespace PR12788 {
158  class A {
159  protected:
160    struct {
161      int x;
162    };
163  };
164  class B : A {
165    void f() {
166      ++x;
167      A::x++;
168    }
169  };
170}
171