188 lines
4.9 KiB
C++
188 lines
4.9 KiB
C++
|
// RUN: %clang_cc1 -std=c++20 -pedantic -verify %s
|
||
|
|
||
|
struct X {
|
||
|
using type = int;
|
||
|
static constexpr int value = 1;
|
||
|
class tclass {};
|
||
|
};
|
||
|
|
||
|
template <typename T>
|
||
|
void f() {
|
||
|
// it is a qualified name in a type-id-only context (see below), or
|
||
|
// [its smallest enclosing [/new/defining/]-type-id is]:
|
||
|
// - a new-type-id
|
||
|
auto *Ptr = new T::type();
|
||
|
// - a defining-type-id
|
||
|
class T::tclass Empty1;
|
||
|
T::tclass Empty2; // expected-error{{missing 'typename'}}
|
||
|
// - a trailing-return-type
|
||
|
auto f()->T::type;
|
||
|
// - default argument of a type-parameter of a template [see below]
|
||
|
|
||
|
// - type-id of a
|
||
|
// static_cast,
|
||
|
auto StaticCast = static_cast<T::type>(1.2);
|
||
|
// const_cast,
|
||
|
const auto *ConstCast = const_cast<const T::type *>(Ptr);
|
||
|
// reinterpret_cast,
|
||
|
int ReinterpretCast = reinterpret_cast<T::type>(4);
|
||
|
// dynamic_cast
|
||
|
struct B {
|
||
|
virtual ~B() = default;
|
||
|
};
|
||
|
struct D : T::tclass {};
|
||
|
auto *Base = dynamic_cast<T::tclass *>(new B);
|
||
|
|
||
|
T::type Invalid; // expected-error{{missing 'typename'}}
|
||
|
}
|
||
|
|
||
|
template void f<X>();
|
||
|
|
||
|
// As default argument.
|
||
|
template <typename T, typename = T::type>
|
||
|
struct DefaultArg {};
|
||
|
|
||
|
template struct DefaultArg<X>;
|
||
|
|
||
|
// it is a decl-specifier of the decl-specifier-seq of a
|
||
|
// - simple-declaration or a function-definition in namespace scope
|
||
|
template <typename T>
|
||
|
T::type VarTemp = 1;
|
||
|
|
||
|
template int VarTemp<X>;
|
||
|
|
||
|
template <typename T>
|
||
|
T::type FuncDef() { return 1; }
|
||
|
|
||
|
template int FuncDef<X>();
|
||
|
|
||
|
template <typename T>
|
||
|
T::type funcDecl();
|
||
|
|
||
|
template <typename T>
|
||
|
void FuncParam(T::type); // ok, but variable template
|
||
|
// expected-error@-1{{variable has incomplete type 'void'}}
|
||
|
|
||
|
template <typename T>
|
||
|
void FuncParam2(const T::type, int); // expected-error{{missing 'typename'}}
|
||
|
|
||
|
template <typename T>
|
||
|
struct MemberDecl {
|
||
|
// member-declaration,
|
||
|
T::type Member;
|
||
|
|
||
|
// parameter-declaration in a member-declaration, unless that
|
||
|
// parameter-declaration appears in a default argument
|
||
|
void NoDefault(T::type);
|
||
|
void Default(int A = T::value);
|
||
|
};
|
||
|
|
||
|
template struct MemberDecl<X>;
|
||
|
|
||
|
// parameter-declaration in a declarator of a function or function template
|
||
|
// declaration where the declarator-id is qualified, unless that
|
||
|
// parameter-declaration appears in a default argument,
|
||
|
struct QualifiedFunc {
|
||
|
template <typename T>
|
||
|
void foo(typename T::type);
|
||
|
template <typename T>
|
||
|
void bar(T::type);
|
||
|
};
|
||
|
|
||
|
template <typename T>
|
||
|
void QualifiedFunc::foo(T::type) {}
|
||
|
template <typename T>
|
||
|
void QualifiedFunc::bar(typename T::type) {}
|
||
|
|
||
|
template <typename T>
|
||
|
void g() {
|
||
|
// parameter-declaration in a lambda-declarator, unless that
|
||
|
// parameter-declaration appears in a default argument, or
|
||
|
auto Lambda1 = [](T::type) {};
|
||
|
auto Lambda2 = [](int A = T::value) {};
|
||
|
}
|
||
|
|
||
|
template void g<X>();
|
||
|
|
||
|
// parameter-declaration of a (non-type) template-parameter.
|
||
|
template <typename T, T::type>
|
||
|
void NonTypeArg() {}
|
||
|
|
||
|
template void NonTypeArg<X, 0>();
|
||
|
|
||
|
template <typename T>
|
||
|
void f(T::type) {} // expected-error {{missing 'typename'}}
|
||
|
|
||
|
namespace N {
|
||
|
template <typename T>
|
||
|
int f(typename T::type);
|
||
|
template <typename T>
|
||
|
extern int Var;
|
||
|
}
|
||
|
|
||
|
template <typename T>
|
||
|
int N::f(T::type); // ok, function
|
||
|
template <typename T>
|
||
|
int N::Var(T::value); // ok, variable
|
||
|
|
||
|
int h() {
|
||
|
return N::f<X>(10) + N::Var<X>;
|
||
|
}
|
||
|
|
||
|
namespace NN {
|
||
|
inline namespace A { template <typename T> int f(typename T::type); } // expected-note{{previous definition is here}}
|
||
|
inline namespace B { template <typename T> int f(T::type); }
|
||
|
}
|
||
|
|
||
|
template <typename T>
|
||
|
int NN::f(T::type); // expected-error{{redefinition of 'f' as different kind of symbol}}
|
||
|
|
||
|
template <auto V>
|
||
|
struct videntity {
|
||
|
static constexpr auto value = V;
|
||
|
};
|
||
|
|
||
|
template <typename T,
|
||
|
bool = T::value,
|
||
|
bool = bool(T::value),
|
||
|
bool = videntity<bool(T::value)>::value>
|
||
|
void f(int = T::value) {}
|
||
|
|
||
|
template <typename> int test() = delete;
|
||
|
template <auto> int test();
|
||
|
|
||
|
template <typename T>
|
||
|
int Test = test<int(T::value)>();
|
||
|
template int Test<X>;
|
||
|
|
||
|
template<typename T> struct A {
|
||
|
enum E : T::type {}; // expected-error{{missing 'typename'}}
|
||
|
operator T::type() {} // expected-error{{missing 'typename'}}
|
||
|
void f() { this->operator T::type(); } // expected-error{{missing 'typename'}}
|
||
|
};
|
||
|
|
||
|
template<typename T>
|
||
|
struct C {
|
||
|
C(T::type); // implicit typename context
|
||
|
friend C (T::fn)(); // not implicit typename context, declarator-id of friend declaration
|
||
|
C(T::type::*x)[3]; // not implicit typename context, pointer-to-member type
|
||
|
};
|
||
|
|
||
|
template <typename T>
|
||
|
C<T>::C(T::type) {}
|
||
|
|
||
|
namespace GH63119 {
|
||
|
struct X {
|
||
|
X(int);
|
||
|
X(auto);
|
||
|
void f(int);
|
||
|
};
|
||
|
template<typename T> struct S {
|
||
|
friend X::X(T::type);
|
||
|
friend X::X(T::type = (int)(void(*)(typename T::type))(nullptr)); // expected-error {{friend declaration specifying a default argument must be a definition}}
|
||
|
friend X::X(T::type = (int)(void(*)(T::type))(nullptr)); // expected-error {{friend declaration specifying a default argument must be a definition}} \
|
||
|
// expected-error {{expected expression}}
|
||
|
friend void X::f(T::type);
|
||
|
};
|
||
|
}
|