aboutsummaryrefslogtreecommitdiff
path: root/lib/Parse/Parser.cpp
diff options
context:
space:
mode:
authorDouglas Gregor <dgregor@apple.com>2009-04-01 00:28:59 +0000
committerDouglas Gregor <dgregor@apple.com>2009-04-01 00:28:59 +0000
commit1734317845d60307d474b5da8a8d33adbaf5e723 (patch)
tree1507be0d13c9f841e5f42f3b9e2cc53835b43055 /lib/Parse/Parser.cpp
parent8e4fea6750dbac032c172f3279c63b7815b7423e (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.cpp39
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;