De-nest tentative parsing to disambiguate lambdas from designators; no

functionality change.

llvm-svn: 150817
This commit is contained in:
Douglas Gregor 2012-02-17 16:41:16 +00:00
parent fd7d1b47ba
commit 23b05417c9
1 changed files with 45 additions and 42 deletions

View File

@ -58,52 +58,55 @@ bool Parser::MayBeDesignationStart() {
return true;
}
// Parse up to (at most) the token after the closing ']' to determine
// whether this is a C99 designator or a lambda.
TentativeParsingAction Tentative(*this);
ConsumeBracket();
while (true) {
switch (Tok.getKind()) {
case tok::equal:
case tok::amp:
case tok::identifier:
case tok::kw_this:
// These tokens can occur in a capture list or a constant-expression.
// Keep looking.
ConsumeToken();
continue;
case tok::comma:
// Since a comma cannot occur in a constant-expression, this must
// be a lambda.
Tentative.Revert();
return false;
case tok::r_square: {
// Once we hit the closing square bracket, we look at the next
// token. If it's an '=', this is a designator. Otherwise, it's a
// lambda expression. This decision favors lambdas over the older
// GNU designator syntax, which allows one to omit the '=', but is
// consistent with GCC.
ConsumeBracket();
tok::TokenKind Kind = Tok.getKind();
Tentative.Revert();
return Kind == tok::equal;
}
default:
// Anything else cannot occur in a lambda capture list, so it
// must be a designator.
Tentative.Revert();
return true;
}
}
return true;
// Handle the complicated case below.
break;
}
case tok::identifier: // designation: identifier ':'
return PP.LookAhead(0).is(tok::colon);
}
// Parse up to (at most) the token after the closing ']' to determine
// whether this is a C99 designator or a lambda.
TentativeParsingAction Tentative(*this);
ConsumeBracket();
while (true) {
switch (Tok.getKind()) {
case tok::equal:
case tok::amp:
case tok::identifier:
case tok::kw_this:
// These tokens can occur in a capture list or a constant-expression.
// Keep looking.
ConsumeToken();
continue;
case tok::comma:
// Since a comma cannot occur in a constant-expression, this must
// be a lambda.
Tentative.Revert();
return false;
case tok::r_square: {
// Once we hit the closing square bracket, we look at the next
// token. If it's an '=', this is a designator. Otherwise, it's a
// lambda expression. This decision favors lambdas over the older
// GNU designator syntax, which allows one to omit the '=', but is
// consistent with GCC.
ConsumeBracket();
tok::TokenKind Kind = Tok.getKind();
Tentative.Revert();
return Kind == tok::equal;
}
default:
// Anything else cannot occur in a lambda capture list, so it
// must be a designator.
Tentative.Revert();
return true;
}
}
return true;
}
static void CheckArrayDesignatorSyntax(Parser &P, SourceLocation Loc,