1// RUN: %clang_cc1 -fsyntax-only -verify %s
2
3// This is just the test for [namespace.udecl]p4 with 'using'
4// uniformly stripped out.
5
6// C++03 [namespace.udecl]p4:
7//   A using-declaration used as a member-declaration shall refer to a
8//   member of a base class of the class being defined, shall refer to
9//   a member of an anonymous union that is a member of a base class
10//   of the class being defined, or shall refer to an enumerator for
11//   an enumeration type that is a member of a base class of the class
12//   being defined.
13
14// There is no directly analogous paragraph in C++0x, and the feature
15// works sufficiently differently there that it needs a separate test.
16
17namespace test0 {
18  namespace NonClass {
19    typedef int type;
20    struct hiding {};
21    int hiding;
22    static union { double union_member; };
23    enum tagname { enumerator };
24  }
25
26  class Test0 {
27    NonClass::type; // expected-error {{not a class}} expected-warning {{access declarations are deprecated}}
28    NonClass::hiding; // expected-error {{not a class}} expected-warning {{access declarations are deprecated}}
29    NonClass::union_member; // expected-error {{not a class}} expected-warning {{access declarations are deprecated}}
30    NonClass::enumerator; // expected-error {{not a class}} expected-warning {{access declarations are deprecated}}
31  };
32}
33
34struct Opaque0 {};
35
36namespace test1 {
37  struct A {
38    typedef int type;
39    struct hiding {}; // expected-note {{previous use is here}}
40    Opaque0 hiding;
41    union { double union_member; };
42    enum tagname { enumerator };
43  };
44
45  struct B : A {
46    A::type; // expected-warning {{access declarations are deprecated}}
47    A::hiding; // expected-warning {{access declarations are deprecated}}
48    A::union_member; // expected-warning {{access declarations are deprecated}}
49    A::enumerator; // expected-warning {{access declarations are deprecated}}
50    A::tagname; // expected-warning {{access declarations are deprecated}}
51
52    void test0() {
53      type t = 0;
54    }
55
56    void test1() {
57      typedef struct A::hiding local;
58      struct hiding _ = local();
59    }
60
61    void test2() {
62      union hiding _; // expected-error {{tag type that does not match previous}}
63    }
64
65    void test3() {
66      char array[sizeof(union_member) == sizeof(double) ? 1 : -1];
67    }
68
69    void test4() {
70      enum tagname _ = enumerator;
71    }
72
73    void test5() {
74      Opaque0 _ = hiding;
75    }
76  };
77}
78
79namespace test2 {
80  struct A {
81    typedef int type;
82    struct hiding {}; // expected-note {{previous use is here}}
83    int hiding;
84    union { double union_member; };
85    enum tagname { enumerator };
86  };
87
88  template <class T> struct B : A {
89    A::type; // expected-warning {{access declarations are deprecated}}
90    A::hiding; // expected-warning {{access declarations are deprecated}}
91    A::union_member; // expected-warning {{access declarations are deprecated}}
92    A::enumerator; // expected-warning {{access declarations are deprecated}}
93    A::tagname; // expected-warning {{access declarations are deprecated}}
94
95    void test0() {
96      type t = 0;
97    }
98
99    void test1() {
100      typedef struct A::hiding local;
101      struct hiding _ = local();
102    }
103
104    void test2() {
105      union hiding _; // expected-error {{tag type that does not match previous}}
106    }
107
108    void test3() {
109      char array[sizeof(union_member) == sizeof(double) ? 1 : -1];
110    }
111
112    void test4() {
113      enum tagname _ = enumerator;
114    }
115
116    void test5() {
117      Opaque0 _ = hiding;
118    }
119  };
120}
121
122namespace test3 {
123  struct hiding {};
124
125  template <class T> struct A {
126    typedef int type; // expected-note {{target of using declaration}}
127    struct hiding {};
128    Opaque0 hiding;
129    union { double union_member; };
130    enum tagname { enumerator }; // expected-note {{target of using declaration}}
131  };
132
133  template <class T> struct B : A<T> {
134    A<T>::type; // expected-error {{dependent using declaration resolved to type without 'typename'}} // expected-warning {{access declarations are deprecated}}
135    A<T>::hiding; // expected-warning {{access declarations are deprecated}}
136    A<T>::union_member; // expected-warning {{access declarations are deprecated}}
137    A<T>::enumerator; // expected-warning {{access declarations are deprecated}}
138    A<T>::tagname; // expected-error {{dependent using declaration resolved to type without 'typename'}} // expected-warning {{access declarations are deprecated}}
139
140    // FIXME: re-enable these when the various bugs involving tags are fixed
141#if 0
142    void test1() {
143      typedef struct A<T>::hiding local;
144      struct hiding _ = local();
145    }
146
147    void test2() {
148      typedef struct A<T>::hiding local;
149      union hiding _ = local();
150    }
151#endif
152
153    void test3() {
154      char array[sizeof(union_member) == sizeof(double) ? 1 : -1];
155    }
156
157#if 0
158    void test4() {
159      enum tagname _ = enumerator;
160    }
161#endif
162
163    void test5() {
164      Opaque0 _ = hiding;
165    }
166  };
167
168  template struct B<int>; // expected-note {{in instantiation}}
169}
170
171namespace test4 {
172  struct Base {
173    int foo();
174  };
175
176  struct Unrelated {
177    int foo();
178  };
179
180  struct Subclass : Base {
181  };
182
183  namespace InnerNS {
184    int foo();
185  }
186
187  // We should be able to diagnose these without instantiation.
188  template <class T> struct C : Base {
189    InnerNS::foo; // expected-error {{not a class}} expected-warning {{access declarations are deprecated}}
190    Base::bar; // expected-error {{no member named 'bar'}} expected-warning {{access declarations are deprecated}}
191    Unrelated::foo; // expected-error {{not a base class}} expected-warning {{access declarations are deprecated}}
192    C::foo; // legal in C++03 // expected-warning {{access declarations are deprecated}}
193    Subclass::foo; // legal in C++03 // expected-warning {{access declarations are deprecated}}
194
195    int bar(); //expected-note {{target of using declaration}}
196    C::bar; // expected-error {{refers to its own class}} expected-warning {{access declarations are deprecated}}
197  };
198}
199
200