diff options
author | Roberto Raggi <roberto.raggi@nokia.com> | 2011-01-20 11:01:16 +0100 |
---|---|---|
committer | Roberto Raggi <roberto.raggi@nokia.com> | 2011-01-20 11:01:16 +0100 |
commit | abff92c0fbfba5fdd5edfe8d3fce91726bc2e7a6 (patch) | |
tree | efb86056d2cba62026168e696f85b0f56ec65744 /src/shared/cplusplus | |
parent | c238eb93000f5c2803a9058ae37353fd77bc993f (diff) | |
download | qt-creator-abff92c0fbfba5fdd5edfe8d3fce91726bc2e7a6.tar.gz |
Parse ambiguous postfix expressions.
Diffstat (limited to 'src/shared/cplusplus')
-rw-r--r-- | src/shared/cplusplus/Parser.cpp | 41 |
1 files changed, 41 insertions, 0 deletions
diff --git a/src/shared/cplusplus/Parser.cpp b/src/shared/cplusplus/Parser.cpp index f11389e1a2..56f0a6cf48 100644 --- a/src/shared/cplusplus/Parser.cpp +++ b/src/shared/cplusplus/Parser.cpp @@ -4743,6 +4743,44 @@ bool Parser::parseCastExpression(ExpressionAST *&node) unsigned lparen_token = consumeToken(); ExpressionAST *type_id = 0; if (parseTypeId(type_id) && LA() == T_RPAREN) { + + if (TypeIdAST *tid = type_id->asTypeId()) { + if (tid->type_specifier_list && ! tid->type_specifier_list->next) { + if (tid->type_specifier_list->value->asNamedTypeSpecifier()) { + switch (LA(2)) { + case T_LBRACKET: // ... it's definitely a unary expression followed by an array access. + goto parse_as_unary_expression; + + case T_PLUS_PLUS: + case T_MINUS_MINUS: { + const unsigned rparen_token = consumeToken(); + + const bool blocked = blockErrors(true); + ExpressionAST *unary = 0; + bool followedByUnaryExpression = parseUnaryExpression(unary); + blockErrors(blocked); + rewind(rparen_token); + + if (followedByUnaryExpression) { + if (! unary) + followedByUnaryExpression = false; + else if (UnaryExpressionAST *u = unary->asUnaryExpression()) + followedByUnaryExpression = u->expression != 0; + } + + if (! followedByUnaryExpression) + goto parse_as_unary_expression; + + } break; + + case T_LPAREN: // .. it can be parsed as a function call. + // ### TODO: check if it is followed by a parenthesized expression list. + break; + } + } + } + } + unsigned rparen_token = consumeToken(); ExpressionAST *expression = 0; if (parseCastExpression(expression)) { @@ -4755,8 +4793,11 @@ bool Parser::parseCastExpression(ExpressionAST *&node) return true; } } + +parse_as_unary_expression: rewind(lparen_token); } + return parseUnaryExpression(node); } |