forked from qt-creator/qt-creator
C++11: Allow for typename Foo<T>{}, Foo{} and int{}.
As a postfix expression. Change-Id: I65cae0571080a9fb699af61c661328ef06f97890 Reviewed-by: hjk <qthjk@ovi.com>
This commit is contained in:
Vendored
+8
-24
@@ -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;
|
||||
|
||||
Vendored
+4
-12
@@ -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; }
|
||||
|
||||
+4
-10
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
+6
-14
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
+4
-4
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
+2
-2
@@ -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);
|
||||
}
|
||||
|
||||
Vendored
+2
-10
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
+27
-18
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,3 @@
|
||||
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;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user