Clang Project

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