diff options
| author | gingerBill <bill@gingerbill.org> | 2021-07-13 17:28:39 +0100 |
|---|---|---|
| committer | gingerBill <bill@gingerbill.org> | 2021-07-13 17:28:39 +0100 |
| commit | bd954d9990460912246245d77aa47584e4912659 (patch) | |
| tree | 38f7a121ce934de3ec576216138db19c4bc94200 /src/checker.cpp | |
| parent | 4ded42a33b2427e2d8b850422f4e1c1798ce4df1 (diff) | |
Minor code reorganization
Diffstat (limited to 'src/checker.cpp')
| -rw-r--r-- | src/checker.cpp | 333 |
1 files changed, 168 insertions, 165 deletions
diff --git a/src/checker.cpp b/src/checker.cpp index aa2aa2494..5f6e03a4f 100644 --- a/src/checker.cpp +++ b/src/checker.cpp @@ -4562,145 +4562,7 @@ void add_untyped_expressions(CheckerInfo *cinfo, UntypedExprInfoMap *untyped) { map_clear(untyped); } - -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->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->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) { - c->info.init_package = p; - c->info.init_scope = scope; - } - if (p->kind == Package_Runtime) { - GB_ASSERT(c->info.runtime_package == nullptr); - c->info.runtime_package = p; - } - } - - 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 = &collect_entity_ctx; - - for_array(j, pkg->files) { - AstFile *f = pkg->files[j]; - string_map_set(&c->info.files, f->fullpath, f); - - create_scope_from_file(nullptr, f); - reset_checker_context(ctx, f); - check_collect_entities(ctx, f->decls); - } - - pkg->used = true; - } - - TIME_SECTION("import entities"); - check_import_entities(c); - - TIME_SECTION("check all global entities"); - check_all_global_entities(c); - - TIME_SECTION("init preload"); - init_preload(c); - - TIME_SECTION("add global untyped expression to queue"); - add_untyped_expressions(&c->info, &c->info.global_untyped); - - 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"); - check_procedure_bodies(c); - - TIME_SECTION("check scope usage"); - for_array(i, c->info.files.entries) { - AstFile *f = c->info.files.entries[i].value; - check_scope_usage(c, f->scope); - } - - TIME_SECTION("generate minimum dependency set"); - generate_minimum_dependency_set(c, c->info.entry_point); - - TIME_SECTION("check test names"); - check_test_names(c); - - TIME_SECTION("calculate global init order"); - // Calculate initialization order of global variables - calculate_global_init_order(c); - - TIME_SECTION("check bodies have all been checked"); - check_unchecked_bodies(c); - - TIME_SECTION("add untyped expression values"); - // Add untyped expression values - for (UntypedExprInfo u = {}; mpmc_dequeue(&c->info.untyped_queue, &u); /**/) { - GB_ASSERT(u.expr != nullptr && u.info != nullptr); - if (is_type_typed(u.info->type)) { - compiler_error("%s (type %s) is typed!", expr_to_string(u.expr), type_to_string(u.info->type)); - } - add_type_and_value(&c->info, u.expr, u.info->mode, u.info->type, u.info->value); - } - - // TODO(bill): Check for unused imports (and remove) or even warn/err - // TODO(bill): Any other checks? - - - TIME_SECTION("add type information"); - // Add "Basic" type information - for (isize i = 0; i < Basic_COUNT; i++) { - Type *t = &basic_types[i]; - if (t->Basic.size > 0 && - (t->Basic.flags & BasicFlag_LLVM) == 0) { - add_type_info_type(&c->builtin_ctx, t); - } - } - - TIME_SECTION("check for type cycles and inline cycles"); - // NOTE(bill): Check for illegal cyclic type declarations - for_array(i, c->info.definitions) { - Entity *e = c->info.definitions[i]; - if (e->kind == Entity_TypeName && e->type != nullptr) { - (void)type_align_of(e->type); - } else if (e->kind == Entity_Procedure) { - DeclInfo *decl = e->decl_info; - ast_node(pl, ProcLit, decl->proc_lit); - if (pl->inlining == ProcInlining_inline) { - for_array(j, decl->deps.entries) { - Entity *dep = decl->deps.entries[j].ptr; - if (dep == e) { - error(e->token, "Cannot inline recursive procedure '%.*s'", LIT(e->token.string)); - break; - } - } - } - } - } - TIME_SECTION("add type info for type definitions"); - for_array(i, c->info.definitions) { - Entity *e = c->info.definitions[i]; - if (e->kind == Entity_TypeName && e->type != nullptr) { - i64 align = type_align_of(e->type); - if (align > 0 && ptr_set_exists(&c->info.minimum_dependency_set, e)) { - add_type_info_type(&c->builtin_ctx, e->type); - } - } - } - - TIME_SECTION("check deferred procedures"); +void check_deferred_procedures(Checker *c) { for (Entity *src = nullptr; mpmc_dequeue(&c->procs_with_deferred_to_check, &src); /**/) { GB_ASSERT(src->kind == Entity_Procedure); @@ -4851,6 +4713,172 @@ void check_parsed_files(Checker *c) { } } +} + +void check_unique_package_names(Checker *c) { + StringMap<AstPackage *> pkgs = {}; // Key: package name + string_map_init(&pkgs, heap_allocator(), 2*c->info.packages.entries.count); + defer (string_map_destroy(&pkgs)); + + for_array(i, c->info.packages.entries) { + AstPackage *pkg = c->info.packages.entries[i].value; + if (pkg->files.count == 0) { + continue; // Sanity check + } + + String name = pkg->name; + auto key = string_hash_string(name); + auto *found = string_map_get(&pkgs, key); + if (found == nullptr) { + string_map_set(&pkgs, key, pkg); + continue; + } + + error(pkg->files[0]->pkg_decl, "Duplicate declaration of 'package %.*s'", LIT(name)); + error_line("\tA package name must be unique\n" + "\tThere is no relation between a package name and the directory that contains it, so they can be completely different\n" + "\tA package name is required for link name prefixing to have a consistent ABI\n"); + error((*found)->files[0]->pkg_decl, "found at previous location"); + } +} + + +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->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->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) { + c->info.init_package = p; + c->info.init_scope = scope; + } + if (p->kind == Package_Runtime) { + GB_ASSERT(c->info.runtime_package == nullptr); + c->info.runtime_package = p; + } + } + + 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 = &collect_entity_ctx; + + for_array(j, pkg->files) { + AstFile *f = pkg->files[j]; + string_map_set(&c->info.files, f->fullpath, f); + + create_scope_from_file(nullptr, f); + reset_checker_context(ctx, f); + check_collect_entities(ctx, f->decls); + } + + pkg->used = true; + } + + TIME_SECTION("import entities"); + check_import_entities(c); + + TIME_SECTION("check all global entities"); + check_all_global_entities(c); + + TIME_SECTION("init preload"); + init_preload(c); + + TIME_SECTION("add global untyped expression to queue"); + add_untyped_expressions(&c->info, &c->info.global_untyped); + + 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"); + check_procedure_bodies(c); + + TIME_SECTION("check scope usage"); + for_array(i, c->info.files.entries) { + AstFile *f = c->info.files.entries[i].value; + check_scope_usage(c, f->scope); + } + + TIME_SECTION("generate minimum dependency set"); + generate_minimum_dependency_set(c, c->info.entry_point); + + TIME_SECTION("check test names"); + check_test_names(c); + + TIME_SECTION("calculate global init order"); + // Calculate initialization order of global variables + calculate_global_init_order(c); + + TIME_SECTION("check bodies have all been checked"); + check_unchecked_bodies(c); + + TIME_SECTION("add untyped expression values"); + // Add untyped expression values + for (UntypedExprInfo u = {}; mpmc_dequeue(&c->info.untyped_queue, &u); /**/) { + GB_ASSERT(u.expr != nullptr && u.info != nullptr); + if (is_type_typed(u.info->type)) { + compiler_error("%s (type %s) is typed!", expr_to_string(u.expr), type_to_string(u.info->type)); + } + add_type_and_value(&c->info, u.expr, u.info->mode, u.info->type, u.info->value); + } + + + TIME_SECTION("add type information"); + // Add "Basic" type information + for (isize i = 0; i < Basic_COUNT; i++) { + Type *t = &basic_types[i]; + if (t->Basic.size > 0 && + (t->Basic.flags & BasicFlag_LLVM) == 0) { + add_type_info_type(&c->builtin_ctx, t); + } + } + + TIME_SECTION("check for type cycles and inline cycles"); + // NOTE(bill): Check for illegal cyclic type declarations + for_array(i, c->info.definitions) { + Entity *e = c->info.definitions[i]; + if (e->kind == Entity_TypeName && e->type != nullptr) { + (void)type_align_of(e->type); + } else if (e->kind == Entity_Procedure) { + DeclInfo *decl = e->decl_info; + ast_node(pl, ProcLit, decl->proc_lit); + if (pl->inlining == ProcInlining_inline) { + for_array(j, decl->deps.entries) { + Entity *dep = decl->deps.entries[j].ptr; + if (dep == e) { + error(e->token, "Cannot inline recursive procedure '%.*s'", LIT(e->token.string)); + break; + } + } + } + } + } + TIME_SECTION("add type info for type definitions"); + for_array(i, c->info.definitions) { + Entity *e = c->info.definitions[i]; + if (e->kind == Entity_TypeName && e->type != nullptr) { + i64 align = type_align_of(e->type); + if (align > 0 && ptr_set_exists(&c->info.minimum_dependency_set, e)) { + add_type_info_type(&c->builtin_ctx, e->type); + } + } + } + + TIME_SECTION("check deferred procedures"); + check_deferred_procedures(c); TIME_SECTION("check entry point"); if (build_context.build_mode == BuildMode_Executable && !build_context.no_entry_point && build_context.command_kind != Command_test) { @@ -4875,32 +4903,7 @@ void check_parsed_files(Checker *c) { } TIME_SECTION("check unique package names"); - { - StringMap<AstPackage *> pkgs = {}; // Key: package name - string_map_init(&pkgs, heap_allocator(), 2*c->info.packages.entries.count); - defer (string_map_destroy(&pkgs)); - - for_array(i, c->info.packages.entries) { - AstPackage *pkg = c->info.packages.entries[i].value; - if (pkg->files.count == 0) { - continue; // Sanity check - } - - String name = pkg->name; - auto key = string_hash_string(name); - auto *found = string_map_get(&pkgs, key); - if (found == nullptr) { - string_map_set(&pkgs, key, pkg); - continue; - } - - error(pkg->files[0]->pkg_decl, "Duplicate declaration of 'package %.*s'", LIT(name)); - error_line("\tA package name must be unique\n" - "\tThere is no relation between a package name and the directory that contains it, so they can be completely different\n" - "\tA package name is required for link name prefixing to have a consistent ABI\n"); - error((*found)->files[0]->pkg_decl, "found at previous location"); - } - } + check_unique_package_names(c); TIME_SECTION("type check finish"); |