diff options
author | Christian Kamm <kamm@incasoftware.de> | 2012-09-19 10:26:07 +0200 |
---|---|---|
committer | hjk <qthjk@ovi.com> | 2012-09-19 12:21:31 +0200 |
commit | 83da5f68bec13dcb05b84a005f4bb3bc7e8bc82b (patch) | |
tree | f29e5c977a316cd757e9a00ddb43bcbf98999880 | |
parent | 2aa27e6d22757976811ac9f29291bb12e8871f0a (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.cpp | 32 | ||||
-rw-r--r-- | src/libs/3rdparty/cplusplus/AST.h | 16 | ||||
-rw-r--r-- | src/libs/3rdparty/cplusplus/ASTClone.cpp | 14 | ||||
-rw-r--r-- | src/libs/3rdparty/cplusplus/ASTMatcher.cpp | 20 | ||||
-rw-r--r-- | src/libs/3rdparty/cplusplus/ASTPatternBuilder.h | 8 | ||||
-rw-r--r-- | src/libs/3rdparty/cplusplus/ASTVisit.cpp | 4 | ||||
-rw-r--r-- | src/libs/3rdparty/cplusplus/Bind.cpp | 12 | ||||
-rw-r--r-- | src/libs/3rdparty/cplusplus/Parser.cpp | 45 | ||||
-rw-r--r-- | src/libs/cplusplus/FindUsages.cpp | 12 | ||||
-rw-r--r-- | tests/auto/cplusplus/cxx11/data/braceInitializers.3.cpp | 3 | ||||
-rw-r--r-- | tests/auto/cplusplus/cxx11/tst_cxx11.cpp | 1 | ||||
-rw-r--r-- | tests/tools/cplusplus-dump/dumpers.inc | 14 |
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; } |