Commit 83da5f68 authored by Christian Kamm's avatar Christian Kamm Committed by hjk

C++11: Allow for typename Foo<T>{}, Foo{} and int{}.

As a postfix expression.

Change-Id: I65cae0571080a9fb699af61c661328ef06f97890
Reviewed-by: default avatarhjk <qthjk@ovi.com>
parent 2aa27e6d
......@@ -3924,26 +3924,18 @@ unsigned TypeConstructorCallAST::firstToken() const
if (type_specifier_list)
if (unsigned candidate = type_specifier_list->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 TypeConstructorCallAST::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 (type_specifier_list)
if (unsigned candidate = type_specifier_list->lastToken())
return candidate;
......@@ -4012,26 +4004,18 @@ unsigned TypenameCallExpressionAST::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 TypenameCallExpressionAST::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;
......
......@@ -2803,17 +2803,13 @@ class CPLUSPLUS_EXPORT TypenameCallExpressionAST: public ExpressionAST
public:
unsigned typename_token;
NameAST *name;
unsigned lparen_token;
ExpressionListAST *expression_list;
unsigned rparen_token;
ExpressionAST *expression; // either ExpressionListParenAST or BracedInitializerAST
public:
TypenameCallExpressionAST()
: typename_token(0)
, name(0)
, lparen_token(0)
, expression_list(0)
, rparen_token(0)
, expression(0)
{}
virtual TypenameCallExpressionAST *asTypenameCallExpression() { return this; }
......@@ -2832,16 +2828,12 @@ class CPLUSPLUS_EXPORT TypeConstructorCallAST: public ExpressionAST
{
public:
SpecifierListAST *type_specifier_list;
unsigned lparen_token;
ExpressionListAST *expression_list;
unsigned rparen_token;
ExpressionAST *expression; // either ExpressionListParenAST or BracedInitializerAST
public:
TypeConstructorCallAST()
: type_specifier_list(0)
, lparen_token(0)
, expression_list(0)
, rparen_token(0)
, expression(0)
{}
virtual TypeConstructorCallAST *asTypeConstructorCall() { return this; }
......
......@@ -1051,11 +1051,8 @@ TypenameCallExpressionAST *TypenameCallExpressionAST::clone(MemoryPool *pool) co
ast->typename_token = typename_token;
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;
}
......@@ -1065,11 +1062,8 @@ TypeConstructorCallAST *TypeConstructorCallAST::clone(MemoryPool *pool) const
for (SpecifierListAST *iter = type_specifier_list, **ast_iter = &ast->type_specifier_list;
iter; iter = iter->next, ast_iter = &(*ast_iter)->next)
*ast_iter = new (pool) SpecifierListAST((iter->value) ? iter->value->clone(pool) : 0);
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;
}
......
......@@ -1791,15 +1791,11 @@ bool ASTMatcher::match(TypenameCallExpressionAST *node, TypenameCallExpressionAS
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;
}
......@@ -1813,15 +1809,11 @@ bool ASTMatcher::match(TypeConstructorCallAST *node, TypeConstructorCallAST *pat
else if (! AST::match(node->type_specifier_list, pattern->type_specifier_list, 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;
}
......
......@@ -685,19 +685,19 @@ public:
return __ast;
}
TypenameCallExpressionAST *TypenameCallExpression(NameAST *name = 0, ExpressionListAST *expression_list = 0)
TypenameCallExpressionAST *TypenameCallExpression(NameAST *name = 0, ExpressionAST *expression = 0)
{
TypenameCallExpressionAST *__ast = new (&pool) TypenameCallExpressionAST;
__ast->name = name;
__ast->expression_list = expression_list;
__ast->expression = expression;
return __ast;
}
TypeConstructorCallAST *TypeConstructorCall(SpecifierListAST *type_specifier_list = 0, ExpressionListAST *expression_list = 0)
TypeConstructorCallAST *TypeConstructorCall(SpecifierListAST *type_specifier_list = 0, ExpressionAST *expression = 0)
{
TypeConstructorCallAST *__ast = new (&pool) TypeConstructorCallAST;
__ast->type_specifier_list = type_specifier_list;
__ast->expression_list = expression_list;
__ast->expression = expression;
return __ast;
}
......
......@@ -761,7 +761,7 @@ void TypenameCallExpressionAST::accept0(ASTVisitor *visitor)
{
if (visitor->visit(this)) {
accept(name, visitor);
accept(expression_list, visitor);
accept(expression, visitor);
}
visitor->endVisit(this);
}
......@@ -770,7 +770,7 @@ void TypeConstructorCallAST::accept0(ASTVisitor *visitor)
{
if (visitor->visit(this)) {
accept(type_specifier_list, visitor);
accept(expression_list, visitor);
accept(expression, visitor);
}
visitor->endVisit(this);
}
......
......@@ -1654,11 +1654,7 @@ bool Bind::visit(TypenameCallExpressionAST *ast)
{
// unsigned typename_token = ast->typename_token;
/*const Name *name =*/ this->name(ast->name);
// 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;
this->expression(ast->expression);
return false;
}
......@@ -1668,11 +1664,7 @@ bool Bind::visit(TypeConstructorCallAST *ast)
for (SpecifierListAST *it = ast->type_specifier_list; it; it = it->next) {
type = this->specifier(it->value, type);
}
// 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;
this->expression(ast->expression);
return false;
}
......
......@@ -4712,13 +4712,16 @@ bool Parser::parseTypenameCallExpression(ExpressionAST *&node)
if (LA() == T_TYPENAME) {
unsigned typename_token = consumeToken();
NameAST *name = 0;
if (parseName(name) && LA() == T_LPAREN) {
if (parseName(name)
&& (LA() == T_LPAREN || (_cxx0xEnabled && LA() == T_LBRACE))) {
TypenameCallExpressionAST *ast = new (_pool) TypenameCallExpressionAST;
ast->typename_token = typename_token;
ast->name = name;
ast->lparen_token = consumeToken();
parseExpressionList(ast->expression_list);
match(T_RPAREN, &ast->rparen_token);
if (LA() == T_LPAREN) {
parseExpressionListParen(ast->expression);
} else { // T_LBRACE
parseBracedInitList0x(ast->expression);
}
node = ast;
return true;
}
......@@ -4771,21 +4774,19 @@ bool Parser::parseCorePostfixExpression(ExpressionAST *&node)
bool blocked = blockErrors(true);
if (lookAtBuiltinTypeSpecifier() &&
parseSimpleTypeSpecifier(type_specifier) &&
LA() == T_LPAREN) {
unsigned lparen_token = consumeToken();
ExpressionListAST *expression_list = 0;
parseExpressionList(expression_list);
if (LA() == T_RPAREN) {
unsigned rparen_token = consumeToken();
TypeConstructorCallAST *ast = new (_pool) TypeConstructorCallAST;
ast->type_specifier_list = type_specifier;
ast->lparen_token = lparen_token;
ast->expression_list = expression_list;
ast->rparen_token = rparen_token;
node = ast;
blockErrors(blocked);
return true;
(LA() == T_LPAREN || (_cxx0xEnabled && LA() == T_LBRACE))) {
ExpressionAST *expr;
if (LA() == T_LPAREN) {
parseExpressionListParen(expr);
} else { // T_LBRACE
parseBracedInitList0x(expr);
}
TypeConstructorCallAST *ast = new (_pool) TypeConstructorCallAST;
ast->type_specifier_list = type_specifier;
ast->expression = expr;
node = ast;
blockErrors(blocked);
return true;
}
rewind(start);
......@@ -4835,6 +4836,14 @@ bool Parser::parsePostfixExpression(ExpressionAST *&node)
match(T_RBRACKET, &ast->rbracket_token);
ast->base_expression = node;
node = ast;
} else if (_cxx0xEnabled && LA() == T_LBRACE && node->asIdExpression()) {
// this is slightly inconsistent: simple-type-specifier '(' expression-list ')'
// gets parsed as a CallAST while simple-type-specifier brace-init-list
// is a TypenameCallExpressionAST
TypenameCallExpressionAST *ast = new (_pool) TypenameCallExpressionAST;
ast->name = node->asIdExpression()->name;
parseBracedInitList0x(ast->expression);
node = ast;
} else if (LA() == T_PLUS_PLUS || LA() == T_MINUS_MINUS) {
PostIncrDecrAST *ast = new (_pool) PostIncrDecrAST;
ast->incr_decr_token = consumeToken();
......
......@@ -1312,11 +1312,7 @@ bool FindUsages::visit(TypenameCallExpressionAST *ast)
{
// unsigned typename_token = ast->typename_token;
/*const Name *name =*/ this->name(ast->name);
// unsigned lparen_token = ast->lparen_token;
for (ExpressionListAST *it = ast->expression_list; it; it = it->next) {
this->expression(it->value);
}
// unsigned rparen_token = ast->rparen_token;
this->expression(ast->expression);
return false;
}
......@@ -1325,11 +1321,7 @@ bool FindUsages::visit(TypeConstructorCallAST *ast)
for (SpecifierListAST *it = ast->type_specifier_list; it; it = it->next) {
this->specifier(it->value);
}
// unsigned lparen_token = ast->lparen_token;
for (ExpressionListAST *it = ast->expression_list; it; it = it->next) {
this->expression(it->value);
}
// unsigned rparen_token = ast->rparen_token;
this->expression(ast->expression);
return false;
}
......
auto x = int{};
auto y = Foo{};
auto z = typename Foo<T>{};
......@@ -138,6 +138,7 @@ void tst_cxx11::parse_data()
QTest::newRow("noExcept.1") << "noExcept.1.cpp" << "noExcept.1.errors.txt";
QTest::newRow("braceInitializers.1") << "braceInitializers.1.cpp" << "braceInitializers.1.errors.txt";
QTest::newRow("braceInitializers.2") << "braceInitializers.2.cpp" << "";
QTest::newRow("braceInitializers.3") << "braceInitializers.3.cpp" << "";
QTest::newRow("defaultdeleteInitializer.1") << "defaultdeleteInitializer.1.cpp" << "";
QTest::newRow("refQualifier.1") << "refQualifier.1.cpp" << "";
QTest::newRow("alignofAlignas.1") << "alignofAlignas.1.cpp" << "";
......
......@@ -1017,12 +1017,7 @@ virtual bool visit(TypenameCallExpressionAST *ast)
if (ast->typename_token)
terminal(ast->typename_token, ast);
nonterminal(ast->name);
if (ast->lparen_token)
terminal(ast->lparen_token, ast);
for (ExpressionListAST *iter = ast->expression_list; iter; iter = iter->next)
nonterminal(iter->value);
if (ast->rparen_token)
terminal(ast->rparen_token, ast);
nonterminal(ast->expression);
return false;
}
......@@ -1030,12 +1025,7 @@ virtual bool visit(TypeConstructorCallAST *ast)
{
for (SpecifierListAST *iter = ast->type_specifier_list; iter; iter = iter->next)
nonterminal(iter->value);
if (ast->lparen_token)
terminal(ast->lparen_token, ast);
for (ExpressionListAST *iter = ast->expression_list; iter; iter = iter->next)
nonterminal(iter->value);
if (ast->rparen_token)
terminal(ast->rparen_token, ast);
nonterminal(ast->expression);
return false;
}
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment