aboutsummaryrefslogtreecommitdiff
path: root/lib/Parse/ParseTentative.cpp
diff options
context:
space:
mode:
authorNick Lewycky <nicholas@mxc.ca>2012-01-25 01:19:14 +0000
committerNick Lewycky <nicholas@mxc.ca>2012-01-25 01:19:14 +0000
commit443aac9bd22624c6abb1fe7e581ac30c4e654eea (patch)
tree48190e9139228c03617d30a99f0e4a927f46d6d1 /lib/Parse/ParseTentative.cpp
parent8efca6bb688d32fd7c0d91b504ef3307f97ee66a (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.cpp27
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