diff options
author | Jeffrey Yasskin <jyasskin@google.com> | 2010-04-08 21:04:54 +0000 |
---|---|---|
committer | Jeffrey Yasskin <jyasskin@google.com> | 2010-04-08 21:04:54 +0000 |
commit | 54eba427ed4b415c636670aa0b1edaccf7b5ac9e (patch) | |
tree | dcb883c6d6deca25da1ee65c33ff00d20e659725 | |
parent | 433d40695bb7d6876e540e84c4fc5fd270edc311 (diff) | |
download | bcm5719-llvm-54eba427ed4b415c636670aa0b1edaccf7b5ac9e.tar.gz bcm5719-llvm-54eba427ed4b415c636670aa0b1edaccf7b5ac9e.zip |
Explain that a template needs arguments to make it into a type, for
variable declarations.
llvm-svn: 100809
-rw-r--r-- | clang/lib/Sema/SemaDecl.cpp | 18 | ||||
-rw-r--r-- | clang/test/SemaTemplate/temp_arg.cpp | 3 |
2 files changed, 20 insertions, 1 deletions
diff --git a/clang/lib/Sema/SemaDecl.cpp b/clang/lib/Sema/SemaDecl.cpp index 92d2f4b50c5..82cecc3f4d0 100644 --- a/clang/lib/Sema/SemaDecl.cpp +++ b/clang/lib/Sema/SemaDecl.cpp @@ -275,6 +275,24 @@ bool Sema::DiagnoseUnknownTypeName(const IdentifierInfo &II, } } + if (getLangOptions().CPlusPlus) { + // See if II is a class template that the user forgot to pass arguments to. + UnqualifiedId Name; + Name.setIdentifier(&II, IILoc); + CXXScopeSpec EmptySS; + TemplateTy TemplateResult; + if (isTemplateName(S, SS ? *SS : EmptySS, Name, 0, true, TemplateResult) + == TNK_Type_template) { + TemplateName TplName = TemplateResult.getAsVal<TemplateName>(); + Diag(IILoc, diag::err_template_missing_args) << TplName; + if (TemplateDecl *TplDecl = TplName.getAsTemplateDecl()) { + Diag(TplDecl->getLocation(), diag::note_template_decl_here) + << TplDecl->getTemplateParameters()->getSourceRange(); + } + return true; + } + } + // FIXME: Should we move the logic that tries to recover from a missing tag // (struct, union, enum) from Parser::ParseImplicitInt here, instead? diff --git a/clang/test/SemaTemplate/temp_arg.cpp b/clang/test/SemaTemplate/temp_arg.cpp index 80bbda785d0..5a4c8fc16fd 100644 --- a/clang/test/SemaTemplate/temp_arg.cpp +++ b/clang/test/SemaTemplate/temp_arg.cpp @@ -2,7 +2,7 @@ template<typename T, int I, template<typename> class TT> - class A; // expected-note 2 {{template is declared here}} + class A; // expected-note 3 {{template is declared here}} template<typename> class X; @@ -10,6 +10,7 @@ A<int, 0, X> * a1; A<float, 1, X, double> *a2; // expected-error{{too many template arguments for class template 'A'}} A<float, 1> *a3; // expected-error{{too few template arguments for class template 'A'}} +A a3; // expected-error{{use of class template A requires template arguments}} namespace test0 { template <class t> class foo {}; |