summaryrefslogtreecommitdiff
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
parent885d908ea336de72e7fce2141c1060e425f2af0a (diff)
downloadqt-creator-2d80acbe763e1cd1f872e4d49ba653d09bca8c6e.tar.gz
Improved the implementation of new-expressions.
-rw-r--r--src/shared/cplusplus/AST.cpp114
-rw-r--r--src/shared/cplusplus/AST.h46
-rw-r--r--src/shared/cplusplus/ASTVisitor.h6
-rw-r--r--src/shared/cplusplus/ASTfwd.h3
-rw-r--r--src/shared/cplusplus/CheckExpression.cpp5
-rw-r--r--src/shared/cplusplus/Parser.cpp123
-rw-r--r--src/shared/cplusplus/Parser.h3
-rw-r--r--src/shared/cplusplus/PrettyPrinter.cpp59
-rw-r--r--src/shared/cplusplus/PrettyPrinter.h3
-rw-r--r--tests/auto/cplusplus/ast/tst_ast.cpp55
10 files changed, 293 insertions, 124 deletions
diff --git a/src/shared/cplusplus/AST.cpp b/src/shared/cplusplus/AST.cpp
index b75994f366..8a9c201dc5 100644
--- a/src/shared/cplusplus/AST.cpp
+++ b/src/shared/cplusplus/AST.cpp
@@ -2225,56 +2225,79 @@ unsigned NestedNameSpecifierAST::lastToken() const
return class_or_namespace_name->lastToken();
}
-NewDeclaratorAST *NewDeclaratorAST::clone(MemoryPool *pool) const
+NewPlacementAST *NewPlacementAST::clone(MemoryPool *pool) const
{
- NewDeclaratorAST *ast = new (pool) NewDeclaratorAST;
- if (ptr_operators)
- ast->ptr_operators = ptr_operators->clone(pool);
- if (declarator)
- ast->declarator = declarator->clone(pool);
+ NewPlacementAST *ast = new (pool) NewPlacementAST;
+ ast->lparen_token = lparen_token;
+ if (expression_list)
+ ast->expression_list = expression_list->clone(pool);
+ ast->rparen_token = rparen_token;
return ast;
}
-void NewDeclaratorAST::accept0(ASTVisitor *visitor)
+void NewPlacementAST::accept0(ASTVisitor *visitor)
{
if (visitor->visit(this)) {
- for (PtrOperatorAST *ptr_op = ptr_operators; ptr_op;
- ptr_op = static_cast<PtrOperatorAST *>(ptr_op->next)) {
- accept(ptr_op, visitor);
+ for (ExpressionListAST *it = expression_list; it; it = it->next) {
+ accept(it->expression, visitor);
}
-
- accept(declarator, visitor);
}
visitor->endVisit(this);
}
-unsigned NewDeclaratorAST::firstToken() const
+unsigned NewPlacementAST::firstToken() const
{
- return ptr_operators->firstToken();
+ return lparen_token;
}
-unsigned NewDeclaratorAST::lastToken() const
+unsigned NewPlacementAST::lastToken() const
{
- if (declarator)
- return declarator->lastToken();
+ return rparen_token + 1;
+}
- for (PtrOperatorAST *it = ptr_operators; it; it = it->next) {
- if (! it->next)
- return it->lastToken();
+NewArrayDeclaratorAST *NewArrayDeclaratorAST::clone(MemoryPool *pool) const
+{
+ NewArrayDeclaratorAST *ast = new (pool) NewArrayDeclaratorAST;
+ ast->lbracket_token = lbracket_token;
+ if (expression)
+ ast->expression = expression->clone(pool);
+ ast->rbracket_token = rbracket_token;
+ if (next)
+ ast->next = next->clone(pool);
+ return ast;
+}
+
+void NewArrayDeclaratorAST::accept0(ASTVisitor *visitor)
+{
+ if (visitor->visit(this)) {
+ accept(expression, visitor);
+ accept(next, visitor);
}
+ visitor->endVisit(this);
+}
- return 0;
+unsigned NewArrayDeclaratorAST::firstToken() const
+{
+ return lbracket_token;
+}
+
+unsigned NewArrayDeclaratorAST::lastToken() const
+{
+ return rbracket_token + 1;
}
NewExpressionAST *NewExpressionAST::clone(MemoryPool *pool) const
{
NewExpressionAST *ast = new (pool) NewExpressionAST;
+
ast->scope_token = scope_token;
ast->new_token = new_token;
- if (expression)
- ast->expression = expression->clone(pool);
+ if (new_placement)
+ ast->new_placement = new_placement->clone(pool);
+ ast->lparen_token = lparen_token;
if (type_id)
ast->type_id = type_id->clone(pool);
+ ast->rparen_token = rparen_token;
if (new_type_id)
ast->new_type_id = new_type_id->clone(pool);
if (new_initializer)
@@ -2285,7 +2308,7 @@ NewExpressionAST *NewExpressionAST::clone(MemoryPool *pool) const
void NewExpressionAST::accept0(ASTVisitor *visitor)
{
if (visitor->visit(this)) {
- accept(expression, visitor);
+ accept(new_placement, visitor);
accept(type_id, visitor);
accept(new_type_id, visitor);
accept(new_initializer, visitor);
@@ -2302,15 +2325,8 @@ unsigned NewExpressionAST::firstToken() const
unsigned NewExpressionAST::lastToken() const
{
- if (new_initializer)
- return new_initializer->lastToken();
- else if (new_type_id)
- return new_type_id->lastToken();
- else if (type_id)
- return type_id->lastToken();
- else if (expression)
- return expression->lastToken();
- else if (new_token)
+ // ### FIXME
+ if (new_token)
return new_token + 1;
else if (scope_token)
return scope_token + 1;
@@ -2363,12 +2379,13 @@ TypeIdAST *TypeIdAST::clone(MemoryPool *pool) const
NewTypeIdAST *NewTypeIdAST::clone(MemoryPool *pool) const
{
NewTypeIdAST *ast = new (pool) NewTypeIdAST;
+
if (type_specifier)
ast->type_specifier = type_specifier->clone(pool);
- if (new_initializer)
- ast->new_initializer = new_initializer->clone(pool);
- if (new_declarator)
- ast->new_declarator = new_declarator->clone(pool);
+ if (ptr_operators)
+ ast->ptr_operators = ptr_operators->clone(pool);
+ if (new_array_declarators)
+ ast->new_array_declarators = new_array_declarators->clone(pool);
return ast;
}
@@ -2377,8 +2394,13 @@ void NewTypeIdAST::accept0(ASTVisitor *visitor)
if (visitor->visit(this)) {
for (SpecifierAST *spec = type_specifier; spec; spec = spec->next)
accept(spec, visitor);
- accept(new_initializer, visitor);
- accept(new_declarator, visitor);
+
+ for (PtrOperatorAST *it = ptr_operators; it; it = it->next)
+ accept(it, visitor);
+
+ for (NewArrayDeclaratorAST *it = new_array_declarators; it; it = it->next)
+ accept(it, visitor);
+
}
visitor->endVisit(this);
}
@@ -2390,15 +2412,19 @@ unsigned NewTypeIdAST::firstToken() const
unsigned NewTypeIdAST::lastToken() const
{
- if (new_declarator)
- return new_declarator->lastToken();
- else if (new_initializer)
- return new_initializer->lastToken();
- for (SpecifierAST *it = type_specifier; it; it = it->next) {
+ for (NewArrayDeclaratorAST *it = new_array_declarators; it; it = it->next) {
if (! it->next)
return it->lastToken();
}
+ for (PtrOperatorAST *it = ptr_operators; it; it = it->next) {
+ if (it->next)
+ return it->lastToken();
+ }
+
+ if (type_specifier)
+ return type_specifier->lastToken();
+
// ### assert?
return 0;
}
diff --git a/src/shared/cplusplus/AST.h b/src/shared/cplusplus/AST.h
index 26f0a6692b..78e45ce328 100644
--- a/src/shared/cplusplus/AST.h
+++ b/src/shared/cplusplus/AST.h
@@ -152,7 +152,8 @@ public:
virtual NestedDeclaratorAST *asNestedDeclarator() { return 0; }
virtual NestedExpressionAST *asNestedExpression() { return 0; }
virtual NestedNameSpecifierAST *asNestedNameSpecifier() { return 0; }
- virtual NewDeclaratorAST *asNewDeclarator() { return 0; }
+ virtual NewPlacementAST *asNewPlacement() { return 0; }
+ virtual NewArrayDeclaratorAST *asNewArrayDeclarator() { return 0; }
virtual NewExpressionAST *asNewExpression() { return 0; }
virtual NewInitializerAST *asNewInitializer() { return 0; }
virtual NewTypeIdAST *asNewTypeId() { return 0; }
@@ -1440,20 +1441,42 @@ protected:
virtual void accept0(ASTVisitor *visitor);
};
-class CPLUSPLUS_EXPORT NewDeclaratorAST: public AST
+class CPLUSPLUS_EXPORT NewPlacementAST: public AST
{
public:
- PtrOperatorAST *ptr_operators;
- NewDeclaratorAST *declarator;
+ unsigned lparen_token;
+ ExpressionListAST *expression_list;
+ unsigned rparen_token;
public:
- virtual NewDeclaratorAST *asNewDeclarator()
+ virtual NewPlacementAST *asNewPlacement()
{ return this; }
virtual unsigned firstToken() const;
virtual unsigned lastToken() const;
- virtual NewDeclaratorAST *clone(MemoryPool *pool) const;
+ virtual NewPlacementAST *clone(MemoryPool *pool) const;
+
+protected:
+ virtual void accept0(ASTVisitor *visitor);
+};
+
+class CPLUSPLUS_EXPORT NewArrayDeclaratorAST: public AST
+{
+public:
+ unsigned lbracket_token;
+ ExpressionAST *expression;
+ unsigned rbracket_token;
+ NewArrayDeclaratorAST *next;
+
+public:
+ virtual NewArrayDeclaratorAST *asNewArrayDeclarator()
+ { return this; }
+
+ virtual unsigned firstToken() const;
+ virtual unsigned lastToken() const;
+
+ virtual NewArrayDeclaratorAST *clone(MemoryPool *pool) const;
protected:
virtual void accept0(ASTVisitor *visitor);
@@ -1464,9 +1487,14 @@ class CPLUSPLUS_EXPORT NewExpressionAST: public ExpressionAST
public:
unsigned scope_token;
unsigned new_token;
- ExpressionAST *expression;
+ NewPlacementAST *new_placement;
+
+ unsigned lparen_token;
ExpressionAST *type_id;
+ unsigned rparen_token;
+
NewTypeIdAST *new_type_id;
+
NewInitializerAST *new_initializer;
public:
@@ -1506,8 +1534,8 @@ class CPLUSPLUS_EXPORT NewTypeIdAST: public AST
{
public:
SpecifierAST *type_specifier;
- NewInitializerAST *new_initializer;
- NewDeclaratorAST *new_declarator;
+ PtrOperatorAST *ptr_operators;
+ NewArrayDeclaratorAST *new_array_declarators;
public:
virtual NewTypeIdAST *asNewTypeId()
diff --git a/src/shared/cplusplus/ASTVisitor.h b/src/shared/cplusplus/ASTVisitor.h
index 92fa70e55b..3ab1fc66e9 100644
--- a/src/shared/cplusplus/ASTVisitor.h
+++ b/src/shared/cplusplus/ASTVisitor.h
@@ -144,7 +144,8 @@ public:
virtual bool visit(NestedDeclaratorAST *) { return true; }
virtual bool visit(NestedExpressionAST *) { return true; }
virtual bool visit(NestedNameSpecifierAST *) { return true; }
- virtual bool visit(NewDeclaratorAST *) { return true; }
+ virtual bool visit(NewPlacementAST *) { return true; }
+ virtual bool visit(NewArrayDeclaratorAST *) { return true; }
virtual bool visit(NewExpressionAST *) { return true; }
virtual bool visit(NewInitializerAST *) { return true; }
virtual bool visit(NewTypeIdAST *) { return true; }
@@ -248,7 +249,8 @@ public:
virtual void endVisit(NestedDeclaratorAST *) { }
virtual void endVisit(NestedExpressionAST *) { }
virtual void endVisit(NestedNameSpecifierAST *) { }
- virtual void endVisit(NewDeclaratorAST *) { }
+ virtual void endVisit(NewPlacementAST *) { }
+ virtual void endVisit(NewArrayDeclaratorAST *) { }
virtual void endVisit(NewExpressionAST *) { }
virtual void endVisit(NewInitializerAST *) { }
virtual void endVisit(NewTypeIdAST *) { }
diff --git a/src/shared/cplusplus/ASTfwd.h b/src/shared/cplusplus/ASTfwd.h
index b4f5283a74..140b0820c0 100644
--- a/src/shared/cplusplus/ASTfwd.h
+++ b/src/shared/cplusplus/ASTfwd.h
@@ -121,8 +121,9 @@ class NamespaceAliasDefinitionAST;
class NestedDeclaratorAST;
class NestedExpressionAST;
class NestedNameSpecifierAST;
-class NewDeclaratorAST;
+class NewArrayDeclaratorAST;
class NewExpressionAST;
+class NewPlacementAST;
class NewInitializerAST;
class NewTypeIdAST;
class NumericLiteralAST;
diff --git a/src/shared/cplusplus/CheckExpression.cpp b/src/shared/cplusplus/CheckExpression.cpp
index e26a19ba80..aaf24c48e1 100644
--- a/src/shared/cplusplus/CheckExpression.cpp
+++ b/src/shared/cplusplus/CheckExpression.cpp
@@ -214,8 +214,9 @@ bool CheckExpression::visit(TemplateIdAST *ast)
bool CheckExpression::visit(NewExpressionAST *ast)
{
- FullySpecifiedType exprTy = semantic()->check(ast->expression, _scope);
- FullySpecifiedType typeIdTy = semantic()->check(ast->type_id, _scope);
+ // ### FIXME
+ //FullySpecifiedType exprTy = semantic()->check(ast->expression, _scope);
+ //FullySpecifiedType typeIdTy = semantic()->check(ast->type_id, _scope);
// ### process new-typeid
// ### process new-initializer
return false;
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;
}
diff --git a/src/shared/cplusplus/Parser.h b/src/shared/cplusplus/Parser.h
index e6a29d199e..fbd2e7194f 100644
--- a/src/shared/cplusplus/Parser.h
+++ b/src/shared/cplusplus/Parser.h
@@ -150,8 +150,9 @@ public:
bool parseNestedNameSpecifierOpt(NestedNameSpecifierAST *&name, bool acceptTemplateId);
bool parseNamespace(DeclarationAST *&node);
bool parseNamespaceAliasDefinition(DeclarationAST *&node);
- bool parseNewDeclarator(NewDeclaratorAST *&node);
+ bool parseNewArrayDeclarator(NewArrayDeclaratorAST *&node);
bool parseNewExpression(ExpressionAST *&node);
+ bool parseNewPlacement(NewPlacementAST *&node);
bool parseNewInitializer(NewInitializerAST *&node);
bool parseNewTypeId(NewTypeIdAST *&node);
bool parseOperator(OperatorAST *&node);
diff --git a/src/shared/cplusplus/PrettyPrinter.cpp b/src/shared/cplusplus/PrettyPrinter.cpp
index d6c604c3ab..8c00791ade 100644
--- a/src/shared/cplusplus/PrettyPrinter.cpp
+++ b/src/shared/cplusplus/PrettyPrinter.cpp
@@ -764,15 +764,11 @@ bool PrettyPrinter::visit(NestedNameSpecifierAST *ast)
return false;
}
-bool PrettyPrinter::visit(NewDeclaratorAST *ast)
+bool PrettyPrinter::visit(NewArrayDeclaratorAST *ast)
{
- for (PtrOperatorAST *it = ast->ptr_operators; it; it = it->next) {
- accept(it);
- if (it->next)
- out << ' ';
- }
- if (ast->declarator)
- accept(ast->declarator);
+ out << '[';
+ accept(ast->expression);
+ out << ']';
return false;
}
@@ -782,25 +778,32 @@ bool PrettyPrinter::visit(NewExpressionAST *ast)
out << "::";
out << "new";
out << ' ';
- if (ast->expression) {
- accept(ast->expression);
- if (ast->type_id)
- out << ' ';
- }
- if (ast->type_id) {
+ accept(ast->new_placement);
+ if (ast->new_placement)
+ out << ' ';
+ if (ast->lparen_token) {
+ out << '(';
accept(ast->type_id);
- if (ast->new_type_id)
- out << ' ';
- }
- if (ast->new_type_id) {
+ out << ')';
+ } else {
accept(ast->new_type_id);
- if (ast->new_initializer)
- out << ' ';
}
accept(ast->new_initializer);
return false;
}
+bool PrettyPrinter::visit(NewPlacementAST *ast)
+{
+ out << '(';
+ for (ExpressionListAST *it = ast->expression_list; it; it = it->next) {
+ accept(it->expression);
+ if (it->next)
+ out << ", ";
+ }
+ out << ')';
+ return false;
+}
+
bool PrettyPrinter::visit(NewInitializerAST *ast)
{
out << '(';
@@ -812,18 +815,16 @@ bool PrettyPrinter::visit(NewInitializerAST *ast)
bool PrettyPrinter::visit(NewTypeIdAST *ast)
{
for (SpecifierAST *it = ast->type_specifier; it; it = it->next) {
- accept(it);
- if (it->next)
+ if (it != ast->type_specifier)
out << ' ';
+ accept(it);
}
- if (ast->type_specifier)
- out << ' ';
- if (ast->new_initializer) {
- accept(ast->new_initializer);
- if (ast->new_declarator)
- out << ' ';
+ for (PtrOperatorAST *it = ast->ptr_operators; it; it = it->next) {
+ accept(it);
+ }
+ for (NewArrayDeclaratorAST *it = ast->new_array_declarators; it; it = it->next) {
+ accept(it);
}
- accept(ast->new_declarator);
return false;
}
diff --git a/src/shared/cplusplus/PrettyPrinter.h b/src/shared/cplusplus/PrettyPrinter.h
index c69ea2cf54..f20b8e360d 100644
--- a/src/shared/cplusplus/PrettyPrinter.h
+++ b/src/shared/cplusplus/PrettyPrinter.h
@@ -106,7 +106,8 @@ protected:
virtual bool visit(NestedDeclaratorAST *ast);
virtual bool visit(NestedExpressionAST *ast);
virtual bool visit(NestedNameSpecifierAST *ast);
- virtual bool visit(NewDeclaratorAST *ast);
+ virtual bool visit(NewArrayDeclaratorAST *ast);
+ virtual bool visit(NewPlacementAST *ast);
virtual bool visit(NewExpressionAST *ast);
virtual bool visit(NewInitializerAST *ast);
virtual bool visit(NewTypeIdAST *ast);
diff --git a/tests/auto/cplusplus/ast/tst_ast.cpp b/tests/auto/cplusplus/ast/tst_ast.cpp
index 689da076ea..e4ef03211d 100644
--- a/tests/auto/cplusplus/ast/tst_ast.cpp
+++ b/tests/auto/cplusplus/ast/tst_ast.cpp
@@ -42,6 +42,8 @@ private slots:
// expressions
void simple_name();
void template_id();
+ void new_expression_1();
+ void new_expression_2();
// statements
void if_statement();
@@ -91,6 +93,59 @@ void tst_AST::template_id()
QCOMPARE(ast->asTemplateId()->greater_token, 4U);
}
+void tst_AST::new_expression_1()
+{
+ QSharedPointer<TranslationUnit> unit(parseExpression("\n"
+"new char"
+ ));
+
+ AST *ast = unit->ast();
+ QVERIFY(ast != 0);
+
+ NewExpressionAST *expr = ast->asNewExpression();
+ QVERIFY(expr != 0);
+
+ QCOMPARE(expr->scope_token, 0U);
+ QCOMPARE(expr->new_token, 1U);
+ QVERIFY(expr->new_placement == 0);
+ QCOMPARE(expr->lparen_token, 0U);
+ QVERIFY(expr->type_id == 0);
+ QCOMPARE(expr->rparen_token, 0U);
+ QVERIFY(expr->new_type_id != 0);
+ QVERIFY(expr->new_initializer == 0);
+
+ QVERIFY(expr->new_type_id->type_specifier != 0);
+ QVERIFY(expr->new_type_id->ptr_operators == 0);
+ QVERIFY(expr->new_type_id->new_array_declarators == 0);
+}
+
+void tst_AST::new_expression_2()
+{
+ QSharedPointer<TranslationUnit> unit(parseStatement("\n"
+"::new(__p) _Tp(__val);"
+ ));
+
+ AST *ast = unit->ast();
+ QVERIFY(ast != 0);
+
+ ExpressionStatementAST *stmt = ast->asExpressionStatement();
+ QVERIFY(stmt != 0);
+ QVERIFY(stmt->expression != 0);
+ QVERIFY(stmt->semicolon_token != 0);
+
+ NewExpressionAST *expr = stmt->expression->asNewExpression();
+ QVERIFY(expr != 0);
+
+ QCOMPARE(expr->scope_token, 1U);
+ QCOMPARE(expr->new_token, 2U);
+ QVERIFY(expr->new_placement != 0);
+ QCOMPARE(expr->lparen_token, 0U);
+ QVERIFY(expr->type_id == 0);
+ QCOMPARE(expr->rparen_token, 0U);
+ QVERIFY(expr->new_type_id != 0);
+ QVERIFY(expr->new_initializer != 0);
+}
+
void tst_AST::if_statement()
{
QSharedPointer<TranslationUnit> unit(parseStatement("if (a) b;"));