diff options
-rw-r--r-- | src/shared/cplusplus/AST.cpp | 19 | ||||
-rw-r--r-- | src/shared/cplusplus/AST.h | 29 | ||||
-rw-r--r-- | src/shared/cplusplus/ASTClone.cpp | 13 | ||||
-rw-r--r-- | src/shared/cplusplus/ASTMatch0.cpp | 8 | ||||
-rw-r--r-- | src/shared/cplusplus/ASTMatcher.cpp | 21 | ||||
-rw-r--r-- | src/shared/cplusplus/ASTMatcher.h | 1 | ||||
-rw-r--r-- | src/shared/cplusplus/ASTVisit.cpp | 8 | ||||
-rw-r--r-- | src/shared/cplusplus/ASTVisitor.h | 3 | ||||
-rw-r--r-- | src/shared/cplusplus/ASTfwd.h | 1 | ||||
-rw-r--r-- | src/shared/cplusplus/CheckExpression.cpp | 7 | ||||
-rw-r--r-- | src/shared/cplusplus/CheckExpression.h | 1 | ||||
-rw-r--r-- | src/shared/cplusplus/Parser.cpp | 107 | ||||
-rw-r--r-- | src/shared/cplusplus/Parser.h | 6 |
13 files changed, 219 insertions, 5 deletions
diff --git a/src/shared/cplusplus/AST.cpp b/src/shared/cplusplus/AST.cpp index 12a520a4fc..55b978790b 100644 --- a/src/shared/cplusplus/AST.cpp +++ b/src/shared/cplusplus/AST.cpp @@ -2555,3 +2555,22 @@ unsigned TrailingReturnTypeAST::lastToken() const return arrow_token + 1; } + +unsigned BracedInitializerAST::firstToken() const +{ + return lbrace_token; +} + +unsigned BracedInitializerAST::lastToken() const +{ + if (rbrace_token) + return rbrace_token + 1; + + else if (comma_token) + return comma_token + 1; + + else if (expression_list) + return expression_list->lastToken(); + + return lbrace_token + 1; +} diff --git a/src/shared/cplusplus/AST.h b/src/shared/cplusplus/AST.h index 2baf4bb3b4..8f90555af7 100644 --- a/src/shared/cplusplus/AST.h +++ b/src/shared/cplusplus/AST.h @@ -162,6 +162,7 @@ public: virtual BaseSpecifierAST *asBaseSpecifier() { return 0; } virtual BinaryExpressionAST *asBinaryExpression() { return 0; } virtual BoolLiteralAST *asBoolLiteral() { return 0; } + virtual BracedInitializerAST *asBracedInitializer() { return 0; } virtual BreakStatementAST *asBreakStatement() { return 0; } virtual CallAST *asCall() { return 0; } virtual CaptureAST *asCapture() { return 0; } @@ -2895,6 +2896,7 @@ public: public: SizeofExpressionAST() : sizeof_token(0) + , dot_dot_dot_token(0) , lparen_token(0) , expression(0) , rparen_token(0) @@ -4265,6 +4267,33 @@ protected: virtual bool match0(AST *, ASTMatcher *); }; +class BracedInitializerAST: public ExpressionAST +{ +public: + unsigned lbrace_token; + ExpressionListAST *expression_list; + unsigned comma_token; + unsigned rbrace_token; + +public: + BracedInitializerAST() + : lbrace_token(0) + , expression_list(0) + , comma_token(0) + , rbrace_token(0) + {} + + virtual BracedInitializerAST *asBracedInitializer() { return this; } + virtual unsigned firstToken() const; + virtual unsigned lastToken() const; + + virtual BracedInitializerAST *clone(MemoryPool *pool) const; + +protected: + virtual void accept0(ASTVisitor *visitor); + virtual bool match0(AST *, ASTMatcher *); +}; + } // end of namespace CPlusPlus #endif // CPLUSPLUS_AST_H diff --git a/src/shared/cplusplus/ASTClone.cpp b/src/shared/cplusplus/ASTClone.cpp index 42b4ed6600..73237e1765 100644 --- a/src/shared/cplusplus/ASTClone.cpp +++ b/src/shared/cplusplus/ASTClone.cpp @@ -1083,6 +1083,7 @@ SizeofExpressionAST *SizeofExpressionAST::clone(MemoryPool *pool) const { SizeofExpressionAST *ast = new (pool) SizeofExpressionAST; ast->sizeof_token = sizeof_token; + ast->dot_dot_dot_token = dot_dot_dot_token; ast->lparen_token = lparen_token; if (expression) ast->expression = expression->clone(pool); @@ -1659,3 +1660,15 @@ TrailingReturnTypeAST *TrailingReturnTypeAST::clone(MemoryPool *pool) const return ast; } +BracedInitializerAST *BracedInitializerAST::clone(MemoryPool *pool) const +{ + BracedInitializerAST *ast = new (pool) BracedInitializerAST; + ast->lbrace_token = lbrace_token; + for (ExpressionListAST *iter = expression_list, **ast_iter = &ast->expression_list; + iter; iter = iter->next, ast_iter = &(*ast_iter)->next) + *ast_iter = new (pool) ExpressionListAST((iter->value) ? iter->value->clone(pool) : 0); + ast->comma_token = comma_token; + ast->rbrace_token = rbrace_token; + return ast; +} + diff --git a/src/shared/cplusplus/ASTMatch0.cpp b/src/shared/cplusplus/ASTMatch0.cpp index bc2f252b81..0838f3e2a4 100644 --- a/src/shared/cplusplus/ASTMatch0.cpp +++ b/src/shared/cplusplus/ASTMatch0.cpp @@ -1137,3 +1137,11 @@ bool TrailingReturnTypeAST::match0(AST *pattern, ASTMatcher *matcher) return false; } +bool BracedInitializerAST::match0(AST *pattern, ASTMatcher *matcher) +{ + if (BracedInitializerAST *_other = pattern->asBracedInitializer()) + return matcher->match(this, _other); + + return false; +} + diff --git a/src/shared/cplusplus/ASTMatcher.cpp b/src/shared/cplusplus/ASTMatcher.cpp index e6c447823b..4be5014abd 100644 --- a/src/shared/cplusplus/ASTMatcher.cpp +++ b/src/shared/cplusplus/ASTMatcher.cpp @@ -1808,6 +1808,8 @@ bool ASTMatcher::match(SizeofExpressionAST *node, SizeofExpressionAST *pattern) pattern->sizeof_token = node->sizeof_token; + pattern->dot_dot_dot_token = node->dot_dot_dot_token; + pattern->lparen_token = node->lparen_token; if (! pattern->expression) @@ -2796,3 +2798,22 @@ bool ASTMatcher::match(TrailingReturnTypeAST *node, TrailingReturnTypeAST *patte return true; } +bool ASTMatcher::match(BracedInitializerAST *node, BracedInitializerAST *pattern) +{ + (void) node; + (void) pattern; + + pattern->lbrace_token = node->lbrace_token; + + if (! pattern->expression_list) + pattern->expression_list = node->expression_list; + else if (! AST::match(node->expression_list, pattern->expression_list, this)) + return false; + + pattern->comma_token = node->comma_token; + + pattern->rbrace_token = node->rbrace_token; + + return true; +} + diff --git a/src/shared/cplusplus/ASTMatcher.h b/src/shared/cplusplus/ASTMatcher.h index d3fcab5dcf..7179328771 100644 --- a/src/shared/cplusplus/ASTMatcher.h +++ b/src/shared/cplusplus/ASTMatcher.h @@ -176,6 +176,7 @@ public: virtual bool match(LambdaDeclaratorAST *node, LambdaDeclaratorAST *pattern); virtual bool match(CaptureAST *node, CaptureAST *pattern); virtual bool match(TrailingReturnTypeAST *node, TrailingReturnTypeAST *pattern); + virtual bool match(BracedInitializerAST *node, BracedInitializerAST *pattern); }; } // end of namespace CPlusPlus diff --git a/src/shared/cplusplus/ASTVisit.cpp b/src/shared/cplusplus/ASTVisit.cpp index d2a0812db4..3c790aadb3 100644 --- a/src/shared/cplusplus/ASTVisit.cpp +++ b/src/shared/cplusplus/ASTVisit.cpp @@ -1214,3 +1214,11 @@ void TrailingReturnTypeAST::accept0(ASTVisitor *visitor) visitor->endVisit(this); } +void BracedInitializerAST::accept0(ASTVisitor *visitor) +{ + if (visitor->visit(this)) { + accept(expression_list, visitor); + } + visitor->endVisit(this); +} + diff --git a/src/shared/cplusplus/ASTVisitor.h b/src/shared/cplusplus/ASTVisitor.h index 078dfee89e..f5d9140560 100644 --- a/src/shared/cplusplus/ASTVisitor.h +++ b/src/shared/cplusplus/ASTVisitor.h @@ -216,6 +216,7 @@ public: virtual bool visit(LambdaDeclaratorAST *) { return true; } virtual bool visit(CaptureAST *) { return true; } virtual bool visit(TrailingReturnTypeAST *) { return true; } + virtual bool visit(BracedInitializerAST *) { return true; } // ObjC++ virtual bool visit(ObjCClassDeclarationAST *) { return true; } @@ -351,12 +352,14 @@ public: virtual void endVisit(QtInterfacesDeclarationAST *) { } virtual void endVisit(QtInterfaceNameAST *) { } + // C++0x virtual void endVisit(LambdaExpressionAST *) { } virtual void endVisit(LambdaIntroducerAST *) { } virtual void endVisit(LambdaCaptureAST *) { } virtual void endVisit(LambdaDeclaratorAST *) { } virtual void endVisit(CaptureAST *) { } virtual void endVisit(TrailingReturnTypeAST *) { } + virtual void endVisit(BracedInitializerAST *) { } // ObjC++ virtual void endVisit(ObjCClassDeclarationAST *) { } diff --git a/src/shared/cplusplus/ASTfwd.h b/src/shared/cplusplus/ASTfwd.h index ac6006256b..dbec328c2a 100644 --- a/src/shared/cplusplus/ASTfwd.h +++ b/src/shared/cplusplus/ASTfwd.h @@ -69,6 +69,7 @@ class AttributeSpecifierAST; class BaseSpecifierAST; class BinaryExpressionAST; class BoolLiteralAST; +class BracedInitializerAST; class BreakStatementAST; class CallAST; class CaptureAST; diff --git a/src/shared/cplusplus/CheckExpression.cpp b/src/shared/cplusplus/CheckExpression.cpp index 42f1d85a71..17ac2ebfe9 100644 --- a/src/shared/cplusplus/CheckExpression.cpp +++ b/src/shared/cplusplus/CheckExpression.cpp @@ -404,3 +404,10 @@ bool CheckExpression::visit(LambdaExpressionAST *ast) return false; } +bool CheckExpression::visit(BracedInitializerAST *ast) +{ + for (ExpressionListAST *it = ast->expression_list; it; it = it->next) + (void) semantic()->check(it->value, _scope); + + return false; +} diff --git a/src/shared/cplusplus/CheckExpression.h b/src/shared/cplusplus/CheckExpression.h index 736eefa0ed..6c5452de11 100644 --- a/src/shared/cplusplus/CheckExpression.h +++ b/src/shared/cplusplus/CheckExpression.h @@ -96,6 +96,7 @@ protected: virtual bool visit(CompoundLiteralAST *ast); virtual bool visit(CompoundExpressionAST *ast); virtual bool visit(LambdaExpressionAST *ast); + virtual bool visit(BracedInitializerAST *ast); //names virtual bool visit(QualifiedNameAST *ast); diff --git a/src/shared/cplusplus/Parser.cpp b/src/shared/cplusplus/Parser.cpp index a1c6f74f39..d36226ce25 100644 --- a/src/shared/cplusplus/Parser.cpp +++ b/src/shared/cplusplus/Parser.cpp @@ -1278,7 +1278,10 @@ bool Parser::parseDeclarator(DeclaratorAST *&node, bool stopAtCppInitializer) bool blocked = blockErrors(true); if (parseInitializer(initializer, &node->equals_token)) { - if (NestedExpressionAST *expr = initializer->asNestedExpression()) { + NestedExpressionAST *expr = 0; + if (initializer) + expr = initializer->asNestedExpression(); + if (expr) { if (expr->expression && expr->rparen_token && (LA() == T_COMMA || LA() == T_SEMICOLON)) { rewind(lparen_token); @@ -2269,15 +2272,101 @@ bool Parser::parseBaseClause(BaseSpecifierListAST *&node) bool Parser::parseInitializer(ExpressionAST *&node, unsigned *equals_token) { DEBUG_THIS_RULE(); - if (LA() == T_LPAREN) { + + return parseInitializer0x(node, equals_token); +} + +bool Parser::parseInitializer0x(ExpressionAST *&node, unsigned *equals_token) +{ + DEBUG_THIS_RULE(); + + if ((_cxx0xEnabled && LA() == T_LBRACE) || LA() == T_EQUAL) { + if (LA() == T_EQUAL) + *equals_token = cursor(); + + return parseBraceOrEqualInitializer0x(node); + } + + else if (LA() == T_LPAREN) { return parsePrimaryExpression(node); - } else if (LA() == T_EQUAL) { - (*equals_token) = consumeToken(); - return parseInitializerClause(node); } + + return false; +} + +bool Parser::parseBraceOrEqualInitializer0x(ExpressionAST *&node) +{ + if (LA() == T_EQUAL) { + consumeToken(); + parseInitializerClause0x(node); + return true; + + } else if (LA() == T_LBRACE) { + return parseBracedInitList0x(node); + + } + return false; } +bool Parser::parseInitializerClause0x(ExpressionAST *&node) +{ + if (LA() == T_LBRACE) + return parseBracedInitList0x(node); + + parseAssignmentExpression(node); + return true; +} + +bool Parser::parseInitializerList0x(ExpressionListAST *&node) +{ + ExpressionListAST **expression_list_ptr = &node; + ExpressionAST *expression = 0; + + if (parseInitializerClause0x(expression)) { + *expression_list_ptr = new (_pool) ExpressionListAST; + (*expression_list_ptr)->value = expression; + expression_list_ptr = &(*expression_list_ptr)->next; + + if (_cxx0xEnabled && LA() == T_DOT_DOT_DOT && (LA(2) == T_COMMA || LA(2) == T_RBRACE || LA(2) == T_RPAREN)) + consumeToken(); // ### create an argument pack + + while (LA() == T_COMMA && LA(2) != T_RBRACE) { + consumeToken(); // consume T_COMMA + + if (parseInitializerClause0x(expression)) { + *expression_list_ptr = new (_pool) ExpressionListAST; + (*expression_list_ptr)->value = expression; + + if (_cxx0xEnabled && LA() == T_DOT_DOT_DOT && (LA(2) == T_COMMA || LA(2) == T_RBRACE || LA(2) == T_RPAREN)) + consumeToken(); // ### create an argument pack + + expression_list_ptr = &(*expression_list_ptr)->next; + } + } + } + + return true; +} + +bool Parser::parseBracedInitList0x(ExpressionAST *&node) +{ + if (LA() != T_LBRACE) + return false; + + BracedInitializerAST *ast = new (_pool) BracedInitializerAST; + ast->lbrace_token = consumeToken(); + + parseInitializerList0x(ast->expression_list); + + if (LA() == T_COMMA && LA(2) == T_RBRACE) + ast->comma_token = consumeToken(); + + match(T_RBRACE, &ast->rbrace_token); + node = ast; + return true; +} + bool Parser::parseMemInitializerList(MemInitializerListAST *&node) { DEBUG_THIS_RULE(); @@ -2374,6 +2463,13 @@ bool Parser::parseTypeIdList(ExpressionListAST *&node) bool Parser::parseExpressionList(ExpressionListAST *&node) { DEBUG_THIS_RULE(); + + if (_cxx0xEnabled) + return parseInitializerList0x(node); + + + + // ### remove me ExpressionListAST **expression_list_ptr = &node; ExpressionAST *expression = 0; if (parseAssignmentExpression(expression)) { @@ -2391,6 +2487,7 @@ bool Parser::parseExpressionList(ExpressionListAST *&node) } return true; } + return false; } diff --git a/src/shared/cplusplus/Parser.h b/src/shared/cplusplus/Parser.h index d31551f187..ff546cada9 100644 --- a/src/shared/cplusplus/Parser.h +++ b/src/shared/cplusplus/Parser.h @@ -222,6 +222,12 @@ public: bool parseQtMethod(ExpressionAST *&node); // C++0x + bool parseInitializer0x(ExpressionAST *&node, unsigned *equals_token); + bool parseBraceOrEqualInitializer0x(ExpressionAST *&node); + bool parseInitializerClause0x(ExpressionAST *&node); + bool parseInitializerList0x(ExpressionListAST *&node); + bool parseBracedInitList0x(ExpressionAST *&node); + bool parseLambdaExpression(ExpressionAST *&node); bool parseLambdaIntroducer(LambdaIntroducerAST *&node); bool parseLambdaCapture(LambdaCaptureAST *&node); |