From fb59c70dcb1ace439cf9a03e95d90dd34dbe9584 Mon Sep 17 00:00:00 2001 From: Christian Kandeler Date: Fri, 26 May 2023 14:10:38 +0200 Subject: [PATCH] CppEditor: Revert changes to parseExpressionStatement() Amends c8f29b9e0148202ab1959466e14fa23411fd8214. 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 Reviewed-by: Christian Stenger --- src/libs/3rdparty/cplusplus/AST.h | 1 - src/libs/3rdparty/cplusplus/ASTClone.cpp | 2 -- src/libs/3rdparty/cplusplus/ASTMatcher.cpp | 5 ---- src/libs/3rdparty/cplusplus/ASTVisit.cpp | 1 - src/libs/3rdparty/cplusplus/Bind.cpp | 4 +-- src/libs/3rdparty/cplusplus/Parser.cpp | 34 ++++++++++++++-------- 6 files changed, 23 insertions(+), 24 deletions(-) diff --git a/src/libs/3rdparty/cplusplus/AST.h b/src/libs/3rdparty/cplusplus/AST.h index 6a5da23306a..3f48e192b93 100644 --- a/src/libs/3rdparty/cplusplus/AST.h +++ b/src/libs/3rdparty/cplusplus/AST.h @@ -1779,7 +1779,6 @@ public: int if_token = 0; int constexpr_token = 0; int lparen_token = 0; - DeclarationAST *initDecl = nullptr; StatementAST *initStmt = nullptr; ExpressionAST *condition = nullptr; int rparen_token = 0; diff --git a/src/libs/3rdparty/cplusplus/ASTClone.cpp b/src/libs/3rdparty/cplusplus/ASTClone.cpp index 57617bb1180..c9c2fc8294a 100644 --- a/src/libs/3rdparty/cplusplus/ASTClone.cpp +++ b/src/libs/3rdparty/cplusplus/ASTClone.cpp @@ -785,8 +785,6 @@ IfStatementAST *IfStatementAST::clone(MemoryPool *pool) const ast->if_token = if_token; ast->constexpr_token = constexpr_token; ast->lparen_token = lparen_token; - if (initDecl) - ast->initDecl = initDecl->clone(pool); if (initStmt) ast->initStmt = initStmt->clone(pool); if (condition) diff --git a/src/libs/3rdparty/cplusplus/ASTMatcher.cpp b/src/libs/3rdparty/cplusplus/ASTMatcher.cpp index 6f12efb8aca..b264098a969 100644 --- a/src/libs/3rdparty/cplusplus/ASTMatcher.cpp +++ b/src/libs/3rdparty/cplusplus/ASTMatcher.cpp @@ -1318,11 +1318,6 @@ bool ASTMatcher::match(IfStatementAST *node, IfStatementAST *pattern) 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) pattern->initStmt = node->initStmt; else if (!AST::match(node->initStmt, pattern->initStmt, this)) diff --git a/src/libs/3rdparty/cplusplus/ASTVisit.cpp b/src/libs/3rdparty/cplusplus/ASTVisit.cpp index 7e8f75f2334..5b0ef3ce330 100644 --- a/src/libs/3rdparty/cplusplus/ASTVisit.cpp +++ b/src/libs/3rdparty/cplusplus/ASTVisit.cpp @@ -563,7 +563,6 @@ void ForStatementAST::accept0(ASTVisitor *visitor) void IfStatementAST::accept0(ASTVisitor *visitor) { if (visitor->visit(this)) { - accept(initDecl, visitor); accept(initStmt, visitor); accept(condition, visitor); accept(statement, visitor); diff --git a/src/libs/3rdparty/cplusplus/Bind.cpp b/src/libs/3rdparty/cplusplus/Bind.cpp index e3d38a09a84..c85d401c49b 100644 --- a/src/libs/3rdparty/cplusplus/Bind.cpp +++ b/src/libs/3rdparty/cplusplus/Bind.cpp @@ -1528,9 +1528,7 @@ bool Bind::visit(IfStatementAST *ast) ast->symbol = block; Scope *previousScope = switchScope(block); - if (ast->initDecl) - this->declaration(ast->initDecl); - else if (ast->initStmt) + if (ast->initStmt) this->statement(ast->initStmt); /*ExpressionTy condition =*/ this->expression(ast->condition); this->statement(ast->statement); diff --git a/src/libs/3rdparty/cplusplus/Parser.cpp b/src/libs/3rdparty/cplusplus/Parser.cpp index 31e290d1ad6..6bf19f59829 100644 --- a/src/libs/3rdparty/cplusplus/Parser.cpp +++ b/src/libs/3rdparty/cplusplus/Parser.cpp @@ -3511,14 +3511,12 @@ bool Parser::parseExpressionStatement(StatementAST *&node) ExpressionAST *expression = nullptr; if (parseExpression(expression)) { - if (LA() == T_SEMICOLON) { - ExpressionStatementAST *ast = new (previousPool) ExpressionStatementAST; - ast->semicolon_token = consumeToken(); - if (expression) - ast->expression = expression->clone(previousPool); - node = ast; - parsed = true; - } + ExpressionStatementAST *ast = new (previousPool) ExpressionStatementAST; + if (expression) + ast->expression = expression->clone(previousPool); + match(T_SEMICOLON, &ast->semicolon_token); + node = ast; + parsed = true; } _inExpressionStatement = wasInExpressionStatement; @@ -4079,14 +4077,26 @@ bool Parser::parseIfStatement(StatementAST *&node) if (_languageFeatures.cxx17Enabled) { const int savedCursor = cursor(); const bool savedBlockErrors = _translationUnit->blockErrors(true); - if (!parseSimpleDeclaration(ast->initDecl)) { + bool foundInitStmt = parseExpressionOrDeclarationStatement(ast->initStmt); + if (foundInitStmt) + 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); - if (!parseExpressionStatement(ast->initStmt)) - rewind(savedCursor); } _translationUnit->blockErrors(savedBlockErrors); } - parseCondition(ast->condition); match(T_RPAREN, &ast->rparen_token); if (! parseStatement(ast->statement))