diff --git a/packages/cxx-frontend/src/AST.ts b/packages/cxx-frontend/src/AST.ts index bf546f42..8e480abf 100644 --- a/packages/cxx-frontend/src/AST.ts +++ b/packages/cxx-frontend/src/AST.ts @@ -2777,9 +2777,12 @@ export class IfStatementAST extends StatementAST { this.parser, ); } + getElseToken(): Token | undefined { + return Token.from(cxx.getASTSlot(this.getHandle(), 7), this.parser); + } getElseStatement(): StatementAST | undefined { return AST.from( - cxx.getASTSlot(this.getHandle(), 7), + cxx.getASTSlot(this.getHandle(), 8), this.parser, ); } diff --git a/src/parser/cxx/ast.cc b/src/parser/cxx/ast.cc index 93645dcf..d8231b02 100644 --- a/src/parser/cxx/ast.cc +++ b/src/parser/cxx/ast.cc @@ -1592,12 +1592,14 @@ auto IfStatementAST::firstSourceLocation() -> SourceLocation { if (auto loc = cxx::firstSourceLocation(condition)) return loc; if (auto loc = cxx::firstSourceLocation(rparenLoc)) return loc; if (auto loc = cxx::firstSourceLocation(statement)) return loc; + if (auto loc = cxx::firstSourceLocation(elseLoc)) return loc; if (auto loc = cxx::firstSourceLocation(elseStatement)) return loc; return {}; } auto IfStatementAST::lastSourceLocation() -> SourceLocation { if (auto loc = cxx::lastSourceLocation(elseStatement)) return loc; + if (auto loc = cxx::lastSourceLocation(elseLoc)) return loc; if (auto loc = cxx::lastSourceLocation(statement)) return loc; if (auto loc = cxx::lastSourceLocation(rparenLoc)) return loc; if (auto loc = cxx::lastSourceLocation(condition)) return loc; diff --git a/src/parser/cxx/ast.fbs b/src/parser/cxx/ast.fbs index b451f959..51e71149 100644 --- a/src/parser/cxx/ast.fbs +++ b/src/parser/cxx/ast.fbs @@ -1529,6 +1529,7 @@ table IfStatement /* StatementAST */ { constexpr_loc: SourceLocation; lparen_loc: SourceLocation; rparen_loc: SourceLocation; + else_loc: SourceLocation; } table SwitchStatement /* StatementAST */ { diff --git a/src/parser/cxx/ast.h b/src/parser/cxx/ast.h index 4b99588d..52c46387 100644 --- a/src/parser/cxx/ast.h +++ b/src/parser/cxx/ast.h @@ -1802,6 +1802,7 @@ class IfStatementAST final : public StatementAST { ExpressionAST* condition = nullptr; SourceLocation rparenLoc; StatementAST* statement = nullptr; + SourceLocation elseLoc; StatementAST* elseStatement = nullptr; void accept(ASTVisitor* visitor) override { visitor->visit(this); } diff --git a/src/parser/cxx/ast_cloner.cc b/src/parser/cxx/ast_cloner.cc index 49c01482..70d27fbc 100644 --- a/src/parser/cxx/ast_cloner.cc +++ b/src/parser/cxx/ast_cloner.cc @@ -2018,6 +2018,8 @@ void ASTCloner::visit(IfStatementAST* ast) { copy->statement = accept(ast->statement); + copy->elseLoc = ast->elseLoc; + copy->elseStatement = accept(ast->elseStatement); } diff --git a/src/parser/cxx/ast_encoder.cc b/src/parser/cxx/ast_encoder.cc index 23c857e5..ec67a849 100644 --- a/src/parser/cxx/ast_encoder.cc +++ b/src/parser/cxx/ast_encoder.cc @@ -2873,6 +2873,8 @@ void ASTEncoder::visit(IfStatementAST* ast) { const auto [statement, statementType] = acceptStatement(ast->statement); + auto elseLoc = encodeSourceLocation(ast->elseLoc); + const auto [elseStatement, elseStatementType] = acceptStatement(ast->elseStatement); @@ -2887,6 +2889,7 @@ void ASTEncoder::visit(IfStatementAST* ast) { builder.add_rparen_loc(rparenLoc.o); builder.add_statement(statement); builder.add_statement_type(static_cast(statementType)); + builder.add_else_loc(elseLoc.o); builder.add_else_statement(elseStatement); builder.add_else_statement_type( static_cast(elseStatementType)); diff --git a/src/parser/cxx/ast_slot.cc b/src/parser/cxx/ast_slot.cc index 96a75f5a..91e476ad 100644 --- a/src/parser/cxx/ast_slot.cc +++ b/src/parser/cxx/ast_slot.cc @@ -2301,13 +2301,17 @@ void ASTSlot::visit(IfStatementAST* ast) { value_ = reinterpret_cast(ast->statement); slotKind_ = ASTSlotKind::kNode; break; - case 7: // elseStatement + case 7: // elseLoc + value_ = ast->elseLoc.index(); + slotKind_ = ASTSlotKind::kToken; + break; + case 8: // elseStatement value_ = reinterpret_cast(ast->elseStatement); slotKind_ = ASTSlotKind::kNode; break; } // switch - slotCount_ = 8; + slotCount_ = 9; } void ASTSlot::visit(SwitchStatementAST* ast) { diff --git a/src/parser/cxx/parser.cc b/src/parser/cxx/parser.cc index 368a34eb..cd6bafcd 100644 --- a/src/parser/cxx/parser.cc +++ b/src/parser/cxx/parser.cc @@ -3074,9 +3074,7 @@ auto Parser::parse_if_statement(StatementAST*& yyast) -> bool { parse_statement(ast->statement); - SourceLocation elseLoc; - - if (!match(TokenKind::T_ELSE, elseLoc)) return true; + if (!match(TokenKind::T_ELSE, ast->elseLoc)) return true; parse_statement(ast->elseStatement); @@ -5662,8 +5660,6 @@ auto Parser::parse_enum_specifier(SpecifierAST*& yyast) -> bool { if (!match(TokenKind::T_LBRACE, lbraceLoc)) return false; - const Name* enumName = name ? name->name : nullptr; - auto ast = new (pool) EnumSpecifierAST(); yyast = ast;