diff --git a/shared/cplusplus/AST.cpp b/shared/cplusplus/AST.cpp index 11be99ea48a1257371a3a584e5894b9669c55ca1..6889ba6fa8cd4d4ecc4ca8a5ea341f7c0f48e3cd 100644 --- a/shared/cplusplus/AST.cpp +++ b/shared/cplusplus/AST.cpp @@ -117,6 +117,9 @@ CatchClauseAST *AST::asCatchClause() ClassSpecifierAST *AST::asClassSpecifier() { return dynamic_cast<ClassSpecifierAST *>(this); } +CompoundLiteralAST *AST::asCompoundLiteral() +{ return dynamic_cast<CompoundLiteralAST *>(this); } + CompoundStatementAST *AST::asCompoundStatement() { return dynamic_cast<CompoundStatementAST *>(this); } @@ -774,6 +777,42 @@ unsigned BoolLiteralAST::lastToken() const return token + 1; } +CompoundLiteralAST *CompoundLiteralAST::clone(MemoryPool *pool) const +{ + CompoundLiteralAST *ast = new (pool) CompoundLiteralAST; + ast->lparen_token = lparen_token; + if (type_id) + ast->type_id = type_id->clone(pool); + ast->rparen_token = rparen_token; + if (initializer) + ast->initializer = initializer->clone(pool); + return ast; +} + +void CompoundLiteralAST::accept0(ASTVisitor *visitor) +{ + if (visitor->visit(this)) { + accept(type_id, visitor); + accept(initializer, visitor); + } +} + +unsigned CompoundLiteralAST::firstToken() const +{ + return lparen_token; +} + +unsigned CompoundLiteralAST::lastToken() const +{ + if (initializer) + return initializer->lastToken(); + else if (rparen_token) + return rparen_token + 1; + else if (type_id) + return type_id->lastToken(); + return lparen_token + 1; +} + BreakStatementAST *BreakStatementAST::clone(MemoryPool *pool) const { BreakStatementAST *ast = new (pool) BreakStatementAST; diff --git a/shared/cplusplus/AST.h b/shared/cplusplus/AST.h index 6607e76805b8072094d40bc4f43551d34ff57920..46322fdd6bcc259dde5653223d20f7da45a81598 100644 --- a/shared/cplusplus/AST.h +++ b/shared/cplusplus/AST.h @@ -94,6 +94,7 @@ public: CastExpressionAST *asCastExpression(); CatchClauseAST *asCatchClause(); ClassSpecifierAST *asClassSpecifier(); + CompoundLiteralAST *asCompoundLiteral(); CompoundStatementAST *asCompoundStatement(); ConditionAST *asCondition(); ConditionalExpressionAST *asConditionalExpression(); @@ -429,6 +430,24 @@ protected: virtual void accept0(ASTVisitor *visitor); }; +class CPLUSPLUS_EXPORT CompoundLiteralAST: public ExpressionAST +{ +public: + unsigned lparen_token; + ExpressionAST *type_id; + unsigned rparen_token; + ExpressionAST *initializer; + +public: + virtual unsigned firstToken() const; + virtual unsigned lastToken() const; + + virtual CompoundLiteralAST *clone(MemoryPool *pool) const; + +protected: + virtual void accept0(ASTVisitor *visitor); +}; + class CPLUSPLUS_EXPORT QtMethodAST: public ExpressionAST { public: diff --git a/shared/cplusplus/ASTVisitor.h b/shared/cplusplus/ASTVisitor.h index 28097c14f704af8151d5a5a76c63f8d3b6458d93..e7a9aed158415b8ecdf8013dcb68f14d9215bb12 100644 --- a/shared/cplusplus/ASTVisitor.h +++ b/shared/cplusplus/ASTVisitor.h @@ -104,6 +104,7 @@ public: virtual bool visit(CastExpressionAST *) { return true; } virtual bool visit(CatchClauseAST *) { return true; } virtual bool visit(ClassSpecifierAST *) { return true; } + virtual bool visit(CompoundLiteralAST *) { return true; } virtual bool visit(CompoundStatementAST *) { return true; } virtual bool visit(ConditionAST *) { return true; } virtual bool visit(ConditionalExpressionAST *) { return true; } diff --git a/shared/cplusplus/ASTfwd.h b/shared/cplusplus/ASTfwd.h index 79f794f629ed7c90235ba29911c7d3e57f710418..db68992e0224f11eebb881e4caf2321f83a0ecc6 100644 --- a/shared/cplusplus/ASTfwd.h +++ b/shared/cplusplus/ASTfwd.h @@ -77,6 +77,7 @@ class CaseStatementAST; class CastExpressionAST; class CatchClauseAST; class ClassSpecifierAST; +class CompoundLiteralAST; class CompoundStatementAST; class ConditionAST; class ConditionalExpressionAST; diff --git a/shared/cplusplus/CheckExpression.cpp b/shared/cplusplus/CheckExpression.cpp index 9976cbf500e874e448cbf4eae1930d139d62cebb..d5d88c3857204152a565a54df8ba41d3e4d39872 100644 --- a/shared/cplusplus/CheckExpression.cpp +++ b/shared/cplusplus/CheckExpression.cpp @@ -333,6 +333,13 @@ bool CheckExpression::visit(QtMethodAST *ast) return false; } +bool CheckExpression::visit(CompoundLiteralAST *ast) +{ + /*FullySpecifiedType exprTy = */ semantic()->check(ast->type_id, _scope); + /*FullySpecifiedType initTy = */ semantic()->check(ast->initializer, _scope); + return false; +} + bool CheckExpression::visit(CallAST *ast) { for (ExpressionListAST *it = ast->expression_list; it; it = it->next) { diff --git a/shared/cplusplus/CheckExpression.h b/shared/cplusplus/CheckExpression.h index e018e7dc89bca032777ed6d4f942a5aa5608126a..f5c9e7c8e9438989d8294753cd9e857cd006bbd9 100644 --- a/shared/cplusplus/CheckExpression.h +++ b/shared/cplusplus/CheckExpression.h @@ -98,6 +98,7 @@ protected: virtual bool visit(TypeIdAST *ast); virtual bool visit(UnaryExpressionAST *ast); virtual bool visit(QtMethodAST *ast); + virtual bool visit(CompoundLiteralAST *ast); //names virtual bool visit(QualifiedNameAST *ast); diff --git a/shared/cplusplus/Parser.cpp b/shared/cplusplus/Parser.cpp index 407cbc36fd8530b797cee2f181ae1708dcc988d3..0e49e9fe88a7a075afe4df7ba74a24c0ef8f968c 100644 --- a/shared/cplusplus/Parser.cpp +++ b/shared/cplusplus/Parser.cpp @@ -1621,8 +1621,7 @@ bool Parser::parseInitializerClause(ExpressionAST *&node) ArrayInitializerAST *ast = new (_pool) ArrayInitializerAST; ast->lbrace_token = consumeToken(); parseInitializerList(ast->expression_list); - if (LA() == T_RBRACE) - ast->rbrace_token = consumeToken(); + match(T_RBRACE, &ast->rbrace_token); node = ast; return true; } @@ -2702,8 +2701,30 @@ bool Parser::parseCorePostfixExpression(ExpressionAST *&node) return true; } } - blockErrors(blocked); rewind(start); + + // look for compound literals + if (LA() == T_LPAREN) { + unsigned lparen_token = consumeToken(); + ExpressionAST *type_id = 0; + if (parseTypeId(type_id) && LA() == T_RPAREN) { + unsigned rparen_token = consumeToken(); + if (LA() == T_LBRACE) { + blockErrors(blocked); + + CompoundLiteralAST *ast = new (_pool) CompoundLiteralAST; + ast->lparen_token = lparen_token; + ast->type_id = type_id; + ast->rparen_token = rparen_token; + parseInitializerClause(ast->initializer); + node = ast; + return true; + } + } + rewind(start); + } + + blockErrors(blocked); return parsePrimaryExpression(node); } } diff --git a/shared/cplusplus/PrettyPrinter.cpp b/shared/cplusplus/PrettyPrinter.cpp index 72338576b6b25665a6154cf6bf4090ede03592d9..af80cee197ea98ffb9287a0a04ce25fdf132d9c9 100644 --- a/shared/cplusplus/PrettyPrinter.cpp +++ b/shared/cplusplus/PrettyPrinter.cpp @@ -1281,3 +1281,13 @@ bool PrettyPrinter::visit(QtMethodAST *ast) out << ')'; return false; } + +bool PrettyPrinter::visit(CompoundLiteralAST *ast) +{ + out << '('; + accept(ast->type_id); + out << ')'; + out << ' '; + accept(ast->initializer); + return false; +} diff --git a/shared/cplusplus/PrettyPrinter.h b/shared/cplusplus/PrettyPrinter.h index 966ebacd0e60c65326f5743e094497128642ef12..fc59100a3c146b2afe142a3c1fb72a1d8ee6f209 100644 --- a/shared/cplusplus/PrettyPrinter.h +++ b/shared/cplusplus/PrettyPrinter.h @@ -66,6 +66,7 @@ protected: virtual bool visit(CastExpressionAST *ast); virtual bool visit(CatchClauseAST *ast); virtual bool visit(ClassSpecifierAST *ast); + virtual bool visit(CompoundLiteralAST *ast); virtual bool visit(CompoundStatementAST *ast); virtual bool visit(ConditionAST *ast); virtual bool visit(ConditionalExpressionAST *ast);