From 8133879c5ec09e97bf4a8a8b0daac83317e5ab9b Mon Sep 17 00:00:00 2001 From: Douglas Gregor Date: Tue, 10 Feb 2009 17:43:50 +0000 Subject: [PATCH] Semantic analysis for non-type template parameter declarations. llvm-svn: 64223 --- .../clang/Basic/DiagnosticSemaKinds.def | 2 ++ clang/lib/Sema/SemaTemplate.cpp | 35 +++++++++++++++++++ clang/test/SemaTemplate/temp_param.cpp | 27 ++++++++++++++ 3 files changed, 64 insertions(+) create mode 100644 clang/test/SemaTemplate/temp_param.cpp diff --git a/clang/include/clang/Basic/DiagnosticSemaKinds.def b/clang/include/clang/Basic/DiagnosticSemaKinds.def index fd6055103b17..9fad3af483f4 100644 --- a/clang/include/clang/Basic/DiagnosticSemaKinds.def +++ b/clang/include/clang/Basic/DiagnosticSemaKinds.def @@ -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, diff --git a/clang/lib/Sema/SemaTemplate.cpp b/clang/lib/Sema/SemaTemplate.cpp index ecbc860d1df0..c0c6e23baf67 100644 --- a/clang/lib/Sema/SemaTemplate.cpp +++ b/clang/lib/Sema/SemaTemplate.cpp @@ -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); diff --git a/clang/test/SemaTemplate/temp_param.cpp b/clang/test/SemaTemplate/temp_param.cpp new file mode 100644 index 000000000000..57a6cdb94542 --- /dev/null +++ b/clang/test/SemaTemplate/temp_param.cpp @@ -0,0 +1,27 @@ +// RUN: clang -fsyntax-only -verify %s + +class X; + +// C++ [temp.param]p4 +typedef int INT; +enum E { enum1, enum2 }; +template struct A1; +template struct A2; +template struct A3; +template struct A4; +template struct A5; +template struct A6; +template struct A7; +template struct A8; +template struct A9; +template struct A10; + +template struct A11; // expected-error{{a non-type template parameter cannot have type 'float'}} + + +// C++ [temp.param]p8 +template struct A5; +template struct A7; + + +