[bazel] Port 0aa831e0edb1c1deabb96ce2435667cc82bac79b
[llvm-project.git] / clang / test / CXX / dcl.dcl / basic.namespace / namespace.udecl / p4.cpp
blob65ccb751b9aa52366718ea7eca56518cd6d83aa2
1 // RUN: %clang_cc1 -fsyntax-only -verify %s
2 // RUN: %clang_cc1 -fsyntax-only -verify -std=c++98 %s
3 // RUN: %clang_cc1 -fsyntax-only -verify -std=c++11 %s
5 // C++03 [namespace.udecl]p4:
6 // A using-declaration used as a member-declaration shall refer to a
7 // member of a base class of the class being defined, shall refer to
8 // a member of an anonymous union that is a member of a base class
9 // of the class being defined, or shall refer to an enumerator for
10 // an enumeration type that is a member of a base class of the class
11 // being defined.
13 // There is no directly analogous paragraph in C++0x, and the feature
14 // works sufficiently differently there that it needs a separate test.
16 namespace test0 {
17 namespace NonClass {
18 typedef int type;
19 struct hiding {};
20 int hiding;
21 static union { double union_member; };
22 enum tagname { enumerator };
25 class Test0 {
26 using NonClass::type; // expected-error {{not a class}}
27 using NonClass::hiding; // expected-error {{not a class}}
28 using NonClass::union_member; // expected-error {{not a class}}
29 using NonClass::enumerator; // expected-error {{not a class}}
33 struct Opaque0 {};
35 namespace test1 {
36 struct A {
37 typedef int type;
38 struct hiding {}; // expected-note {{previous use is here}}
39 Opaque0 hiding;
40 union { double union_member; };
41 enum tagname { enumerator };
44 struct B : A {
45 using A::type;
46 using A::hiding;
47 using A::union_member;
48 using A::enumerator;
49 using A::tagname;
51 void test0() {
52 type t = 0;
55 void test1() {
56 typedef struct A::hiding local;
57 struct hiding _ = local();
60 void test2() {
61 union hiding _; // expected-error {{tag type that does not match previous}}
64 void test3() {
65 char array[sizeof(union_member) == sizeof(double) ? 1 : -1];
68 void test4() {
69 enum tagname _ = enumerator;
72 void test5() {
73 Opaque0 _ = hiding;
78 namespace test2 {
79 struct A {
80 typedef int type;
81 struct hiding {}; // expected-note {{previous use is here}}
82 int hiding;
83 union { double union_member; };
84 enum tagname { enumerator };
87 template <class T> struct B : A {
88 using A::type;
89 using A::hiding;
90 using A::union_member;
91 using A::enumerator;
92 using A::tagname;
94 void test0() {
95 type t = 0;
98 void test1() {
99 typedef struct A::hiding local;
100 struct hiding _ = local();
103 void test2() {
104 union hiding _; // expected-error {{tag type that does not match previous}}
107 void test3() {
108 char array[sizeof(union_member) == sizeof(double) ? 1 : -1];
111 void test4() {
112 enum tagname _ = enumerator;
115 void test5() {
116 Opaque0 _ = hiding;
121 namespace test3 {
122 struct hiding {};
124 template <class T> struct A {
125 typedef int type; // expected-note {{target of using declaration}}
126 struct hiding {};
127 Opaque0 hiding; // expected-note {{target of using declaration}}
128 union { double union_member; }; // expected-note {{target of using declaration}}
129 enum tagname { enumerator }; // expected-note 2 {{target of using declaration}}
132 template <class T> struct B : A<T> {
133 using A<T>::type; // expected-error {{dependent using declaration resolved to type without 'typename'}}
134 using A<T>::hiding;
135 using A<T>::union_member;
136 using A<T>::enumerator;
137 using A<T>::tagname; // expected-error {{dependent using declaration resolved to type without 'typename'}}
139 // FIXME: re-enable these when the various bugs involving tags are fixed
140 #if 0
141 void test1() {
142 typedef struct A<T>::hiding local;
143 struct hiding _ = local();
146 void test2() {
147 typedef struct A<T>::hiding local;
148 union hiding _ = local();
150 #endif
152 void test3() {
153 char array[sizeof(union_member) == sizeof(double) ? 1 : -1];
156 #if 0
157 void test4() {
158 enum tagname _ = enumerator;
160 #endif
162 void test5() {
163 Opaque0 _ = hiding;
167 template struct B<int>; // expected-note {{in instantiation}}
169 template <class T> struct C : A<T> {
170 using typename A<T>::type;
171 using typename A<T>::hiding; // expected-note {{declared here}} \
172 // expected-error {{'typename' keyword used on a non-type}}
173 using typename A<T>::union_member; // expected-error {{'typename' keyword used on a non-type}}
174 using typename A<T>::enumerator; // expected-error {{'typename' keyword used on a non-type}}
176 void test6() {
177 type t = 0;
180 void test7() {
181 Opaque0 _ = hiding; // expected-error {{does not refer to a value}}
185 template struct C<int>; // expected-note {{in instantiation}}
188 namespace test4 {
189 struct Base {
190 int foo();
193 struct Unrelated {
194 int foo();
197 struct Subclass : Base {
200 namespace InnerNS {
201 int foo();
204 // We should be able to diagnose these without instantiation.
205 template <class T> struct C : Base {
206 using InnerNS::foo; // expected-error {{not a class}}
207 using Base::bar; // expected-error {{no member named 'bar'}}
208 using Unrelated::foo; // expected-error {{not a base class}}
209 using C::foo; // legal in C++03
210 using Subclass::foo; // legal in C++03
211 #if __cplusplus >= 201103L
212 // expected-error@-3 {{refers to its own class}}
213 // expected-error@-3 {{refers into 'Subclass::', which is not a base class}}
214 #endif
216 int bar();
217 #if __cplusplus < 201103L
218 // expected-note@-2 {{target of using declaration}}
219 #endif
220 using C::bar; // expected-error {{refers to its own class}}
224 namespace test5 {
225 struct B;
226 struct A {
227 A(const B&);
228 B &operator=(const B&);
230 struct B : A {
231 #if __cplusplus >= 201103L
232 using A::A;
233 #endif
234 using A::operator=;
236 void test(B b) {
237 B b2(b);
238 b2 = b;