From 23b05417c9c7bec556090972ed14a5b4c9e8583b Mon Sep 17 00:00:00 2001 From: Douglas Gregor Date: Fri, 17 Feb 2012 16:41:16 +0000 Subject: [PATCH] De-nest tentative parsing to disambiguate lambdas from designators; no functionality change. llvm-svn: 150817 --- clang/lib/Parse/ParseInit.cpp | 87 ++++++++++++++++++----------------- 1 file changed, 45 insertions(+), 42 deletions(-) diff --git a/clang/lib/Parse/ParseInit.cpp b/clang/lib/Parse/ParseInit.cpp index 45f1825f7e62..d5e06f7fd88f 100644 --- a/clang/lib/Parse/ParseInit.cpp +++ b/clang/lib/Parse/ParseInit.cpp @@ -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,