diff options
author | Nick Lewycky <nicholas@mxc.ca> | 2012-01-25 01:19:14 +0000 |
---|---|---|
committer | Nick Lewycky <nicholas@mxc.ca> | 2012-01-25 01:19:14 +0000 |
commit | 443aac9bd22624c6abb1fe7e581ac30c4e654eea (patch) | |
tree | 48190e9139228c03617d30a99f0e4a927f46d6d1 /lib/Parse/ParseTentative.cpp | |
parent | 8efca6bb688d32fd7c0d91b504ef3307f97ee66a (diff) |
With a little more work in the tentative parse determining whether a statement
is a declaration-stmt or an expression, we can discern a subset of cases where
the user erred in omitting the typename keyword before a dependent type name.
Fixes PR11358!
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@148896 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Parse/ParseTentative.cpp')
-rw-r--r-- | lib/Parse/ParseTentative.cpp | 27 |
1 files changed, 25 insertions, 2 deletions
diff --git a/lib/Parse/ParseTentative.cpp b/lib/Parse/ParseTentative.cpp index 4f80da2dc9..987ae65d06 100644 --- a/lib/Parse/ParseTentative.cpp +++ b/lib/Parse/ParseTentative.cpp @@ -864,7 +864,7 @@ Parser::TPResult Parser::isCXXDeclarationSpecifier() { if (TryAnnotateTypeOrScopeToken()) return TPResult::Error(); return isCXXDeclarationSpecifier(); - + // decl-specifier: // storage-class-specifier // type-specifier @@ -950,8 +950,31 @@ Parser::TPResult Parser::isCXXDeclarationSpecifier() { // We've already annotated a scope; try to annotate a type. if (TryAnnotateTypeOrScopeToken()) return TPResult::Error(); - if (!Tok.is(tok::annot_typename)) + if (!Tok.is(tok::annot_typename)) { + // If the next token is an identifier or a type qualifier, then this + // can't possibly be a valid expression either. + if (Tok.is(tok::annot_cxxscope) && NextToken().is(tok::identifier)) { + CXXScopeSpec SS; + Actions.RestoreNestedNameSpecifierAnnotation(Tok.getAnnotationValue(), + Tok.getAnnotationRange(), + SS); + if (SS.getScopeRep() && SS.getScopeRep()->isDependent()) { + TentativeParsingAction PA(*this); + ConsumeToken(); + ConsumeToken(); + bool isIdentifier = Tok.is(tok::identifier); + TPResult TPR = TPResult::False(); + if (!isIdentifier) + TPR = isCXXDeclarationSpecifier(); + PA.Revert(); + + if (isIdentifier || + TPR == TPResult::True() || TPR == TPResult::Error()) + return TPResult::Error(); + } + } return TPResult::False(); + } // If that succeeded, fallthrough into the generic simple-type-id case. // The ambiguity resides in a simple-type-specifier/typename-specifier |