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