summaryrefslogtreecommitdiff
path: root/src/shared/cplusplus/Parser.cpp
diff options
context:
space:
mode:
authorRoberto Raggi <roberto.raggi@trolltech.com>2009-02-10 14:43:19 +0100
committerRoberto Raggi <qtc-committer@nokia.com>2009-02-10 14:44:03 +0100
commit2d80acbe763e1cd1f872e4d49ba653d09bca8c6e (patch)
treefa98b1339f78093ce5bd5d80751252af765650bb /src/shared/cplusplus/Parser.cpp
parent885d908ea336de72e7fce2141c1060e425f2af0a (diff)
downloadqt-creator-2d80acbe763e1cd1f872e4d49ba653d09bca8c6e.tar.gz
Improved the implementation of new-expressions.
Diffstat (limited to 'src/shared/cplusplus/Parser.cpp')
-rw-r--r--src/shared/cplusplus/Parser.cpp123
1 files changed, 88 insertions, 35 deletions
diff --git a/src/shared/cplusplus/Parser.cpp b/src/shared/cplusplus/Parser.cpp
index bfd2d6696a..c5dacb0811 100644
--- a/src/shared/cplusplus/Parser.cpp
+++ b/src/shared/cplusplus/Parser.cpp
@@ -3104,37 +3104,91 @@ bool Parser::parseUnaryExpression(ExpressionAST *&node)
return parsePostfixExpression(node);
}
+// new-placement ::= T_LPAREN expression-list T_RPAREN
+bool Parser::parseNewPlacement(NewPlacementAST *&node)
+{
+ if (LA() == T_LPAREN) {
+ unsigned lparen_token = consumeToken();
+ ExpressionListAST *expression_list = 0;
+ if (parseExpressionList(expression_list) && expression_list && LA() == T_RPAREN) {
+ unsigned rparen_token = consumeToken();
+ NewPlacementAST *ast = new (_pool) NewPlacementAST;
+ ast->lparen_token = lparen_token;
+ ast->expression_list = expression_list;
+ ast->rparen_token = rparen_token;
+ node = ast;
+ return true;
+ }
+ }
+
+ return false;
+}
+
+// new-expression ::= T_COLON_COLON? T_NEW new-placement.opt
+// new-type-id new-initializer.opt
+// new-expression ::= T_COLON_COLON? T_NEW new-placement.opt
+// T_LPAREN type-id T_RPAREN new-initializer.opt
bool Parser::parseNewExpression(ExpressionAST *&node)
{
- if (LA() == T_NEW || (LA() == T_COLON_COLON && LA(2) == T_NEW)) {
- NewExpressionAST *ast = new (_pool) NewExpressionAST;
+ if (! (LA() == T_NEW || (LA() == T_COLON_COLON && LA(2) == T_NEW)))
+ return false;
- if (LA() == T_COLON_COLON)
- ast->scope_token = consumeToken();
+ NewExpressionAST *ast = new (_pool) NewExpressionAST;
+ if (LA() == T_COLON_COLON)
+ ast->scope_token = consumeToken();
- ast->new_token = consumeToken();
+ ast->new_token = consumeToken();
- if (LA() == T_LPAREN) {
- consumeToken();
- parseExpression(ast->expression);
- if (LA() == T_RPAREN)
- consumeToken();
+ NewPlacementAST *new_placement = 0;
+
+ if (parseNewPlacement(new_placement)) {
+ unsigned after_new_placement = cursor();
+
+ NewTypeIdAST *new_type_id = 0;
+ if (parseNewTypeId(new_type_id)) {
+ ast->new_placement = new_placement;
+ ast->new_type_id = new_type_id;
+ parseNewInitializer(ast->new_initializer);
+ // recognized new-placement.opt new-type-id new-initializer.opt
+ node = ast;
+ return true;
}
+ rewind(after_new_placement);
if (LA() == T_LPAREN) {
- consumeToken();
- parseTypeId(ast->type_id);
- if (LA() == T_RPAREN)
- consumeToken();
- } else {
- parseNewTypeId(ast->new_type_id);
+ unsigned lparen_token = consumeToken();
+ ExpressionAST *type_id = 0;
+ if (parseTypeId(type_id) && LA() == T_RPAREN) {
+ ast->new_placement = new_placement;
+ ast->lparen_token = lparen_token;
+ ast->type_id = type_id;
+ ast->rparen_token = consumeToken();
+ parseNewInitializer(ast->new_initializer);
+ node = ast;
+ return true;
+ }
}
+ }
- parseNewInitializer(ast->new_initializer);
- node = ast;
- return true;
+ rewind(ast->new_token + 1);
+
+ if (LA() == T_LPAREN) {
+ unsigned lparen_token = consumeToken();
+ ExpressionAST *type_id = 0;
+ if (parseTypeId(type_id) && LA() == T_RPAREN) {
+ ast->lparen_token = lparen_token;
+ ast->type_id = type_id;
+ ast->rparen_token = consumeToken();
+ parseNewInitializer(ast->new_initializer);
+ node = ast;
+ return true;
+ }
}
- return false;
+
+ parseNewTypeId(ast->new_type_id);
+ parseNewInitializer(ast->new_initializer);
+ node = ast;
+ return true;
}
bool Parser::parseNewTypeId(NewTypeIdAST *&node)
@@ -3145,27 +3199,26 @@ bool Parser::parseNewTypeId(NewTypeIdAST *&node)
NewTypeIdAST *ast = new (_pool) NewTypeIdAST;
ast->type_specifier = typeSpec;
- parseNewDeclarator(ast->new_declarator);
+ PtrOperatorAST **ptrop_it = &ast->ptr_operators;
+ while (parsePtrOperator(*ptrop_it))
+ ptrop_it = &(*ptrop_it)->next;
+ NewArrayDeclaratorAST **it = &ast->new_array_declarators;
+ while (parseNewArrayDeclarator(*it))
+ it = &(*it)->next;
node = ast;
return true;
}
-bool Parser::parseNewDeclarator(NewDeclaratorAST *&node)
-{
- NewDeclaratorAST *ast = new (_pool) NewDeclaratorAST;
-
- PtrOperatorAST **ptr_operators_tail = &ast->ptr_operators;
- while (parsePtrOperator(*ptr_operators_tail))
- ptr_operators_tail = &(*ptr_operators_tail)->next;
- while (LA() == T_LBRACKET) { // ### create the AST
- consumeToken();
- ExpressionAST *expression = 0;
- parseExpression(expression);
- unsigned rbracket_token = 0;
- match(T_RBRACKET, &rbracket_token);
- }
+bool Parser::parseNewArrayDeclarator(NewArrayDeclaratorAST *&node)
+{
+ if (LA() != T_LBRACKET)
+ return false;
+ NewArrayDeclaratorAST *ast = new (_pool) NewArrayDeclaratorAST;
+ ast->lbracket_token = consumeToken();
+ parseExpression(ast->expression);
+ match(T_RBRACKET, &ast->rbracket_token);
node = ast;
return true;
}