[cfe-commits] r150790 - in /cfe/trunk: include/clang/Parse/Parser.h lib/Parse/ParseInit.cpp test/Parser/cxx0x-lambda-expressions.cpp
Sebastian Redl
sebastian.redl at getdesigned.at
Fri Feb 17 00:05:57 PST 2012
On 17.02.2012, at 04:49, Douglas Gregor wrote:
> Author: dgregor
> Date: Thu Feb 16 21:49:44 2012
> New Revision: 150790
>
> URL: http://llvm.org/viewvc/llvm-project?rev=150790&view=rev
> Log:
> Disambiguate between C++11 lambda expressions and C99 array
> designators in the parser. In the worst case, this disambiguation
> requires tentative parsing just past the closing ']', but for most
> cases we'll be able to tell by looking ahead just one token (without
> going into the heavyweight tentative parsing machinery).
>
> Modified:
> cfe/trunk/include/clang/Parse/Parser.h
> cfe/trunk/lib/Parse/ParseInit.cpp
> cfe/trunk/test/Parser/cxx0x-lambda-expressions.cpp
>
> Modified: cfe/trunk/lib/Parse/ParseInit.cpp
> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Parse/ParseInit.cpp?rev=150790&r1=150789&r2=150790&view=diff
> ==============================================================================
> --- cfe/trunk/lib/Parse/ParseInit.cpp (original)
> +++ cfe/trunk/lib/Parse/ParseInit.cpp Thu Feb 16 21:49:44 2012
> @@ -21,15 +21,86 @@
> using namespace clang;
>
>
> -/// MayBeDesignationStart - Return true if this token might be the start of a
> -/// designator. If we can tell it is impossible that it is a designator, return
> -/// false.
> -static bool MayBeDesignationStart(tok::TokenKind K, Preprocessor &PP) {
> - switch (K) {
> - default: return false;
> +/// MayBeDesignationStart - Return true if the current token might be the start
> +/// of a designator. If we can tell it is impossible that it is a designator,
> +/// return false.
> +bool Parser::MayBeDesignationStart() {
> + switch (Tok.getKind()) {
> + default:
> + return false;
> +
> case tok::period: // designator: '.' identifier
> - case tok::l_square: // designator: array-designator
> + return true;
> +
> + case tok::l_square: { // designator: array-designator
> + if (!PP.getLangOptions().CPlusPlus0x)
> return true;
> +
Maybe reduce nesting by breaking out of the switch here?
> + // C++11 lambda expressions and C99 designators can be ambiguous all the
> + // way through the closing ']' and to the next character. Handle the easy
> + // cases here, and fall back to tentative parsing if those fail.
> + switch (PP.LookAhead(0).getKind()) {
> + case tok::equal:
> + case tok::r_square:
> + // Definitely starts a lambda expression.
> + return false;
> +
> + case tok::amp:
> + case tok::kw_this:
> + case tok::identifier:
> + // We have to do additional analysis, because these could be the
> + // start of a constant expression or a lambda capture list.
> + break;
> +
> + default:
> + // Anything not mentioned above cannot occur following a '[' in a
> + // lambda expression.
> + 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;
> + }
> case tok::identifier: // designation: identifier ':'
> return PP.LookAhead(0).is(tok::colon);
> }
Sebastian
More information about the cfe-commits
mailing list