forked from qt-creator/qt-creator
Improved the implementation of new-expressions.
This commit is contained in:
committed by
Roberto Raggi
parent
885d908ea3
commit
2d80acbe76
@@ -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;
|
||||
}
|
||||
|
@@ -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()
|
||||
|
@@ -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 *) { }
|
||||
|
@@ -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;
|
||||
|
@@ -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;
|
||||
|
@@ -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;
|
||||
}
|
||||
return false;
|
||||
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
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)
|
||||
|
||||
bool Parser::parseNewArrayDeclarator(NewArrayDeclaratorAST *&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);
|
||||
}
|
||||
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;
|
||||
}
|
||||
|
@@ -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);
|
||||
|
@@ -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) {
|
||||
if (it != ast->type_specifier)
|
||||
out << ' ';
|
||||
accept(it);
|
||||
if (it->next)
|
||||
out << ' ';
|
||||
}
|
||||
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;
|
||||
}
|
||||
|
||||
|
@@ -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);
|
||||
|
@@ -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;"));
|
||||
|
Reference in New Issue
Block a user