From 4a932616fc6d8d5c4cad98debf292a1916e5a2be Mon Sep 17 00:00:00 2001 From: gingerBill Date: Sat, 10 Jul 2021 13:02:13 +0100 Subject: Improve CheckerContext usage --- src/checker.cpp | 140 ++++++++++++++++++++++++++++++++------------------------ 1 file changed, 79 insertions(+), 61 deletions(-) (limited to 'src/checker.cpp') diff --git a/src/checker.cpp b/src/checker.cpp index 34a8680ac..7ca56cccc 100644 --- a/src/checker.cpp +++ b/src/checker.cpp @@ -242,7 +242,7 @@ Scope *create_scope(Scope *parent, isize init_elements_capacity=DEFAULT_SCOPE_CA return s; } -Scope *create_scope_from_file(CheckerContext *c, AstFile *f) { +Scope *create_scope_from_file(AstFile *f) { GB_ASSERT(f != nullptr); GB_ASSERT(f->pkg != nullptr); GB_ASSERT(f->pkg->scope != nullptr); @@ -870,7 +870,7 @@ void destroy_checker_info(CheckerInfo *i) { } CheckerContext make_checker_context(Checker *c) { - CheckerContext ctx = c->init_ctx; + CheckerContext ctx = {}; ctx.checker = c; ctx.info = &c->info; ctx.scope = builtin_pkg->scope; @@ -883,6 +883,40 @@ CheckerContext make_checker_context(Checker *c) { return ctx; } +void add_curr_ast_file(CheckerContext *ctx, AstFile *file) { + if (file != nullptr) { + TokenPos zero_pos = {}; + global_error_collector.prev = zero_pos; + ctx->file = file; + ctx->decl = file->pkg->decl_info; + ctx->scope = file->scope; + ctx->pkg = file->pkg; + } +} +void reset_checker_context(CheckerContext *ctx, AstFile *file) { + if (ctx == nullptr) { + return; + } + auto checker = ctx->checker; + auto info = ctx->info; + auto type_path = ctx->type_path; + auto poly_path = ctx->poly_path; + array_clear(type_path); + array_clear(poly_path); + + gb_zero_item(ctx); + ctx->checker = checker; + ctx->info = info; + ctx->type_path = type_path; + ctx->poly_path = poly_path; + ctx->scope = builtin_pkg->scope; + ctx->pkg = builtin_pkg; + + add_curr_ast_file(ctx, file); +} + + + void destroy_checker_context(CheckerContext *ctx) { destroy_checker_type_path(ctx->type_path); destroy_checker_poly_path(ctx->poly_path); @@ -907,7 +941,7 @@ bool init_checker(Checker *c, Parser *parser) { isize total_token_count = c->parser->total_token_count; isize arena_size = 2 * item_size * total_token_count; - c->init_ctx = make_checker_context(c); + c->builtin_ctx = make_checker_context(c); return true; } @@ -917,7 +951,7 @@ void destroy_checker(Checker *c) { array_free(&c->procs_to_check); array_free(&c->procs_with_deferred_to_check); - destroy_checker_context(&c->init_ctx); + destroy_checker_context(&c->builtin_ctx); } @@ -994,10 +1028,11 @@ Scope *scope_of_node(Ast *node) { return node->scope; } ExprInfo *check_get_expr_info(CheckerInfo *i, Ast *expr) { - return map_get(&i->untyped, hash_node(expr)); -} -void check_set_expr_info(CheckerInfo *i, Ast *expr, ExprInfo info) { - map_set(&i->untyped, hash_node(expr), info); + ExprInfo **found = map_get(&i->untyped, hash_node(expr)); + if (found) { + return *found; + } + return nullptr; } void check_remove_expr_info(CheckerInfo *i, Ast *expr) { map_remove(&i->untyped, hash_node(expr)); @@ -1143,7 +1178,7 @@ bool redeclaration_error(String name, Entity *prev, Entity *found) { return false; } -bool add_entity_with_name(Checker *c, Scope *scope, Ast *identifier, Entity *entity, String name) { +bool add_entity_with_name(CheckerContext *c, Scope *scope, Ast *identifier, Entity *entity, String name) { if (scope == nullptr) { return false; } @@ -1155,14 +1190,13 @@ bool add_entity_with_name(Checker *c, Scope *scope, Ast *identifier, Entity *ent } if (identifier != nullptr) { if (entity->file == nullptr) { - GB_ASSERT(c->curr_ctx != nullptr); - entity->file = c->curr_ctx->file; + entity->file = c->file; } - add_entity_definition(&c->info, identifier, entity); + add_entity_definition(c->info, identifier, entity); } return true; } -bool add_entity(Checker *c, Scope *scope, Ast *identifier, Entity *entity) { +bool add_entity(CheckerContext *c, Scope *scope, Ast *identifier, Entity *entity) { return add_entity_with_name(c, scope, identifier, entity, entity->token.string); } @@ -1213,7 +1247,7 @@ void add_entity_and_decl_info(CheckerContext *c, Ast *identifier, Entity *e, Dec scope = pkg->scope; } } - add_entity(c->checker, scope, identifier, e); + add_entity(c, scope, identifier, e); } add_entity_definition(&c->checker->info, identifier, e); @@ -1460,17 +1494,6 @@ void check_procedure_later(Checker *c, AstFile *file, Token token, DeclInfo *dec check_procedure_later(c, info); } -void add_curr_ast_file(CheckerContext *ctx, AstFile *file) { - if (file != nullptr) { - TokenPos zero_pos = {}; - global_error_collector.prev = zero_pos; - ctx->file = file; - ctx->decl = file->pkg->decl_info; - ctx->scope = file->scope; - ctx->pkg = file->pkg; - ctx->checker->curr_ctx = ctx; - } -} void add_min_dep_type_info(Checker *c, Type *t) { if (t == nullptr) { @@ -1488,7 +1511,7 @@ void add_min_dep_type_info(Checker *c, Type *t) { isize ti_index = type_info_index(&c->info, t, false); if (ti_index < 0) { - add_type_info_type(&c->init_ctx, t); // Missing the type information + add_type_info_type(&c->builtin_ctx, t); // Missing the type information ti_index = type_info_index(&c->info, t, false); } GB_ASSERT(ti_index >= 0); @@ -2282,8 +2305,7 @@ void init_core_map_type(Checker *c) { if (t_map_hash == nullptr) { Entity *e = find_core_entity(c, str_lit("Map_Hash")); if (e->state == EntityState_Unresolved) { - auto ctx = c->init_ctx; - check_entity_decl(&ctx, e, nullptr, nullptr); + check_entity_decl(&c->builtin_ctx, e, nullptr, nullptr); } t_map_hash = e->type; GB_ASSERT(t_map_hash != nullptr); @@ -2292,8 +2314,7 @@ void init_core_map_type(Checker *c) { if (t_map_header == nullptr) { Entity *e = find_core_entity(c, str_lit("Map_Header")); if (e->state == EntityState_Unresolved) { - auto ctx = c->init_ctx; - check_entity_decl(&ctx, e, nullptr, nullptr); + check_entity_decl(&c->builtin_ctx, e, nullptr, nullptr); } t_map_header = e->type; GB_ASSERT(t_map_header != nullptr); @@ -2887,7 +2908,7 @@ void check_builtin_attributes(CheckerContext *ctx, Entity *e, Array *attr } if (name == "builtin") { - add_entity(ctx->checker, builtin_pkg->scope, nullptr, e); + add_entity(ctx, builtin_pkg->scope, nullptr, e); GB_ASSERT(scope_lookup(builtin_pkg->scope, e->token.string) != nullptr); if (value != nullptr) { error(value, "'builtin' cannot have a field value"); @@ -3236,8 +3257,8 @@ void check_collect_entities(CheckerContext *c, Slice const &nodes) { } CheckerContext *create_checker_context(Checker *c) { - CheckerContext *ctx = gb_alloc_item(heap_allocator(), CheckerContext); - *ctx = c->init_ctx; + CheckerContext *ctx = gb_alloc_item(permanent_allocator(), CheckerContext); + *ctx = make_checker_context(c); return ctx; } @@ -3611,7 +3632,7 @@ void check_add_import_decl(CheckerContext *ctx, Ast *decl) { id->fullpath, id->import_name.string, scope); - add_entity(ctx->checker, parent_scope, nullptr, e); + add_entity(ctx, parent_scope, nullptr, e); if (force_use || id->is_using) { add_entity_use(ctx, nullptr, e); } @@ -3638,7 +3659,7 @@ void check_add_import_decl(CheckerContext *ctx, Ast *decl) { // file scope otherwise the error would be the wrong way around redeclaration_error(name, found, e); } else { - add_entity_with_name(ctx->checker, parent_scope, e->identifier, e, name); + add_entity_with_name(ctx, parent_scope, e->identifier, e, name); } } } @@ -3700,7 +3721,7 @@ void check_add_foreign_import_decl(CheckerContext *ctx, Ast *decl) { Entity *e = alloc_entity_library_name(parent_scope, fl->library_name, t_invalid, fl->fullpaths, library_name); - add_entity(ctx->checker, parent_scope, nullptr, e); + add_entity(ctx, parent_scope, nullptr, e); AttributeContext ac = {}; @@ -3958,6 +3979,8 @@ void check_import_entities(Checker *c) { } } + CheckerContext ctx = make_checker_context(c); + for (isize loop_count = 0; ; loop_count++) { bool new_files = false; for_array(i, package_order) { @@ -3970,8 +3993,7 @@ void check_import_entities(Checker *c) { for_array(i, pkg->files) { AstFile *f = pkg->files[i]; - CheckerContext ctx = c->init_ctx; - add_curr_ast_file(&ctx, f); + reset_checker_context(&ctx, f); new_files |= collect_checked_packages_from_decl_list(c, f->decls); } } @@ -3994,9 +4016,8 @@ void check_import_entities(Checker *c) { for_array(i, pkg->files) { AstFile *f = pkg->files[i]; - CheckerContext ctx = c->init_ctx; + reset_checker_context(&ctx, f); ctx.collect_delayed_decls = true; - add_curr_ast_file(&ctx, f); if (collect_file_decls(&ctx, f->decls)) { new_packages = true; @@ -4017,8 +4038,7 @@ void check_import_entities(Checker *c) { for_array(i, pkg->files) { AstFile *f = pkg->files[i]; - CheckerContext ctx = c->init_ctx; - add_curr_ast_file(&ctx, f); + reset_checker_context(&ctx, f); for_array(j, f->scope->delayed_imports) { Ast *decl = f->scope->delayed_imports[j]; @@ -4027,8 +4047,7 @@ void check_import_entities(Checker *c) { } for_array(i, pkg->files) { AstFile *f = pkg->files[i]; - CheckerContext ctx = c->init_ctx; - add_curr_ast_file(&ctx, f); + reset_checker_context(&ctx, f); for_array(j, f->scope->delayed_directives) { Ast *expr = f->scope->delayed_directives[j]; @@ -4214,7 +4233,7 @@ void check_proc_info(Checker *c, ProcInfo pi) { CheckerContext ctx = make_checker_context(c); defer (destroy_checker_context(&ctx)); - add_curr_ast_file(&ctx, pi.file); + reset_checker_context(&ctx, pi.file); ctx.decl = pi.decl; TypeProc *pt = &pi.type->Proc; @@ -4332,13 +4351,13 @@ void check_parsed_files(Checker *c) { #define TIME_SECTION(str) do { if (build_context.show_more_timings) timings_start_section(&global_timings, str_lit(str)); } while (0) TIME_SECTION("map full filepaths to scope"); - add_type_info_type(&c->init_ctx, t_invalid); + add_type_info_type(&c->builtin_ctx, t_invalid); // Map full filepaths to Scopes for_array(i, c->parser->packages) { AstPackage *p = c->parser->packages[i]; - Scope *scope = create_scope_from_package(&c->init_ctx, p); - p->decl_info = make_decl_info(scope, c->init_ctx.decl); + Scope *scope = create_scope_from_package(&c->builtin_ctx, p); + p->decl_info = make_decl_info(scope, c->builtin_ctx.decl); string_map_set(&c->info.packages, p->fullpath, p); if (scope->flags&ScopeFlag_Init) { @@ -4353,21 +4372,20 @@ void check_parsed_files(Checker *c) { TIME_SECTION("collect entities"); // Collect Entities + CheckerContext collect_entity_ctx = make_checker_context(c); + defer (destroy_checker_context(&collect_entity_ctx)); for_array(i, c->parser->packages) { AstPackage *pkg = c->parser->packages[i]; - CheckerContext ctx = make_checker_context(c); - defer (destroy_checker_context(&ctx)); - ctx.pkg = pkg; - ctx.collect_delayed_decls = false; + CheckerContext *ctx = &collect_entity_ctx; for_array(j, pkg->files) { AstFile *f = pkg->files[j]; - create_scope_from_file(&ctx, f); string_map_set(&c->info.files, f->fullpath, f); - add_curr_ast_file(&ctx, f); - check_collect_entities(&ctx, f->decls); + create_scope_from_file(f); + reset_checker_context(ctx, f); + check_collect_entities(ctx, f->decls); } pkg->used = true; @@ -4382,9 +4400,9 @@ void check_parsed_files(Checker *c) { TIME_SECTION("init preload"); init_preload(c); - CheckerContext prev_context = c->init_ctx; - defer (c->init_ctx = prev_context); - c->init_ctx.decl = make_decl_info(nullptr, nullptr); + CheckerContext prev_context = c->builtin_ctx; + defer (c->builtin_ctx = prev_context); + c->builtin_ctx.decl = make_decl_info(nullptr, nullptr); TIME_SECTION("check procedure bodies"); // NOTE(bill): Nested procedures bodies will be added to this "queue" @@ -4418,7 +4436,7 @@ void check_parsed_files(Checker *c) { auto *entry = &c->info.untyped.entries[i]; HashKey key = entry->key; Ast *expr = cast(Ast *)cast(uintptr)key.key; - ExprInfo *info = &entry->value; + ExprInfo *info = entry->value; if (info != nullptr && expr != nullptr) { if (is_type_typed(info->type)) { compiler_error("%s (type %s) is typed!", expr_to_string(expr), type_to_string(info->type)); @@ -4444,7 +4462,7 @@ void check_parsed_files(Checker *c) { Type *t = &basic_types[i]; if (t->Basic.size > 0 && (t->Basic.flags & BasicFlag_LLVM) == 0) { - add_type_info_type(&c->init_ctx, t); + add_type_info_type(&c->builtin_ctx, t); } } @@ -4456,7 +4474,7 @@ void check_parsed_files(Checker *c) { // i64 size = type_size_of(c->allocator, e->type); i64 align = type_align_of(e->type); if (align > 0 && ptr_set_exists(&c->info.minimum_dependency_set, e)) { - add_type_info_type(&c->init_ctx, e->type); + add_type_info_type(&c->builtin_ctx, e->type); } } else if (e->kind == Entity_Procedure) { -- cgit v1.2.3