[cfe-commits] r64310 - in /cfe/trunk: include/clang/AST/DeclTemplate.h include/clang/Basic/DiagnosticSemaKinds.def lib/AST/DeclTemplate.cpp lib/Sema/SemaTemplate.cpp test/SemaTemplate/default-arguments.cpp test/SemaTemplate/temp_arg.cpp

Douglas Gregor dgregor at apple.com
Wed Feb 11 10:16:40 PST 2009


Author: dgregor
Date: Wed Feb 11 12:16:40 2009
New Revision: 64310

URL: http://llvm.org/viewvc/llvm-project?rev=64310&view=rev
Log:
Allow the use of default template arguments when forming a class
template specialization (e.g., std::vector<int> would now be
well-formed, since it relies on a default argument for the Allocator
template parameter). 

This is much less interesting than one might expect, since (1) we're
not actually using the default arguments for anything important, such
as naming an actual Decl, and (2) we'll often need to instantiate the
default arguments to check their well-formedness. The real fun will
come later.


Added:
    cfe/trunk/test/SemaTemplate/default-arguments.cpp
Modified:
    cfe/trunk/include/clang/AST/DeclTemplate.h
    cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.def
    cfe/trunk/lib/AST/DeclTemplate.cpp
    cfe/trunk/lib/Sema/SemaTemplate.cpp
    cfe/trunk/test/SemaTemplate/temp_arg.cpp

Modified: cfe/trunk/include/clang/AST/DeclTemplate.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/DeclTemplate.h?rev=64310&r1=64309&r2=64310&view=diff

==============================================================================
--- cfe/trunk/include/clang/AST/DeclTemplate.h (original)
+++ cfe/trunk/include/clang/AST/DeclTemplate.h Wed Feb 11 12:16:40 2009
@@ -66,9 +66,19 @@
 
   unsigned size() const { return NumParams; }
 
+  /// \btief Returns the minimum number of arguments needed to form a
+  /// template specialization. This may be fewer than the number of
+  /// template parameters, if some of the parameters have default
+  /// arguments.
+  unsigned getMinRequiredArguments() const;
+
   SourceLocation getTemplateLoc() const { return TemplateLoc; }
   SourceLocation getLAngleLoc() const { return LAngleLoc; }
   SourceLocation getRAngleLoc() const { return RAngleLoc; }
+
+  SourceRange getSourceRange() const {
+    return SourceRange(TemplateLoc, RAngleLoc);
+  }
 };
 
 //===----------------------------------------------------------------------===//

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

==============================================================================
--- cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.def (original)
+++ cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.def Wed Feb 11 12:16:40 2009
@@ -505,6 +505,8 @@
 // C++ Template Argument Lists
 DIAG(err_template_arg_list_different_arity, ERROR,
      "%select{too few|too many}0 template arguments for %select{class template|function template|template template parameter|template}1 %2")
+DIAG(note_template_decl_here, NOTE,
+     "template is declared here")
 DIAG(err_template_arg_must_be_type, ERROR,
      "template argument for template type parameter must be a type")
 DIAG(err_template_arg_must_be_expr, ERROR,

Modified: cfe/trunk/lib/AST/DeclTemplate.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/DeclTemplate.cpp?rev=64310&r1=64309&r2=64310&view=diff

==============================================================================
--- cfe/trunk/lib/AST/DeclTemplate.cpp (original)
+++ cfe/trunk/lib/AST/DeclTemplate.cpp Wed Feb 11 12:16:40 2009
@@ -44,6 +44,26 @@
                                          NumParams, RAngleLoc);
 }
 
+unsigned TemplateParameterList::getMinRequiredArguments() const {
+  unsigned NumRequiredArgs = size();
+  iterator Param = const_cast<TemplateParameterList *>(this)->end(), 
+      ParamBegin = const_cast<TemplateParameterList *>(this)->begin();
+  while (Param != ParamBegin) {
+    --Param;
+    if (!(isa<TemplateTypeParmDecl>(*Param) && 
+          cast<TemplateTypeParmDecl>(*Param)->hasDefaultArgument()) &&
+        !(isa<NonTypeTemplateParmDecl>(*Param) &&
+          cast<NonTypeTemplateParmDecl>(*Param)->hasDefaultArgument()) &&
+        !(isa<TemplateTemplateParmDecl>(*Param) &&
+          cast<TemplateTemplateParmDecl>(*Param)->hasDefaultArgument()))
+      break;
+        
+    --NumRequiredArgs;
+  }
+
+  return NumRequiredArgs;
+}
+
 //===----------------------------------------------------------------------===//
 // TemplateDecl Implementation
 //===----------------------------------------------------------------------===//

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

==============================================================================
--- cfe/trunk/lib/Sema/SemaTemplate.cpp (original)
+++ cfe/trunk/lib/Sema/SemaTemplate.cpp Wed Feb 11 12:16:40 2009
@@ -685,7 +685,7 @@
   bool Invalid = false;
 
   if (NumArgs > NumParams ||
-      NumArgs < NumParams /*FIXME: default arguments! */) {
+      NumArgs < Params->getMinRequiredArguments()) {
     // FIXME: point at either the first arg beyond what we can handle,
     // or the '>', depending on whether we have too many or too few
     // arguments.
@@ -698,7 +698,8 @@
           isa<FunctionTemplateDecl>(Template)? 1 :
           isa<TemplateTemplateParmDecl>(Template)? 2 : 3)
       << Template << Range;
-
+    Diag(Template->getLocation(), diag::note_template_decl_here)
+      << Params->getSourceRange();
     Invalid = true;
   }
   

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

==============================================================================
--- cfe/trunk/test/SemaTemplate/default-arguments.cpp (added)
+++ cfe/trunk/test/SemaTemplate/default-arguments.cpp Wed Feb 11 12:16:40 2009
@@ -0,0 +1,13 @@
+// RUN: clang -fsyntax-only -verify %s
+
+template<typename T, int N = 2> struct X; // expected-note{{template is declared here}}
+
+X<int, 1> *x1;
+X<int> *x2;
+
+X<> *x3; // expected-error{{too few template arguments for class template 'X'}} \
+        // FIXME: expected-error{{expected unqualified-id}}
+
+template<typename U = float, int M> struct X;
+
+X<> *x4;

Modified: cfe/trunk/test/SemaTemplate/temp_arg.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaTemplate/temp_arg.cpp?rev=64310&r1=64309&r2=64310&view=diff

==============================================================================
--- cfe/trunk/test/SemaTemplate/temp_arg.cpp (original)
+++ cfe/trunk/test/SemaTemplate/temp_arg.cpp Wed Feb 11 12:16:40 2009
@@ -2,7 +2,7 @@
 template<typename T, 
          int I, 
          template<typename> class TT>
-  class A;
+  class A; // expected-note 2 {{template is declared here}}
 
 template<typename> class X;
 





More information about the cfe-commits mailing list