diff options
Diffstat (limited to 'src/checker.cpp')
| -rw-r--r-- | src/checker.cpp | 205 |
1 files changed, 173 insertions, 32 deletions
diff --git a/src/checker.cpp b/src/checker.cpp index da6fe5b9a..6d035760c 100644 --- a/src/checker.cpp +++ b/src/checker.cpp @@ -173,16 +173,17 @@ GB_COMPARE_PROC(ast_node_cmp) { -void init_declaration_info(DeclInfo *d, Scope *scope, DeclInfo *parent) { +void init_decl_info(DeclInfo *d, Scope *scope, DeclInfo *parent) { d->parent = parent; d->scope = scope; - ptr_set_init(&d->deps, heap_allocator()); - array_init (&d->labels, heap_allocator()); + ptr_set_init(&d->deps, heap_allocator()); + ptr_set_init(&d->type_info_deps, heap_allocator()); + array_init (&d->labels, heap_allocator()); } -DeclInfo *make_declaration_info(gbAllocator a, Scope *scope, DeclInfo *parent) { +DeclInfo *make_decl_info(gbAllocator a, Scope *scope, DeclInfo *parent) { DeclInfo *d = gb_alloc_item(a, DeclInfo); - init_declaration_info(d, scope, parent); + init_decl_info(d, scope, parent); return d; } @@ -483,12 +484,20 @@ void check_scope_usage(Checker *c, Scope *scope) { void add_dependency(DeclInfo *d, Entity *e) { ptr_set_add(&d->deps, e); } +void add_type_info_dependency(DeclInfo *d, Type *type) { + if (d == nullptr) { + GB_ASSERT(type == t_invalid); + return; + } + ptr_set_add(&d->type_info_deps, type); +} void add_preload_dependency(Checker *c, char *name) { String n = make_string_c(name); Entity *e = scope_lookup_entity(c->global_scope, n); GB_ASSERT(e != nullptr); ptr_set_add(&c->context.decl->deps, e); + // add_type_info_type(c, e->type); } void add_declaration_dependency(Checker *c, Entity *e) { @@ -959,8 +968,10 @@ void add_type_info_type(Checker *c, Type *t) { return; } - if (map_get(&c->info.type_info_map, hash_type(t)) != nullptr) { + auto found = map_get(&c->info.type_info_map, hash_type(t)); + if (found != nullptr) { // Types have already been added + add_type_info_dependency(c->context.decl, t); return; } @@ -986,6 +997,7 @@ void add_type_info_type(Checker *c, Type *t) { if (prev) { // NOTE(bill): If a previous one exists already, no need to continue + add_type_info_dependency(c->context.decl, t); return; } @@ -1133,43 +1145,175 @@ void add_curr_ast_file(Checker *c, AstFile *file) { } } +void add_min_dep_type_info(Checker *c, Type *t) { + if (t == nullptr) { + return; + } + t = default_type(t); + if (is_type_bit_field_value(t)) { + t = default_bit_field_value_type(t); + } + if (is_type_untyped(t)) { + return; // Could be nil + } + if (is_type_polymorphic(base_type(t))) { + return; + } + + auto *set = &c->info.minimum_dependency_type_info_set; + + isize ti_index = type_info_index(&c->info, t); + if (ptr_set_exists(set, ti_index)) { + // Type Already exists + return; + } + ptr_set_add(set, ti_index); -void add_dependency_to_map(PtrSet<Entity *> *map, CheckerInfo *info, Entity *entity) { + // Add nested types + if (t->kind == Type_Named) { + // NOTE(bill): Just in case + add_min_dep_type_info(c, t->Named.base); + return; + } + + Type *bt = base_type(t); + add_min_dep_type_info(c, bt); + + switch (bt->kind) { + case Type_Basic: + switch (bt->Basic.kind) { + case Basic_string: + add_min_dep_type_info(c, t_u8_ptr); + add_min_dep_type_info(c, t_int); + break; + case Basic_any: + add_min_dep_type_info(c, t_type_info_ptr); + add_min_dep_type_info(c, t_rawptr); + break; + + case Basic_complex64: + add_min_dep_type_info(c, t_type_info_float); + add_min_dep_type_info(c, t_f32); + break; + case Basic_complex128: + add_min_dep_type_info(c, t_type_info_float); + add_min_dep_type_info(c, t_f64); + break; + } + break; + + case Type_Pointer: + add_min_dep_type_info(c, bt->Pointer.elem); + break; + + case Type_Array: + add_min_dep_type_info(c, bt->Array.elem); + add_min_dep_type_info(c, alloc_type_pointer(bt->Array.elem)); + add_min_dep_type_info(c, t_int); + break; + case Type_DynamicArray: + add_min_dep_type_info(c, bt->DynamicArray.elem); + add_min_dep_type_info(c, alloc_type_pointer(bt->DynamicArray.elem)); + add_min_dep_type_info(c, t_int); + add_min_dep_type_info(c, t_allocator); + break; + case Type_Slice: + add_min_dep_type_info(c, bt->Slice.elem); + add_min_dep_type_info(c, alloc_type_pointer(bt->Slice.elem)); + add_min_dep_type_info(c, t_int); + break; + + case Type_Enum: + add_min_dep_type_info(c, bt->Enum.base_type); + break; + + case Type_Union: + add_min_dep_type_info(c, t_int); + add_min_dep_type_info(c, t_type_info_ptr); + for_array(i, bt->Union.variants) { + add_min_dep_type_info(c, bt->Union.variants[i]); + } + break; + + case Type_Struct: + if (bt->Struct.scope != nullptr) { + for_array(i, bt->Struct.scope->elements.entries) { + Entity *e = bt->Struct.scope->elements.entries[i].value; + add_min_dep_type_info(c, e->type); + } + } + for_array(i, bt->Struct.fields) { + Entity *f = bt->Struct.fields[i]; + add_min_dep_type_info(c, f->type); + } + break; + + case Type_Map: + init_map_internal_types(bt); + add_min_dep_type_info(c, bt->Map.key); + add_min_dep_type_info(c, bt->Map.value); + add_min_dep_type_info(c, bt->Map.generated_struct_type); + break; + + case Type_Tuple: + for_array(i, bt->Tuple.variables) { + Entity *var = bt->Tuple.variables[i]; + add_min_dep_type_info(c, var->type); + } + break; + + case Type_Proc: + add_min_dep_type_info(c, bt->Proc.params); + add_min_dep_type_info(c, bt->Proc.results); + break; + } +} + + +void add_dependency_to_set(Checker *c, Entity *entity) { if (entity == nullptr) { return; } + CheckerInfo *info = &c->info; + auto *set = &info->minimum_dependency_set; + String name = entity->token.string; if (entity->type != nullptr && is_type_polymorphic(entity->type)) { - DeclInfo *decl = decl_info_of_entity(info, entity); + DeclInfo *decl = decl_info_of_entity(&c->info, entity); if (decl != nullptr && decl->gen_proc_type == nullptr) { return; } } - if (ptr_set_exists(map, entity)) { + if (ptr_set_exists(set, entity)) { return; } - ptr_set_add(map, entity); + ptr_set_add(set, entity); DeclInfo *decl = decl_info_of_entity(info, entity); if (decl == nullptr) { return; } + for_array(i, decl->type_info_deps.entries) { + Type *type = decl->type_info_deps.entries[i].ptr; + add_min_dep_type_info(c, type); + } + for_array(i, decl->deps.entries) { Entity *e = decl->deps.entries[i].ptr; - add_dependency_to_map(map, info, e); + add_dependency_to_set(c, e); if (e->kind == Entity_Procedure && e->Procedure.is_foreign) { Entity *fl = e->Procedure.foreign_library; if (fl != nullptr) { GB_ASSERT_MSG(fl->kind == Entity_LibraryName && fl->LibraryName.used, "%.*s", LIT(name)); - add_dependency_to_map(map, info, fl); + add_dependency_to_set(c, fl); } } if (e->kind == Entity_Variable && e->Variable.is_foreign) { @@ -1178,16 +1322,15 @@ void add_dependency_to_map(PtrSet<Entity *> *map, CheckerInfo *info, Entity *ent GB_ASSERT_MSG(fl->kind == Entity_LibraryName && fl->LibraryName.used, "%.*s", LIT(name)); - add_dependency_to_map(map, info, fl); + add_dependency_to_set(c, fl); } } } } -PtrSet<Entity *> generate_minimum_dependency_set(Checker *c, Entity *start) { - CheckerInfo *info = &c->info; - PtrSet<Entity *> map = {}; // Key: Entity * - ptr_set_init(&map, heap_allocator()); +void generate_minimum_dependency_set(Checker *c, Entity *start) { + ptr_set_init(&c->info.minimum_dependency_set, heap_allocator()); + ptr_set_init(&c->info.minimum_dependency_type_info_set, heap_allocator()); String required_entities[] = { str_lit("__mem_zero"), @@ -1204,7 +1347,7 @@ PtrSet<Entity *> generate_minimum_dependency_set(Checker *c, Entity *start) { str_lit("Context"), }; for (isize i = 0; i < gb_count_of(required_entities); i++) { - add_dependency_to_map(&map, info, scope_lookup_entity(c->global_scope, required_entities[i])); + add_dependency_to_set(c, scope_lookup_entity(c->global_scope, required_entities[i])); } if (!build_context.no_bounds_check) { @@ -1214,27 +1357,25 @@ PtrSet<Entity *> generate_minimum_dependency_set(Checker *c, Entity *start) { str_lit("__dynamic_array_expr_error"), }; for (isize i = 0; i < gb_count_of(bounds_check_entities); i++) { - add_dependency_to_map(&map, info, scope_lookup_entity(c->global_scope, bounds_check_entities[i])); + add_dependency_to_set(c, scope_lookup_entity(c->global_scope, bounds_check_entities[i])); } } - for_array(i, info->definitions) { - Entity *e = info->definitions[i]; + for_array(i, c->info.definitions) { + Entity *e = c->info.definitions[i]; // if (e->scope->is_global && !is_type_poly_proc(e->type)) { // TODO(bill): is the check enough? if (e->scope == universal_scope) { // TODO(bill): is the check enough? if (e->type == nullptr || !is_type_poly_proc(e->type)) { - add_dependency_to_map(&map, info, e); + add_dependency_to_set(c, e); } } else if (e->kind == Entity_Procedure && e->Procedure.is_export) { - add_dependency_to_map(&map, info, e); + add_dependency_to_set(c, e); } else if (e->kind == Entity_Variable && e->Procedure.is_export) { - add_dependency_to_map(&map, info, e); + add_dependency_to_set(c, e); } } - add_dependency_to_map(&map, info, start); - - return map; + add_dependency_to_set(c, start); } bool is_entity_a_dependency(Entity *e) { @@ -1794,7 +1935,7 @@ void check_collect_value_decl(Checker *c, AstNode *decl) { Entity **entities = gb_alloc_array(c->allocator, Entity *, entity_cap); DeclInfo *di = nullptr; if (vd->values.count > 0) { - di = make_declaration_info(heap_allocator(), c->context.scope, c->context.decl); + di = make_decl_info(heap_allocator(), c->context.scope, c->context.decl); di->entities = entities; di->type_expr = vd->type; di->init_expr = vd->values[0]; @@ -1838,7 +1979,7 @@ void check_collect_value_decl(Checker *c, AstNode *decl) { DeclInfo *d = di; if (d == nullptr || i > 0) { AstNode *init_expr = value; - d = make_declaration_info(heap_allocator(), e->scope, c->context.decl); + d = make_decl_info(heap_allocator(), e->scope, c->context.decl); d->type_expr = vd->type; d->init_expr = init_expr; } @@ -1869,7 +2010,7 @@ void check_collect_value_decl(Checker *c, AstNode *decl) { Token token = name->Ident.token; AstNode *fl = c->context.foreign_context.curr_library; - DeclInfo *d = make_declaration_info(c->allocator, c->context.scope, c->context.decl); + DeclInfo *d = make_decl_info(c->allocator, c->context.scope, c->context.decl); Entity *e = nullptr; d->attributes = vd->attributes; @@ -3088,7 +3229,7 @@ void check_parsed_files(Checker *c) { for_array(i, c->parser->files) { AstFile *f = c->parser->files[i]; Scope *scope = create_scope_from_file(c, f); - f->decl_info = make_declaration_info(c->allocator, f->scope, c->context.decl); + f->decl_info = make_decl_info(c->allocator, f->scope, c->context.decl); HashKey key = hash_string(f->tokenizer.fullpath); map_set(&c->file_scopes, key, scope); map_set(&c->info.files, key, f); @@ -3151,7 +3292,7 @@ void check_parsed_files(Checker *c) { } TIME_SECTION("generate minimum dependency set"); - c->info.minimum_dependency_set = generate_minimum_dependency_set(c, c->info.entry_point); + generate_minimum_dependency_set(c, c->info.entry_point); TIME_SECTION("calculate global init order"); |