Semantic analysis for non-type template parameter declarations.

llvm-svn: 64223
This commit is contained in:
Douglas Gregor 2009-02-10 17:43:50 +00:00
parent 1093e9a021
commit 8133879c5e
3 changed files with 64 additions and 0 deletions
clang
include/clang/Basic
lib/Sema
test/SemaTemplate

View File

@ -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,

View File

@ -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);

View File

@ -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;