diff options
-rw-r--r-- | include/clang/AST/DeclTemplate.h | 10 | ||||
-rw-r--r-- | include/clang/Basic/DiagnosticSemaKinds.def | 2 | ||||
-rw-r--r-- | lib/AST/DeclTemplate.cpp | 20 | ||||
-rw-r--r-- | lib/Sema/SemaTemplate.cpp | 5 | ||||
-rw-r--r-- | test/SemaTemplate/default-arguments.cpp | 13 | ||||
-rw-r--r-- | test/SemaTemplate/temp_arg.cpp | 2 |
6 files changed, 49 insertions, 3 deletions
diff --git a/include/clang/AST/DeclTemplate.h b/include/clang/AST/DeclTemplate.h index ccbe1288f8..334a03a439 100644 --- a/include/clang/AST/DeclTemplate.h +++ b/include/clang/AST/DeclTemplate.h @@ -66,9 +66,19 @@ public: 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); + } }; //===----------------------------------------------------------------------===// diff --git a/include/clang/Basic/DiagnosticSemaKinds.def b/include/clang/Basic/DiagnosticSemaKinds.def index 4fed9443d0..25fe8254bb 100644 --- a/include/clang/Basic/DiagnosticSemaKinds.def +++ b/include/clang/Basic/DiagnosticSemaKinds.def @@ -505,6 +505,8 @@ DIAG(err_template_param_default_arg_missing, ERROR, // 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, diff --git a/lib/AST/DeclTemplate.cpp b/lib/AST/DeclTemplate.cpp index b297dd25cb..dccb8df075 100644 --- a/lib/AST/DeclTemplate.cpp +++ b/lib/AST/DeclTemplate.cpp @@ -44,6 +44,26 @@ TemplateParameterList::Create(ASTContext &C, SourceLocation TemplateLoc, 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 //===----------------------------------------------------------------------===// diff --git a/lib/Sema/SemaTemplate.cpp b/lib/Sema/SemaTemplate.cpp index 86f1e2017f..b4436a2c3c 100644 --- a/lib/Sema/SemaTemplate.cpp +++ b/lib/Sema/SemaTemplate.cpp @@ -685,7 +685,7 @@ bool Sema::CheckTemplateArgumentList(TemplateDecl *Template, 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 @@ bool Sema::CheckTemplateArgumentList(TemplateDecl *Template, isa<FunctionTemplateDecl>(Template)? 1 : isa<TemplateTemplateParmDecl>(Template)? 2 : 3) << Template << Range; - + Diag(Template->getLocation(), diag::note_template_decl_here) + << Params->getSourceRange(); Invalid = true; } diff --git a/test/SemaTemplate/default-arguments.cpp b/test/SemaTemplate/default-arguments.cpp new file mode 100644 index 0000000000..94976e9735 --- /dev/null +++ b/test/SemaTemplate/default-arguments.cpp @@ -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; diff --git a/test/SemaTemplate/temp_arg.cpp b/test/SemaTemplate/temp_arg.cpp index 0f69b5f4b1..b8bb279caf 100644 --- a/test/SemaTemplate/temp_arg.cpp +++ b/test/SemaTemplate/temp_arg.cpp @@ -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; |