forked from qt-creator/qt-creator
C++11: Make expression-list expand to initializer-list.
This will fix a couple more places where brace-init-lists and pack expansions are allowed but are not currently accepted by the parser. For example: foo(abc...); now parses correctly. Change-Id: I93710cef35154fea8437329f3174e4a2d56637b8 Reviewed-by: hjk <qthjk@ovi.com>
This commit is contained in:
39
src/libs/3rdparty/cplusplus/Parser.cpp
vendored
39
src/libs/3rdparty/cplusplus/Parser.cpp
vendored
@@ -2651,7 +2651,7 @@ bool Parser::parseInitializer0x(ExpressionAST *&node, unsigned *equals_token)
|
|||||||
}
|
}
|
||||||
|
|
||||||
else if (LA() == T_LPAREN) {
|
else if (LA() == T_LPAREN) {
|
||||||
return parseExpressionListParen0x(node);
|
return parseExpressionListParen(node);
|
||||||
}
|
}
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
@@ -2787,7 +2787,7 @@ bool Parser::parseMemInitializer(MemInitializerListAST *&node)
|
|||||||
ast->name = name;
|
ast->name = name;
|
||||||
|
|
||||||
if (LA() == T_LPAREN) {
|
if (LA() == T_LPAREN) {
|
||||||
parseExpressionListParen0x(ast->expression);
|
parseExpressionListParen(ast->expression);
|
||||||
} else if (_cxx0xEnabled && LA() == T_LBRACE) {
|
} else if (_cxx0xEnabled && LA() == T_LBRACE) {
|
||||||
parseBracedInitList0x(ast->expression);
|
parseBracedInitList0x(ast->expression);
|
||||||
} else {
|
} else {
|
||||||
@@ -2834,18 +2834,13 @@ bool Parser::parseTypeIdList(ExpressionListAST *&node)
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Note that this function doesn't parse a C++11-style expression-list
|
|
||||||
// yet, so it doesn't allow for brace-initializers.
|
|
||||||
bool Parser::parseExpressionList(ExpressionListAST *&node)
|
bool Parser::parseExpressionList(ExpressionListAST *&node)
|
||||||
{
|
{
|
||||||
DEBUG_THIS_RULE();
|
DEBUG_THIS_RULE();
|
||||||
|
|
||||||
#ifdef CPLUSPLUS_WITH_CXXOX_INITIALIZER_LIST
|
|
||||||
if (_cxx0xEnabled)
|
if (_cxx0xEnabled)
|
||||||
return parseInitializerList0x(node);
|
return parseInitializerList0x(node);
|
||||||
#endif
|
|
||||||
|
|
||||||
// ### remove me
|
|
||||||
ExpressionListAST **expression_list_ptr = &node;
|
ExpressionListAST **expression_list_ptr = &node;
|
||||||
ExpressionAST *expression = 0;
|
ExpressionAST *expression = 0;
|
||||||
if (parseAssignmentExpression(expression)) {
|
if (parseAssignmentExpression(expression)) {
|
||||||
@@ -4959,7 +4954,7 @@ bool Parser::parseUnaryExpression(ExpressionAST *&node)
|
|||||||
}
|
}
|
||||||
|
|
||||||
// new-placement ::= T_LPAREN expression-list T_RPAREN
|
// new-placement ::= T_LPAREN expression-list T_RPAREN
|
||||||
bool Parser::parseExpressionListParen(ExpressionListParenAST *&node)
|
bool Parser::parseExpressionListParen(ExpressionAST *&node)
|
||||||
{
|
{
|
||||||
DEBUG_THIS_RULE();
|
DEBUG_THIS_RULE();
|
||||||
if (LA() == T_LPAREN) {
|
if (LA() == T_LPAREN) {
|
||||||
@@ -4979,28 +4974,6 @@ bool Parser::parseExpressionListParen(ExpressionListParenAST *&node)
|
|||||||
return false;
|
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-expression ::= T_COLON_COLON? T_NEW new-placement.opt
|
||||||
// new-type-id new-initializer.opt
|
// new-type-id new-initializer.opt
|
||||||
@@ -5018,14 +4991,14 @@ bool Parser::parseNewExpression(ExpressionAST *&node)
|
|||||||
|
|
||||||
ast->new_token = consumeToken();
|
ast->new_token = consumeToken();
|
||||||
|
|
||||||
ExpressionListParenAST *parenExpressionList = 0;
|
ExpressionAST *parenExpressionList = 0;
|
||||||
|
|
||||||
if (parseExpressionListParen(parenExpressionList)) {
|
if (parseExpressionListParen(parenExpressionList)) {
|
||||||
unsigned after_new_placement = cursor();
|
unsigned after_new_placement = cursor();
|
||||||
|
|
||||||
NewTypeIdAST *new_type_id = 0;
|
NewTypeIdAST *new_type_id = 0;
|
||||||
if (parseNewTypeId(new_type_id)) {
|
if (parseNewTypeId(new_type_id)) {
|
||||||
ast->new_placement = parenExpressionList;
|
ast->new_placement = parenExpressionList->asExpressionListParen();
|
||||||
ast->new_type_id = new_type_id;
|
ast->new_type_id = new_type_id;
|
||||||
parseNewInitializer(ast->new_initializer);
|
parseNewInitializer(ast->new_initializer);
|
||||||
// recognized new-placement.opt new-type-id new-initializer.opt
|
// recognized new-placement.opt new-type-id new-initializer.opt
|
||||||
@@ -5038,7 +5011,7 @@ bool Parser::parseNewExpression(ExpressionAST *&node)
|
|||||||
unsigned lparen_token = consumeToken();
|
unsigned lparen_token = consumeToken();
|
||||||
ExpressionAST *type_id = 0;
|
ExpressionAST *type_id = 0;
|
||||||
if (parseTypeId(type_id) && LA() == T_RPAREN) {
|
if (parseTypeId(type_id) && LA() == T_RPAREN) {
|
||||||
ast->new_placement = parenExpressionList;
|
ast->new_placement = parenExpressionList->asExpressionListParen();
|
||||||
ast->lparen_token = lparen_token;
|
ast->lparen_token = lparen_token;
|
||||||
ast->type_id = type_id;
|
ast->type_id = type_id;
|
||||||
ast->rparen_token = consumeToken();
|
ast->rparen_token = consumeToken();
|
||||||
|
|||||||
3
src/libs/3rdparty/cplusplus/Parser.h
vendored
3
src/libs/3rdparty/cplusplus/Parser.h
vendored
@@ -132,8 +132,7 @@ public:
|
|||||||
bool parseNamespaceAliasDefinition(DeclarationAST *&node);
|
bool parseNamespaceAliasDefinition(DeclarationAST *&node);
|
||||||
bool parseNewArrayDeclarator(NewArrayDeclaratorListAST *&node);
|
bool parseNewArrayDeclarator(NewArrayDeclaratorListAST *&node);
|
||||||
bool parseNewExpression(ExpressionAST *&node);
|
bool parseNewExpression(ExpressionAST *&node);
|
||||||
bool parseExpressionListParen(ExpressionListParenAST *&node);
|
bool parseExpressionListParen(ExpressionAST *&node);
|
||||||
bool parseExpressionListParen0x(ExpressionAST *&node);
|
|
||||||
bool parseNewInitializer(NewInitializerAST *&node);
|
bool parseNewInitializer(NewInitializerAST *&node);
|
||||||
bool parseNewTypeId(NewTypeIdAST *&node);
|
bool parseNewTypeId(NewTypeIdAST *&node);
|
||||||
bool parseOperator(OperatorAST *&node);
|
bool parseOperator(OperatorAST *&node);
|
||||||
|
|||||||
4
tests/auto/cplusplus/cxx11/data/packExpansion.1.cpp
Normal file
4
tests/auto/cplusplus/cxx11/data/packExpansion.1.cpp
Normal file
@@ -0,0 +1,4 @@
|
|||||||
|
template <class ... Args>
|
||||||
|
int foo(Args args...) {
|
||||||
|
bar(args..., {args...}, e, f);
|
||||||
|
}
|
||||||
@@ -145,6 +145,7 @@ void tst_cxx11::parse_data()
|
|||||||
QTest::newRow("aliasDecl.1") << "aliasDecl.1.cpp" << "";
|
QTest::newRow("aliasDecl.1") << "aliasDecl.1.cpp" << "";
|
||||||
QTest::newRow("enums.1") << "enums.1.cpp" << "";
|
QTest::newRow("enums.1") << "enums.1.cpp" << "";
|
||||||
QTest::newRow("templateGreaterGreater.1") << "templateGreaterGreater.1.cpp" << "";
|
QTest::newRow("templateGreaterGreater.1") << "templateGreaterGreater.1.cpp" << "";
|
||||||
|
QTest::newRow("packExpansion.1") << "packExpansion.1.cpp" << "";
|
||||||
}
|
}
|
||||||
|
|
||||||
void tst_cxx11::parse()
|
void tst_cxx11::parse()
|
||||||
|
|||||||
Reference in New Issue
Block a user