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