C++11: Allow uniform initialization in ctor init lists.

So
class C { C() : _x{12}, _y({12}) {} };
now parses correctly.

Change-Id: I4281dcb0541a86b550e74630cad6ae0a59fef1b4
Reviewed-by: hjk <qthjk@ovi.com>
This commit is contained in:
Christian Kamm
2012-09-17 09:58:09 +02:00
committed by hjk
parent 903ba378c2
commit b9f6f1bcf7
16 changed files with 88 additions and 71 deletions

View File

@@ -1744,26 +1744,18 @@ unsigned MemInitializerAST::firstToken() const
if (name)
if (unsigned candidate = name->firstToken())
return candidate;
if (lparen_token)
return lparen_token;
if (expression_list)
if (unsigned candidate = expression_list->firstToken())
if (expression)
if (unsigned candidate = expression->firstToken())
return candidate;
if (rparen_token)
return rparen_token;
return 0;
}
/** \generated */
unsigned MemInitializerAST::lastToken() const
{
if (rparen_token)
return rparen_token + 1;
if (expression_list)
if (unsigned candidate = expression_list->lastToken())
if (expression)
if (unsigned candidate = expression->lastToken())
return candidate;
if (lparen_token)
return lparen_token + 1;
if (name)
if (unsigned candidate = name->lastToken())
return candidate;

View File

@@ -2138,16 +2138,13 @@ class CPLUSPLUS_EXPORT MemInitializerAST: public AST
{
public:
NameAST *name;
unsigned lparen_token;
ExpressionListAST *expression_list;
unsigned rparen_token;
// either a BracedInitializerAST or a ExpressionListParenAST
ExpressionAST *expression;
public:
MemInitializerAST()
: name(0)
, lparen_token(0)
, expression_list(0)
, rparen_token(0)
, expression(0)
{}
virtual MemInitializerAST *asMemInitializer() { return this; }

View File

@@ -772,11 +772,8 @@ MemInitializerAST *MemInitializerAST::clone(MemoryPool *pool) const
MemInitializerAST *ast = new (pool) MemInitializerAST;
if (name)
ast->name = name->clone(pool);
ast->lparen_token = lparen_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->rparen_token = rparen_token;
if (expression)
ast->expression = expression->clone(pool);
return ast;
}

View File

@@ -1319,15 +1319,11 @@ bool ASTMatcher::match(MemInitializerAST *node, MemInitializerAST *pattern)
else if (! AST::match(node->name, pattern->name, this))
return false;
pattern->lparen_token = node->lparen_token;
if (! pattern->expression_list)
pattern->expression_list = node->expression_list;
else if (! AST::match(node->expression_list, pattern->expression_list, this))
if (! pattern->expression)
pattern->expression = node->expression;
else if (! AST::match(node->expression, pattern->expression, this))
return false;
pattern->rparen_token = node->rparen_token;
return true;
}

View File

@@ -505,11 +505,11 @@ public:
return __ast;
}
MemInitializerAST *MemInitializer(NameAST *name = 0, ExpressionListAST *expression_list = 0)
MemInitializerAST *MemInitializer(NameAST *name = 0, ExpressionAST *expression = 0)
{
MemInitializerAST *__ast = new (&pool) MemInitializerAST;
__ast->name = name;
__ast->expression_list = expression_list;
__ast->expression = expression;
return __ast;
}

View File

@@ -557,7 +557,7 @@ void MemInitializerAST::accept0(ASTVisitor *visitor)
{
if (visitor->visit(this)) {
accept(name, visitor);
accept(expression_list, visitor);
accept(expression, visitor);
}
visitor->endVisit(this);
}

View File

@@ -517,9 +517,7 @@ void Bind::memInitializer(MemInitializerAST *ast, Function *fun)
/*const Name *name =*/ this->name(ast->name);
Scope *previousScope = switchScope(fun);
for (ExpressionListAST *it = ast->expression_list; it; it = it->next) {
/*ExpressionTy value =*/ this->expression(it->value);
}
this->expression(ast->expression);
(void) switchScope(previousScope);
}
@@ -541,8 +539,12 @@ const Name *Bind::nestedNameSpecifier(NestedNameSpecifierAST *ast)
bool Bind::visit(ExpressionListParenAST *ast)
{
(void) ast;
assert(!"unreachable");
// unsigned lparen_token = ast->lparen_token;
for (ExpressionListAST *it = ast->expression_list; it; it = it->next) {
/*ExpressionTy value =*/ this->expression(it->value);
}
// unsigned rparen_token = ast->rparen_token;
return false;
}
@@ -1804,7 +1806,7 @@ bool Bind::visit(BracedInitializerAST *ast)
{
// unsigned lbrace_token = ast->lbrace_token;
for (ExpressionListAST *it = ast->expression_list; it; it = it->next) {
ExpressionTy value = this->expression(it->value);
/*ExpressionTy value =*/ this->expression(it->value);
}
// unsigned comma_token = ast->comma_token;
// unsigned rbrace_token = ast->rbrace_token;

View File

@@ -122,7 +122,6 @@ protected:
virtual bool visit(DynamicExceptionSpecificationAST *ast);
virtual bool visit(MemInitializerAST *ast);
virtual bool visit(NestedNameSpecifierAST *ast);
virtual bool visit(ExpressionListParenAST *ast);
virtual bool visit(NewArrayDeclaratorAST *ast);
virtual bool visit(NewInitializerAST *ast);
virtual bool visit(NewTypeIdAST *ast);
@@ -199,6 +198,7 @@ protected:
virtual bool visit(ObjCSelectorExpressionAST *ast);
virtual bool visit(LambdaExpressionAST *ast);
virtual bool visit(BracedInitializerAST *ast);
virtual bool visit(ExpressionListParenAST *ast);
// DeclarationAST
virtual bool visit(SimpleDeclarationAST *ast);

View File

@@ -2572,15 +2572,7 @@ bool Parser::parseInitializer0x(ExpressionAST *&node, unsigned *equals_token)
}
else if (LA() == T_LPAREN) {
ExpressionListParenAST *expr_list_paren = new (_pool) ExpressionListParenAST;
node = expr_list_paren;
expr_list_paren->lparen_token = consumeToken();
parseInitializerList0x(expr_list_paren->expression_list);
match(T_RPAREN, &expr_list_paren->rparen_token);
return true;
return parseExpressionListParen0x(node);
}
return false;
@@ -2675,7 +2667,9 @@ bool Parser::parseMemInitializerList(MemInitializerListAST *&node)
else if (_cxx0xEnabled && LA() == T_DOT_DOT_DOT && LA(2) == T_LBRACE)
break;
else if (LA() == T_COMMA || (LA() == T_IDENTIFIER && (LA(2) == T_LPAREN || LA(2) == T_COLON_COLON))) {
else if (LA() == T_COMMA
|| (LA() == T_IDENTIFIER
&& (LA(2) == T_LPAREN || LA(2) == T_COLON_COLON || (_cxx0xEnabled && LA(2) == T_LBRACE)))) {
if (LA() != T_COMMA)
error(cursor(), "expected `,'");
else
@@ -2712,9 +2706,18 @@ bool Parser::parseMemInitializer(MemInitializerListAST *&node)
MemInitializerAST *ast = new (_pool) MemInitializerAST;
ast->name = name;
match(T_LPAREN, &ast->lparen_token);
parseExpressionList(ast->expression_list);
match(T_RPAREN, &ast->rparen_token);
if (LA() == T_LPAREN) {
parseExpressionListParen0x(ast->expression);
} else if (_cxx0xEnabled && LA() == T_LBRACE) {
parseBracedInitList0x(ast->expression);
} else {
if (!_cxx0xEnabled)
error(cursor(), "expected '('");
else
error(cursor(), "expected '(' or '{'");
return false;
}
node = new (_pool) MemInitializerListAST;
node->value = ast;
@@ -4873,6 +4876,29 @@ bool Parser::parseExpressionListParen(ExpressionListParenAST *&node)
return false;
}
// like above, but for C++11 where expression-list expands to initializer-list
// and can contain braced-init-list members
bool Parser::parseExpressionListParen0x(ExpressionAST *&node)
{
DEBUG_THIS_RULE();
if (LA() == T_LPAREN) {
unsigned lparen_token = consumeToken();
ExpressionListAST *expression_list = 0;
if (parseInitializerList0x(expression_list) && expression_list && LA() == T_RPAREN) {
unsigned rparen_token = consumeToken();
ExpressionListParenAST *ast = new (_pool) ExpressionListParenAST;
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

View File

@@ -132,6 +132,7 @@ public:
bool parseNewArrayDeclarator(NewArrayDeclaratorListAST *&node);
bool parseNewExpression(ExpressionAST *&node);
bool parseExpressionListParen(ExpressionListParenAST *&node);
bool parseExpressionListParen0x(ExpressionAST *&node);
bool parseNewInitializer(NewInitializerAST *&node);
bool parseNewTypeId(NewTypeIdAST *&node);
bool parseOperator(OperatorAST *&node);