Skip to content

Commit f3b9b98

Browse files
committed
fix: Improve parsing of init statements
1 parent 440192d commit f3b9b98

File tree

1 file changed

+43
-1
lines changed

1 file changed

+43
-1
lines changed

src/parser/cxx/parser.cc

Lines changed: 43 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3734,8 +3734,18 @@ void Parser::parse_init_statement(StatementAST*& yyast) {
37343734
DeclarationAST* declaration = nullptr;
37353735
if (!parse_simple_declaration(declaration, BindingContext::kInitStatement))
37363736
return false;
3737+
37373738
lookahead.commit();
37383739

3740+
if (auto simpleDeclaration = ast_cast<SimpleDeclarationAST>(declaration)) {
3741+
// recover the declared symbols and add them to the scope
3742+
for (auto initDeclaraotr :
3743+
ListView(simpleDeclaration->initDeclaratorList)) {
3744+
auto symbol = initDeclaraotr->symbol;
3745+
std::invoke(DeclareSymbol{this, scope_}, symbol);
3746+
}
3747+
}
3748+
37393749
auto ast = make_node<DeclarationStatementAST>(pool_);
37403750
yyast = ast;
37413751
ast->declaration = declaration;
@@ -3778,6 +3788,15 @@ void Parser::parse_condition(ExpressionAST*& yyast, const ExprContext& ctx) {
37783788
Decl decl{specs};
37793789
if (!parse_declarator(declarator, decl)) return false;
37803790

3791+
auto symbolType = GetDeclaratorType{this}(declarator, decl.specs.getType());
3792+
3793+
auto symbol = control_->newVariableSymbol(scope_, decl.location());
3794+
applySpecifiers(symbol, decl.specs);
3795+
symbol->setName(decl.getName());
3796+
symbol->setType(symbolType);
3797+
3798+
std::invoke(DeclareSymbol{this, scope_}, symbol);
3799+
37813800
ExpressionAST* initializer = nullptr;
37823801

37833802
if (!parse_brace_or_equal_initializer(initializer)) return false;
@@ -3978,6 +3997,10 @@ auto Parser::parse_if_statement(StatementAST*& yyast) -> bool {
39783997

39793998
ScopeGuard scopeGuard{this};
39803999

4000+
auto blockSymbol = control_->newBlockSymbol(scope_, ifLoc);
4001+
std::invoke(DeclareSymbol{this, scope_}, blockSymbol);
4002+
scope_ = blockSymbol->scope();
4003+
39814004
if (LA().isOneOf(TokenKind::T_EXCLAIM, TokenKind::T_CONSTEVAL)) {
39824005
auto ast = make_node<ConstevalIfStatementAST>(pool_);
39834006
yyast = ast;
@@ -4057,6 +4080,10 @@ auto Parser::parse_while_statement(StatementAST*& yyast) -> bool {
40574080

40584081
ScopeGuard scopeGuard{this};
40594082

4083+
auto blockSymbol = control_->newBlockSymbol(scope_, whileLoc);
4084+
std::invoke(DeclareSymbol{this, scope_}, blockSymbol);
4085+
scope_ = blockSymbol->scope();
4086+
40604087
auto ast = make_node<WhileStatementAST>(pool_);
40614088
yyast = ast;
40624089

@@ -4106,6 +4133,11 @@ auto Parser::parse_for_range_statement(StatementAST*& yyast) -> bool {
41064133
SourceLocation forLoc;
41074134
if (!match(TokenKind::T_FOR, forLoc)) return false;
41084135

4136+
ScopeGuard scopeGuard{this};
4137+
4138+
auto blockSymbol = control_->newBlockSymbol(scope_, forLoc);
4139+
scope_ = blockSymbol->scope();
4140+
41094141
SourceLocation lparenLoc;
41104142
if (!match(TokenKind::T_LPAREN, lparenLoc)) return false;
41114143

@@ -4120,6 +4152,8 @@ auto Parser::parse_for_range_statement(StatementAST*& yyast) -> bool {
41204152

41214153
lookahead.commit();
41224154

4155+
std::invoke(DeclareSymbol{this, scope_}, blockSymbol);
4156+
41234157
auto ast = make_node<ForRangeStatementAST>(pool_);
41244158
yyast = ast;
41254159

@@ -4145,6 +4179,12 @@ auto Parser::parse_for_statement(StatementAST*& yyast) -> bool {
41454179

41464180
if (!match(TokenKind::T_FOR, forLoc)) return false;
41474181

4182+
ScopeGuard scopeGuard{this};
4183+
4184+
auto blockSymbol = control_->newBlockSymbol(scope_, forLoc);
4185+
std::invoke(DeclareSymbol{this, scope_}, blockSymbol);
4186+
scope_ = blockSymbol->scope();
4187+
41484188
auto ast = make_node<ForStatementAST>(pool_);
41494189
yyast = ast;
41504190

@@ -6782,7 +6822,9 @@ auto Parser::parse_init_declarator(InitDeclaratorAST*& yyast,
67826822
applySpecifiers(symbol, decl.specs);
67836823
symbol->setName(name);
67846824
symbol->setType(symbolType);
6785-
std::invoke(DeclareSymbol{this, scope_}, symbol);
6825+
if (ctx != BindingContext::kInitStatement) {
6826+
std::invoke(DeclareSymbol{this, scope_}, symbol);
6827+
}
67866828
declaredSynbol = symbol;
67876829
}
67886830
}

0 commit comments

Comments
 (0)