diff --git a/src/libs/cplusplus/ResolveExpression.cpp b/src/libs/cplusplus/ResolveExpression.cpp index fe06d3dabfa81205e855156d7895bfc327196c3c..c6f8bd4b5b8b358df44b898f8df9d0ac8f251eea 100644 --- a/src/libs/cplusplus/ResolveExpression.cpp +++ b/src/libs/cplusplus/ResolveExpression.cpp @@ -293,6 +293,11 @@ bool ResolveExpression::visit(ThisExpressionAST *) return false; } +bool ResolveExpression::visit(CompoundExpressionAST *ast) +{ + return true; // ### +} + bool ResolveExpression::visit(NestedExpressionAST *ast) { accept(ast->expression); diff --git a/src/libs/cplusplus/ResolveExpression.h b/src/libs/cplusplus/ResolveExpression.h index 1d613228d83deefdb5a17bda8bd59a3e5a383d96..3a367964223b1ed7b5fa3a5d17607fcb69ba33e6 100644 --- a/src/libs/cplusplus/ResolveExpression.h +++ b/src/libs/cplusplus/ResolveExpression.h @@ -93,6 +93,7 @@ protected: virtual bool visit(TypeIdAST *ast); virtual bool visit(UnaryExpressionAST *ast); virtual bool visit(CompoundLiteralAST *ast); + virtual bool visit(CompoundExpressionAST *ast); //names virtual bool visit(QualifiedNameAST *ast); diff --git a/src/shared/cplusplus/AST.cpp b/src/shared/cplusplus/AST.cpp index fe697ea91de5869c554b5bcf9eecfaf980ca399b..a6f5bfb674e006c7ff6f207ad4a400a6086cd6b4 100644 --- a/src/shared/cplusplus/AST.cpp +++ b/src/shared/cplusplus/AST.cpp @@ -326,6 +326,20 @@ unsigned BoolLiteralAST::lastToken() const return literal_token + 1; } +unsigned CompoundExpressionAST::firstToken() const +{ + return lparen_token; +} + +unsigned CompoundExpressionAST::lastToken() const +{ + if (rparen_token) + return rparen_token + 1; + else if (compoundStatement) + return compoundStatement->lastToken(); + else + return lparen_token + 1; +} unsigned CompoundLiteralAST::firstToken() const { @@ -2300,5 +2314,3 @@ unsigned ObjCSynchronizedStatementAST::lastToken() const if (lparen_token) return lparen_token + 1; return synchronized_token + 1; } - - diff --git a/src/shared/cplusplus/AST.h b/src/shared/cplusplus/AST.h index 19239f32d9c9ef85b064a3d5765acad4dc93f1a6..c719f311608b5f0087c46c939cd55652ac2b074a 100644 --- a/src/shared/cplusplus/AST.h +++ b/src/shared/cplusplus/AST.h @@ -161,6 +161,7 @@ public: virtual CastExpressionAST *asCastExpression() { return 0; } virtual CatchClauseAST *asCatchClause() { return 0; } virtual ClassSpecifierAST *asClassSpecifier() { return 0; } + virtual CompoundExpressionAST *asCompoundExpression() { return 0; } virtual CompoundLiteralAST *asCompoundLiteral() { return 0; } virtual CompoundStatementAST *asCompoundStatement() { return 0; } virtual ConditionAST *asCondition() { return 0; } @@ -700,6 +701,26 @@ protected: virtual bool match0(AST *, ASTMatcher *); }; +class CPLUSPLUS_EXPORT CompoundExpressionAST: public ExpressionAST +{ +public: + unsigned lparen_token; + CompoundStatementAST *compoundStatement; + unsigned rparen_token; + +public: + virtual CompoundExpressionAST *asCompoundExpression() { return this; } + + virtual unsigned firstToken() const; + virtual unsigned lastToken() const; + + virtual CompoundExpressionAST *clone(MemoryPool *pool) const; + +protected: + virtual void accept0(ASTVisitor *visitor); + virtual bool match0(AST *, ASTMatcher *); +}; + class CPLUSPLUS_EXPORT CompoundLiteralAST: public ExpressionAST { public: diff --git a/src/shared/cplusplus/ASTClone.cpp b/src/shared/cplusplus/ASTClone.cpp index a3bb26e7d6803ef69296362565c8830876d252fc..b794a8b4b12f9454f1d6735c8b3d9be950791fd5 100644 --- a/src/shared/cplusplus/ASTClone.cpp +++ b/src/shared/cplusplus/ASTClone.cpp @@ -213,6 +213,16 @@ BaseSpecifierAST *BaseSpecifierAST::clone(MemoryPool *pool) const return ast; } +CompoundExpressionAST *CompoundExpressionAST::clone(MemoryPool *pool) const +{ + CompoundExpressionAST *ast = new (pool) CompoundExpressionAST; + ast->lparen_token = lparen_token; + if (compoundStatement) + ast->compoundStatement = compoundStatement->clone(pool); + ast->rparen_token = rparen_token; + return ast; +} + CompoundLiteralAST *CompoundLiteralAST::clone(MemoryPool *pool) const { CompoundLiteralAST *ast = new (pool) CompoundLiteralAST; diff --git a/src/shared/cplusplus/ASTMatch0.cpp b/src/shared/cplusplus/ASTMatch0.cpp index 807bfbf4d04b747f6789b69352be313aad1e8ace..f1d47aaa8a28d56fd6f764bd44de46eb0aa89092 100644 --- a/src/shared/cplusplus/ASTMatch0.cpp +++ b/src/shared/cplusplus/ASTMatch0.cpp @@ -153,6 +153,14 @@ bool BaseSpecifierAST::match0(AST *pattern, ASTMatcher *matcher) return false; } +bool CompoundExpressionAST::match0(AST *pattern, ASTMatcher *matcher) +{ + if (CompoundExpressionAST *_other = pattern->asCompoundExpression()) + return matcher->match(this, _other); + + return false; +} + bool CompoundLiteralAST::match0(AST *pattern, ASTMatcher *matcher) { if (CompoundLiteralAST *_other = pattern->asCompoundLiteral()) diff --git a/src/shared/cplusplus/ASTMatcher.cpp b/src/shared/cplusplus/ASTMatcher.cpp index febb9e5fe2aa4afd3eb81ebdeddf8ffaca67df4b..aa1a0f3ba62f55c68edc2cb2341b4838eeee5163 100644 --- a/src/shared/cplusplus/ASTMatcher.cpp +++ b/src/shared/cplusplus/ASTMatcher.cpp @@ -331,6 +331,23 @@ bool ASTMatcher::match(BaseSpecifierAST *node, BaseSpecifierAST *pattern) return true; } +bool ASTMatcher::match(CompoundExpressionAST *node, CompoundExpressionAST *pattern) +{ + (void) node; + (void) pattern; + + pattern->lparen_token = node->lparen_token; + + if (! pattern->compoundStatement) + pattern->compoundStatement = node->compoundStatement; + else if (! AST::match(node->compoundStatement, pattern->compoundStatement, this)) + return false; + + pattern->rparen_token = node->rparen_token; + + return true; +} + bool ASTMatcher::match(CompoundLiteralAST *node, CompoundLiteralAST *pattern) { (void) node; diff --git a/src/shared/cplusplus/ASTMatcher.h b/src/shared/cplusplus/ASTMatcher.h index df3aa6cf5a92f39f4a49a9f7aa13b46ccb629c07..c8263ab23775e73dae2852d41556b2c78e68fe45 100644 --- a/src/shared/cplusplus/ASTMatcher.h +++ b/src/shared/cplusplus/ASTMatcher.h @@ -59,6 +59,7 @@ public: virtual bool match(CastExpressionAST *node, CastExpressionAST *pattern); virtual bool match(CatchClauseAST *node, CatchClauseAST *pattern); virtual bool match(ClassSpecifierAST *node, ClassSpecifierAST *pattern); + virtual bool match(CompoundExpressionAST *node, CompoundExpressionAST *pattern); virtual bool match(CompoundLiteralAST *node, CompoundLiteralAST *pattern); virtual bool match(CompoundStatementAST *node, CompoundStatementAST *pattern); virtual bool match(ConditionAST *node, ConditionAST *pattern); diff --git a/src/shared/cplusplus/ASTVisit.cpp b/src/shared/cplusplus/ASTVisit.cpp index 5a563778fbb14acfb87099883147e2957bfe624c..0d7d7fee19fe599b26a11f65e9be40b6f6f28203 100644 --- a/src/shared/cplusplus/ASTVisit.cpp +++ b/src/shared/cplusplus/ASTVisit.cpp @@ -153,6 +153,14 @@ void BaseSpecifierAST::accept0(ASTVisitor *visitor) visitor->endVisit(this); } +void CompoundExpressionAST::accept0(ASTVisitor *visitor) +{ + if (visitor->visit(this)) { + accept(compoundStatement, visitor); + } + visitor->endVisit(this); +} + void CompoundLiteralAST::accept0(ASTVisitor *visitor) { if (visitor->visit(this)) { diff --git a/src/shared/cplusplus/ASTVisitor.h b/src/shared/cplusplus/ASTVisitor.h index 4c80732cd6f9cf383386a567c82dffad3d9bce22..2e10093c5bcd170ef27dc1fa61040bb324f933b0 100644 --- a/src/shared/cplusplus/ASTVisitor.h +++ b/src/shared/cplusplus/ASTVisitor.h @@ -122,6 +122,7 @@ public: virtual bool visit(CastExpressionAST *) { return true; } virtual bool visit(CatchClauseAST *) { return true; } virtual bool visit(ClassSpecifierAST *) { return true; } + virtual bool visit(CompoundExpressionAST *) { return true; } virtual bool visit(CompoundLiteralAST *) { return true; } virtual bool visit(CompoundStatementAST *) { return true; } virtual bool visit(ConditionAST *) { return true; } @@ -252,6 +253,7 @@ public: virtual void endVisit(CastExpressionAST *) { } virtual void endVisit(CatchClauseAST *) { } virtual void endVisit(ClassSpecifierAST *) { } + virtual void endVisit(CompoundExpressionAST *) { } virtual void endVisit(CompoundLiteralAST *) { } virtual void endVisit(CompoundStatementAST *) { } virtual void endVisit(ConditionAST *) { } diff --git a/src/shared/cplusplus/ASTfwd.h b/src/shared/cplusplus/ASTfwd.h index 722e36907a30c88280ef8c66a88dc3e8045fab99..13a02c0e5cf44f58bf27fbdedc1ff6d870ed61cc 100644 --- a/src/shared/cplusplus/ASTfwd.h +++ b/src/shared/cplusplus/ASTfwd.h @@ -75,6 +75,7 @@ class CaseStatementAST; class CastExpressionAST; class CatchClauseAST; class ClassSpecifierAST; +class CompoundExpressionAST; class CompoundLiteralAST; class CompoundStatementAST; class ConditionAST; diff --git a/src/shared/cplusplus/CheckExpression.cpp b/src/shared/cplusplus/CheckExpression.cpp index f8da07534c59942131230e59ebece213ecff701d..c971204c2e4d8647d8f493202b8fc7ecb0b7af09 100644 --- a/src/shared/cplusplus/CheckExpression.cpp +++ b/src/shared/cplusplus/CheckExpression.cpp @@ -287,6 +287,11 @@ bool CheckExpression::visit(ThisExpressionAST *) return false; } +bool CheckExpression::visit(CompoundExpressionAST *ast) +{ + return true; // ### +} + bool CheckExpression::visit(NestedExpressionAST *ast) { FullySpecifiedType exprTy = semantic()->check(ast->expression, _scope); diff --git a/src/shared/cplusplus/CheckExpression.h b/src/shared/cplusplus/CheckExpression.h index 8085731df5da9e68c8e6567ce207dd4e388cdd5e..9cc1722d7c2fc6ffccee251bd1b015c13df62235 100644 --- a/src/shared/cplusplus/CheckExpression.h +++ b/src/shared/cplusplus/CheckExpression.h @@ -94,6 +94,7 @@ protected: virtual bool visit(UnaryExpressionAST *ast); virtual bool visit(QtMethodAST *ast); virtual bool visit(CompoundLiteralAST *ast); + virtual bool visit(CompoundExpressionAST *ast); //names virtual bool visit(QualifiedNameAST *ast); diff --git a/src/shared/cplusplus/Parser.cpp b/src/shared/cplusplus/Parser.cpp index de66dbfac82fca6d614533eb06cfc500bfbcf40d..84a92a186aa52d0db468fc9e170c97a09e8a328a 100644 --- a/src/shared/cplusplus/Parser.cpp +++ b/src/shared/cplusplus/Parser.cpp @@ -3437,7 +3437,19 @@ bool Parser::parsePrimaryExpression(ExpressionAST *&node) return parseThisExpression(node); case T_LPAREN: - return parseNestedExpression(node); + if (LA(2) == T_LBRACE) { + // GNU extension: '(' '{' statement-list '}' ')' + CompoundExpressionAST *ast = new (_pool) CompoundExpressionAST; + ast->lparen_token = consumeToken(); + StatementAST *statement = 0; + parseCompoundStatement(statement); + ast->compoundStatement = statement->asCompoundStatement(); + match(T_RPAREN, &ast->rparen_token); + node = ast; + return true; + } else { + return parseNestedExpression(node); + } case T_SIGNAL: case T_SLOT: @@ -3799,19 +3811,6 @@ bool Parser::parseNestedExpression(ExpressionAST *&node) DEBUG_THIS_RULE(); if (LA() == T_LPAREN) { unsigned lparen_token = consumeToken(); - - if (LA() == T_LBRACE) { - NestedExpressionAST *ast = new (_pool) NestedExpressionAST; - ast->lparen_token = lparen_token; - - // ### ast - StatementAST *statement = 0; - parseCompoundStatement(statement); - match(T_RPAREN, &ast->rparen_token); - node = ast; - return true; - } - bool previousTemplateArguments = switchTemplateArguments(false); ExpressionAST *expression = 0; @@ -5275,12 +5274,11 @@ bool Parser::parseObjCContextKeyword(int kind, unsigned &in_token) { DEBUG_THIS_RULE(); - if (peekAtObjCContextKeyword(kind)) { - in_token = consumeToken(); - return true; - } else { + if (!peekAtObjCContextKeyword(kind)) return false; - } + + in_token = consumeToken(); + return true; }