Skip to content

Commit 8a5cb3f

Browse files
committed
fix: Postpone parsing of mem-intiializers
Signed-off-by: Roberto Raggi <[email protected]>
1 parent d06f944 commit 8a5cb3f

File tree

1 file changed

+72
-37
lines changed

1 file changed

+72
-37
lines changed

src/parser/cxx/parser.cc

Lines changed: 72 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -7577,19 +7577,18 @@ auto Parser::parse_initializer_clause(ExpressionAST*& yyast,
75777577
return true;
75787578
}
75797579

7580-
auto Parser::parse_braced_init_list(BracedInitListAST*& yyast,
7580+
auto Parser::parse_braced_init_list(BracedInitListAST*& ast,
75817581
const ExprContext& ctx) -> bool {
75827582
SourceLocation lbraceLoc;
7583-
SourceLocation rbraceLoc;
7584-
75857583
if (!match(TokenKind::T_LBRACE, lbraceLoc)) return false;
75867584

7587-
if (lookat(TokenKind::T_DOT)) {
7588-
auto ast = make_node<BracedInitListAST>(pool_);
7589-
yyast = ast;
7585+
if (!ast) {
7586+
ast = make_node<BracedInitListAST>(pool_);
7587+
}
75907588

7591-
ast->lbraceLoc = lbraceLoc;
7589+
ast->lbraceLoc = lbraceLoc;
75927590

7591+
if (lookat(TokenKind::T_DOT)) {
75937592
auto it = &ast->expressionList;
75947593

75957594
DesignatedInitializerClauseAST* designatedInitializerClause = nullptr;
@@ -7625,38 +7624,20 @@ auto Parser::parse_braced_init_list(BracedInitListAST*& yyast,
76257624
return true;
76267625
}
76277626

7628-
SourceLocation commaLoc;
7629-
7630-
if (match(TokenKind::T_COMMA, commaLoc)) {
7631-
expect(TokenKind::T_RBRACE, rbraceLoc);
7632-
7633-
auto ast = make_node<BracedInitListAST>(pool_);
7634-
yyast = ast;
7635-
7636-
ast->lbraceLoc = lbraceLoc;
7637-
ast->commaLoc = commaLoc;
7638-
ast->rbraceLoc = rbraceLoc;
7627+
if (match(TokenKind::T_COMMA, ast->commaLoc)) {
7628+
expect(TokenKind::T_RBRACE, ast->rbraceLoc);
76397629

76407630
return true;
76417631
}
76427632

7643-
List<ExpressionAST*>* expressionList = nullptr;
7644-
7645-
if (!match(TokenKind::T_RBRACE, rbraceLoc)) {
7646-
if (!parse_initializer_list(expressionList, ctx)) {
7633+
if (!match(TokenKind::T_RBRACE, ast->rbraceLoc)) {
7634+
if (!parse_initializer_list(ast->expressionList, ctx)) {
76477635
parse_error("expected initializer list");
76487636
}
76497637

7650-
expect(TokenKind::T_RBRACE, rbraceLoc);
7638+
expect(TokenKind::T_RBRACE, ast->rbraceLoc);
76517639
}
76527640

7653-
auto ast = make_node<BracedInitListAST>(pool_);
7654-
yyast = ast;
7655-
7656-
ast->lbraceLoc = lbraceLoc;
7657-
ast->expressionList = expressionList;
7658-
ast->rbraceLoc = rbraceLoc;
7659-
76607641
return true;
76617642
}
76627643

@@ -10013,8 +9994,16 @@ void Parser::parse_mem_initializer(MemInitializerAST*& yyast) {
100139994
ast->nestedNameSpecifier = nestedNameSpecifier;
100149995
ast->unqualifiedId = name;
100159996

10016-
if (!parse_braced_init_list(ast->bracedInitList, ExprContext{})) {
10017-
parse_error("expected an initializer");
9997+
if (classDepth_) {
9998+
ast->bracedInitList = make_node<BracedInitListAST>(pool_);
9999+
ast->bracedInitList->lbraceLoc = currentLocation();
10000+
if (parse_skip_balanced()) {
10001+
ast->bracedInitList->rbraceLoc = currentLocation().previous();
10002+
}
10003+
} else {
10004+
if (!parse_braced_init_list(ast->bracedInitList, ExprContext{})) {
10005+
parse_error("expected an initializer");
10006+
}
1001810007
}
1001910008

1002010009
match(TokenKind::T_DOT_DOT_DOT, ast->ellipsisLoc);
@@ -10028,14 +10017,27 @@ void Parser::parse_mem_initializer(MemInitializerAST*& yyast) {
1002810017
ast->nestedNameSpecifier = nestedNameSpecifier;
1002910018
ast->unqualifiedId = name;
1003010019

10031-
expect(TokenKind::T_LPAREN, ast->lparenLoc);
10020+
if (classDepth_) {
10021+
// postpone parsing of the intiializer
10022+
if (lookat(TokenKind::T_LPAREN)) {
10023+
ast->lparenLoc = currentLocation();
1003210024

10033-
if (!match(TokenKind::T_RPAREN, ast->rparenLoc)) {
10034-
if (!parse_expression_list(ast->expressionList, ExprContext{})) {
10035-
parse_error("expected an expression");
10025+
if (parse_skip_balanced()) {
10026+
ast->rparenLoc = currentLocation().previous();
10027+
}
10028+
} else {
10029+
expect(TokenKind::T_LPAREN, ast->lparenLoc);
1003610030
}
10031+
} else {
10032+
expect(TokenKind::T_LPAREN, ast->lparenLoc);
1003710033

10038-
expect(TokenKind::T_RPAREN, ast->rparenLoc);
10034+
if (!match(TokenKind::T_RPAREN, ast->rparenLoc)) {
10035+
if (!parse_expression_list(ast->expressionList, ExprContext{})) {
10036+
parse_error("expected an expression");
10037+
}
10038+
10039+
expect(TokenKind::T_RPAREN, ast->rparenLoc);
10040+
}
1003910041
}
1004010042

1004110043
match(TokenKind::T_DOT_DOT_DOT, ast->ellipsisLoc);
@@ -11296,6 +11298,39 @@ void Parser::completeFunctionDefinition(FunctionDefinitionAST* ast) {
1129611298

1129711299
const auto saved = currentLocation();
1129811300

11301+
for (auto memInitializer : ListView{functionBody->memInitializerList}) {
11302+
if (auto parenMemInitializer =
11303+
ast_cast<ParenMemInitializerAST>(memInitializer)) {
11304+
if (!parenMemInitializer->lparenLoc) {
11305+
// found an invalid mem-initializer, the parser
11306+
// already reported an error in this case, so
11307+
// we just skip it
11308+
continue;
11309+
}
11310+
11311+
// go after the lparen
11312+
rewind(parenMemInitializer->lparenLoc.next());
11313+
11314+
if (SourceLocation rparenLoc; !match(TokenKind::T_RPAREN, rparenLoc)) {
11315+
if (!parse_expression_list(parenMemInitializer->expressionList,
11316+
ExprContext{})) {
11317+
parse_error("expected an expression");
11318+
}
11319+
11320+
expect(TokenKind::T_RPAREN, rparenLoc);
11321+
}
11322+
}
11323+
11324+
if (auto bracedMemInitializer =
11325+
ast_cast<BracedMemInitializerAST>(memInitializer)) {
11326+
rewind(bracedMemInitializer->bracedInitList->lbraceLoc);
11327+
if (!parse_braced_init_list(bracedMemInitializer->bracedInitList,
11328+
ExprContext{})) {
11329+
parse_error("expected a braced-init-list");
11330+
}
11331+
}
11332+
}
11333+
1129911334
rewind(functionBody->statement->lbraceLoc.next());
1130011335

1130111336
finish_compound_statement(functionBody->statement);

0 commit comments

Comments
 (0)