[cfe-commits] r64223 - in /cfe/trunk: include/clang/Basic/DiagnosticSemaKinds.def lib/Sema/SemaTemplate.cpp test/SemaTemplate/temp_param.cpp

Douglas Gregor dgregor at apple.com
Tue Feb 10 09:43:50 PST 2009


Author: dgregor
Date: Tue Feb 10 11:43:50 2009
New Revision: 64223

URL: http://llvm.org/viewvc/llvm-project?rev=64223&view=rev
Log:
Semantic analysis for non-type template parameter declarations.

Added:
    cfe/trunk/test/SemaTemplate/temp_param.cpp
Modified:
    cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.def
    cfe/trunk/lib/Sema/SemaTemplate.cpp

Modified: cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.def
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.def?rev=64223&r1=64222&r2=64223&view=diff

==============================================================================
--- cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.def (original)
+++ cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.def Tue Feb 10 11:43:50 2009
@@ -493,6 +493,8 @@
      "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,

Modified: cfe/trunk/lib/Sema/SemaTemplate.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaTemplate.cpp?rev=64223&r1=64222&r2=64223&view=diff

==============================================================================
--- cfe/trunk/lib/Sema/SemaTemplate.cpp (original)
+++ cfe/trunk/lib/Sema/SemaTemplate.cpp Tue Feb 10 11:43:50 2009
@@ -161,6 +161,41 @@
                                                            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);

Added: cfe/trunk/test/SemaTemplate/temp_param.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaTemplate/temp_param.cpp?rev=64223&view=auto

==============================================================================
--- cfe/trunk/test/SemaTemplate/temp_param.cpp (added)
+++ cfe/trunk/test/SemaTemplate/temp_param.cpp Tue Feb 10 11:43:50 2009
@@ -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;
+
+
+





More information about the cfe-commits mailing list