1 // RUN: %clang_cc1 -fsyntax-only -std=c++98 -verify %s
2 // RUN: %clang_cc1 -fsyntax-only -std=c++11 -verify %s
3 // RUN: %clang_cc1 -fsyntax-only -std=c++14 -verify %s
4 // RUN: not %clang_cc1 -fsyntax-only -std=c++98 -fdiagnostics-parseable-fixits %s 2>&1 | FileCheck --check-prefix=CXX98 %s
5 // RUN: not %clang_cc1 -fsyntax-only -std=c++11 -fdiagnostics-parseable-fixits %s 2>&1 | FileCheck --check-prefix=CXX11 %s
6 // C++0x N2914.
7
8 struct X {
9 int i;
10 static int a;
11 enum E { e };
12 };
13
14 using X::i; // expected-error{{using declaration cannot refer to class member}}
15 using X::s; // expected-error{{using declaration cannot refer to class member}}
16 using X::e; // expected-error{{using declaration cannot refer to class member}}
17 using X::E::e; // expected-error{{using declaration cannot refer to class member}} expected-warning 0-1{{C++11}}
18 #if __cplusplus < 201103L
19 // expected-note@-3 {{use a const variable}}
20 // expected-note@-3 {{use a const variable}}
21 // CXX98-NOT: fix-it:"{{.*}}":{[[@LINE-5]]:
22 // CXX98-NOT: fix-it:"{{.*}}":{[[@LINE-5]]:
23 #else
24 // expected-note@-8 {{use a constexpr variable}}
25 // expected-note@-8 {{use a constexpr variable}}
26 // CXX11: fix-it:"{{.*}}":{[[@LINE-10]]:1-[[@LINE-10]]:6}:"constexpr auto e = "
27 // CXX11: fix-it:"{{.*}}":{[[@LINE-10]]:1-[[@LINE-10]]:6}:"constexpr auto e = "
28 #endif
29
f()30 void f() {
31 using X::i; // expected-error{{using declaration cannot refer to class member}}
32 using X::s; // expected-error{{using declaration cannot refer to class member}}
33 using X::e; // expected-error{{using declaration cannot refer to class member}}
34 using X::E::e; // expected-error{{using declaration cannot refer to class member}} expected-warning 0-1{{C++11}}
35 #if __cplusplus < 201103L
36 // expected-note@-3 {{use a const variable}}
37 // expected-note@-3 {{use a const variable}}
38 // CXX98-NOT: fix-it:"{{.*}}":{[[@LINE-5]]:
39 // CXX98-NOT: fix-it:"{{.*}}":{[[@LINE-5]]:
40 #else
41 // expected-note@-8 {{use a constexpr variable}}
42 // expected-note@-8 {{use a constexpr variable}}
43 // CXX11: fix-it:"{{.*}}":{[[@LINE-10]]:3-[[@LINE-10]]:8}:"constexpr auto e = "
44 // CXX11: fix-it:"{{.*}}":{[[@LINE-10]]:3-[[@LINE-10]]:8}:"constexpr auto e = "
45 #endif
46 }
47
48 namespace PR21933 {
49 struct A { int member; };
50 struct B { static int member; };
51 enum C { member };
52
53 template <typename T>
54 struct X {
StaticFunPR21933::X55 static void StaticFun() {
56 using T::member; // expected-error 2{{class member}} expected-note {{use a reference instead}}
57 #if __cplusplus < 201103L
58 // expected-error@-2 {{cannot be used prior to '::'}}
59 #endif
60 (void)member;
61 }
62 };
63 template<typename T>
64 struct Y : T {
StaticFunPR21933::Y65 static void StaticFun() {
66 using T::member; // expected-error 2{{class member}} expected-note {{use a reference instead}}
67 (void)member;
68 }
69 };
70
f()71 void f() {
72 X<A>::StaticFun(); // expected-note {{instantiation of}}
73 X<B>::StaticFun(); // expected-note {{instantiation of}}
74 X<C>::StaticFun();
75 #if __cplusplus < 201103L
76 // expected-note@-2 {{instantiation of}}
77 #endif
78 Y<A>::StaticFun(); // expected-note {{instantiation of}}
79 Y<B>::StaticFun(); // expected-note {{instantiation of}}
80 }
81
value_vs_value()82 template<typename T, typename U> void value_vs_value() {
83 using T::a; // expected-note {{previous}}
84 #if __cplusplus < 201103L
85 // expected-error@-2 {{cannot be used prior to '::'}}
86 #endif
87 extern int a(); // expected-error {{different kind of symbol}}
88 a();
89
90 extern int b(); // expected-note {{previous}}
91 using T::b; // expected-error {{different kind of symbol}}
92 b();
93
94 using T::c; // expected-note {{previous}}
95 using U::c; // expected-error-re {{redefinition of 'c'{{$}}}}
96 c();
97 }
98
value_vs_type()99 template<typename T, typename U> void value_vs_type() {
100 using T::Xt; // expected-note {{previous}}
101 typedef struct {} Xt; // expected-error {{different kind of symbol}}
102 (void)Xt;
103
104 using T::Xs; // expected-note {{hidden by}}
105 struct Xs {};
106 (void)Xs;
107 Xs xs; // expected-error {{must use 'struct'}}
108
109 using T::Xe; // expected-note {{hidden by}}
110 enum Xe {};
111 (void)Xe;
112 Xe xe; // expected-error {{must use 'enum'}}
113
114 typedef struct {} Yt; // expected-note {{candidate}}
115 using T::Yt; // eypected-error {{different kind of symbol}} expected-note {{candidate}}
116 Yt yt; // expected-error {{ambiguous}}
117
118 struct Ys {};
119 using T::Ys; // expected-note {{hidden by}}
120 (void)Ys;
121 Ys ys; // expected-error {{must use 'struct'}}
122
123 enum Ye {};
124 using T::Ye; // expected-note {{hidden by}}
125 Ye ye; // expected-error {{must use 'enum'}}
126 }
127
type()128 template<typename T> void type() {
129 // Must be a class member because T:: can only name a class or enum,
130 // and an enum cannot have a type member.
131 using typename T::X; // expected-error {{cannot refer to class member}}
132 }
133
134 namespace N1 { enum E { a, b, c }; }
135 namespace N2 { enum E { a, b, c }; }
g()136 void g() { value_vs_value<N1::E, N2::E>(); }
137 #if __cplusplus < 201103L
138 // expected-note@-2 {{in instantiation of}}
139 #endif
140
141 #if __cplusplus >= 201402L
142 namespace partial_substitute {
f()143 template<typename T> auto f() {
144 return [](auto x) {
145 using A = typename T::template U<decltype(x)>;
146 using A::E::e;
147 struct S : A {
148 using A::f;
149 using typename A::type;
150 type f(int) { return e; }
151 };
152 return S();
153 };
154 }
155 enum Enum { e };
156 struct X {
157 template<typename T> struct U {
158 int f(int, int);
159 using type = int;
160 using E = Enum;
161 };
162 };
test()163 int test() {
164 auto s = f<X>()(0);
165 return s.f(0) + s.f(0, 0);
166 }
167
g()168 template<typename T, typename U> auto g() {
169 return [](auto x) {
170 using X = decltype(x);
171 struct S : T::template Q<X>, U::template Q<X> {
172 using T::template Q<X>::f;
173 using U::template Q<X>::f;
174 void h() { f(); }
175 void h(int n) { f(n); }
176 };
177 return S();
178 };
179 }
180 struct A { template<typename> struct Q { int f(); }; };
181 struct B { template<typename> struct Q { int f(int); }; };
test2()182 int test2() {
183 auto s = g<A, B>()(0);
184 s.f();
185 s.f(0);
186 s.h();
187 s.h(0);
188 }
189 }
190 #endif
191
192 template<typename T, typename U> struct RepeatedMember : T, U {
193 // FIXME: This is the wrong error: we should complain that a member type
194 // cannot be redeclared at class scope.
195 using typename T::type; // expected-note {{candidate}}
196 using typename U::type; // expected-note {{candidate}}
197 type x; // expected-error {{ambiguous}}
198 };
199 }
200
201 struct S {
202 static int n;
203 struct Q {};
204 enum E {};
205 typedef Q T;
206 void f();
207 static void g();
208 };
209
210 using S::n; // expected-error{{class member}} expected-note {{use a reference instead}}
211 #if __cplusplus < 201103L
212 // CXX98-NOT: fix-it:"{{.*}}":{[[@LINE-2]]
213 #else
214 // CXX11: fix-it:"{{.*}}":{[[@LINE-4]]:1-[[@LINE-4]]:6}:"auto &n = "
215 #endif
216
217 using S::Q; // expected-error{{class member}}
218 #if __cplusplus < 201103L
219 // expected-note@-2 {{use a typedef declaration instead}}
220 // CXX98: fix-it:"{{.*}}":{[[@LINE-3]]:1-[[@LINE-3]]:6}:"typedef"
221 // CXX98: fix-it:"{{.*}}":{[[@LINE-4]]:11-[[@LINE-4]]:11}:" Q"
222 #else
223 // expected-note@-6 {{use an alias declaration instead}}
224 // CXX11: fix-it:"{{.*}}":{[[@LINE-7]]:7-[[@LINE-7]]:7}:"Q = "
225 #endif
226
227 using S::E; // expected-error{{class member}}
228 #if __cplusplus < 201103L
229 // expected-note@-2 {{use a typedef declaration instead}}
230 // CXX98: fix-it:"{{.*}}":{[[@LINE-3]]:1-[[@LINE-3]]:6}:"typedef"
231 // CXX98: fix-it:"{{.*}}":{[[@LINE-4]]:11-[[@LINE-4]]:11}:" E"
232 #else
233 // expected-note@-6 {{use an alias declaration instead}}
234 // CXX11: fix-it:"{{.*}}":{[[@LINE-7]]:7-[[@LINE-7]]:7}:"E = "
235 #endif
236
237 using S::T; // expected-error{{class member}}
238 #if __cplusplus < 201103L
239 // expected-note@-2 {{use a typedef declaration instead}}
240 // CXX98: fix-it:"{{.*}}":{[[@LINE-3]]:1-[[@LINE-3]]:6}:"typedef"
241 // CXX98: fix-it:"{{.*}}":{[[@LINE-4]]:11-[[@LINE-4]]:11}:" T"
242 #else
243 // expected-note@-6 {{use an alias declaration instead}}
244 // CXX11: fix-it:"{{.*}}":{[[@LINE-7]]:7-[[@LINE-7]]:7}:"T = "
245 #endif
246
247 using S::f; // expected-error{{class member}}
248 using S::g; // expected-error{{class member}}
249
h()250 void h() {
251 using S::n; // expected-error{{class member}} expected-note {{use a reference instead}}
252 #if __cplusplus < 201103L
253 // CXX98-NOT: fix-it:"{{.*}}":{[[@LINE-2]]
254 #else
255 // CXX11: fix-it:"{{.*}}":{[[@LINE-4]]:3-[[@LINE-4]]:8}:"auto &n = "
256 #endif
257
258 using S::Q; // expected-error{{class member}}
259 #if __cplusplus < 201103L
260 // expected-note@-2 {{use a typedef declaration instead}}
261 // CXX98: fix-it:"{{.*}}":{[[@LINE-3]]:3-[[@LINE-3]]:8}:"typedef"
262 // CXX98: fix-it:"{{.*}}":{[[@LINE-4]]:13-[[@LINE-4]]:13}:" Q"
263 #else
264 // expected-note@-6 {{use an alias declaration instead}}
265 // CXX11: fix-it:"{{.*}}":{[[@LINE-7]]:9-[[@LINE-7]]:9}:"Q = "
266 #endif
267
268 using S::E; // expected-error{{class member}}
269 #if __cplusplus < 201103L
270 // expected-note@-2 {{use a typedef declaration instead}}
271 // CXX98: fix-it:"{{.*}}":{[[@LINE-3]]:3-[[@LINE-3]]:8}:"typedef"
272 // CXX98: fix-it:"{{.*}}":{[[@LINE-4]]:13-[[@LINE-4]]:13}:" E"
273 #else
274 // expected-note@-6 {{use an alias declaration instead}}
275 // CXX11: fix-it:"{{.*}}":{[[@LINE-7]]:9-[[@LINE-7]]:9}:"E = "
276 #endif
277
278 using S::T; // expected-error{{class member}}
279 #if __cplusplus < 201103L
280 // expected-note@-2 {{use a typedef declaration instead}}
281 // CXX98: fix-it:"{{.*}}":{[[@LINE-3]]:3-[[@LINE-3]]:8}:"typedef"
282 // CXX98: fix-it:"{{.*}}":{[[@LINE-4]]:13-[[@LINE-4]]:13}:" T"
283 #else
284 // expected-note@-6 {{use an alias declaration instead}}
285 // CXX11: fix-it:"{{.*}}":{[[@LINE-7]]:9-[[@LINE-7]]:9}:"T = "
286 #endif
287
288 using S::f; // expected-error{{class member}}
289 using S::g; // expected-error{{class member}}
290 }
291