From e9585060398960d78cce6dd59b79e31e736b8f51 Mon Sep 17 00:00:00 2001 From: Richard Smith Date: Mon, 20 May 2019 18:01:54 +0000 Subject: 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 --- clang/lib/Parse/ParseInit.cpp | 31 ++++++++++++++++++++----------- 1 file changed, 20 insertions(+), 11 deletions(-) (limited to 'clang/lib/Parse/ParseInit.cpp') 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 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, -- cgit v1.2.3