diff options
author | Richard Smith <richard-llvm@metafoo.co.uk> | 2019-05-20 18:01:54 +0000 |
---|---|---|
committer | Richard Smith <richard-llvm@metafoo.co.uk> | 2019-05-20 18:01:54 +0000 |
commit | e9585060398960d78cce6dd59b79e31e736b8f51 (patch) | |
tree | 8aec90e80180321de91daaf2765a0b616d9fcb4b /clang/lib/Parse/ParseInit.cpp | |
parent | d91f1dd4706d2bc591fc64d7f315c020f521678e (diff) | |
download | bcm5719-llvm-e9585060398960d78cce6dd59b79e31e736b8f51.tar.gz bcm5719-llvm-e9585060398960d78cce6dd59b79e31e736b8f51.zip |
Rearrange and clean up how we disambiguate lambda-introducers from ObjC
message sends, designators, and attributes.
Instead of having the tentative parsing phase sometimes return an
indicator to say what diagnostic to produce if parsing fails and
sometimes ask the caller to run it again, consistently ask the caller to
try parsing again if tentative parsing would fail or is otherwise unable
to completely parse the lambda-introducer without producing an
irreversible semantic effect.
Mostly NFC, but we should recover marginally better in some error cases
(avoiding duplicate diagnostics).
llvm-svn: 361182
Diffstat (limited to 'clang/lib/Parse/ParseInit.cpp')
-rw-r--r-- | clang/lib/Parse/ParseInit.cpp | 31 |
1 files changed, 20 insertions, 11 deletions
diff --git a/clang/lib/Parse/ParseInit.cpp b/clang/lib/Parse/ParseInit.cpp index 1444671a310..7a455484b90 100644 --- a/clang/lib/Parse/ParseInit.cpp +++ b/clang/lib/Parse/ParseInit.cpp @@ -65,15 +65,28 @@ bool Parser::MayBeDesignationStart() { // Parse up to (at most) the token after the closing ']' to determine // whether this is a C99 designator or a lambda. - TentativeParsingAction Tentative(*this); + RevertingTentativeParsingAction Tentative(*this); LambdaIntroducer Intro; - bool SkippedInits = false; - Optional<unsigned> DiagID(ParseLambdaIntroducer(Intro, &SkippedInits)); + LambdaIntroducerTentativeParse ParseResult; + if (ParseLambdaIntroducer(Intro, &ParseResult)) { + // Hit and diagnosed an error in a lambda. + // FIXME: Tell the caller this happened so they can recover. + return true; + } + + switch (ParseResult) { + case LambdaIntroducerTentativeParse::Success: + case LambdaIntroducerTentativeParse::Incomplete: + // Might be a lambda-expression. Keep looking. + // FIXME: If our tentative parse was not incomplete, parse the lambda from + // here rather than throwing away then reparsing the LambdaIntroducer. + break; - if (DiagID) { - // If this can't be a lambda capture list, it's a designator. - Tentative.Revert(); + case LambdaIntroducerTentativeParse::MessageSend: + case LambdaIntroducerTentativeParse::Invalid: + // Can't be a lambda-expression. Treat it as a designator. + // FIXME: Should we disambiguate against a message-send? return true; } @@ -82,11 +95,7 @@ bool Parser::MayBeDesignationStart() { // lambda expression. This decision favors lambdas over the older // GNU designator syntax, which allows one to omit the '=', but is // consistent with GCC. - tok::TokenKind Kind = Tok.getKind(); - // FIXME: If we didn't skip any inits, parse the lambda from here - // rather than throwing away then reparsing the LambdaIntroducer. - Tentative.Revert(); - return Kind == tok::equal; + return Tok.is(tok::equal); } static void CheckArrayDesignatorSyntax(Parser &P, SourceLocation Loc, |