291 lines
		
	
	
		
			9.5 KiB
		
	
	
	
		
			C++
		
	
	
	
			
		
		
	
	
			291 lines
		
	
	
		
			9.5 KiB
		
	
	
	
		
			C++
		
	
	
	
| // RUN: %clang_cc1 -fsyntax-only -std=c++98 -verify %s
 | |
| // RUN: %clang_cc1 -fsyntax-only -std=c++11 -verify %s
 | |
| // RUN: %clang_cc1 -fsyntax-only -std=c++14 -verify %s
 | |
| // RUN: not %clang_cc1 -fsyntax-only -std=c++98 -fdiagnostics-parseable-fixits %s 2>&1 | FileCheck --check-prefix=CXX98 %s
 | |
| // RUN: not %clang_cc1 -fsyntax-only -std=c++11 -fdiagnostics-parseable-fixits %s 2>&1 | FileCheck --check-prefix=CXX11 %s
 | |
| // C++0x N2914.
 | |
| 
 | |
| struct X {
 | |
|   int i;
 | |
|   static int a;
 | |
|   enum E { e };
 | |
| };
 | |
| 
 | |
| using X::i; // expected-error{{using declaration cannot refer to class member}}
 | |
| using X::s; // expected-error{{using declaration cannot refer to class member}}
 | |
| using X::e; // expected-error{{using declaration cannot refer to class member}}
 | |
| using X::E::e; // expected-error{{using declaration cannot refer to class member}} expected-warning 0-1{{C++11}}
 | |
| #if __cplusplus < 201103L
 | |
| // expected-note@-3 {{use a const variable}}
 | |
| // expected-note@-3 {{use a const variable}}
 | |
| // CXX98-NOT: fix-it:"{{.*}}":{[[@LINE-5]]:
 | |
| // CXX98-NOT: fix-it:"{{.*}}":{[[@LINE-5]]:
 | |
| #else
 | |
| // expected-note@-8 {{use a constexpr variable}}
 | |
| // expected-note@-8 {{use a constexpr variable}}
 | |
| // CXX11: fix-it:"{{.*}}":{[[@LINE-10]]:1-[[@LINE-10]]:6}:"constexpr auto e = "
 | |
| // CXX11: fix-it:"{{.*}}":{[[@LINE-10]]:1-[[@LINE-10]]:6}:"constexpr auto e = "
 | |
| #endif
 | |
| 
 | |
| void f() {
 | |
|   using X::i; // expected-error{{using declaration cannot refer to class member}}
 | |
|   using X::s; // expected-error{{using declaration cannot refer to class member}}
 | |
|   using X::e; // expected-error{{using declaration cannot refer to class member}}
 | |
|   using X::E::e; // expected-error{{using declaration cannot refer to class member}} expected-warning 0-1{{C++11}}
 | |
| #if __cplusplus < 201103L
 | |
|   // expected-note@-3 {{use a const variable}}
 | |
|   // expected-note@-3 {{use a const variable}}
 | |
|   // CXX98-NOT: fix-it:"{{.*}}":{[[@LINE-5]]:
 | |
|   // CXX98-NOT: fix-it:"{{.*}}":{[[@LINE-5]]:
 | |
| #else
 | |
|   // expected-note@-8 {{use a constexpr variable}}
 | |
|   // expected-note@-8 {{use a constexpr variable}}
 | |
|   // CXX11: fix-it:"{{.*}}":{[[@LINE-10]]:3-[[@LINE-10]]:8}:"constexpr auto e = "
 | |
|   // CXX11: fix-it:"{{.*}}":{[[@LINE-10]]:3-[[@LINE-10]]:8}:"constexpr auto e = "
 | |
| #endif
 | |
| }
 | |
| 
 | |
| namespace PR21933 {
 | |
|   struct A { int member; };
 | |
|   struct B { static int member; };
 | |
|   enum C { member };
 | |
| 
 | |
|   template <typename T>
 | |
|   struct X {
 | |
|     static void StaticFun() {
 | |
|       using T::member; // expected-error 2{{class member}} expected-note {{use a reference instead}}
 | |
| #if __cplusplus < 201103L
 | |
|     // expected-error@-2 {{cannot be used prior to '::'}}
 | |
| #endif
 | |
|       (void)member;
 | |
|     }
 | |
|   };
 | |
|   template<typename T>
 | |
|   struct Y : T { 
 | |
|     static void StaticFun() {
 | |
|       using T::member; // expected-error 2{{class member}} expected-note {{use a reference instead}}
 | |
|       (void)member;
 | |
|     }
 | |
|   };
 | |
| 
 | |
|   void f() { 
 | |
|     X<A>::StaticFun(); // expected-note {{instantiation of}}
 | |
|     X<B>::StaticFun(); // expected-note {{instantiation of}}
 | |
|     X<C>::StaticFun();
 | |
| #if __cplusplus < 201103L
 | |
|     // expected-note@-2 {{instantiation of}}
 | |
| #endif
 | |
|     Y<A>::StaticFun(); // expected-note {{instantiation of}}
 | |
|     Y<B>::StaticFun(); // expected-note {{instantiation of}}
 | |
|   }
 | |
| 
 | |
|   template<typename T, typename U> void value_vs_value() {
 | |
|     using T::a; // expected-note {{previous}}
 | |
| #if __cplusplus < 201103L
 | |
|     // expected-error@-2 {{cannot be used prior to '::'}}
 | |
| #endif
 | |
|     extern int a(); // expected-error {{different kind of symbol}}
 | |
|     a();
 | |
| 
 | |
|     extern int b(); // expected-note {{previous}}
 | |
|     using T::b; // expected-error {{different kind of symbol}}
 | |
|     b();
 | |
| 
 | |
|     using T::c; // expected-note {{previous}}
 | |
|     using U::c; // expected-error-re {{redefinition of 'c'{{$}}}}
 | |
|     c();
 | |
|   }
 | |
| 
 | |
|   template<typename T, typename U> void value_vs_type() {
 | |
|     using T::Xt; // expected-note {{previous}}
 | |
|     typedef struct {} Xt; // expected-error {{different kind of symbol}}
 | |
|     (void)Xt;
 | |
| 
 | |
|     using T::Xs; // expected-note {{hidden by}}
 | |
|     struct Xs {};
 | |
|     (void)Xs;
 | |
|     Xs xs; // expected-error {{must use 'struct'}}
 | |
| 
 | |
|     using T::Xe; // expected-note {{hidden by}}
 | |
|     enum Xe {};
 | |
|     (void)Xe;
 | |
|     Xe xe; // expected-error {{must use 'enum'}}
 | |
| 
 | |
|     typedef struct {} Yt; // expected-note {{candidate}}
 | |
|     using T::Yt; // eypected-error {{different kind of symbol}} expected-note {{candidate}}
 | |
|     Yt yt; // expected-error {{ambiguous}}
 | |
| 
 | |
|     struct Ys {};
 | |
|     using T::Ys; // expected-note {{hidden by}}
 | |
|     (void)Ys;
 | |
|     Ys ys; // expected-error {{must use 'struct'}}
 | |
| 
 | |
|     enum Ye {};
 | |
|     using T::Ye; // expected-note {{hidden by}}
 | |
|     Ye ye; // expected-error {{must use 'enum'}}
 | |
|   }
 | |
| 
 | |
|   template<typename T> void type() {
 | |
|     // Must be a class member because T:: can only name a class or enum,
 | |
|     // and an enum cannot have a type member.
 | |
|     using typename T::X; // expected-error {{cannot refer to class member}}
 | |
|   }
 | |
| 
 | |
|   namespace N1 { enum E { a, b, c }; }
 | |
|   namespace N2 { enum E { a, b, c }; }
 | |
|   void g() { value_vs_value<N1::E, N2::E>(); }
 | |
| #if __cplusplus < 201103L
 | |
|     // expected-note@-2 {{in instantiation of}}
 | |
| #endif
 | |
| 
 | |
| #if __cplusplus >= 201402L
 | |
|   namespace partial_substitute {
 | |
|     template<typename T> auto f() {
 | |
|       return [](auto x) {
 | |
|         using A = typename T::template U<decltype(x)>;
 | |
|         using A::E::e;
 | |
|         struct S : A {
 | |
|           using A::f;
 | |
|           using typename A::type;
 | |
|           type f(int) { return e; }
 | |
|         };
 | |
|         return S();
 | |
|       };
 | |
|     }
 | |
|     enum Enum { e };
 | |
|     struct X {
 | |
|       template<typename T> struct U {
 | |
|         int f(int, int);
 | |
|         using type = int;
 | |
|         using E = Enum;
 | |
|       };
 | |
|     };
 | |
|     int test() {
 | |
|       auto s = f<X>()(0);
 | |
|       return s.f(0) + s.f(0, 0);
 | |
|     }
 | |
| 
 | |
|     template<typename T, typename U> auto g() {
 | |
|       return [](auto x) {
 | |
|         using X = decltype(x);
 | |
|         struct S : T::template Q<X>, U::template Q<X> {
 | |
|           using T::template Q<X>::f;
 | |
|           using U::template Q<X>::f;
 | |
|           void h() { f(); }
 | |
|           void h(int n) { f(n); }
 | |
|         };
 | |
|         return S();
 | |
|       };
 | |
|     }
 | |
|     struct A { template<typename> struct Q { int f(); }; };
 | |
|     struct B { template<typename> struct Q { int f(int); }; };
 | |
|     int test2() {
 | |
|       auto s = g<A, B>()(0);
 | |
|       s.f();
 | |
|       s.f(0);
 | |
|       s.h();
 | |
|       s.h(0);
 | |
|     }
 | |
|   }
 | |
| #endif
 | |
| 
 | |
|   template<typename T, typename U> struct RepeatedMember : T, U {
 | |
|     // FIXME: This is the wrong error: we should complain that a member type
 | |
|     // cannot be redeclared at class scope.
 | |
|     using typename T::type; // expected-note {{candidate}}
 | |
|     using typename U::type; // expected-note {{candidate}}
 | |
|     type x; // expected-error {{ambiguous}}
 | |
|   };
 | |
| }
 | |
| 
 | |
| struct S {
 | |
|   static int n;
 | |
|   struct Q {};
 | |
|   enum E {};
 | |
|   typedef Q T;
 | |
|   void f();
 | |
|   static void g();
 | |
| };
 | |
| 
 | |
| using S::n; // expected-error{{class member}} expected-note {{use a reference instead}}
 | |
| #if __cplusplus < 201103L
 | |
| // CXX98-NOT: fix-it:"{{.*}}":{[[@LINE-2]]
 | |
| #else
 | |
| // CXX11: fix-it:"{{.*}}":{[[@LINE-4]]:1-[[@LINE-4]]:6}:"auto &n = "
 | |
| #endif
 | |
| 
 | |
| using S::Q; // expected-error{{class member}}
 | |
| #if __cplusplus < 201103L
 | |
| // expected-note@-2 {{use a typedef declaration instead}}
 | |
| // CXX98: fix-it:"{{.*}}":{[[@LINE-3]]:1-[[@LINE-3]]:6}:"typedef"
 | |
| // CXX98: fix-it:"{{.*}}":{[[@LINE-4]]:11-[[@LINE-4]]:11}:" Q"
 | |
| #else
 | |
| // expected-note@-6 {{use an alias declaration instead}}
 | |
| // CXX11: fix-it:"{{.*}}":{[[@LINE-7]]:7-[[@LINE-7]]:7}:"Q = "
 | |
| #endif
 | |
| 
 | |
| using S::E; // expected-error{{class member}}
 | |
| #if __cplusplus < 201103L
 | |
| // expected-note@-2 {{use a typedef declaration instead}}
 | |
| // CXX98: fix-it:"{{.*}}":{[[@LINE-3]]:1-[[@LINE-3]]:6}:"typedef"
 | |
| // CXX98: fix-it:"{{.*}}":{[[@LINE-4]]:11-[[@LINE-4]]:11}:" E"
 | |
| #else
 | |
| // expected-note@-6 {{use an alias declaration instead}}
 | |
| // CXX11: fix-it:"{{.*}}":{[[@LINE-7]]:7-[[@LINE-7]]:7}:"E = "
 | |
| #endif
 | |
| 
 | |
| using S::T; // expected-error{{class member}}
 | |
| #if __cplusplus < 201103L
 | |
| // expected-note@-2 {{use a typedef declaration instead}}
 | |
| // CXX98: fix-it:"{{.*}}":{[[@LINE-3]]:1-[[@LINE-3]]:6}:"typedef"
 | |
| // CXX98: fix-it:"{{.*}}":{[[@LINE-4]]:11-[[@LINE-4]]:11}:" T"
 | |
| #else
 | |
| // expected-note@-6 {{use an alias declaration instead}}
 | |
| // CXX11: fix-it:"{{.*}}":{[[@LINE-7]]:7-[[@LINE-7]]:7}:"T = "
 | |
| #endif
 | |
| 
 | |
| using S::f; // expected-error{{class member}}
 | |
| using S::g; // expected-error{{class member}}
 | |
| 
 | |
| void h() {
 | |
|   using S::n; // expected-error{{class member}} expected-note {{use a reference instead}}
 | |
| #if __cplusplus < 201103L
 | |
|   // CXX98-NOT: fix-it:"{{.*}}":{[[@LINE-2]]
 | |
| #else
 | |
|   // CXX11: fix-it:"{{.*}}":{[[@LINE-4]]:3-[[@LINE-4]]:8}:"auto &n = "
 | |
| #endif
 | |
| 
 | |
|   using S::Q; // expected-error{{class member}}
 | |
| #if __cplusplus < 201103L
 | |
|   // expected-note@-2 {{use a typedef declaration instead}}
 | |
|   // CXX98: fix-it:"{{.*}}":{[[@LINE-3]]:3-[[@LINE-3]]:8}:"typedef"
 | |
|   // CXX98: fix-it:"{{.*}}":{[[@LINE-4]]:13-[[@LINE-4]]:13}:" Q"
 | |
| #else
 | |
|   // expected-note@-6 {{use an alias declaration instead}}
 | |
|   // CXX11: fix-it:"{{.*}}":{[[@LINE-7]]:9-[[@LINE-7]]:9}:"Q = "
 | |
| #endif
 | |
| 
 | |
|   using S::E; // expected-error{{class member}}
 | |
| #if __cplusplus < 201103L
 | |
|   // expected-note@-2 {{use a typedef declaration instead}}
 | |
|   // CXX98: fix-it:"{{.*}}":{[[@LINE-3]]:3-[[@LINE-3]]:8}:"typedef"
 | |
|   // CXX98: fix-it:"{{.*}}":{[[@LINE-4]]:13-[[@LINE-4]]:13}:" E"
 | |
| #else
 | |
|   // expected-note@-6 {{use an alias declaration instead}}
 | |
|   // CXX11: fix-it:"{{.*}}":{[[@LINE-7]]:9-[[@LINE-7]]:9}:"E = "
 | |
| #endif
 | |
| 
 | |
|   using S::T; // expected-error{{class member}}
 | |
| #if __cplusplus < 201103L
 | |
|   // expected-note@-2 {{use a typedef declaration instead}}
 | |
|   // CXX98: fix-it:"{{.*}}":{[[@LINE-3]]:3-[[@LINE-3]]:8}:"typedef"
 | |
|   // CXX98: fix-it:"{{.*}}":{[[@LINE-4]]:13-[[@LINE-4]]:13}:" T"
 | |
| #else
 | |
|   // expected-note@-6 {{use an alias declaration instead}}
 | |
|   // CXX11: fix-it:"{{.*}}":{[[@LINE-7]]:9-[[@LINE-7]]:9}:"T = "
 | |
| #endif
 | |
| 
 | |
|   using S::f; // expected-error{{class member}}
 | |
|   using S::g; // expected-error{{class member}}
 | |
| }
 |