Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
69 changes: 58 additions & 11 deletions src/parser/cxx/parser.cc
Original file line number Diff line number Diff line change
Expand Up @@ -3734,8 +3734,18 @@ void Parser::parse_init_statement(StatementAST*& yyast) {
DeclarationAST* declaration = nullptr;
if (!parse_simple_declaration(declaration, BindingContext::kInitStatement))
return false;

lookahead.commit();

if (auto simpleDeclaration = ast_cast<SimpleDeclarationAST>(declaration)) {
// recover the declared symbols and add them to the scope
for (auto initDeclaraotr :
ListView(simpleDeclaration->initDeclaratorList)) {
auto symbol = initDeclaraotr->symbol;
std::invoke(DeclareSymbol{this, scope_}, symbol);
}
}

auto ast = make_node<DeclarationStatementAST>(pool_);
yyast = ast;
ast->declaration = declaration;
Expand Down Expand Up @@ -3778,6 +3788,15 @@ void Parser::parse_condition(ExpressionAST*& yyast, const ExprContext& ctx) {
Decl decl{specs};
if (!parse_declarator(declarator, decl)) return false;

auto symbolType = GetDeclaratorType{this}(declarator, decl.specs.getType());

auto symbol = control_->newVariableSymbol(scope_, decl.location());
applySpecifiers(symbol, decl.specs);
symbol->setName(decl.getName());
symbol->setType(symbolType);

std::invoke(DeclareSymbol{this, scope_}, symbol);

ExpressionAST* initializer = nullptr;

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

ScopeGuard scopeGuard{this};

auto blockSymbol = control_->newBlockSymbol(scope_, ifLoc);
std::invoke(DeclareSymbol{this, scope_}, blockSymbol);
scope_ = blockSymbol->scope();

if (LA().isOneOf(TokenKind::T_EXCLAIM, TokenKind::T_CONSTEVAL)) {
auto ast = make_node<ConstevalIfStatementAST>(pool_);
yyast = ast;
Expand Down Expand Up @@ -4057,6 +4080,10 @@ auto Parser::parse_while_statement(StatementAST*& yyast) -> bool {

ScopeGuard scopeGuard{this};

auto blockSymbol = control_->newBlockSymbol(scope_, whileLoc);
std::invoke(DeclareSymbol{this, scope_}, blockSymbol);
scope_ = blockSymbol->scope();

auto ast = make_node<WhileStatementAST>(pool_);
yyast = ast;

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

ScopeGuard scopeGuard{this};

auto blockSymbol = control_->newBlockSymbol(scope_, forLoc);
scope_ = blockSymbol->scope();

SourceLocation lparenLoc;
if (!match(TokenKind::T_LPAREN, lparenLoc)) return false;

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

lookahead.commit();

std::invoke(DeclareSymbol{this, scope_}, blockSymbol);

auto ast = make_node<ForRangeStatementAST>(pool_);
yyast = ast;

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

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

ScopeGuard scopeGuard{this};

auto blockSymbol = control_->newBlockSymbol(scope_, forLoc);
std::invoke(DeclareSymbol{this, scope_}, blockSymbol);
scope_ = blockSymbol->scope();

auto ast = make_node<ForStatementAST>(pool_);
yyast = ast;

Expand Down Expand Up @@ -4567,7 +4607,8 @@ auto Parser::parse_template_class_declaration(
}

auto Parser::parse_empty_or_attribute_declaration(
DeclarationAST*& yyast, List<AttributeSpecifierAST*>* attributes) -> auto {
DeclarationAST*& yyast, List<AttributeSpecifierAST*>* attributes,
BindingContext ctx) -> auto {
LookaheadParser lookahead{this};

SourceLocation semicolonLoc;
Expand All @@ -4594,10 +4635,10 @@ auto Parser::parse_notypespec_function_definition(
DeclarationAST*& yyast, List<AttributeSpecifierAST*>* atributes,
const std::vector<TemplateDeclarationAST*>& templateDeclarations,
BindingContext ctx) -> bool {
LookaheadParser lookahead{this};

if (!context_allows_function_definition(ctx)) return false;

LookaheadParser lookahead{this};

DeclSpecs specs{this};
List<SpecifierAST*>* declSpecifierList = nullptr;

Expand Down Expand Up @@ -4625,6 +4666,8 @@ auto Parser::parse_type_or_forward_declaration(
List<SpecifierAST*>* declSpecifierList, const DeclSpecs& specs,
const std::vector<TemplateDeclarationAST*>& templateDeclarations,
BindingContext ctx) -> bool {
if (ctx == BindingContext::kInitStatement) return false;

LookaheadParser lookahead{this};

List<AttributeSpecifierAST*>* trailingAttributes = nullptr;
Expand Down Expand Up @@ -4738,7 +4781,7 @@ auto Parser::parse_simple_declaration(
if (parse_template_class_declaration(yyast, attributes, templateDeclarations,
ctx))
return true;
else if (parse_empty_or_attribute_declaration(yyast, attributes))
else if (parse_empty_or_attribute_declaration(yyast, attributes, ctx))
return true;
else if (parse_notypespec_function_definition(yyast, attributes,
templateDeclarations, ctx))
Expand Down Expand Up @@ -4864,7 +4907,8 @@ auto Parser::parse_simple_declaration(
auto declIt = &initDeclaratorList;

InitDeclaratorAST* initDeclarator = nullptr;
if (!parse_init_declarator(initDeclarator, declarator, decl)) return false;
if (!parse_init_declarator(initDeclarator, declarator, decl, ctx))
return false;

if (ctx == BindingContext::kTemplate) {
auto declarator = initDeclarator->declarator;
Expand All @@ -4879,7 +4923,7 @@ auto Parser::parse_simple_declaration(

while (match(TokenKind::T_COMMA, commaLoc)) {
InitDeclaratorAST* initDeclarator = nullptr;
if (!parse_init_declarator(initDeclarator, specs)) return false;
if (!parse_init_declarator(initDeclarator, specs, ctx)) return false;

*declIt = make_list_node(pool_, initDeclarator);
declIt = &(*declIt)->next;
Expand Down Expand Up @@ -6742,17 +6786,18 @@ auto Parser::parse_placeholder_type_specifier(SpecifierAST*& yyast,
}

auto Parser::parse_init_declarator(InitDeclaratorAST*& yyast,
const DeclSpecs& specs) -> bool {
const DeclSpecs& specs, BindingContext ctx)
-> bool {
DeclaratorAST* declarator = nullptr;
Decl decl{specs};
if (!parse_declarator(declarator, decl)) return false;

return parse_init_declarator(yyast, declarator, decl);
return parse_init_declarator(yyast, declarator, decl, ctx);
}

auto Parser::parse_init_declarator(InitDeclaratorAST*& yyast,
DeclaratorAST* declarator, Decl& decl)
-> bool {
DeclaratorAST* declarator, Decl& decl,
BindingContext ctx) -> bool {
Symbol* declaredSynbol = nullptr;
if (auto declId = decl.declaratorId; declId) {
auto symbolType = GetDeclaratorType{this}(declarator, decl.specs.getType());
Expand All @@ -6777,7 +6822,9 @@ auto Parser::parse_init_declarator(InitDeclaratorAST*& yyast,
applySpecifiers(symbol, decl.specs);
symbol->setName(name);
symbol->setType(symbolType);
std::invoke(DeclareSymbol{this, scope_}, symbol);
if (ctx != BindingContext::kInitStatement) {
std::invoke(DeclareSymbol{this, scope_}, symbol);
}
declaredSynbol = symbol;
}
}
Expand Down
9 changes: 6 additions & 3 deletions src/parser/cxx/parser.h
Original file line number Diff line number Diff line change
Expand Up @@ -383,7 +383,8 @@ class Parser final {
const std::vector<TemplateDeclarationAST*>& templateDeclarations,
BindingContext ctx) -> bool;
[[nodiscard]] auto parse_empty_or_attribute_declaration(
DeclarationAST*& yyast, List<AttributeSpecifierAST*>* attributes) -> auto;
DeclarationAST*& yyast, List<AttributeSpecifierAST*>* attributes,
BindingContext ctx) -> auto;

[[nodiscard]] auto parse_notypespec_function_definition(
DeclarationAST*& yyast, List<AttributeSpecifierAST*>* atributes,
Expand Down Expand Up @@ -472,10 +473,12 @@ class Parser final {
[[nodiscard]] auto parse_placeholder_type_specifier(SpecifierAST*& yyast,
DeclSpecs& specs) -> bool;
[[nodiscard]] auto parse_init_declarator(InitDeclaratorAST*& yyast,
const DeclSpecs& specs) -> bool;
const DeclSpecs& specs,
BindingContext ctx) -> bool;
[[nodiscard]] auto parse_init_declarator(InitDeclaratorAST*& yyast,
DeclaratorAST* declarator,
Decl& decl) -> bool;
Decl& decl, BindingContext ctx)
-> bool;
[[nodiscard]] auto parse_declarator_initializer(
RequiresClauseAST*& requiresClause, ExpressionAST*& yyast) -> bool;
void parse_optional_declarator_or_abstract_declarator(DeclaratorAST*& yyast,
Expand Down