diff --git a/src/check_stmt.cpp b/src/check_stmt.cpp index d88a9e810..b5c88ab14 100644 --- a/src/check_stmt.cpp +++ b/src/check_stmt.cpp @@ -1620,8 +1620,9 @@ void check_stmt_internal(CheckerContext *ctx, AstNode *node, u32 flags) { check_decl_attributes(&c, fb->attributes, foreign_block_decl_attribute, nullptr); - for_array(i, fb->decls) { - AstNode *decl = fb->decls[i]; + ast_node(block, BlockStmt, fb->body); + for_array(i, block->stmts) { + AstNode *decl = block->stmts[i]; if (decl->kind == AstNode_ValueDecl && decl->ValueDecl.is_mutable) { check_stmt(&c, decl, flags); } diff --git a/src/checker.cpp b/src/checker.cpp index 97f1e61e2..a59592e46 100644 --- a/src/checker.cpp +++ b/src/checker.cpp @@ -2002,10 +2002,10 @@ void check_builtin_attributes(CheckerContext *ctx, Entity *e, Array * } void check_collect_value_decl(CheckerContext *c, AstNode *decl) { - ast_node(vd, ValueDecl, decl); + if (decl->been_handled) return; + decl->been_handled = true; - if (vd->been_handled) return; - vd->been_handled = true; + ast_node(vd, ValueDecl, decl); if (vd->is_mutable) { if (!c->scope->is_file) { @@ -2169,11 +2169,10 @@ void check_collect_value_decl(CheckerContext *c, AstNode *decl) { } void check_add_foreign_block_decl(CheckerContext *ctx, AstNode *decl) { + if (decl->been_handled) return; + decl->been_handled = true; + ast_node(fb, ForeignBlockDecl, decl); - - if (fb->been_handled) return; - fb->been_handled = true; - AstNode *foreign_library = fb->foreign_library; CheckerContext c = *ctx; @@ -2189,7 +2188,8 @@ void check_add_foreign_block_decl(CheckerContext *ctx, AstNode *decl) { check_decl_attributes(&c, fb->attributes, foreign_block_decl_attribute, nullptr); c.collect_delayed_decls = true; - check_collect_entities(&c, fb->decls); + ast_node(block, BlockStmt, fb->body); + check_collect_entities(&c, block->stmts); } // NOTE(bill): If file_scopes == nullptr, this will act like a local scope @@ -2537,9 +2537,11 @@ Array find_import_path(Checker *c, AstPackage *start, AstPackage return empty_path; } #endif -void check_add_import_decl(CheckerContext *ctx, AstNodeImportDecl *id) { - if (id->been_handled) return; - id->been_handled = true; +void check_add_import_decl(CheckerContext *ctx, AstNode *decl) { + if (decl->been_handled) return; + decl->been_handled = true; + + ast_node(id, ImportDecl, decl); Scope *parent_scope = ctx->scope; GB_ASSERT(parent_scope->is_file); @@ -2623,10 +2625,10 @@ void check_add_import_decl(CheckerContext *ctx, AstNodeImportDecl *id) { void check_add_foreign_import_decl(CheckerContext *ctx, AstNode *decl) { - ast_node(fl, ForeignImportDecl, decl); + if (decl->been_handled) return; + decl->been_handled = true; - if (fl->been_handled) return; - fl->been_handled = true; + ast_node(fl, ForeignImportDecl, decl); Scope *parent_scope = ctx->scope; GB_ASSERT(parent_scope->is_file); @@ -2778,7 +2780,7 @@ bool collect_file_decls(CheckerContext *ctx, Array const &decls) { case_end; case_ast_node(id, ImportDecl, decl); - check_add_import_decl(ctx, id); + check_add_import_decl(ctx, decl); case_end; case_ast_node(fl, ForeignImportDecl, decl); @@ -2974,8 +2976,7 @@ void check_import_entities(Checker *c) { add_curr_ast_file(&ctx, f); for_array(j, f->scope->delayed_imports) { AstNode *decl = f->scope->delayed_imports[j]; - ast_node(id, ImportDecl, decl); - check_add_import_decl(&ctx, id); + check_add_import_decl(&ctx, decl); } for_array(j, f->scope->delayed_directives) { AstNode *expr = f->scope->delayed_directives[j]; diff --git a/src/checker.hpp b/src/checker.hpp index d80e012d5..4ead1c6cc 100644 --- a/src/checker.hpp +++ b/src/checker.hpp @@ -408,8 +408,7 @@ void add_implicit_entity (CheckerContext *c, AstNode *node, Entity *e); void add_entity_and_decl_info(CheckerContext *c, AstNode *identifier, Entity *e, DeclInfo *d); void add_type_info_type (CheckerContext *c, Type *t); -void check_add_import_decl(CheckerContext *c, AstNodeImportDecl *id); -// void check_add_export_decl(Checker *c, AstNodeExportDecl *ed); +void check_add_import_decl(CheckerContext *c, AstNode *decl); void check_add_foreign_import_decl(CheckerContext *c, AstNode *decl); diff --git a/src/ir.cpp b/src/ir.cpp index 359fcc144..8eed0dc02 100644 --- a/src/ir.cpp +++ b/src/ir.cpp @@ -6285,7 +6285,8 @@ void ir_build_stmt_list(irProcedure *proc, Array stmts) { ir_build_constant_value_decl(proc, vd); case_end; case_ast_node(fb, ForeignBlockDecl, stmt); - ir_build_stmt_list(proc, fb->decls); + ast_node(block, BlockStmt, fb->body); + ir_build_stmt_list(proc, block->stmts); case_end; } } diff --git a/src/parser.cpp b/src/parser.cpp index 58e5647a7..cc6bead02 100644 --- a/src/parser.cpp +++ b/src/parser.cpp @@ -283,7 +283,7 @@ AstNode *clone_ast_node(gbAllocator a, AstNode *node) { case AstNode_ForeignBlockDecl: n->ForeignBlockDecl.foreign_library = clone_ast_node(a, n->ForeignBlockDecl.foreign_library); - n->ForeignBlockDecl.decls = clone_ast_node_array(a, n->ForeignBlockDecl.decls); + n->ForeignBlockDecl.body = clone_ast_node(a, n->ForeignBlockDecl.body); n->ForeignBlockDecl.attributes = clone_ast_node_array(a, n->ForeignBlockDecl.attributes); break; case AstNode_Label: @@ -946,14 +946,12 @@ AstNode *ast_map_type(AstFile *f, Token token, AstNode *key, AstNode *value) { } -AstNode *ast_foreign_block_decl(AstFile *f, Token token, AstNode *foreign_library, Token open, Token close, Array decls, +AstNode *ast_foreign_block_decl(AstFile *f, Token token, AstNode *foreign_library, AstNode *body, CommentGroup *docs) { AstNode *result = alloc_ast_node(f, AstNode_ForeignBlockDecl); result->ForeignBlockDecl.token = token; result->ForeignBlockDecl.foreign_library = foreign_library; - result->ForeignBlockDecl.open = open; - result->ForeignBlockDecl.close = close; - result->ForeignBlockDecl.decls = decls; + result->ForeignBlockDecl.body = body; result->ForeignBlockDecl.docs = docs; result->ForeignBlockDecl.attributes.allocator = heap_allocator(); @@ -1261,6 +1259,7 @@ bool is_semicolon_optional_for_node(AstFile *f, AstNode *s) { switch (s->kind) { case AstNode_EmptyStmt: + case AstNode_BlockStmt: return true; case AstNode_IfStmt: @@ -1303,13 +1302,7 @@ bool is_semicolon_optional_for_node(AstFile *f, AstNode *s) { break; case AstNode_ForeignBlockDecl: - if (s->ForeignBlockDecl.close.pos.line != 0) { - return true; - } - if (s->ForeignBlockDecl.decls.count == 1) { - return is_semicolon_optional_for_node(f, s->ForeignBlockDecl.decls[0]); - } - break; + return is_semicolon_optional_for_node(f, s->ForeignBlockDecl.body); } return false; @@ -2401,7 +2394,9 @@ AstNode *parse_foreign_block(AstFile *f, Token token) { close = expect_token(f, Token_CloseBrace); - AstNode *decl = ast_foreign_block_decl(f, token, foreign_library, open, close, decls, docs); + AstNode *body = ast_block_stmt(f, decls, open, close); + + AstNode *decl = ast_foreign_block_decl(f, token, foreign_library, body, docs); expect_semicolon(f, decl); return decl; } diff --git a/src/parser.hpp b/src/parser.hpp index e6255fc0e..4b56154ef 100644 --- a/src/parser.hpp +++ b/src/parser.hpp @@ -334,11 +334,9 @@ AST_NODE_KIND(_DeclBegin, "", struct {}) \ AST_NODE_KIND(ForeignBlockDecl, "foreign block declaration", struct { \ Token token; \ AstNode * foreign_library; \ - Token open, close; \ - Array decls; \ + AstNode * body; \ Array attributes; \ CommentGroup * docs; \ - bool been_handled; \ }) \ AST_NODE_KIND(Label, "label", struct { \ Token token; \ @@ -353,7 +351,6 @@ AST_NODE_KIND(_DeclBegin, "", struct {}) \ CommentGroup * comment; \ bool is_using; \ bool is_mutable; \ - bool been_handled; \ }) \ AST_NODE_KIND(PackageDecl, "package declaration", struct { \ Token token; \ @@ -370,7 +367,6 @@ AST_NODE_KIND(_DeclBegin, "", struct {}) \ CommentGroup *docs; \ CommentGroup *comment; \ bool is_using; \ - bool been_handled; \ }) \ AST_NODE_KIND(ForeignImportDecl, "foreign import declaration", struct { \ Token token; \ @@ -380,7 +376,6 @@ AST_NODE_KIND(_DeclBegin, "", struct {}) \ String fullpath; \ CommentGroup *docs; \ CommentGroup *comment; \ - bool been_handled; \ }) \ AST_NODE_KIND(_DeclEnd, "", struct {}) \ AST_NODE_KIND(Attribute, "attribute", struct { \ @@ -510,6 +505,7 @@ struct AstNode { u32 stmt_state_flags; AstFile * file; Scope * scope; + bool been_handled; union { #define AST_NODE_KIND(_kind_name_, name, ...) GB_JOIN2(AstNode, _kind_name_) _kind_name_;