blob: 0ea4eeb1e9b08dba56fdbfed6c3fa5438083f75e [file] [log] [blame]
// 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}}
}