aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorChristian Kamm <kamm@incasoftware.de>2012-09-19 10:26:07 +0200
committerhjk <qthjk@ovi.com>2012-09-19 12:21:31 +0200
commit83da5f68bec13dcb05b84a005f4bb3bc7e8bc82b (patch)
treef29e5c977a316cd757e9a00ddb43bcbf98999880
parent2aa27e6d22757976811ac9f29291bb12e8871f0a (diff)
C++11: Allow for typename Foo<T>{}, Foo{} and int{}.
As a postfix expression. Change-Id: I65cae0571080a9fb699af61c661328ef06f97890 Reviewed-by: hjk <qthjk@ovi.com>
-rw-r--r--src/libs/3rdparty/cplusplus/AST.cpp32
-rw-r--r--src/libs/3rdparty/cplusplus/AST.h16
-rw-r--r--src/libs/3rdparty/cplusplus/ASTClone.cpp14
-rw-r--r--src/libs/3rdparty/cplusplus/ASTMatcher.cpp20
-rw-r--r--src/libs/3rdparty/cplusplus/ASTPatternBuilder.h8
-rw-r--r--src/libs/3rdparty/cplusplus/ASTVisit.cpp4
-rw-r--r--src/libs/3rdparty/cplusplus/Bind.cpp12
-rw-r--r--src/libs/3rdparty/cplusplus/Parser.cpp45
-rw-r--r--src/libs/cplusplus/FindUsages.cpp12
-rw-r--r--tests/auto/cplusplus/cxx11/data/braceInitializers.3.cpp3
-rw-r--r--tests/auto/cplusplus/cxx11/tst_cxx11.cpp1
-rw-r--r--tests/tools/cplusplus-dump/dumpers.inc14
12 files changed, 65 insertions, 116 deletions
diff --git a/src/libs/3rdparty/cplusplus/AST.cpp b/src/libs/3rdparty/cplusplus/AST.cpp
index 89d5a1a84a..1510d4dcfc 100644
--- a/src/libs/3rdparty/cplusplus/AST.cpp
+++ b/src/libs/3rdparty/cplusplus/AST.cpp
@@ -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;
diff --git a/src/libs/3rdparty/cplusplus/AST.h b/src/libs/3rdparty/cplusplus/AST.h
index 6dc218dd31..9ebe42bd17 100644
--- a/src/libs/3rdparty/cplusplus/AST.h
+++ b/src/libs/3rdparty/cplusplus/AST.h
@@ -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; }
diff --git a/src/libs/3rdparty/cplusplus/ASTClone.cpp b/src/libs/3rdparty/cplusplus/ASTClone.cpp
index a2a3ef3759..5223ce8c73 100644
--- a/src/libs/3rdparty/cplusplus/ASTClone.cpp
+++ b/src/libs/3rdparty/cplusplus/ASTClone.cpp
@@ -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;
}
diff --git a/src/libs/3rdparty/cplusplus/ASTMatcher.cpp b/src/libs/3rdparty/cplusplus/ASTMatcher.cpp
index e4e899c7e5..31401c8f4f 100644
--- a/src/libs/3rdparty/cplusplus/ASTMatcher.cpp
+++ b/src/libs/3rdparty/cplusplus/ASTMatcher.cpp
@@ -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;
}
diff --git a/src/libs/3rdparty/cplusplus/ASTPatternBuilder.h b/src/libs/3rdparty/cplusplus/ASTPatternBuilder.h
index ec21afabe7..4406849444 100644
--- a/src/libs/3rdparty/cplusplus/ASTPatternBuilder.h
+++ b/src/libs/3rdparty/cplusplus/ASTPatternBuilder.h
@@ -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;
}
diff --git a/src/libs/3rdparty/cplusplus/ASTVisit.cpp b/src/libs/3rdparty/cplusplus/ASTVisit.cpp
index 5e5cbefe71..b06b9ea3b6 100644
--- a/src/libs/3rdparty/cplusplus/ASTVisit.cpp
+++ b/src/libs/3rdparty/cplusplus/ASTVisit.cpp
@@ -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);
}
diff --git a/src/libs/3rdparty/cplusplus/Bind.cpp b/src/libs/3rdparty/cplusplus/Bind.cpp
index 30745c14bd..7a6a1cbf43 100644
--- a/src/libs/3rdparty/cplusplus/Bind.cpp
+++ b/src/libs/3rdparty/cplusplus/Bind.cpp
@@ -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;
}
diff --git a/src/libs/3rdparty/cplusplus/Parser.cpp b/src/libs/3rdparty/cplusplus/Parser.cpp
index 8304980453..58b4f90535 100644
--- a/src/libs/3rdparty/cplusplus/Parser.cpp
+++ b/src/libs/3rdparty/cplusplus/Parser.cpp
@@ -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();
diff --git a/src/libs/cplusplus/FindUsages.cpp b/src/libs/cplusplus/FindUsages.cpp
index d9ca28a705..f84056ff94 100644
--- a/src/libs/cplusplus/FindUsages.cpp
+++ b/src/libs/cplusplus/FindUsages.cpp
@@ -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;
}
diff --git a/tests/auto/cplusplus/cxx11/data/braceInitializers.3.cpp b/tests/auto/cplusplus/cxx11/data/braceInitializers.3.cpp
new file mode 100644
index 0000000000..58b5a8dd48
--- /dev/null
+++ b/tests/auto/cplusplus/cxx11/data/braceInitializers.3.cpp
@@ -0,0 +1,3 @@
+auto x = int{};
+auto y = Foo{};
+auto z = typename Foo<T>{};
diff --git a/tests/auto/cplusplus/cxx11/tst_cxx11.cpp b/tests/auto/cplusplus/cxx11/tst_cxx11.cpp
index 09a1632115..53d2cae2a1 100644
--- a/tests/auto/cplusplus/cxx11/tst_cxx11.cpp
+++ b/tests/auto/cplusplus/cxx11/tst_cxx11.cpp
@@ -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" << "";
diff --git a/tests/tools/cplusplus-dump/dumpers.inc b/tests/tools/cplusplus-dump/dumpers.inc
index 015e2a39be..6e4ec32e74 100644
--- a/tests/tools/cplusplus-dump/dumpers.inc
+++ b/tests/tools/cplusplus-dump/dumpers.inc
@@ -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;
}