diff options
author | Douglas Gregor <dgregor@apple.com> | 2009-04-01 00:28:59 +0000 |
---|---|---|
committer | Douglas Gregor <dgregor@apple.com> | 2009-04-01 00:28:59 +0000 |
commit | 1734317845d60307d474b5da8a8d33adbaf5e723 (patch) | |
tree | 1507be0d13c9f841e5f42f3b9e2cc53835b43055 /lib/Parse/Parser.cpp | |
parent | 8e4fea6750dbac032c172f3279c63b7815b7423e (diff) |
Parsing, semantic analysis, and template instantiation for typename
specifiers that terminate in a simple-template-id, e.g.,
typename MetaFun::template apply<T1, T2>
Also, implement template instantiation for dependent
nested-name-specifiers that involve unresolved identifiers, e.g.,
typename T::type::type
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@68166 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Parse/Parser.cpp')
-rw-r--r-- | lib/Parse/Parser.cpp | 39 |
1 files changed, 29 insertions, 10 deletions
diff --git a/lib/Parse/Parser.cpp b/lib/Parse/Parser.cpp index 56e217a329..17eca37ef3 100644 --- a/lib/Parse/Parser.cpp +++ b/lib/Parse/Parser.cpp @@ -828,7 +828,7 @@ bool Parser::TryAnnotateTypeOrScopeToken() { // typename-specifier: // 'typename' '::' [opt] nested-name-specifier identifier // 'typename' '::' [opt] nested-name-specifier template [opt] - // simple-template-id [TODO] + // simple-template-id SourceLocation TypenameLoc = ConsumeToken(); CXXScopeSpec SS; bool HadNestedNameSpecifier = ParseOptionalCXXScopeSpecifier(SS); @@ -842,16 +842,35 @@ bool Parser::TryAnnotateTypeOrScopeToken() { // FIXME: check whether the next token is '<', first! Ty = Actions.ActOnTypenameType(TypenameLoc, SS, *Tok.getIdentifierInfo(), Tok.getLocation()); - // FIXME: better error recovery! - Tok.setKind(tok::annot_typename); - Tok.setAnnotationValue(Ty.get()); - Tok.setAnnotationEndLoc(Tok.getLocation()); - Tok.setLocation(TypenameLoc); - PP.AnnotateCachedTokens(Tok); - return true; - } + } else if (Tok.is(tok::annot_template_id)) { + TemplateIdAnnotation *TemplateId + = static_cast<TemplateIdAnnotation *>(Tok.getAnnotationValue()); + if (TemplateId->Kind == TNK_Function_template) { + Diag(Tok, diag::err_typename_refers_to_non_type_template) + << Tok.getAnnotationRange(); + return false; + } - return false; + if (AnnotateTemplateIdTokenAsType(0)) + return false; + + assert(Tok.is(tok::annot_typename) && + "AnnotateTemplateIdTokenAsType isn't working properly"); + Ty = Actions.ActOnTypenameType(TypenameLoc, SS, SourceLocation(), + Tok.getAnnotationValue()); + } else { + Diag(Tok, diag::err_expected_type_name_after_typename) + << SS.getRange(); + return false; + } + + // FIXME: better error recovery! + Tok.setKind(tok::annot_typename); + Tok.setAnnotationValue(Ty.get()); + Tok.setAnnotationEndLoc(Tok.getLocation()); + Tok.setLocation(TypenameLoc); + PP.AnnotateCachedTokens(Tok); + return true; } CXXScopeSpec SS; |