CppEditor: Revert changes to parseExpressionStatement()

Amends c8f29b9e01.
It turns out that there are contexts where we want to parse an
expression statement even with the semicolon missing (e.g. completion on
incomplete code).
So leave the existing functions unchanged and do the thorough check
afterwards in parseIfStatement().

Change-Id: Id6209ef1abfe9d155c5b9381e6ae655cc721feb2
Reviewed-by: Qt CI Bot <qt_ci_bot@qt-project.org>
Reviewed-by: Christian Stenger <christian.stenger@qt.io>
This commit is contained in:
Christian Kandeler
2023-05-26 14:10:38 +02:00
parent 809f7c6cfd
commit fb59c70dcb
6 changed files with 23 additions and 24 deletions

View File

@@ -1779,7 +1779,6 @@ public:
int if_token = 0; int if_token = 0;
int constexpr_token = 0; int constexpr_token = 0;
int lparen_token = 0; int lparen_token = 0;
DeclarationAST *initDecl = nullptr;
StatementAST *initStmt = nullptr; StatementAST *initStmt = nullptr;
ExpressionAST *condition = nullptr; ExpressionAST *condition = nullptr;
int rparen_token = 0; int rparen_token = 0;

View File

@@ -785,8 +785,6 @@ IfStatementAST *IfStatementAST::clone(MemoryPool *pool) const
ast->if_token = if_token; ast->if_token = if_token;
ast->constexpr_token = constexpr_token; ast->constexpr_token = constexpr_token;
ast->lparen_token = lparen_token; ast->lparen_token = lparen_token;
if (initDecl)
ast->initDecl = initDecl->clone(pool);
if (initStmt) if (initStmt)
ast->initStmt = initStmt->clone(pool); ast->initStmt = initStmt->clone(pool);
if (condition) if (condition)

View File

@@ -1318,11 +1318,6 @@ bool ASTMatcher::match(IfStatementAST *node, IfStatementAST *pattern)
pattern->lparen_token = node->lparen_token; pattern->lparen_token = node->lparen_token;
if (!pattern->initDecl)
pattern->initDecl = node->initDecl;
else if (!AST::match(node->initDecl, pattern->initDecl, this))
return false;
if (!pattern->initStmt) if (!pattern->initStmt)
pattern->initStmt = node->initStmt; pattern->initStmt = node->initStmt;
else if (!AST::match(node->initStmt, pattern->initStmt, this)) else if (!AST::match(node->initStmt, pattern->initStmt, this))

View File

@@ -563,7 +563,6 @@ void ForStatementAST::accept0(ASTVisitor *visitor)
void IfStatementAST::accept0(ASTVisitor *visitor) void IfStatementAST::accept0(ASTVisitor *visitor)
{ {
if (visitor->visit(this)) { if (visitor->visit(this)) {
accept(initDecl, visitor);
accept(initStmt, visitor); accept(initStmt, visitor);
accept(condition, visitor); accept(condition, visitor);
accept(statement, visitor); accept(statement, visitor);

View File

@@ -1528,9 +1528,7 @@ bool Bind::visit(IfStatementAST *ast)
ast->symbol = block; ast->symbol = block;
Scope *previousScope = switchScope(block); Scope *previousScope = switchScope(block);
if (ast->initDecl) if (ast->initStmt)
this->declaration(ast->initDecl);
else if (ast->initStmt)
this->statement(ast->initStmt); this->statement(ast->initStmt);
/*ExpressionTy condition =*/ this->expression(ast->condition); /*ExpressionTy condition =*/ this->expression(ast->condition);
this->statement(ast->statement); this->statement(ast->statement);

View File

@@ -3511,15 +3511,13 @@ bool Parser::parseExpressionStatement(StatementAST *&node)
ExpressionAST *expression = nullptr; ExpressionAST *expression = nullptr;
if (parseExpression(expression)) { if (parseExpression(expression)) {
if (LA() == T_SEMICOLON) {
ExpressionStatementAST *ast = new (previousPool) ExpressionStatementAST; ExpressionStatementAST *ast = new (previousPool) ExpressionStatementAST;
ast->semicolon_token = consumeToken();
if (expression) if (expression)
ast->expression = expression->clone(previousPool); ast->expression = expression->clone(previousPool);
match(T_SEMICOLON, &ast->semicolon_token);
node = ast; node = ast;
parsed = true; parsed = true;
} }
}
_inExpressionStatement = wasInExpressionStatement; _inExpressionStatement = wasInExpressionStatement;
@@ -4079,14 +4077,26 @@ bool Parser::parseIfStatement(StatementAST *&node)
if (_languageFeatures.cxx17Enabled) { if (_languageFeatures.cxx17Enabled) {
const int savedCursor = cursor(); const int savedCursor = cursor();
const bool savedBlockErrors = _translationUnit->blockErrors(true); const bool savedBlockErrors = _translationUnit->blockErrors(true);
if (!parseSimpleDeclaration(ast->initDecl)) { bool foundInitStmt = parseExpressionOrDeclarationStatement(ast->initStmt);
rewind(savedCursor); if (foundInitStmt)
if (!parseExpressionStatement(ast->initStmt)) foundInitStmt = ast->initStmt;
if (foundInitStmt) {
if (const auto exprStmt = ast->initStmt->asExpressionStatement()) {
foundInitStmt = exprStmt->semicolon_token;
} else if (const auto declStmt = ast->initStmt->asDeclarationStatement()) {
foundInitStmt = declStmt->declaration
&& declStmt->declaration->asSimpleDeclaration()
&& declStmt->declaration->asSimpleDeclaration()->semicolon_token;
} else {
foundInitStmt = false;
}
}
if (!foundInitStmt) {
ast->initStmt = nullptr;
rewind(savedCursor); rewind(savedCursor);
} }
_translationUnit->blockErrors(savedBlockErrors); _translationUnit->blockErrors(savedBlockErrors);
} }
parseCondition(ast->condition); parseCondition(ast->condition);
match(T_RPAREN, &ast->rparen_token); match(T_RPAREN, &ast->rparen_token);
if (! parseStatement(ast->statement)) if (! parseStatement(ast->statement))