mirror of
https://github.com/Ed94/Odin.git
synced 2026-08-04 22:58:46 +00:00
Minimal Type Info Dependency handling
This commit is contained in:
@@ -1032,8 +1032,13 @@ void check_proc_body(Checker *c, Token token, DeclInfo *decl, Type *type, AstNod
|
|||||||
Entity *e = decl->deps.entries[i].ptr;
|
Entity *e = decl->deps.entries[i].ptr;
|
||||||
ptr_set_add(&decl->parent->deps, e);
|
ptr_set_add(&decl->parent->deps, e);
|
||||||
}
|
}
|
||||||
|
for_array(i, decl->type_info_deps.entries) {
|
||||||
|
Type *t = decl->type_info_deps.entries[i].ptr;
|
||||||
|
ptr_set_add(&decl->parent->type_info_deps, t);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
+5
-2
@@ -329,7 +329,7 @@ bool find_or_generate_polymorphic_procedure(Checker *c, Entity *base_entity, Typ
|
|||||||
u64 tags = base_entity->Procedure.tags;
|
u64 tags = base_entity->Procedure.tags;
|
||||||
AstNode *ident = clone_ast_node(a, base_entity->identifier);
|
AstNode *ident = clone_ast_node(a, base_entity->identifier);
|
||||||
Token token = ident->Ident.token;
|
Token token = ident->Ident.token;
|
||||||
DeclInfo *d = make_declaration_info(c->allocator, scope, old_decl->parent);
|
DeclInfo *d = make_decl_info(c->allocator, scope, old_decl->parent);
|
||||||
d->gen_proc_type = final_proc_type;
|
d->gen_proc_type = final_proc_type;
|
||||||
d->type_expr = pl->type;
|
d->type_expr = pl->type;
|
||||||
d->proc_lit = proc_lit;
|
d->proc_lit = proc_lit;
|
||||||
@@ -4327,6 +4327,9 @@ CALL_ARGUMENT_CHECKER(check_call_arguments_internal) {
|
|||||||
err = CallArgumentError_WrongTypes;
|
err = CallArgumentError_WrongTypes;
|
||||||
}
|
}
|
||||||
score += s;
|
score += s;
|
||||||
|
if (is_type_any(elem)) {
|
||||||
|
add_type_info_type(c, o.type);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -5299,7 +5302,7 @@ ExprKind check_expr_base_internal(Checker *c, Operand *o, AstNode *node, Type *t
|
|||||||
Type *type = alloc_type(Type_Proc);
|
Type *type = alloc_type(Type_Proc);
|
||||||
check_open_scope(c, pl->type);
|
check_open_scope(c, pl->type);
|
||||||
{
|
{
|
||||||
decl = make_declaration_info(c->allocator, c->context.scope, c->context.decl);
|
decl = make_decl_info(c->allocator, c->context.scope, c->context.decl);
|
||||||
decl->proc_lit = node;
|
decl->proc_lit = node;
|
||||||
c->context.decl = decl;
|
c->context.decl = decl;
|
||||||
|
|
||||||
|
|||||||
@@ -871,6 +871,7 @@ void check_type_switch_stmt(Checker *c, AstNode *node, u32 mod_flags) {
|
|||||||
|
|
||||||
check_expr(c, &x, rhs);
|
check_expr(c, &x, rhs);
|
||||||
check_assignment(c, &x, nullptr, str_lit("type switch expression"));
|
check_assignment(c, &x, nullptr, str_lit("type switch expression"));
|
||||||
|
add_type_info_type(c, x.type);
|
||||||
|
|
||||||
TypeSwitchKind switch_kind = check_valid_type_switch_type(x.type);
|
TypeSwitchKind switch_kind = check_valid_type_switch_type(x.type);
|
||||||
if (switch_kind == TypeSwitch_Invalid) {
|
if (switch_kind == TypeSwitch_Invalid) {
|
||||||
@@ -962,8 +963,10 @@ void check_type_switch_stmt(Checker *c, AstNode *node, u32 mod_flags) {
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
case_type = y.type;
|
case_type = y.type;
|
||||||
|
add_type_info_type(c, y.type);
|
||||||
} else if (switch_kind == TypeSwitch_Any) {
|
} else if (switch_kind == TypeSwitch_Any) {
|
||||||
case_type = y.type;
|
case_type = y.type;
|
||||||
|
add_type_info_type(c, y.type);
|
||||||
} else {
|
} else {
|
||||||
GB_PANIC("Unknown type to type switch statement");
|
GB_PANIC("Unknown type to type switch statement");
|
||||||
}
|
}
|
||||||
|
|||||||
+173
-32
@@ -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->parent = parent;
|
||||||
d->scope = scope;
|
d->scope = scope;
|
||||||
ptr_set_init(&d->deps, heap_allocator());
|
ptr_set_init(&d->deps, heap_allocator());
|
||||||
array_init (&d->labels, 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);
|
DeclInfo *d = gb_alloc_item(a, DeclInfo);
|
||||||
init_declaration_info(d, scope, parent);
|
init_decl_info(d, scope, parent);
|
||||||
return d;
|
return d;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -483,12 +484,20 @@ void check_scope_usage(Checker *c, Scope *scope) {
|
|||||||
void add_dependency(DeclInfo *d, Entity *e) {
|
void add_dependency(DeclInfo *d, Entity *e) {
|
||||||
ptr_set_add(&d->deps, 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) {
|
void add_preload_dependency(Checker *c, char *name) {
|
||||||
String n = make_string_c(name);
|
String n = make_string_c(name);
|
||||||
Entity *e = scope_lookup_entity(c->global_scope, n);
|
Entity *e = scope_lookup_entity(c->global_scope, n);
|
||||||
GB_ASSERT(e != nullptr);
|
GB_ASSERT(e != nullptr);
|
||||||
ptr_set_add(&c->context.decl->deps, e);
|
ptr_set_add(&c->context.decl->deps, e);
|
||||||
|
// add_type_info_type(c, e->type);
|
||||||
}
|
}
|
||||||
|
|
||||||
void add_declaration_dependency(Checker *c, Entity *e) {
|
void add_declaration_dependency(Checker *c, Entity *e) {
|
||||||
@@ -959,8 +968,10 @@ void add_type_info_type(Checker *c, Type *t) {
|
|||||||
return;
|
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
|
// Types have already been added
|
||||||
|
add_type_info_dependency(c->context.decl, t);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -986,6 +997,7 @@ void add_type_info_type(Checker *c, Type *t) {
|
|||||||
|
|
||||||
if (prev) {
|
if (prev) {
|
||||||
// NOTE(bill): If a previous one exists already, no need to continue
|
// NOTE(bill): If a previous one exists already, no need to continue
|
||||||
|
add_type_info_dependency(c->context.decl, t);
|
||||||
return;
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
void add_dependency_to_map(PtrSet<Entity *> *map, CheckerInfo *info, Entity *entity) {
|
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);
|
||||||
|
|
||||||
|
// 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) {
|
if (entity == nullptr) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
CheckerInfo *info = &c->info;
|
||||||
|
auto *set = &info->minimum_dependency_set;
|
||||||
|
|
||||||
String name = entity->token.string;
|
String name = entity->token.string;
|
||||||
|
|
||||||
if (entity->type != nullptr &&
|
if (entity->type != nullptr &&
|
||||||
is_type_polymorphic(entity->type)) {
|
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) {
|
if (decl != nullptr && decl->gen_proc_type == nullptr) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ptr_set_exists(map, entity)) {
|
if (ptr_set_exists(set, entity)) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
ptr_set_add(map, entity);
|
ptr_set_add(set, entity);
|
||||||
DeclInfo *decl = decl_info_of_entity(info, entity);
|
DeclInfo *decl = decl_info_of_entity(info, entity);
|
||||||
if (decl == nullptr) {
|
if (decl == nullptr) {
|
||||||
return;
|
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) {
|
for_array(i, decl->deps.entries) {
|
||||||
Entity *e = decl->deps.entries[i].ptr;
|
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) {
|
if (e->kind == Entity_Procedure && e->Procedure.is_foreign) {
|
||||||
Entity *fl = e->Procedure.foreign_library;
|
Entity *fl = e->Procedure.foreign_library;
|
||||||
if (fl != nullptr) {
|
if (fl != nullptr) {
|
||||||
GB_ASSERT_MSG(fl->kind == Entity_LibraryName &&
|
GB_ASSERT_MSG(fl->kind == Entity_LibraryName &&
|
||||||
fl->LibraryName.used,
|
fl->LibraryName.used,
|
||||||
"%.*s", LIT(name));
|
"%.*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) {
|
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 &&
|
GB_ASSERT_MSG(fl->kind == Entity_LibraryName &&
|
||||||
fl->LibraryName.used,
|
fl->LibraryName.used,
|
||||||
"%.*s", LIT(name));
|
"%.*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) {
|
void generate_minimum_dependency_set(Checker *c, Entity *start) {
|
||||||
CheckerInfo *info = &c->info;
|
ptr_set_init(&c->info.minimum_dependency_set, heap_allocator());
|
||||||
PtrSet<Entity *> map = {}; // Key: Entity *
|
ptr_set_init(&c->info.minimum_dependency_type_info_set, heap_allocator());
|
||||||
ptr_set_init(&map, heap_allocator());
|
|
||||||
|
|
||||||
String required_entities[] = {
|
String required_entities[] = {
|
||||||
str_lit("__mem_zero"),
|
str_lit("__mem_zero"),
|
||||||
@@ -1204,7 +1347,7 @@ PtrSet<Entity *> generate_minimum_dependency_set(Checker *c, Entity *start) {
|
|||||||
str_lit("Context"),
|
str_lit("Context"),
|
||||||
};
|
};
|
||||||
for (isize i = 0; i < gb_count_of(required_entities); i++) {
|
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) {
|
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"),
|
str_lit("__dynamic_array_expr_error"),
|
||||||
};
|
};
|
||||||
for (isize i = 0; i < gb_count_of(bounds_check_entities); i++) {
|
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) {
|
for_array(i, c->info.definitions) {
|
||||||
Entity *e = info->definitions[i];
|
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->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->scope == universal_scope) { // TODO(bill): is the check enough?
|
||||||
if (e->type == nullptr || !is_type_poly_proc(e->type)) {
|
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) {
|
} 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) {
|
} 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);
|
add_dependency_to_set(c, start);
|
||||||
|
|
||||||
return map;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool is_entity_a_dependency(Entity *e) {
|
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);
|
Entity **entities = gb_alloc_array(c->allocator, Entity *, entity_cap);
|
||||||
DeclInfo *di = nullptr;
|
DeclInfo *di = nullptr;
|
||||||
if (vd->values.count > 0) {
|
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->entities = entities;
|
||||||
di->type_expr = vd->type;
|
di->type_expr = vd->type;
|
||||||
di->init_expr = vd->values[0];
|
di->init_expr = vd->values[0];
|
||||||
@@ -1838,7 +1979,7 @@ void check_collect_value_decl(Checker *c, AstNode *decl) {
|
|||||||
DeclInfo *d = di;
|
DeclInfo *d = di;
|
||||||
if (d == nullptr || i > 0) {
|
if (d == nullptr || i > 0) {
|
||||||
AstNode *init_expr = value;
|
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->type_expr = vd->type;
|
||||||
d->init_expr = init_expr;
|
d->init_expr = init_expr;
|
||||||
}
|
}
|
||||||
@@ -1869,7 +2010,7 @@ void check_collect_value_decl(Checker *c, AstNode *decl) {
|
|||||||
Token token = name->Ident.token;
|
Token token = name->Ident.token;
|
||||||
|
|
||||||
AstNode *fl = c->context.foreign_context.curr_library;
|
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;
|
Entity *e = nullptr;
|
||||||
|
|
||||||
d->attributes = vd->attributes;
|
d->attributes = vd->attributes;
|
||||||
@@ -3088,7 +3229,7 @@ void check_parsed_files(Checker *c) {
|
|||||||
for_array(i, c->parser->files) {
|
for_array(i, c->parser->files) {
|
||||||
AstFile *f = c->parser->files[i];
|
AstFile *f = c->parser->files[i];
|
||||||
Scope *scope = create_scope_from_file(c, f);
|
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);
|
HashKey key = hash_string(f->tokenizer.fullpath);
|
||||||
map_set(&c->file_scopes, key, scope);
|
map_set(&c->file_scopes, key, scope);
|
||||||
map_set(&c->info.files, key, f);
|
map_set(&c->info.files, key, f);
|
||||||
@@ -3151,7 +3292,7 @@ void check_parsed_files(Checker *c) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
TIME_SECTION("generate minimum dependency set");
|
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");
|
TIME_SECTION("calculate global init order");
|
||||||
|
|||||||
+4
-1
@@ -186,6 +186,7 @@ struct DeclInfo {
|
|||||||
Type * gen_proc_type; // Precalculated
|
Type * gen_proc_type; // Precalculated
|
||||||
|
|
||||||
PtrSet<Entity *> deps;
|
PtrSet<Entity *> deps;
|
||||||
|
PtrSet<Type *> type_info_deps;
|
||||||
Array<BlockLabel> labels;
|
Array<BlockLabel> labels;
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -303,9 +304,11 @@ struct CheckerInfo {
|
|||||||
Array<Type *> type_info_types;
|
Array<Type *> type_info_types;
|
||||||
Map<isize> type_info_map; // Key: Type *
|
Map<isize> type_info_map; // Key: Type *
|
||||||
|
|
||||||
|
|
||||||
Scope * init_scope;
|
Scope * init_scope;
|
||||||
Entity * entry_point;
|
Entity * entry_point;
|
||||||
PtrSet<Entity *> minimum_dependency_set;
|
PtrSet<Entity *> minimum_dependency_set;
|
||||||
|
PtrSet<isize> minimum_dependency_type_info_set;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct Checker {
|
struct Checker {
|
||||||
@@ -374,13 +377,13 @@ void add_type_and_value (CheckerInfo *i, AstNode *expression, Addressi
|
|||||||
void add_entity_use (Checker *c, AstNode *identifier, Entity *entity);
|
void add_entity_use (Checker *c, AstNode *identifier, Entity *entity);
|
||||||
void add_implicit_entity (Checker *c, AstNode *node, Entity *e);
|
void add_implicit_entity (Checker *c, AstNode *node, Entity *e);
|
||||||
void add_entity_and_decl_info(Checker *c, AstNode *identifier, Entity *e, DeclInfo *d);
|
void add_entity_and_decl_info(Checker *c, AstNode *identifier, Entity *e, DeclInfo *d);
|
||||||
|
void add_type_info_type (Checker *c, Type *t);
|
||||||
|
|
||||||
void check_add_import_decl(Checker *c, AstNodeImportDecl *id);
|
void check_add_import_decl(Checker *c, AstNodeImportDecl *id);
|
||||||
void check_add_export_decl(Checker *c, AstNodeExportDecl *ed);
|
void check_add_export_decl(Checker *c, AstNodeExportDecl *ed);
|
||||||
void check_add_foreign_import_decl(Checker *c, AstNode *decl);
|
void check_add_foreign_import_decl(Checker *c, AstNode *decl);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
bool check_arity_match(Checker *c, AstNodeValueDecl *vd, bool is_global = false);
|
bool check_arity_match(Checker *c, AstNodeValueDecl *vd, bool is_global = false);
|
||||||
void check_collect_entities(Checker *c, Array<AstNode *> nodes);
|
void check_collect_entities(Checker *c, Array<AstNode *> nodes);
|
||||||
void check_collect_entities_from_when_stmt(Checker *c, AstNodeWhenStmt *ws);
|
void check_collect_entities_from_when_stmt(Checker *c, AstNodeWhenStmt *ws);
|
||||||
|
|||||||
+36
-6
@@ -3586,13 +3586,41 @@ gb_global i32 ir_global_type_info_member_names_index = 0;
|
|||||||
gb_global i32 ir_global_type_info_member_offsets_index = 0;
|
gb_global i32 ir_global_type_info_member_offsets_index = 0;
|
||||||
gb_global i32 ir_global_type_info_member_usings_index = 0;
|
gb_global i32 ir_global_type_info_member_usings_index = 0;
|
||||||
|
|
||||||
|
#if 1
|
||||||
|
isize ir_type_info_count(CheckerInfo *info) {
|
||||||
|
return info->minimum_dependency_type_info_set.entries.count+1;
|
||||||
|
}
|
||||||
|
|
||||||
|
isize ir_type_info_index(CheckerInfo *info, Type *type, bool err_on_not_found=true) {
|
||||||
|
isize index = type_info_index(info, type);
|
||||||
|
auto *set = &info->minimum_dependency_type_info_set;
|
||||||
|
for_array(i, set->entries) {
|
||||||
|
if (set->entries[i].ptr == index) {
|
||||||
|
return i+1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (err_on_not_found) {
|
||||||
|
GB_PANIC("NOT FOUND ir_type_info_index %s", type_to_string(type));
|
||||||
|
}
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
isize ir_type_info_count(CheckerInfo *info) {
|
||||||
|
return info->type_info_types.count;
|
||||||
|
}
|
||||||
|
|
||||||
|
isize ir_type_info_index(CheckerInfo *info, Type *type) {
|
||||||
|
isize index = type_info_index(info, type);
|
||||||
|
return index;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
irValue *ir_type_info(irProcedure *proc, Type *type) {
|
irValue *ir_type_info(irProcedure *proc, Type *type) {
|
||||||
CheckerInfo *info = proc->module->info;
|
CheckerInfo *info = proc->module->info;
|
||||||
|
|
||||||
type = default_type(type);
|
type = default_type(type);
|
||||||
|
|
||||||
i32 entry_index = cast(i32)type_info_index(info, type);
|
i32 entry_index = cast(i32)ir_type_info_index(info, type);
|
||||||
GB_ASSERT(entry_index >= 0);
|
GB_ASSERT(entry_index >= 0);
|
||||||
|
|
||||||
// gb_printf_err("%d %s\n", entry_index, type_to_string(type));
|
// gb_printf_err("%d %s\n", entry_index, type_to_string(type));
|
||||||
@@ -4173,7 +4201,6 @@ irValue *ir_build_builtin_proc(irProcedure *proc, AstNode *expr, TypeAndValue tv
|
|||||||
case BuiltinProc_type_info_of: {
|
case BuiltinProc_type_info_of: {
|
||||||
Type *t = default_type(type_of_expr(proc->module->info, ce->args[0]));
|
Type *t = default_type(type_of_expr(proc->module->info, ce->args[0]));
|
||||||
return ir_type_info(proc, t);
|
return ir_type_info(proc, t);
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
case BuiltinProc_len: {
|
case BuiltinProc_len: {
|
||||||
@@ -4806,7 +4833,7 @@ irValue *ir_build_expr_internal(irProcedure *proc, AstNode *expr) {
|
|||||||
if (tv.mode == Addressing_Type) {
|
if (tv.mode == Addressing_Type) {
|
||||||
// // TODO(bill): Handle this correctly
|
// // TODO(bill): Handle this correctly
|
||||||
#if 0
|
#if 0
|
||||||
i32 entry_index = type_info_index(proc->module->info, tv.type, false);
|
i32 entry_index = ir_type_info_index(proc->module->info, tv.type, false);
|
||||||
if (entry_index >= 0) {
|
if (entry_index >= 0) {
|
||||||
return ir_get_type_info_ptr(proc, tv.type);
|
return ir_get_type_info_ptr(proc, tv.type);
|
||||||
// i32 id = entry_index+1;
|
// i32 id = entry_index+1;
|
||||||
@@ -7615,7 +7642,7 @@ void ir_init_module(irModule *m, Checker *c) {
|
|||||||
{
|
{
|
||||||
// Add type info data
|
// Add type info data
|
||||||
{
|
{
|
||||||
isize max_type_info_count = m->info->type_info_types.count;
|
isize max_type_info_count = ir_type_info_count(m->info);
|
||||||
|
|
||||||
String name = str_lit(IR_TYPE_INFO_DATA_NAME);
|
String name = str_lit(IR_TYPE_INFO_DATA_NAME);
|
||||||
Entity *e = alloc_entity_variable(nullptr, make_token_ident(name), alloc_type_array(t_type_info, max_type_info_count), false);
|
Entity *e = alloc_entity_variable(nullptr, make_token_ident(name), alloc_type_array(t_type_info, max_type_info_count), false);
|
||||||
@@ -7774,7 +7801,7 @@ void ir_gen_destroy(irGen *s) {
|
|||||||
// Type Info stuff
|
// Type Info stuff
|
||||||
//
|
//
|
||||||
irValue *ir_get_type_info_ptr(irProcedure *proc, Type *type) {
|
irValue *ir_get_type_info_ptr(irProcedure *proc, Type *type) {
|
||||||
i32 index = cast(i32)type_info_index(proc->module->info, type);
|
i32 index = cast(i32)ir_type_info_index(proc->module->info, type);
|
||||||
// gb_printf_err("%d %s\n", index, type_to_string(type));
|
// gb_printf_err("%d %s\n", index, type_to_string(type));
|
||||||
irValue *ptr = ir_emit_array_epi(proc, ir_global_type_info_data, index);
|
irValue *ptr = ir_emit_array_epi(proc, ir_global_type_info_data, index);
|
||||||
return ir_emit_bitcast(proc, ptr, t_type_info_ptr);
|
return ir_emit_bitcast(proc, ptr, t_type_info_ptr);
|
||||||
@@ -7837,7 +7864,10 @@ void ir_setup_type_info_data(irProcedure *proc) { // NOTE(bill): Setup type_info
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
isize entry_index = type_info_index(info, t);
|
isize entry_index = ir_type_info_index(info, t, false);
|
||||||
|
if (entry_index <= 0) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
irValue *tag = nullptr;
|
irValue *tag = nullptr;
|
||||||
irValue *ti_ptr = ir_emit_array_epi(proc, ir_global_type_info_data, cast(i32)entry_index);
|
irValue *ti_ptr = ir_emit_array_epi(proc, ir_global_type_info_data, cast(i32)entry_index);
|
||||||
|
|||||||
Reference in New Issue
Block a user