forked from OSchip/llvm-project
Semantic analysis for non-type template parameter declarations.
llvm-svn: 64223
This commit is contained in:
parent
1093e9a021
commit
8133879c5e
|
@ -493,6 +493,8 @@ DIAG(note_template_nontype_parm_different_type, NOTE,
|
|||
"template non-type parameter has a different type %0 in template argument")
|
||||
DIAG(note_template_nontype_parm_prev_declaration, NOTE,
|
||||
"previous non-type template parameter with type %0 is here")
|
||||
DIAG(err_template_nontype_parm_bad_type, ERROR,
|
||||
"a non-type template parameter cannot have type %0")
|
||||
|
||||
// C++ Template Argument Lists
|
||||
DIAG(err_template_arg_list_different_arity, ERROR,
|
||||
|
|
|
@ -161,6 +161,41 @@ Sema::DeclTy *Sema::ActOnNonTypeTemplateParameter(Scope *S, Declarator &D,
|
|||
PrevDecl);
|
||||
}
|
||||
|
||||
// C++ [temp.param]p4:
|
||||
//
|
||||
// A non-type template-parameter shall have one of the following
|
||||
// (optionally cv-qualified) types:
|
||||
//
|
||||
// -- integral or enumeration type,
|
||||
if (T->isIntegralType() || T->isEnumeralType() ||
|
||||
// -- pointer to object or pointer to function,
|
||||
T->isPointerType() ||
|
||||
// -- reference to object or reference to function,
|
||||
T->isReferenceType() ||
|
||||
// -- pointer to member.
|
||||
T->isMemberPointerType() ||
|
||||
// If T is a dependent type, we can't do the check now, so we
|
||||
// assume that it is well-formed.
|
||||
T->isDependentType()) {
|
||||
// Okay: The template parameter is well-formed.
|
||||
}
|
||||
// C++ [temp.param]p8:
|
||||
//
|
||||
// A non-type template-parameter of type "array of T" or
|
||||
// "function returning T" is adjusted to be of type "pointer to
|
||||
// T" or "pointer to function returning T", respectively.
|
||||
else if (T->isArrayType())
|
||||
// FIXME: Keep the type prior to promotion?
|
||||
T = Context.getArrayDecayedType(T);
|
||||
else if (T->isFunctionType())
|
||||
// FIXME: Keep the type prior to promotion?
|
||||
T = Context.getPointerType(T);
|
||||
else {
|
||||
Diag(D.getIdentifierLoc(), diag::err_template_nontype_parm_bad_type)
|
||||
<< T;
|
||||
return 0;
|
||||
}
|
||||
|
||||
NonTypeTemplateParmDecl *Param
|
||||
= NonTypeTemplateParmDecl::Create(Context, CurContext, D.getIdentifierLoc(),
|
||||
Depth, Position, ParamName, T);
|
||||
|
|
|
@ -0,0 +1,27 @@
|
|||
// RUN: clang -fsyntax-only -verify %s
|
||||
|
||||
class X;
|
||||
|
||||
// C++ [temp.param]p4
|
||||
typedef int INT;
|
||||
enum E { enum1, enum2 };
|
||||
template<int N> struct A1;
|
||||
template<INT N, INT M> struct A2;
|
||||
template<enum E x, E y> struct A3;
|
||||
template<int &X> struct A4;
|
||||
template<int *Ptr> struct A5;
|
||||
template<int (&f)(int, int)> struct A6;
|
||||
template<int (*fp)(float, double)> struct A7;
|
||||
template<int X::*pm> struct A8;
|
||||
template<float (X::*pmf)(float, int)> struct A9;
|
||||
template<typename T, T x> struct A10;
|
||||
|
||||
template<float f> struct A11; // expected-error{{a non-type template parameter cannot have type 'float'}}
|
||||
|
||||
|
||||
// C++ [temp.param]p8
|
||||
template<int X[10]> struct A5;
|
||||
template<int f(float, double)> struct A7;
|
||||
|
||||
|
||||
|
Loading…
Reference in New Issue