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}}
 | 
						|
}
 |