From 248480b7c952b2b981e3ec9c40bf0f0761c12ac5 Mon Sep 17 00:00:00 2001 From: Roberto Raggi <qtc-committer@nokia.com> Date: Tue, 13 Jan 2009 14:58:29 +0100 Subject: [PATCH] Added support for C99 compound literals. --- shared/cplusplus/AST.cpp | 39 ++++++++++++++++++++++++++++ shared/cplusplus/AST.h | 19 ++++++++++++++ shared/cplusplus/ASTVisitor.h | 1 + shared/cplusplus/ASTfwd.h | 1 + shared/cplusplus/CheckExpression.cpp | 7 +++++ shared/cplusplus/CheckExpression.h | 1 + shared/cplusplus/Parser.cpp | 27 ++++++++++++++++--- shared/cplusplus/PrettyPrinter.cpp | 10 +++++++ shared/cplusplus/PrettyPrinter.h | 1 + 9 files changed, 103 insertions(+), 3 deletions(-) diff --git a/shared/cplusplus/AST.cpp b/shared/cplusplus/AST.cpp index 11be99ea48a..6889ba6fa8c 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 6607e76805b..46322fdd6bc 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 28097c14f70..e7a9aed1584 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 79f794f629e..db68992e022 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 9976cbf500e..d5d88c38572 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 e018e7dc89b..f5c9e7c8e94 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 407cbc36fd8..0e49e9fe88a 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 72338576b6b..af80cee197e 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 966ebacd0e6..fc59100a3c1 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); -- GitLab