forked from qt-creator/qt-creator
CPlusPlus: Allow empty argument list in member initialization
Fixes: QTCREATORBUG-30797 Change-Id: I6de0f05e071a5e73317d7a8e3d035e23e23a41aa Reviewed-by: Christian Stenger <christian.stenger@qt.io>
This commit is contained in:
19
src/libs/3rdparty/cplusplus/Parser.cpp
vendored
19
src/libs/3rdparty/cplusplus/Parser.cpp
vendored
@@ -20,7 +20,6 @@
|
||||
|
||||
#include "Parser.h"
|
||||
#include "Token.h"
|
||||
#include "Lexer.h"
|
||||
#include "Control.h"
|
||||
#include "AST.h"
|
||||
#include "Literals.h"
|
||||
@@ -30,7 +29,6 @@
|
||||
#include <unordered_map>
|
||||
#include <utility>
|
||||
|
||||
#include <string>
|
||||
#include <cstdio> // for putchar
|
||||
|
||||
#if defined(__INTEL_COMPILER) && !defined(va_copy)
|
||||
@@ -3088,7 +3086,7 @@ bool Parser::parseInitializer0x(ExpressionAST *&node, int *equals_token)
|
||||
}
|
||||
|
||||
else if (LA() == T_LPAREN) {
|
||||
return parseExpressionListParen(node);
|
||||
return parseExpressionListParen(node, false);
|
||||
}
|
||||
|
||||
return false;
|
||||
@@ -3258,7 +3256,7 @@ bool Parser::parseMemInitializer(MemInitializerListAST *&node)
|
||||
ast->name = name;
|
||||
|
||||
if (LA() == T_LPAREN) {
|
||||
parseExpressionListParen(ast->expression);
|
||||
parseExpressionListParen(ast->expression, true);
|
||||
} else if (_languageFeatures.cxx11Enabled && LA() == T_LBRACE) {
|
||||
parseBracedInitList0x(ast->expression);
|
||||
} else {
|
||||
@@ -5452,7 +5450,7 @@ bool Parser::parseTypenameCallExpression(ExpressionAST *&node)
|
||||
ast->typename_token = typename_token;
|
||||
ast->name = name;
|
||||
if (LA() == T_LPAREN) {
|
||||
parseExpressionListParen(ast->expression);
|
||||
parseExpressionListParen(ast->expression, false);
|
||||
} else { // T_LBRACE
|
||||
parseBracedInitList0x(ast->expression);
|
||||
}
|
||||
@@ -5511,7 +5509,7 @@ bool Parser::parseCorePostfixExpression(ExpressionAST *&node)
|
||||
(LA() == T_LPAREN || (_languageFeatures.cxx11Enabled && LA() == T_LBRACE))) {
|
||||
ExpressionAST *expr = nullptr;
|
||||
if (LA() == T_LPAREN) {
|
||||
parseExpressionListParen(expr);
|
||||
parseExpressionListParen(expr, false);
|
||||
} else { // T_LBRACE
|
||||
parseBracedInitList0x(expr);
|
||||
}
|
||||
@@ -5707,13 +5705,14 @@ bool Parser::parseUnaryExpression(ExpressionAST *&node)
|
||||
}
|
||||
|
||||
// new-placement ::= T_LPAREN expression-list T_RPAREN
|
||||
bool Parser::parseExpressionListParen(ExpressionAST *&node)
|
||||
bool Parser::parseExpressionListParen(ExpressionAST *&node, bool allowEmpty)
|
||||
{
|
||||
DEBUG_THIS_RULE();
|
||||
if (LA() == T_LPAREN) {
|
||||
int lparen_token = consumeToken();
|
||||
ExpressionListAST *expression_list = nullptr;
|
||||
if (parseExpressionList(expression_list) && LA() == T_RPAREN) {
|
||||
const bool hasList = parseExpressionList(expression_list);
|
||||
if ((hasList || allowEmpty) && LA() == T_RPAREN) {
|
||||
int rparen_token = consumeToken();
|
||||
ExpressionListParenAST *ast = new (_pool) ExpressionListParenAST;
|
||||
ast->lparen_token = lparen_token;
|
||||
@@ -5746,7 +5745,7 @@ bool Parser::parseNewExpression(ExpressionAST *&node)
|
||||
|
||||
ExpressionAST *parenExpressionList = nullptr;
|
||||
|
||||
if (parseExpressionListParen(parenExpressionList)) {
|
||||
if (parseExpressionListParen(parenExpressionList, false)) {
|
||||
int after_new_placement = cursor();
|
||||
|
||||
NewTypeIdAST *new_type_id = nullptr;
|
||||
@@ -5839,7 +5838,7 @@ bool Parser::parseNewInitializer(ExpressionAST *&node)
|
||||
{
|
||||
DEBUG_THIS_RULE();
|
||||
if (LA() == T_LPAREN)
|
||||
return parseExpressionListParen(node);
|
||||
return parseExpressionListParen(node, false);
|
||||
else if (_languageFeatures.cxx11Enabled && LA() == T_LBRACE)
|
||||
return parseBracedInitList0x(node);
|
||||
return false;
|
||||
|
2
src/libs/3rdparty/cplusplus/Parser.h
vendored
2
src/libs/3rdparty/cplusplus/Parser.h
vendored
@@ -117,7 +117,7 @@ public:
|
||||
bool parseNamespaceAliasDefinition(DeclarationAST *&node);
|
||||
bool parseNewArrayDeclarator(NewArrayDeclaratorListAST *&node);
|
||||
bool parseNewExpression(ExpressionAST *&node);
|
||||
bool parseExpressionListParen(ExpressionAST *&node);
|
||||
bool parseExpressionListParen(ExpressionAST *&node, bool allowEmpty);
|
||||
bool parseNewInitializer(ExpressionAST *&node);
|
||||
bool parseNewTypeId(NewTypeIdAST *&node);
|
||||
bool parseOperator(OperatorAST *&node);
|
||||
|
@@ -112,6 +112,7 @@ private slots:
|
||||
void templated_dtor_3();
|
||||
void templated_dtor_4();
|
||||
void templated_dtor_5();
|
||||
void emptyMemberInitialization();
|
||||
|
||||
// possible declaration-or-expression statements
|
||||
void call_call_1();
|
||||
@@ -2061,6 +2062,14 @@ void tst_AST::invalidFunctionInitializer()
|
||||
QVERIFY(diag.errorCount != 0);
|
||||
}
|
||||
|
||||
void tst_AST::emptyMemberInitialization()
|
||||
{
|
||||
const std::shared_ptr<TranslationUnit> unit(parse(
|
||||
"struct S\n{\n S(): i() {}\n int i;};", TranslationUnit::ParseTranlationUnit));
|
||||
QVERIFY(unit->ast());
|
||||
QCOMPARE(diag.errorCount, 0);
|
||||
}
|
||||
|
||||
void tst_AST::initTestCase()
|
||||
{
|
||||
control.setDiagnosticClient(&diag);
|
||||
|
Reference in New Issue
Block a user