mirror of
https://github.com/Ed94/Odin.git
synced 2026-08-06 15:48:51 +00:00
Use templated Map for extra type safety
This commit is contained in:
+9
-9
@@ -319,7 +319,7 @@ void check_proc_lit(Checker *c, Entity *e, DeclInfo *d) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (is_foreign) {
|
if (is_foreign) {
|
||||||
MapEntity *fp = &c->info.foreigns;
|
auto *fp = &c->info.foreigns;
|
||||||
String name = e->token.string;
|
String name = e->token.string;
|
||||||
if (pd->foreign_name.len > 0) {
|
if (pd->foreign_name.len > 0) {
|
||||||
name = pd->foreign_name;
|
name = pd->foreign_name;
|
||||||
@@ -352,7 +352,7 @@ void check_proc_lit(Checker *c, Entity *e, DeclInfo *d) {
|
|||||||
e->Procedure.foreign_name = name;
|
e->Procedure.foreign_name = name;
|
||||||
|
|
||||||
HashKey key = hash_string(name);
|
HashKey key = hash_string(name);
|
||||||
Entity **found = map_entity_get(fp, key);
|
Entity **found = map_get(fp, key);
|
||||||
if (found) {
|
if (found) {
|
||||||
Entity *f = *found;
|
Entity *f = *found;
|
||||||
TokenPos pos = f->token.pos;
|
TokenPos pos = f->token.pos;
|
||||||
@@ -365,7 +365,7 @@ void check_proc_lit(Checker *c, Entity *e, DeclInfo *d) {
|
|||||||
LIT(name), LIT(pos.file), pos.line, pos.column);
|
LIT(name), LIT(pos.file), pos.line, pos.column);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
map_entity_set(fp, key, e);
|
map_set(fp, key, e);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
String name = e->token.string;
|
String name = e->token.string;
|
||||||
@@ -374,12 +374,12 @@ void check_proc_lit(Checker *c, Entity *e, DeclInfo *d) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (is_link_name || is_export) {
|
if (is_link_name || is_export) {
|
||||||
MapEntity *fp = &c->info.foreigns;
|
auto *fp = &c->info.foreigns;
|
||||||
|
|
||||||
e->Procedure.link_name = name;
|
e->Procedure.link_name = name;
|
||||||
|
|
||||||
HashKey key = hash_string(name);
|
HashKey key = hash_string(name);
|
||||||
Entity **found = map_entity_get(fp, key);
|
Entity **found = map_get(fp, key);
|
||||||
if (found) {
|
if (found) {
|
||||||
Entity *f = *found;
|
Entity *f = *found;
|
||||||
TokenPos pos = f->token.pos;
|
TokenPos pos = f->token.pos;
|
||||||
@@ -389,7 +389,7 @@ void check_proc_lit(Checker *c, Entity *e, DeclInfo *d) {
|
|||||||
"\tother at %.*s(%td:%td)",
|
"\tother at %.*s(%td:%td)",
|
||||||
LIT(name), LIT(pos.file), pos.line, pos.column);
|
LIT(name), LIT(pos.file), pos.line, pos.column);
|
||||||
} else {
|
} else {
|
||||||
map_entity_set(fp, key, e);
|
map_set(fp, key, e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -443,7 +443,7 @@ void check_entity_decl(Checker *c, Entity *e, DeclInfo *d, Type *named_type) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (d == NULL) {
|
if (d == NULL) {
|
||||||
DeclInfo **found = map_decl_info_get(&c->info.entities, hash_pointer(e));
|
DeclInfo **found = map_get(&c->info.entities, hash_pointer(e));
|
||||||
if (found) {
|
if (found) {
|
||||||
d = *found;
|
d = *found;
|
||||||
} else {
|
} else {
|
||||||
@@ -511,7 +511,7 @@ void check_proc_body(Checker *c, Token token, DeclInfo *decl, Type *type, AstNod
|
|||||||
String name = e->token.string;
|
String name = e->token.string;
|
||||||
Type *t = base_type(type_deref(e->type));
|
Type *t = base_type(type_deref(e->type));
|
||||||
if (is_type_struct(t) || is_type_raw_union(t)) {
|
if (is_type_struct(t) || is_type_raw_union(t)) {
|
||||||
Scope **found = map_scope_get(&c->info.scopes, hash_pointer(t->Record.node));
|
Scope **found = map_get(&c->info.scopes, hash_pointer(t->Record.node));
|
||||||
GB_ASSERT(found != NULL);
|
GB_ASSERT(found != NULL);
|
||||||
for_array(i, (*found)->elements.entries) {
|
for_array(i, (*found)->elements.entries) {
|
||||||
Entity *f = (*found)->elements.entries[i].value;
|
Entity *f = (*found)->elements.entries[i].value;
|
||||||
@@ -557,7 +557,7 @@ void check_proc_body(Checker *c, Token token, DeclInfo *decl, Type *type, AstNod
|
|||||||
for_array(i, decl->deps.entries) {
|
for_array(i, decl->deps.entries) {
|
||||||
HashKey key = decl->deps.entries[i].key;
|
HashKey key = decl->deps.entries[i].key;
|
||||||
Entity *e = cast(Entity *)key.ptr;
|
Entity *e = cast(Entity *)key.ptr;
|
||||||
map_bool_set(&decl->parent->deps, key, true);
|
map_set(&decl->parent->deps, key, true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+33
-33
@@ -62,7 +62,7 @@ void check_scope_decls(Checker *c, Array<AstNode *> nodes, isize reserve_size) {
|
|||||||
default:
|
default:
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
DeclInfo **found = map_decl_info_get(&c->info.entities, hash_pointer(e));
|
DeclInfo **found = map_get(&c->info.entities, hash_pointer(e));
|
||||||
if (found != NULL) {
|
if (found != NULL) {
|
||||||
DeclInfo *d = *found;
|
DeclInfo *d = *found;
|
||||||
check_entity_decl(c, e, d, NULL);
|
check_entity_decl(c, e, d, NULL);
|
||||||
@@ -348,7 +348,7 @@ void check_assignment(Checker *c, Operand *operand, Type *type, String context_n
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void populate_using_entity_map(Checker *c, AstNode *node, Type *t, MapEntity *entity_map) {
|
void populate_using_entity_map(Checker *c, AstNode *node, Type *t, Map<Entity *> *entity_map) {
|
||||||
t = base_type(type_deref(t));
|
t = base_type(type_deref(t));
|
||||||
gbString str = NULL;
|
gbString str = NULL;
|
||||||
if (node != NULL) {
|
if (node != NULL) {
|
||||||
@@ -361,7 +361,7 @@ void populate_using_entity_map(Checker *c, AstNode *node, Type *t, MapEntity *en
|
|||||||
GB_ASSERT(f->kind == Entity_Variable);
|
GB_ASSERT(f->kind == Entity_Variable);
|
||||||
String name = f->token.string;
|
String name = f->token.string;
|
||||||
HashKey key = hash_string(name);
|
HashKey key = hash_string(name);
|
||||||
Entity **found = map_entity_get(entity_map, key);
|
Entity **found = map_get(entity_map, key);
|
||||||
if (found != NULL) {
|
if (found != NULL) {
|
||||||
Entity *e = *found;
|
Entity *e = *found;
|
||||||
// TODO(bill): Better type error
|
// TODO(bill): Better type error
|
||||||
@@ -371,7 +371,7 @@ void populate_using_entity_map(Checker *c, AstNode *node, Type *t, MapEntity *en
|
|||||||
error(e->token, "`%.*s` is already declared`", LIT(name));
|
error(e->token, "`%.*s` is already declared`", LIT(name));
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
map_entity_set(entity_map, key, f);
|
map_set(entity_map, key, f);
|
||||||
add_entity(c, c->context.scope, NULL, f);
|
add_entity(c, c->context.scope, NULL, f);
|
||||||
if (f->flags & EntityFlag_Using) {
|
if (f->flags & EntityFlag_Using) {
|
||||||
populate_using_entity_map(c, node, f->type, entity_map);
|
populate_using_entity_map(c, node, f->type, entity_map);
|
||||||
@@ -390,8 +390,8 @@ isize check_fields(Checker *c, AstNode *node, Array<AstNode *> decls,
|
|||||||
String context) {
|
String context) {
|
||||||
gbTempArenaMemory tmp = gb_temp_arena_memory_begin(&c->tmp_arena);
|
gbTempArenaMemory tmp = gb_temp_arena_memory_begin(&c->tmp_arena);
|
||||||
|
|
||||||
MapEntity entity_map = {};
|
Map<Entity *> entity_map = {};
|
||||||
map_entity_init_with_reserve(&entity_map, c->tmp_allocator, 2*field_count);
|
map_init_with_reserve(&entity_map, c->tmp_allocator, 2*field_count);
|
||||||
|
|
||||||
Entity *using_index_expr = NULL;
|
Entity *using_index_expr = NULL;
|
||||||
|
|
||||||
@@ -433,7 +433,7 @@ isize check_fields(Checker *c, AstNode *node, Array<AstNode *> decls,
|
|||||||
error_node(name, "`__tag` is a reserved identifier for fields");
|
error_node(name, "`__tag` is a reserved identifier for fields");
|
||||||
} else {
|
} else {
|
||||||
HashKey key = hash_string(name_token.string);
|
HashKey key = hash_string(name_token.string);
|
||||||
Entity **found = map_entity_get(&entity_map, key);
|
Entity **found = map_get(&entity_map, key);
|
||||||
if (found != NULL) {
|
if (found != NULL) {
|
||||||
Entity *e = *found;
|
Entity *e = *found;
|
||||||
// NOTE(bill): Scope checking already checks the declaration but in many cases, this can happen so why not?
|
// NOTE(bill): Scope checking already checks the declaration but in many cases, this can happen so why not?
|
||||||
@@ -441,7 +441,7 @@ isize check_fields(Checker *c, AstNode *node, Array<AstNode *> decls,
|
|||||||
error(name_token, "`%.*s` is already declared in this type", LIT(name_token.string));
|
error(name_token, "`%.*s` is already declared in this type", LIT(name_token.string));
|
||||||
error(e->token, "\tpreviously declared");
|
error(e->token, "\tpreviously declared");
|
||||||
} else {
|
} else {
|
||||||
map_entity_set(&entity_map, key, e);
|
map_set(&entity_map, key, e);
|
||||||
fields[field_index++] = e;
|
fields[field_index++] = e;
|
||||||
add_entity(c, c->context.scope, name, e);
|
add_entity(c, c->context.scope, name, e);
|
||||||
}
|
}
|
||||||
@@ -650,8 +650,8 @@ void check_union_type(Checker *c, Type *union_type, AstNode *node) {
|
|||||||
|
|
||||||
gbTempArenaMemory tmp = gb_temp_arena_memory_begin(&c->tmp_arena);
|
gbTempArenaMemory tmp = gb_temp_arena_memory_begin(&c->tmp_arena);
|
||||||
|
|
||||||
MapEntity entity_map = {}; // Key: String
|
Map<Entity *> entity_map = {}; // Key: String
|
||||||
map_entity_init_with_reserve(&entity_map, c->tmp_allocator, 2*variant_count);
|
map_init_with_reserve(&entity_map, c->tmp_allocator, 2*variant_count);
|
||||||
|
|
||||||
Entity *using_index_expr = NULL;
|
Entity *using_index_expr = NULL;
|
||||||
|
|
||||||
@@ -666,7 +666,7 @@ void check_union_type(Checker *c, Type *union_type, AstNode *node) {
|
|||||||
for (isize i = 0; i < field_count; i++) {
|
for (isize i = 0; i < field_count; i++) {
|
||||||
Entity *f = fields[i];
|
Entity *f = fields[i];
|
||||||
String name = f->token.string;
|
String name = f->token.string;
|
||||||
map_entity_set(&entity_map, hash_string(name), f);
|
map_set(&entity_map, hash_string(name), f);
|
||||||
}
|
}
|
||||||
|
|
||||||
union_type->Record.fields = fields;
|
union_type->Record.fields = fields;
|
||||||
@@ -735,11 +735,11 @@ void check_union_type(Checker *c, Type *union_type, AstNode *node) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
HashKey key = hash_string(name_token.string);
|
HashKey key = hash_string(name_token.string);
|
||||||
if (map_entity_get(&entity_map, key) != NULL) {
|
if (map_get(&entity_map, key) != NULL) {
|
||||||
// NOTE(bill): Scope checking already checks the declaration
|
// NOTE(bill): Scope checking already checks the declaration
|
||||||
error(name_token, "`%.*s` is already declared in this union", LIT(name_token.string));
|
error(name_token, "`%.*s` is already declared in this union", LIT(name_token.string));
|
||||||
} else {
|
} else {
|
||||||
map_entity_set(&entity_map, key, e);
|
map_set(&entity_map, key, e);
|
||||||
variants[variant_index++] = e;
|
variants[variant_index++] = e;
|
||||||
}
|
}
|
||||||
add_entity_use(c, f->name, e);
|
add_entity_use(c, f->name, e);
|
||||||
@@ -801,8 +801,8 @@ void check_enum_type(Checker *c, Type *enum_type, Type *named_type, AstNode *nod
|
|||||||
// NOTE(bill): Must be up here for the `check_init_constant` system
|
// NOTE(bill): Must be up here for the `check_init_constant` system
|
||||||
enum_type->Record.enum_base_type = base_type;
|
enum_type->Record.enum_base_type = base_type;
|
||||||
|
|
||||||
MapEntity entity_map = {}; // Key: String
|
Map<Entity *> entity_map = {}; // Key: String
|
||||||
map_entity_init_with_reserve(&entity_map, c->tmp_allocator, 2*(et->fields.count));
|
map_init_with_reserve(&entity_map, c->tmp_allocator, 2*(et->fields.count));
|
||||||
|
|
||||||
Entity **fields = gb_alloc_array(c->allocator, Entity *, et->fields.count);
|
Entity **fields = gb_alloc_array(c->allocator, Entity *, et->fields.count);
|
||||||
isize field_count = 0;
|
isize field_count = 0;
|
||||||
@@ -888,10 +888,10 @@ void check_enum_type(Checker *c, Type *enum_type, Type *named_type, AstNode *nod
|
|||||||
e->flags |= EntityFlag_Visited;
|
e->flags |= EntityFlag_Visited;
|
||||||
|
|
||||||
HashKey key = hash_string(name);
|
HashKey key = hash_string(name);
|
||||||
if (map_entity_get(&entity_map, key) != NULL) {
|
if (map_get(&entity_map, key) != NULL) {
|
||||||
error_node(ident, "`%.*s` is already declared in this enumeration", LIT(name));
|
error_node(ident, "`%.*s` is already declared in this enumeration", LIT(name));
|
||||||
} else {
|
} else {
|
||||||
map_entity_set(&entity_map, key, e);
|
map_set(&entity_map, key, e);
|
||||||
add_entity(c, c->context.scope, NULL, e);
|
add_entity(c, c->context.scope, NULL, e);
|
||||||
fields[field_count++] = e;
|
fields[field_count++] = e;
|
||||||
add_entity_use(c, field, e);
|
add_entity_use(c, field, e);
|
||||||
@@ -922,8 +922,8 @@ void check_bit_field_type(Checker *c, Type *bit_field_type, Type *named_type, As
|
|||||||
gbTempArenaMemory tmp = gb_temp_arena_memory_begin(&c->tmp_arena);
|
gbTempArenaMemory tmp = gb_temp_arena_memory_begin(&c->tmp_arena);
|
||||||
|
|
||||||
|
|
||||||
MapEntity entity_map = {}; // Key: String
|
Map<Entity *> entity_map = {}; // Key: String
|
||||||
map_entity_init_with_reserve(&entity_map, c->tmp_allocator, 2*(bft->fields.count));
|
map_init_with_reserve(&entity_map, c->tmp_allocator, 2*(bft->fields.count));
|
||||||
|
|
||||||
isize field_count = 0;
|
isize field_count = 0;
|
||||||
Entity **fields = gb_alloc_array(c->allocator, Entity *, bft->fields.count);
|
Entity **fields = gb_alloc_array(c->allocator, Entity *, bft->fields.count);
|
||||||
@@ -967,10 +967,10 @@ void check_bit_field_type(Checker *c, Type *bit_field_type, Type *named_type, As
|
|||||||
|
|
||||||
HashKey key = hash_string(name);
|
HashKey key = hash_string(name);
|
||||||
if (name != "_" &&
|
if (name != "_" &&
|
||||||
map_entity_get(&entity_map, key) != NULL) {
|
map_get(&entity_map, key) != NULL) {
|
||||||
error_node(ident, "`%.*s` is already declared in this bit field", LIT(name));
|
error_node(ident, "`%.*s` is already declared in this bit field", LIT(name));
|
||||||
} else {
|
} else {
|
||||||
map_entity_set(&entity_map, key, e);
|
map_set(&entity_map, key, e);
|
||||||
add_entity(c, c->context.scope, NULL, e);
|
add_entity(c, c->context.scope, NULL, e);
|
||||||
add_entity_use(c, field, e);
|
add_entity_use(c, field, e);
|
||||||
|
|
||||||
@@ -1418,7 +1418,7 @@ Entity *check_ident(Checker *c, Operand *o, AstNode *n, Type *named_type, Type *
|
|||||||
if (e->kind == Entity_Procedure) {
|
if (e->kind == Entity_Procedure) {
|
||||||
// NOTE(bill): Overloads are only allowed with the same scope
|
// NOTE(bill): Overloads are only allowed with the same scope
|
||||||
Scope *s = e->scope;
|
Scope *s = e->scope;
|
||||||
overload_count = map_entity_multi_count(&s->elements, key);
|
overload_count = multi_map_count(&s->elements, key);
|
||||||
if (overload_count > 1) {
|
if (overload_count > 1) {
|
||||||
is_overloaded = true;
|
is_overloaded = true;
|
||||||
}
|
}
|
||||||
@@ -1429,7 +1429,7 @@ Entity *check_ident(Checker *c, Operand *o, AstNode *n, Type *named_type, Type *
|
|||||||
bool skip = false;
|
bool skip = false;
|
||||||
|
|
||||||
Entity **procs = gb_alloc_array(heap_allocator(), Entity *, overload_count);
|
Entity **procs = gb_alloc_array(heap_allocator(), Entity *, overload_count);
|
||||||
map_entity_multi_get_all(&s->elements, key, procs);
|
multi_map_get_all(&s->elements, key, procs);
|
||||||
if (type_hint != NULL) {
|
if (type_hint != NULL) {
|
||||||
gbTempArenaMemory tmp = gb_temp_arena_memory_begin(&c->tmp_arena);
|
gbTempArenaMemory tmp = gb_temp_arena_memory_begin(&c->tmp_arena);
|
||||||
// NOTE(bill): These should be done
|
// NOTE(bill): These should be done
|
||||||
@@ -2488,7 +2488,7 @@ void check_shift(Checker *c, Operand *x, Operand *y, AstNode *node) {
|
|||||||
|
|
||||||
TokenPos pos = ast_node_token(x->expr).pos;
|
TokenPos pos = ast_node_token(x->expr).pos;
|
||||||
if (x_is_untyped) {
|
if (x_is_untyped) {
|
||||||
ExprInfo *info = map_expr_info_get(&c->info.untyped, hash_pointer(x->expr));
|
ExprInfo *info = map_get(&c->info.untyped, hash_pointer(x->expr));
|
||||||
if (info != NULL) {
|
if (info != NULL) {
|
||||||
info->is_lhs = true;
|
info->is_lhs = true;
|
||||||
}
|
}
|
||||||
@@ -2944,7 +2944,7 @@ void check_binary_expr(Checker *c, Operand *x, AstNode *node) {
|
|||||||
|
|
||||||
void update_expr_type(Checker *c, AstNode *e, Type *type, bool final) {
|
void update_expr_type(Checker *c, AstNode *e, Type *type, bool final) {
|
||||||
HashKey key = hash_pointer(e);
|
HashKey key = hash_pointer(e);
|
||||||
ExprInfo *found = map_expr_info_get(&c->info.untyped, key);
|
ExprInfo *found = map_get(&c->info.untyped, key);
|
||||||
if (found == NULL) {
|
if (found == NULL) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -2983,12 +2983,12 @@ void update_expr_type(Checker *c, AstNode *e, Type *type, bool final) {
|
|||||||
|
|
||||||
if (!final && is_type_untyped(type)) {
|
if (!final && is_type_untyped(type)) {
|
||||||
old.type = base_type(type);
|
old.type = base_type(type);
|
||||||
map_expr_info_set(&c->info.untyped, key, old);
|
map_set(&c->info.untyped, key, old);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// We need to remove it and then give it a new one
|
// We need to remove it and then give it a new one
|
||||||
map_expr_info_remove(&c->info.untyped, key);
|
map_remove(&c->info.untyped, key);
|
||||||
|
|
||||||
if (old.is_lhs && !is_type_integer(type)) {
|
if (old.is_lhs && !is_type_integer(type)) {
|
||||||
gbString expr_str = expr_to_string(e);
|
gbString expr_str = expr_to_string(e);
|
||||||
@@ -3003,7 +3003,7 @@ void update_expr_type(Checker *c, AstNode *e, Type *type, bool final) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void update_expr_value(Checker *c, AstNode *e, ExactValue value) {
|
void update_expr_value(Checker *c, AstNode *e, ExactValue value) {
|
||||||
ExprInfo *found = map_expr_info_get(&c->info.untyped, hash_pointer(e));
|
ExprInfo *found = map_get(&c->info.untyped, hash_pointer(e));
|
||||||
if (found) {
|
if (found) {
|
||||||
found->value = value;
|
found->value = value;
|
||||||
}
|
}
|
||||||
@@ -3206,7 +3206,7 @@ isize entity_overload_count(Scope *s, String name) {
|
|||||||
}
|
}
|
||||||
if (e->kind == Entity_Procedure) {
|
if (e->kind == Entity_Procedure) {
|
||||||
// NOTE(bill): Overloads are only allowed with the same scope
|
// NOTE(bill): Overloads are only allowed with the same scope
|
||||||
return map_entity_multi_count(&s->elements, hash_string(e->token.string));
|
return multi_map_count(&s->elements, hash_string(e->token.string));
|
||||||
}
|
}
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
@@ -3298,7 +3298,7 @@ Entity *check_selector(Checker *c, Operand *operand, AstNode *node, Type *type_h
|
|||||||
isize overload_count = entity_overload_count(import_scope, entity_name);
|
isize overload_count = entity_overload_count(import_scope, entity_name);
|
||||||
bool is_overloaded = overload_count > 1;
|
bool is_overloaded = overload_count > 1;
|
||||||
|
|
||||||
bool implicit_is_found = map_bool_get(&e->ImportName.scope->implicit, hash_pointer(entity)) != NULL;
|
bool implicit_is_found = map_get(&e->ImportName.scope->implicit, hash_pointer(entity)) != NULL;
|
||||||
bool is_not_exported = !is_entity_exported(entity);
|
bool is_not_exported = !is_entity_exported(entity);
|
||||||
if (!implicit_is_found) {
|
if (!implicit_is_found) {
|
||||||
is_not_exported = false;
|
is_not_exported = false;
|
||||||
@@ -3320,7 +3320,7 @@ Entity *check_selector(Checker *c, Operand *operand, AstNode *node, Type *type_h
|
|||||||
bool skip = false;
|
bool skip = false;
|
||||||
|
|
||||||
Entity **procs = gb_alloc_array(heap_allocator(), Entity *, overload_count);
|
Entity **procs = gb_alloc_array(heap_allocator(), Entity *, overload_count);
|
||||||
map_entity_multi_get_all(&import_scope->elements, key, procs);
|
multi_map_get_all(&import_scope->elements, key, procs);
|
||||||
|
|
||||||
for (isize i = 0; i < overload_count; i++) {
|
for (isize i = 0; i < overload_count; i++) {
|
||||||
Type *t = base_type(procs[i]->type);
|
Type *t = base_type(procs[i]->type);
|
||||||
@@ -3329,7 +3329,7 @@ Entity *check_selector(Checker *c, Operand *operand, AstNode *node, Type *type_h
|
|||||||
}
|
}
|
||||||
|
|
||||||
// NOTE(bill): Check to see if it's imported
|
// NOTE(bill): Check to see if it's imported
|
||||||
if (map_bool_get(&import_scope->implicit, hash_pointer(procs[i]))) {
|
if (map_get(&import_scope->implicit, hash_pointer(procs[i]))) {
|
||||||
gb_swap(Entity *, procs[i], procs[overload_count-1]);
|
gb_swap(Entity *, procs[i], procs[overload_count-1]);
|
||||||
overload_count--;
|
overload_count--;
|
||||||
i--; // NOTE(bill): Counteract the post event
|
i--; // NOTE(bill): Counteract the post event
|
||||||
@@ -4892,7 +4892,7 @@ Type *check_call_arguments(Checker *c, Operand *operand, Type *proc_type, AstNod
|
|||||||
|
|
||||||
for (isize i = 0; i < overload_count; i++) {
|
for (isize i = 0; i < overload_count; i++) {
|
||||||
Entity *e = procs[i];
|
Entity *e = procs[i];
|
||||||
DeclInfo **found = map_decl_info_get(&c->info.entities, hash_pointer(e));
|
DeclInfo **found = map_get(&c->info.entities, hash_pointer(e));
|
||||||
GB_ASSERT(found != NULL);
|
GB_ASSERT(found != NULL);
|
||||||
DeclInfo *d = *found;
|
DeclInfo *d = *found;
|
||||||
check_entity_decl(c, e, d, NULL);
|
check_entity_decl(c, e, d, NULL);
|
||||||
|
|||||||
+14
-19
@@ -389,11 +389,6 @@ struct TypeAndToken {
|
|||||||
Token token;
|
Token token;
|
||||||
};
|
};
|
||||||
|
|
||||||
#define MAP_TYPE TypeAndToken
|
|
||||||
#define MAP_PROC map_type_and_token_
|
|
||||||
#define MAP_NAME MapTypeAndToken
|
|
||||||
#include "map.cpp"
|
|
||||||
|
|
||||||
void check_when_stmt(Checker *c, AstNodeWhenStmt *ws, u32 flags) {
|
void check_when_stmt(Checker *c, AstNodeWhenStmt *ws, u32 flags) {
|
||||||
flags &= ~Stmt_CheckScopeDecls;
|
flags &= ~Stmt_CheckScopeDecls;
|
||||||
Operand operand = {Addressing_Invalid};
|
Operand operand = {Addressing_Invalid};
|
||||||
@@ -535,7 +530,7 @@ bool check_using_stmt_entity(Checker *c, AstNodeUsingStmt *us, AstNode *expr, bo
|
|||||||
Type *t = base_type(type_deref(e->type));
|
Type *t = base_type(type_deref(e->type));
|
||||||
if (is_type_struct(t) || is_type_raw_union(t) || is_type_union(t)) {
|
if (is_type_struct(t) || is_type_raw_union(t) || is_type_union(t)) {
|
||||||
// TODO(bill): Make it work for unions too
|
// TODO(bill): Make it work for unions too
|
||||||
Scope **found_ = map_scope_get(&c->info.scopes, hash_pointer(t->Record.node));
|
Scope **found_ = map_get(&c->info.scopes, hash_pointer(t->Record.node));
|
||||||
GB_ASSERT(found_ != NULL);
|
GB_ASSERT(found_ != NULL);
|
||||||
Scope *found = *found_;
|
Scope *found = *found_;
|
||||||
for_array(i, found->elements.entries) {
|
for_array(i, found->elements.entries) {
|
||||||
@@ -1130,8 +1125,8 @@ void check_stmt_internal(Checker *c, AstNode *node, u32 flags) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
MapTypeAndToken seen = {}; // NOTE(bill): Multimap
|
Map<TypeAndToken> seen = {}; // NOTE(bill): Multimap
|
||||||
map_type_and_token_init(&seen, heap_allocator());
|
map_init(&seen, heap_allocator());
|
||||||
|
|
||||||
for_array(i, bs->stmts) {
|
for_array(i, bs->stmts) {
|
||||||
AstNode *stmt = bs->stmts[i];
|
AstNode *stmt = bs->stmts[i];
|
||||||
@@ -1222,13 +1217,13 @@ void check_stmt_internal(Checker *c, AstNode *node, u32 flags) {
|
|||||||
|
|
||||||
if (y.value.kind != ExactValue_Invalid) {
|
if (y.value.kind != ExactValue_Invalid) {
|
||||||
HashKey key = hash_exact_value(y.value);
|
HashKey key = hash_exact_value(y.value);
|
||||||
TypeAndToken *found = map_type_and_token_get(&seen, key);
|
TypeAndToken *found = map_get(&seen, key);
|
||||||
if (found != NULL) {
|
if (found != NULL) {
|
||||||
gbTempArenaMemory tmp = gb_temp_arena_memory_begin(&c->tmp_arena);
|
gbTempArenaMemory tmp = gb_temp_arena_memory_begin(&c->tmp_arena);
|
||||||
isize count = map_type_and_token_multi_count(&seen, key);
|
isize count = multi_map_count(&seen, key);
|
||||||
TypeAndToken *taps = gb_alloc_array(c->tmp_allocator, TypeAndToken, count);
|
TypeAndToken *taps = gb_alloc_array(c->tmp_allocator, TypeAndToken, count);
|
||||||
|
|
||||||
map_type_and_token_multi_get_all(&seen, key, taps);
|
multi_map_get_all(&seen, key, taps);
|
||||||
bool continue_outer = false;
|
bool continue_outer = false;
|
||||||
|
|
||||||
for (isize i = 0; i < count; i++) {
|
for (isize i = 0; i < count; i++) {
|
||||||
@@ -1254,7 +1249,7 @@ void check_stmt_internal(Checker *c, AstNode *node, u32 flags) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
TypeAndToken tap = {y.type, ast_node_token(y.expr)};
|
TypeAndToken tap = {y.type, ast_node_token(y.expr)};
|
||||||
map_type_and_token_multi_insert(&seen, key, tap);
|
multi_map_insert(&seen, key, tap);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1268,7 +1263,7 @@ void check_stmt_internal(Checker *c, AstNode *node, u32 flags) {
|
|||||||
check_close_scope(c);
|
check_close_scope(c);
|
||||||
}
|
}
|
||||||
|
|
||||||
map_type_and_token_destroy(&seen);
|
map_destroy(&seen);
|
||||||
|
|
||||||
check_close_scope(c);
|
check_close_scope(c);
|
||||||
case_end;
|
case_end;
|
||||||
@@ -1346,8 +1341,8 @@ void check_stmt_internal(Checker *c, AstNode *node, u32 flags) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
MapBool seen = {}; // Multimap
|
Map<bool> seen = {}; // Multimap
|
||||||
map_bool_init(&seen, heap_allocator());
|
map_init(&seen, heap_allocator());
|
||||||
|
|
||||||
for_array(i, bs->stmts) {
|
for_array(i, bs->stmts) {
|
||||||
AstNode *stmt = bs->stmts[i];
|
AstNode *stmt = bs->stmts[i];
|
||||||
@@ -1391,7 +1386,7 @@ void check_stmt_internal(Checker *c, AstNode *node, u32 flags) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
HashKey key = hash_pointer(y.type);
|
HashKey key = hash_pointer(y.type);
|
||||||
bool *found = map_bool_get(&seen, key);
|
bool *found = map_get(&seen, key);
|
||||||
if (found) {
|
if (found) {
|
||||||
TokenPos pos = cc->token.pos;
|
TokenPos pos = cc->token.pos;
|
||||||
gbString expr_str = expr_to_string(y.expr);
|
gbString expr_str = expr_to_string(y.expr);
|
||||||
@@ -1403,7 +1398,7 @@ void check_stmt_internal(Checker *c, AstNode *node, u32 flags) {
|
|||||||
gb_string_free(expr_str);
|
gb_string_free(expr_str);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
map_bool_set(&seen, key, cast(bool)true);
|
map_set(&seen, key, cast(bool)true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1434,7 +1429,7 @@ void check_stmt_internal(Checker *c, AstNode *node, u32 flags) {
|
|||||||
check_stmt_list(c, cc->stmts, mod_flags);
|
check_stmt_list(c, cc->stmts, mod_flags);
|
||||||
check_close_scope(c);
|
check_close_scope(c);
|
||||||
}
|
}
|
||||||
map_bool_destroy(&seen);
|
map_destroy(&seen);
|
||||||
|
|
||||||
check_close_scope(c);
|
check_close_scope(c);
|
||||||
case_end;
|
case_end;
|
||||||
@@ -1635,7 +1630,7 @@ void check_stmt_internal(Checker *c, AstNode *node, u32 flags) {
|
|||||||
Type *t = base_type(type_deref(e->type));
|
Type *t = base_type(type_deref(e->type));
|
||||||
|
|
||||||
if (is_type_struct(t) || is_type_raw_union(t)) {
|
if (is_type_struct(t) || is_type_raw_union(t)) {
|
||||||
Scope **found = map_scope_get(&c->info.scopes, hash_pointer(t->Record.node));
|
Scope **found = map_get(&c->info.scopes, hash_pointer(t->Record.node));
|
||||||
GB_ASSERT(found != NULL);
|
GB_ASSERT(found != NULL);
|
||||||
for_array(i, (*found)->elements.entries) {
|
for_array(i, (*found)->elements.entries) {
|
||||||
Entity *f = (*found)->elements.entries[i].value;
|
Entity *f = (*found)->elements.entries[i].value;
|
||||||
|
|||||||
+84
-114
@@ -195,7 +195,7 @@ struct DeclInfo {
|
|||||||
AstNode * init_expr;
|
AstNode * init_expr;
|
||||||
AstNode * proc_lit; // AstNode_ProcLit
|
AstNode * proc_lit; // AstNode_ProcLit
|
||||||
|
|
||||||
MapBool deps; // Key: Entity *
|
Map<bool> deps; // Key: Entity *
|
||||||
Array<BlockLabel> labels;
|
Array<BlockLabel> labels;
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -226,18 +226,13 @@ ExprInfo make_expr_info(bool is_lhs, AddressingMode mode, Type *type, ExactValue
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
#define MAP_TYPE Entity *
|
|
||||||
#define MAP_PROC map_entity_
|
|
||||||
#define MAP_NAME MapEntity
|
|
||||||
#include "map.cpp"
|
|
||||||
|
|
||||||
struct Scope {
|
struct Scope {
|
||||||
Scope * parent;
|
Scope * parent;
|
||||||
Scope * prev, *next;
|
Scope * prev, *next;
|
||||||
Scope * first_child;
|
Scope * first_child;
|
||||||
Scope * last_child;
|
Scope * last_child;
|
||||||
MapEntity elements; // Key: String
|
Map<Entity *> elements; // Key: String
|
||||||
MapBool implicit; // Key: Entity *
|
Map<bool> implicit; // Key: Entity *
|
||||||
|
|
||||||
Array<Scope *> shared;
|
Array<Scope *> shared;
|
||||||
Array<Scope *> imported;
|
Array<Scope *> imported;
|
||||||
@@ -254,31 +249,6 @@ gb_global Scope *universal_scope = NULL;
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
#define MAP_TYPE TypeAndValue
|
|
||||||
#define MAP_PROC map_tav_
|
|
||||||
#define MAP_NAME MapTypeAndValue
|
|
||||||
#include "map.cpp"
|
|
||||||
|
|
||||||
#define MAP_TYPE Scope *
|
|
||||||
#define MAP_PROC map_scope_
|
|
||||||
#define MAP_NAME MapScope
|
|
||||||
#include "map.cpp"
|
|
||||||
|
|
||||||
#define MAP_TYPE DeclInfo *
|
|
||||||
#define MAP_PROC map_decl_info_
|
|
||||||
#define MAP_NAME MapDeclInfo
|
|
||||||
#include "map.cpp"
|
|
||||||
|
|
||||||
#define MAP_TYPE AstFile *
|
|
||||||
#define MAP_PROC map_ast_file_
|
|
||||||
#define MAP_NAME MapAstFile
|
|
||||||
#include "map.cpp"
|
|
||||||
|
|
||||||
#define MAP_TYPE ExprInfo
|
|
||||||
#define MAP_PROC map_expr_info_
|
|
||||||
#define MAP_NAME MapExprInfo
|
|
||||||
#include "map.cpp"
|
|
||||||
|
|
||||||
struct DelayedDecl {
|
struct DelayedDecl {
|
||||||
Scope * parent;
|
Scope * parent;
|
||||||
AstNode *decl;
|
AstNode *decl;
|
||||||
@@ -304,16 +274,16 @@ struct CheckerContext {
|
|||||||
|
|
||||||
// CheckerInfo stores all the symbol information for a type-checked program
|
// CheckerInfo stores all the symbol information for a type-checked program
|
||||||
struct CheckerInfo {
|
struct CheckerInfo {
|
||||||
MapTypeAndValue types; // Key: AstNode * | Expression -> Type (and value)
|
Map<TypeAndValue> types; // Key: AstNode * | Expression -> Type (and value)
|
||||||
MapEntity definitions; // Key: AstNode * | Identifier -> Entity
|
Map<Entity *> definitions; // Key: AstNode * | Identifier -> Entity
|
||||||
MapEntity uses; // Key: AstNode * | Identifier -> Entity
|
Map<Entity *> uses; // Key: AstNode * | Identifier -> Entity
|
||||||
MapScope scopes; // Key: AstNode * | Node -> Scope
|
Map<Scope *> scopes; // Key: AstNode * | Node -> Scope
|
||||||
MapExprInfo untyped; // Key: AstNode * | Expression -> ExprInfo
|
Map<ExprInfo> untyped; // Key: AstNode * | Expression -> ExprInfo
|
||||||
MapEntity implicits; // Key: AstNode *
|
Map<Entity *> implicits; // Key: AstNode *
|
||||||
MapDeclInfo entities; // Key: Entity *
|
Map<DeclInfo *> entities; // Key: Entity *
|
||||||
MapEntity foreigns; // Key: String
|
Map<Entity *> foreigns; // Key: String
|
||||||
MapAstFile files; // Key: String (full path)
|
Map<AstFile *> files; // Key: String (full path)
|
||||||
MapIsize type_info_map; // Key: Type *
|
Map<isize> type_info_map; // Key: Type *
|
||||||
isize type_info_count;
|
isize type_info_count;
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -352,7 +322,7 @@ struct DelayedEntity {
|
|||||||
void init_declaration_info(DeclInfo *d, Scope *scope, DeclInfo *parent) {
|
void init_declaration_info(DeclInfo *d, Scope *scope, DeclInfo *parent) {
|
||||||
d->parent = parent;
|
d->parent = parent;
|
||||||
d->scope = scope;
|
d->scope = scope;
|
||||||
map_bool_init(&d->deps, heap_allocator());
|
map_init(&d->deps, heap_allocator());
|
||||||
array_init(&d->labels, heap_allocator());
|
array_init(&d->labels, heap_allocator());
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -363,7 +333,7 @@ DeclInfo *make_declaration_info(gbAllocator a, Scope *scope, DeclInfo *parent) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void destroy_declaration_info(DeclInfo *d) {
|
void destroy_declaration_info(DeclInfo *d) {
|
||||||
map_bool_destroy(&d->deps);
|
map_destroy(&d->deps);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool decl_info_has_init(DeclInfo *d) {
|
bool decl_info_has_init(DeclInfo *d) {
|
||||||
@@ -390,8 +360,8 @@ bool decl_info_has_init(DeclInfo *d) {
|
|||||||
Scope *make_scope(Scope *parent, gbAllocator allocator) {
|
Scope *make_scope(Scope *parent, gbAllocator allocator) {
|
||||||
Scope *s = gb_alloc_item(allocator, Scope);
|
Scope *s = gb_alloc_item(allocator, Scope);
|
||||||
s->parent = parent;
|
s->parent = parent;
|
||||||
map_entity_init(&s->elements, heap_allocator());
|
map_init(&s->elements, heap_allocator());
|
||||||
map_bool_init(&s->implicit, heap_allocator());
|
map_init(&s->implicit, heap_allocator());
|
||||||
array_init(&s->shared, heap_allocator());
|
array_init(&s->shared, heap_allocator());
|
||||||
array_init(&s->imported, heap_allocator());
|
array_init(&s->imported, heap_allocator());
|
||||||
|
|
||||||
@@ -417,8 +387,8 @@ void destroy_scope(Scope *scope) {
|
|||||||
destroy_scope(child);
|
destroy_scope(child);
|
||||||
}
|
}
|
||||||
|
|
||||||
map_entity_destroy(&scope->elements);
|
map_destroy(&scope->elements);
|
||||||
map_bool_destroy(&scope->implicit);
|
map_destroy(&scope->implicit);
|
||||||
array_free(&scope->shared);
|
array_free(&scope->shared);
|
||||||
array_free(&scope->imported);
|
array_free(&scope->imported);
|
||||||
|
|
||||||
@@ -428,7 +398,7 @@ void destroy_scope(Scope *scope) {
|
|||||||
void add_scope(Checker *c, AstNode *node, Scope *scope) {
|
void add_scope(Checker *c, AstNode *node, Scope *scope) {
|
||||||
GB_ASSERT(node != NULL);
|
GB_ASSERT(node != NULL);
|
||||||
GB_ASSERT(scope != NULL);
|
GB_ASSERT(scope != NULL);
|
||||||
map_scope_set(&c->info.scopes, hash_pointer(node), scope);
|
map_set(&c->info.scopes, hash_pointer(node), scope);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -454,13 +424,13 @@ void check_close_scope(Checker *c) {
|
|||||||
|
|
||||||
Entity *current_scope_lookup_entity(Scope *s, String name) {
|
Entity *current_scope_lookup_entity(Scope *s, String name) {
|
||||||
HashKey key = hash_string(name);
|
HashKey key = hash_string(name);
|
||||||
Entity **found = map_entity_get(&s->elements, key);
|
Entity **found = map_get(&s->elements, key);
|
||||||
if (found) {
|
if (found) {
|
||||||
return *found;
|
return *found;
|
||||||
}
|
}
|
||||||
for_array(i, s->shared) {
|
for_array(i, s->shared) {
|
||||||
Scope *shared = s->shared[i];
|
Scope *shared = s->shared[i];
|
||||||
Entity **found = map_entity_get(&shared->elements, key);
|
Entity **found = map_get(&shared->elements, key);
|
||||||
if (found) {
|
if (found) {
|
||||||
Entity *e = *found;
|
Entity *e = *found;
|
||||||
if (e->kind == Entity_Variable &&
|
if (e->kind == Entity_Variable &&
|
||||||
@@ -485,7 +455,7 @@ void scope_lookup_parent_entity(Scope *scope, String name, Scope **scope_, Entit
|
|||||||
bool gone_thru_file = false;
|
bool gone_thru_file = false;
|
||||||
HashKey key = hash_string(name);
|
HashKey key = hash_string(name);
|
||||||
for (Scope *s = scope; s != NULL; s = s->parent) {
|
for (Scope *s = scope; s != NULL; s = s->parent) {
|
||||||
Entity **found = map_entity_get(&s->elements, key);
|
Entity **found = map_get(&s->elements, key);
|
||||||
if (found) {
|
if (found) {
|
||||||
Entity *e = *found;
|
Entity *e = *found;
|
||||||
if (gone_thru_proc) {
|
if (gone_thru_proc) {
|
||||||
@@ -510,7 +480,7 @@ void scope_lookup_parent_entity(Scope *scope, String name, Scope **scope_, Entit
|
|||||||
// Check shared scopes - i.e. other files @ global scope
|
// Check shared scopes - i.e. other files @ global scope
|
||||||
for_array(i, s->shared) {
|
for_array(i, s->shared) {
|
||||||
Scope *shared = s->shared[i];
|
Scope *shared = s->shared[i];
|
||||||
Entity **found = map_entity_get(&shared->elements, key);
|
Entity **found = map_get(&shared->elements, key);
|
||||||
if (found) {
|
if (found) {
|
||||||
Entity *e = *found;
|
Entity *e = *found;
|
||||||
if (e->kind == Entity_Variable &&
|
if (e->kind == Entity_Variable &&
|
||||||
@@ -558,7 +528,7 @@ Entity *scope_lookup_entity(Scope *s, String name) {
|
|||||||
Entity *scope_insert_entity(Scope *s, Entity *entity) {
|
Entity *scope_insert_entity(Scope *s, Entity *entity) {
|
||||||
String name = entity->token.string;
|
String name = entity->token.string;
|
||||||
HashKey key = hash_string(name);
|
HashKey key = hash_string(name);
|
||||||
Entity **found = map_entity_get(&s->elements, key);
|
Entity **found = map_get(&s->elements, key);
|
||||||
|
|
||||||
#if 1
|
#if 1
|
||||||
// IMPORTANT NOTE(bill): Procedure overloading code
|
// IMPORTANT NOTE(bill): Procedure overloading code
|
||||||
@@ -576,15 +546,15 @@ Entity *scope_insert_entity(Scope *s, Entity *entity) {
|
|||||||
if (s->is_global) {
|
if (s->is_global) {
|
||||||
return prev;
|
return prev;
|
||||||
}
|
}
|
||||||
map_entity_multi_insert(&s->elements, key, entity);
|
multi_map_insert(&s->elements, key, entity);
|
||||||
} else {
|
} else {
|
||||||
map_entity_set(&s->elements, key, entity);
|
map_set(&s->elements, key, entity);
|
||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
if (found) {
|
if (found) {
|
||||||
return *found;
|
return *found;
|
||||||
}
|
}
|
||||||
map_entity_set(&s->elements, key, entity);
|
map_set(&s->elements, key, entity);
|
||||||
#endif
|
#endif
|
||||||
if (entity->scope == NULL) {
|
if (entity->scope == NULL) {
|
||||||
entity->scope = s;
|
entity->scope = s;
|
||||||
@@ -599,7 +569,7 @@ void check_scope_usage(Checker *c, Scope *scope) {
|
|||||||
|
|
||||||
|
|
||||||
void add_dependency(DeclInfo *d, Entity *e) {
|
void add_dependency(DeclInfo *d, Entity *e) {
|
||||||
map_bool_set(&d->deps, hash_pointer(e), cast(bool)true);
|
map_set(&d->deps, hash_pointer(e), cast(bool)true);
|
||||||
}
|
}
|
||||||
|
|
||||||
void add_declaration_dependency(Checker *c, Entity *e) {
|
void add_declaration_dependency(Checker *c, Entity *e) {
|
||||||
@@ -607,7 +577,7 @@ void add_declaration_dependency(Checker *c, Entity *e) {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (c->context.decl != NULL) {
|
if (c->context.decl != NULL) {
|
||||||
DeclInfo **found = map_decl_info_get(&c->info.entities, hash_pointer(e));
|
DeclInfo **found = map_get(&c->info.entities, hash_pointer(e));
|
||||||
if (found) {
|
if (found) {
|
||||||
add_dependency(c->context.decl, e);
|
add_dependency(c->context.decl, e);
|
||||||
}
|
}
|
||||||
@@ -705,31 +675,31 @@ void init_universal_scope(void) {
|
|||||||
|
|
||||||
void init_checker_info(CheckerInfo *i) {
|
void init_checker_info(CheckerInfo *i) {
|
||||||
gbAllocator a = heap_allocator();
|
gbAllocator a = heap_allocator();
|
||||||
map_tav_init(&i->types, a);
|
map_init(&i->types, a);
|
||||||
map_entity_init(&i->definitions, a);
|
map_init(&i->definitions, a);
|
||||||
map_entity_init(&i->uses, a);
|
map_init(&i->uses, a);
|
||||||
map_scope_init(&i->scopes, a);
|
map_init(&i->scopes, a);
|
||||||
map_decl_info_init(&i->entities, a);
|
map_init(&i->entities, a);
|
||||||
map_expr_info_init(&i->untyped, a);
|
map_init(&i->untyped, a);
|
||||||
map_entity_init(&i->foreigns, a);
|
map_init(&i->foreigns, a);
|
||||||
map_entity_init(&i->implicits, a);
|
map_init(&i->implicits, a);
|
||||||
map_isize_init(&i->type_info_map, a);
|
map_init(&i->type_info_map, a);
|
||||||
map_ast_file_init(&i->files, a);
|
map_init(&i->files, a);
|
||||||
i->type_info_count = 0;
|
i->type_info_count = 0;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void destroy_checker_info(CheckerInfo *i) {
|
void destroy_checker_info(CheckerInfo *i) {
|
||||||
map_tav_destroy(&i->types);
|
map_destroy(&i->types);
|
||||||
map_entity_destroy(&i->definitions);
|
map_destroy(&i->definitions);
|
||||||
map_entity_destroy(&i->uses);
|
map_destroy(&i->uses);
|
||||||
map_scope_destroy(&i->scopes);
|
map_destroy(&i->scopes);
|
||||||
map_decl_info_destroy(&i->entities);
|
map_destroy(&i->entities);
|
||||||
map_expr_info_destroy(&i->untyped);
|
map_destroy(&i->untyped);
|
||||||
map_entity_destroy(&i->foreigns);
|
map_destroy(&i->foreigns);
|
||||||
map_entity_destroy(&i->implicits);
|
map_destroy(&i->implicits);
|
||||||
map_isize_destroy(&i->type_info_map);
|
map_destroy(&i->type_info_map);
|
||||||
map_ast_file_destroy(&i->files);
|
map_destroy(&i->files);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -793,11 +763,11 @@ void destroy_checker(Checker *c) {
|
|||||||
|
|
||||||
Entity *entity_of_ident(CheckerInfo *i, AstNode *identifier) {
|
Entity *entity_of_ident(CheckerInfo *i, AstNode *identifier) {
|
||||||
if (identifier->kind == AstNode_Ident) {
|
if (identifier->kind == AstNode_Ident) {
|
||||||
Entity **found = map_entity_get(&i->definitions, hash_pointer(identifier));
|
Entity **found = map_get(&i->definitions, hash_pointer(identifier));
|
||||||
if (found) {
|
if (found) {
|
||||||
return *found;
|
return *found;
|
||||||
}
|
}
|
||||||
found = map_entity_get(&i->uses, hash_pointer(identifier));
|
found = map_get(&i->uses, hash_pointer(identifier));
|
||||||
if (found) {
|
if (found) {
|
||||||
return *found;
|
return *found;
|
||||||
}
|
}
|
||||||
@@ -808,7 +778,7 @@ Entity *entity_of_ident(CheckerInfo *i, AstNode *identifier) {
|
|||||||
|
|
||||||
TypeAndValue type_and_value_of_expr(CheckerInfo *i, AstNode *expression) {
|
TypeAndValue type_and_value_of_expr(CheckerInfo *i, AstNode *expression) {
|
||||||
TypeAndValue result = {};
|
TypeAndValue result = {};
|
||||||
TypeAndValue *found = map_tav_get(&i->types, hash_pointer(expression));
|
TypeAndValue *found = map_get(&i->types, hash_pointer(expression));
|
||||||
if (found) result = *found;
|
if (found) result = *found;
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
@@ -831,7 +801,7 @@ Type *type_of_expr(CheckerInfo *i, AstNode *expr) {
|
|||||||
|
|
||||||
|
|
||||||
void add_untyped(CheckerInfo *i, AstNode *expression, bool lhs, AddressingMode mode, Type *basic_type, ExactValue value) {
|
void add_untyped(CheckerInfo *i, AstNode *expression, bool lhs, AddressingMode mode, Type *basic_type, ExactValue value) {
|
||||||
map_expr_info_set(&i->untyped, hash_pointer(expression), make_expr_info(lhs, mode, basic_type, value));
|
map_set(&i->untyped, hash_pointer(expression), make_expr_info(lhs, mode, basic_type, value));
|
||||||
}
|
}
|
||||||
|
|
||||||
void add_type_and_value(CheckerInfo *i, AstNode *expression, AddressingMode mode, Type *type, ExactValue value) {
|
void add_type_and_value(CheckerInfo *i, AstNode *expression, AddressingMode mode, Type *type, ExactValue value) {
|
||||||
@@ -858,7 +828,7 @@ void add_type_and_value(CheckerInfo *i, AstNode *expression, AddressingMode mode
|
|||||||
tv.type = type;
|
tv.type = type;
|
||||||
tv.value = value;
|
tv.value = value;
|
||||||
tv.mode = mode;
|
tv.mode = mode;
|
||||||
map_tav_set(&i->types, hash_pointer(expression), tv);
|
map_set(&i->types, hash_pointer(expression), tv);
|
||||||
}
|
}
|
||||||
|
|
||||||
void add_entity_definition(CheckerInfo *i, AstNode *identifier, Entity *entity) {
|
void add_entity_definition(CheckerInfo *i, AstNode *identifier, Entity *entity) {
|
||||||
@@ -868,7 +838,7 @@ void add_entity_definition(CheckerInfo *i, AstNode *identifier, Entity *entity)
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
HashKey key = hash_pointer(identifier);
|
HashKey key = hash_pointer(identifier);
|
||||||
map_entity_set(&i->definitions, key, entity);
|
map_set(&i->definitions, key, entity);
|
||||||
} else {
|
} else {
|
||||||
// NOTE(bill): Error should handled elsewhere
|
// NOTE(bill): Error should handled elsewhere
|
||||||
}
|
}
|
||||||
@@ -918,7 +888,7 @@ void add_entity_use(Checker *c, AstNode *identifier, Entity *entity) {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
HashKey key = hash_pointer(identifier);
|
HashKey key = hash_pointer(identifier);
|
||||||
map_entity_set(&c->info.uses, key, entity);
|
map_set(&c->info.uses, key, entity);
|
||||||
add_declaration_dependency(c, entity); // TODO(bill): Should this be here?
|
add_declaration_dependency(c, entity); // TODO(bill): Should this be here?
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -928,14 +898,14 @@ void add_entity_and_decl_info(Checker *c, AstNode *identifier, Entity *e, DeclIn
|
|||||||
GB_ASSERT(e != NULL && d != NULL);
|
GB_ASSERT(e != NULL && d != NULL);
|
||||||
GB_ASSERT(identifier->Ident.string == e->token.string);
|
GB_ASSERT(identifier->Ident.string == e->token.string);
|
||||||
add_entity(c, e->scope, identifier, e);
|
add_entity(c, e->scope, identifier, e);
|
||||||
map_decl_info_set(&c->info.entities, hash_pointer(e), d);
|
map_set(&c->info.entities, hash_pointer(e), d);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void add_implicit_entity(Checker *c, AstNode *node, Entity *e) {
|
void add_implicit_entity(Checker *c, AstNode *node, Entity *e) {
|
||||||
GB_ASSERT(node != NULL);
|
GB_ASSERT(node != NULL);
|
||||||
GB_ASSERT(e != NULL);
|
GB_ASSERT(e != NULL);
|
||||||
map_entity_set(&c->info.implicits, hash_pointer(node), e);
|
map_set(&c->info.implicits, hash_pointer(node), e);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -951,14 +921,14 @@ void add_type_info_type(Checker *c, Type *t) {
|
|||||||
return; // Could be nil
|
return; // Could be nil
|
||||||
}
|
}
|
||||||
|
|
||||||
if (map_isize_get(&c->info.type_info_map, hash_pointer(t)) != NULL) {
|
if (map_get(&c->info.type_info_map, hash_pointer(t)) != NULL) {
|
||||||
// Types have already been added
|
// Types have already been added
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
isize ti_index = -1;
|
isize ti_index = -1;
|
||||||
for_array(i, c->info.type_info_map.entries) {
|
for_array(i, c->info.type_info_map.entries) {
|
||||||
MapIsizeEntry *e = &c->info.type_info_map.entries[i];
|
auto *e = &c->info.type_info_map.entries[i];
|
||||||
Type *prev_type = cast(Type *)e->key.ptr;
|
Type *prev_type = cast(Type *)e->key.ptr;
|
||||||
if (are_types_identical(t, prev_type)) {
|
if (are_types_identical(t, prev_type)) {
|
||||||
// Duplicate entry
|
// Duplicate entry
|
||||||
@@ -972,7 +942,7 @@ void add_type_info_type(Checker *c, Type *t) {
|
|||||||
ti_index = c->info.type_info_count;
|
ti_index = c->info.type_info_count;
|
||||||
c->info.type_info_count++;
|
c->info.type_info_count++;
|
||||||
}
|
}
|
||||||
map_isize_set(&c->info.type_info_map, hash_pointer(t), ti_index);
|
map_set(&c->info.type_info_map, hash_pointer(t), ti_index);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@@ -1123,17 +1093,17 @@ void add_curr_ast_file(Checker *c, AstFile *file) {
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
void add_dependency_to_map(MapEntity *map, CheckerInfo *info, Entity *node) {
|
void add_dependency_to_map(Map<Entity *> *map, CheckerInfo *info, Entity *node) {
|
||||||
if (node == NULL) {
|
if (node == NULL) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (map_entity_get(map, hash_pointer(node)) != NULL) {
|
if (map_get(map, hash_pointer(node)) != NULL) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
map_entity_set(map, hash_pointer(node), node);
|
map_set(map, hash_pointer(node), node);
|
||||||
|
|
||||||
|
|
||||||
DeclInfo **found = map_decl_info_get(&info->entities, hash_pointer(node));
|
DeclInfo **found = map_get(&info->entities, hash_pointer(node));
|
||||||
if (found == NULL) {
|
if (found == NULL) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -1145,9 +1115,9 @@ void add_dependency_to_map(MapEntity *map, CheckerInfo *info, Entity *node) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
MapEntity generate_minimum_dependency_map(CheckerInfo *info, Entity *start) {
|
Map<Entity *> generate_minimum_dependency_map(CheckerInfo *info, Entity *start) {
|
||||||
MapEntity map = {}; // Key: Entity *
|
Map<Entity *> map = {}; // Key: Entity *
|
||||||
map_entity_init(&map, heap_allocator());
|
map_init(&map, heap_allocator());
|
||||||
|
|
||||||
for_array(i, info->definitions.entries) {
|
for_array(i, info->definitions.entries) {
|
||||||
Entity *e = info->definitions.entries[i].value;
|
Entity *e = info->definitions.entries[i].value;
|
||||||
@@ -1289,7 +1259,7 @@ bool check_is_entity_overloaded(Entity *e) {
|
|||||||
}
|
}
|
||||||
Scope *s = e->scope;
|
Scope *s = e->scope;
|
||||||
HashKey key = hash_string(e->token.string);
|
HashKey key = hash_string(e->token.string);
|
||||||
isize overload_count = map_entity_multi_count(&s->elements, key);
|
isize overload_count = multi_map_count(&s->elements, key);
|
||||||
return overload_count > 1;
|
return overload_count > 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1309,7 +1279,7 @@ void check_procedure_overloading(Checker *c, Entity *e) {
|
|||||||
String name = e->token.string;
|
String name = e->token.string;
|
||||||
HashKey key = hash_string(name);
|
HashKey key = hash_string(name);
|
||||||
Scope *s = e->scope;
|
Scope *s = e->scope;
|
||||||
isize overload_count = map_entity_multi_count(&s->elements, key);
|
isize overload_count = multi_map_count(&s->elements, key);
|
||||||
GB_ASSERT(overload_count >= 1);
|
GB_ASSERT(overload_count >= 1);
|
||||||
if (overload_count == 1) {
|
if (overload_count == 1) {
|
||||||
e->Procedure.overload_kind = Overload_No;
|
e->Procedure.overload_kind = Overload_No;
|
||||||
@@ -1320,7 +1290,7 @@ void check_procedure_overloading(Checker *c, Entity *e) {
|
|||||||
|
|
||||||
gbTempArenaMemory tmp = gb_temp_arena_memory_begin(&c->tmp_arena);
|
gbTempArenaMemory tmp = gb_temp_arena_memory_begin(&c->tmp_arena);
|
||||||
Entity **procs = gb_alloc_array(c->tmp_allocator, Entity *, overload_count);
|
Entity **procs = gb_alloc_array(c->tmp_allocator, Entity *, overload_count);
|
||||||
map_entity_multi_get_all(&s->elements, key, procs);
|
multi_map_get_all(&s->elements, key, procs);
|
||||||
|
|
||||||
for (isize j = 0; j < overload_count; j++) {
|
for (isize j = 0; j < overload_count; j++) {
|
||||||
Entity *p = procs[j];
|
Entity *p = procs[j];
|
||||||
@@ -1660,7 +1630,7 @@ void check_all_global_entities(Checker *c) {
|
|||||||
Scope *prev_file = {};
|
Scope *prev_file = {};
|
||||||
|
|
||||||
for_array(i, c->info.entities.entries) {
|
for_array(i, c->info.entities.entries) {
|
||||||
MapDeclInfoEntry *entry = &c->info.entities.entries[i];
|
auto *entry = &c->info.entities.entries[i];
|
||||||
Entity *e = cast(Entity *)cast(uintptr)entry->key.key;
|
Entity *e = cast(Entity *)cast(uintptr)entry->key.key;
|
||||||
DeclInfo *d = entry->value;
|
DeclInfo *d = entry->value;
|
||||||
|
|
||||||
@@ -1698,7 +1668,7 @@ void check_all_global_entities(Checker *c) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
for_array(i, c->info.entities.entries) {
|
for_array(i, c->info.entities.entries) {
|
||||||
MapDeclInfoEntry *entry = &c->info.entities.entries[i];
|
auto *entry = &c->info.entities.entries[i];
|
||||||
Entity *e = cast(Entity *)cast(uintptr)entry->key.key;
|
Entity *e = cast(Entity *)cast(uintptr)entry->key.key;
|
||||||
if (e->kind != Entity_Procedure) {
|
if (e->kind != Entity_Procedure) {
|
||||||
continue;
|
continue;
|
||||||
@@ -1769,7 +1739,7 @@ String path_to_entity_name(String name, String fullpath) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void check_import_entities(Checker *c, MapScope *file_scopes) {
|
void check_import_entities(Checker *c, Map<Scope *> *file_scopes) {
|
||||||
#if 0
|
#if 0
|
||||||
// TODO(bill): Dependency ordering for imports
|
// TODO(bill): Dependency ordering for imports
|
||||||
{
|
{
|
||||||
@@ -1810,7 +1780,7 @@ void check_import_entities(Checker *c, MapScope *file_scopes) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
HashKey key = hash_string(id->fullpath);
|
HashKey key = hash_string(id->fullpath);
|
||||||
Scope **found = map_scope_get(file_scopes, key);
|
Scope **found = map_get(file_scopes, key);
|
||||||
if (found == NULL) {
|
if (found == NULL) {
|
||||||
for_array(scope_index, file_scopes->entries) {
|
for_array(scope_index, file_scopes->entries) {
|
||||||
Scope *scope = file_scopes->entries[scope_index].value;
|
Scope *scope = file_scopes->entries[scope_index].value;
|
||||||
@@ -1883,7 +1853,7 @@ void check_import_entities(Checker *c, MapScope *file_scopes) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
HashKey key = hash_string(id->fullpath);
|
HashKey key = hash_string(id->fullpath);
|
||||||
Scope **found = map_scope_get(file_scopes, key);
|
Scope **found = map_get(file_scopes, key);
|
||||||
if (found == NULL) {
|
if (found == NULL) {
|
||||||
for_array(scope_index, file_scopes->entries) {
|
for_array(scope_index, file_scopes->entries) {
|
||||||
Scope *scope = file_scopes->entries[scope_index].value;
|
Scope *scope = file_scopes->entries[scope_index].value;
|
||||||
@@ -1946,7 +1916,7 @@ void check_import_entities(Checker *c, MapScope *file_scopes) {
|
|||||||
// TODO(bill): Should these entities be imported but cause an error when used?
|
// TODO(bill): Should these entities be imported but cause an error when used?
|
||||||
bool ok = add_entity(c, parent_scope, e->identifier, e);
|
bool ok = add_entity(c, parent_scope, e->identifier, e);
|
||||||
if (ok) {
|
if (ok) {
|
||||||
map_bool_set(&parent_scope->implicit, hash_pointer(e), true);
|
map_set(&parent_scope->implicit, hash_pointer(e), true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
@@ -2021,8 +1991,8 @@ void check_import_entities(Checker *c, MapScope *file_scopes) {
|
|||||||
|
|
||||||
|
|
||||||
void check_parsed_files(Checker *c) {
|
void check_parsed_files(Checker *c) {
|
||||||
MapScope file_scopes; // Key: String (fullpath)
|
Map<Scope *> file_scopes; // Key: String (fullpath)
|
||||||
map_scope_init(&file_scopes, heap_allocator());
|
map_init(&file_scopes, heap_allocator());
|
||||||
|
|
||||||
// Map full filepaths to Scopes
|
// Map full filepaths to Scopes
|
||||||
for_array(i, c->parser->files) {
|
for_array(i, c->parser->files) {
|
||||||
@@ -2047,8 +2017,8 @@ void check_parsed_files(Checker *c) {
|
|||||||
f->scope = scope;
|
f->scope = scope;
|
||||||
f->decl_info = make_declaration_info(c->allocator, f->scope, c->context.decl);
|
f->decl_info = make_declaration_info(c->allocator, f->scope, c->context.decl);
|
||||||
HashKey key = hash_string(f->tokenizer.fullpath);
|
HashKey key = hash_string(f->tokenizer.fullpath);
|
||||||
map_scope_set(&file_scopes, key, scope);
|
map_set(&file_scopes, key, scope);
|
||||||
map_ast_file_set(&c->info.files, key, f);
|
map_set(&c->info.files, key, f);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Collect Entities
|
// Collect Entities
|
||||||
@@ -2091,7 +2061,7 @@ void check_parsed_files(Checker *c) {
|
|||||||
|
|
||||||
// Add untyped expression values
|
// Add untyped expression values
|
||||||
for_array(i, c->info.untyped.entries) {
|
for_array(i, c->info.untyped.entries) {
|
||||||
MapExprInfoEntry *entry = &c->info.untyped.entries[i];
|
auto *entry = &c->info.untyped.entries[i];
|
||||||
HashKey key = entry->key;
|
HashKey key = entry->key;
|
||||||
AstNode *expr = cast(AstNode *)cast(uintptr)key.key;
|
AstNode *expr = cast(AstNode *)cast(uintptr)key.key;
|
||||||
ExprInfo *info = &entry->value;
|
ExprInfo *info = &entry->value;
|
||||||
@@ -2166,6 +2136,6 @@ void check_parsed_files(Checker *c) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
map_scope_destroy(&file_scopes);
|
map_destroy(&file_scopes);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
+1
-19
@@ -18,6 +18,7 @@ gbAllocator heap_allocator(void) {
|
|||||||
#include "array.cpp"
|
#include "array.cpp"
|
||||||
#include "integer128.cpp"
|
#include "integer128.cpp"
|
||||||
#include "murmurhash3.cpp"
|
#include "murmurhash3.cpp"
|
||||||
|
#include "map.cpp"
|
||||||
|
|
||||||
u128 fnv128a(void const *data, isize len) {
|
u128 fnv128a(void const *data, isize len) {
|
||||||
u128 o = u128_lo_hi(0x13bull, 0x1000000ull);
|
u128 o = u128_lo_hi(0x13bull, 0x1000000ull);
|
||||||
@@ -234,23 +235,4 @@ f64 gb_sqrt(f64 x) {
|
|||||||
} \
|
} \
|
||||||
} while (0)
|
} while (0)
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////
|
|
||||||
//
|
|
||||||
// Generic Data Structures
|
|
||||||
//
|
|
||||||
////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
#define MAP_TYPE String
|
|
||||||
#define MAP_PROC map_string_
|
|
||||||
#define MAP_NAME MapString
|
|
||||||
#include "map.cpp"
|
|
||||||
|
|
||||||
#define MAP_TYPE bool
|
|
||||||
#define MAP_PROC map_bool_
|
|
||||||
#define MAP_NAME MapBool
|
|
||||||
#include "map.cpp"
|
|
||||||
|
|
||||||
#define MAP_TYPE isize
|
|
||||||
#define MAP_PROC map_isize_
|
|
||||||
#define MAP_NAME MapIsize
|
|
||||||
#include "map.cpp"
|
|
||||||
|
|||||||
@@ -4,6 +4,7 @@
|
|||||||
// IMPORTANT TODO(bill): This needs to be completely fixed!!!!!!!!
|
// IMPORTANT TODO(bill): This needs to be completely fixed!!!!!!!!
|
||||||
|
|
||||||
struct AstNode;
|
struct AstNode;
|
||||||
|
struct HashKey;
|
||||||
|
|
||||||
struct Complex128 {
|
struct Complex128 {
|
||||||
f64 real, imag;
|
f64 real, imag;
|
||||||
|
|||||||
+79
-88
@@ -3,15 +3,6 @@ struct irBlock;
|
|||||||
struct irValue;
|
struct irValue;
|
||||||
struct irDebugInfo;
|
struct irDebugInfo;
|
||||||
|
|
||||||
#define MAP_TYPE irValue *
|
|
||||||
#define MAP_PROC map_ir_value_
|
|
||||||
#define MAP_NAME MapIrValue
|
|
||||||
#include "map.cpp"
|
|
||||||
|
|
||||||
#define MAP_TYPE irDebugInfo *
|
|
||||||
#define MAP_PROC map_ir_debug_info_
|
|
||||||
#define MAP_NAME MapIrDebugInfo
|
|
||||||
#include "map.cpp"
|
|
||||||
|
|
||||||
|
|
||||||
struct irModule {
|
struct irModule {
|
||||||
@@ -28,11 +19,11 @@ struct irModule {
|
|||||||
String layout;
|
String layout;
|
||||||
// String triple;
|
// String triple;
|
||||||
|
|
||||||
MapEntity min_dep_map; // Key: Entity *
|
Map<Entity *> min_dep_map; // Key: Entity *
|
||||||
MapIrValue values; // Key: Entity *
|
Map<irValue *> values; // Key: Entity *
|
||||||
MapIrValue members; // Key: String
|
Map<irValue *> members; // Key: String
|
||||||
MapString entity_names; // Key: Entity * of the typename
|
Map<String> entity_names; // Key: Entity * of the typename
|
||||||
MapIrDebugInfo debug_info; // Key: Unique pointer
|
Map<irDebugInfo *> debug_info; // Key: Unique pointer
|
||||||
i32 global_string_index;
|
i32 global_string_index;
|
||||||
i32 global_array_index; // For ConstantSlice
|
i32 global_array_index; // For ConstantSlice
|
||||||
i32 global_generated_index;
|
i32 global_generated_index;
|
||||||
@@ -811,7 +802,7 @@ String ir_get_global_name(irModule *m, irValue *v) {
|
|||||||
irValueGlobal *g = &v->Global;
|
irValueGlobal *g = &v->Global;
|
||||||
Entity *e = g->entity;
|
Entity *e = g->entity;
|
||||||
String name = e->token.string;
|
String name = e->token.string;
|
||||||
String *found = map_string_get(&m->entity_names, hash_pointer(e));
|
String *found = map_get(&m->entity_names, hash_pointer(e));
|
||||||
if (found != NULL) {
|
if (found != NULL) {
|
||||||
name = *found;
|
name = *found;
|
||||||
}
|
}
|
||||||
@@ -1136,14 +1127,14 @@ irValue *ir_generate_array(irModule *m, Type *elem_type, i64 count, String prefi
|
|||||||
irValue *value = ir_value_global(a, e, NULL);
|
irValue *value = ir_value_global(a, e, NULL);
|
||||||
value->Global.is_private = true;
|
value->Global.is_private = true;
|
||||||
ir_module_add_value(m, e, value);
|
ir_module_add_value(m, e, value);
|
||||||
map_ir_value_set(&m->members, hash_string(token.string), value);
|
map_set(&m->members, hash_string(token.string), value);
|
||||||
return value;
|
return value;
|
||||||
}
|
}
|
||||||
|
|
||||||
irBlock *ir_new_block(irProcedure *proc, AstNode *node, char *label) {
|
irBlock *ir_new_block(irProcedure *proc, AstNode *node, char *label) {
|
||||||
Scope *scope = NULL;
|
Scope *scope = NULL;
|
||||||
if (node != NULL) {
|
if (node != NULL) {
|
||||||
Scope **found = map_scope_get(&proc->module->info->scopes, hash_pointer(node));
|
Scope **found = map_get(&proc->module->info->scopes, hash_pointer(node));
|
||||||
if (found) {
|
if (found) {
|
||||||
scope = *found;
|
scope = *found;
|
||||||
} else {
|
} else {
|
||||||
@@ -1239,7 +1230,7 @@ irValue *ir_add_module_constant(irModule *m, Type *type, ExactValue value) {
|
|||||||
Entity *e = make_entity_constant(a, NULL, make_token_ident(name), t, value);
|
Entity *e = make_entity_constant(a, NULL, make_token_ident(name), t, value);
|
||||||
irValue *g = ir_value_global(a, e, backing_array);
|
irValue *g = ir_value_global(a, e, backing_array);
|
||||||
ir_module_add_value(m, e, g);
|
ir_module_add_value(m, e, g);
|
||||||
map_ir_value_set(&m->members, hash_string(name), g);
|
map_set(&m->members, hash_string(name), g);
|
||||||
|
|
||||||
return ir_value_constant_slice(a, type, g, count);
|
return ir_value_constant_slice(a, type, g, count);
|
||||||
}
|
}
|
||||||
@@ -1270,7 +1261,7 @@ irValue *ir_add_global_string_array(irModule *m, String string) {
|
|||||||
// g->Global.is_constant = true;
|
// g->Global.is_constant = true;
|
||||||
|
|
||||||
ir_module_add_value(m, entity, g);
|
ir_module_add_value(m, entity, g);
|
||||||
map_ir_value_set(&m->members, hash_string(name), g);
|
map_set(&m->members, hash_string(name), g);
|
||||||
|
|
||||||
return g;
|
return g;
|
||||||
}
|
}
|
||||||
@@ -1291,7 +1282,7 @@ irValue *ir_add_local(irProcedure *proc, Entity *e, AstNode *expr) {
|
|||||||
// }
|
// }
|
||||||
|
|
||||||
if (expr != NULL && proc->entity != NULL) {
|
if (expr != NULL && proc->entity != NULL) {
|
||||||
irDebugInfo *di = *map_ir_debug_info_get(&proc->module->debug_info, hash_pointer(proc->entity));
|
irDebugInfo *di = *map_get(&proc->module->debug_info, hash_pointer(proc->entity));
|
||||||
ir_emit(proc, ir_instr_debug_declare(proc, di, expr, e, true, instr));
|
ir_emit(proc, ir_instr_debug_declare(proc, di, expr, e, true, instr));
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1299,7 +1290,7 @@ irValue *ir_add_local(irProcedure *proc, Entity *e, AstNode *expr) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
irValue *ir_add_local_for_identifier(irProcedure *proc, AstNode *name, bool zero_initialized) {
|
irValue *ir_add_local_for_identifier(irProcedure *proc, AstNode *name, bool zero_initialized) {
|
||||||
Entity **found = map_entity_get(&proc->module->info->definitions, hash_pointer(name));
|
Entity **found = map_get(&proc->module->info->definitions, hash_pointer(name));
|
||||||
if (found) {
|
if (found) {
|
||||||
Entity *e = *found;
|
Entity *e = *found;
|
||||||
ir_emit_comment(proc, e->token.string);
|
ir_emit_comment(proc, e->token.string);
|
||||||
@@ -1341,7 +1332,7 @@ irValue *ir_add_global_generated(irModule *m, Type *type, irValue *value) {
|
|||||||
|
|
||||||
irValue *g = ir_value_global(a, e, value);
|
irValue *g = ir_value_global(a, e, value);
|
||||||
ir_module_add_value(m, e, g);
|
ir_module_add_value(m, e, g);
|
||||||
map_ir_value_set(&m->members, hash_string(name), g);
|
map_set(&m->members, hash_string(name), g);
|
||||||
return g;
|
return g;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1407,7 +1398,7 @@ irDebugInfo *ir_add_debug_info_file(irProcedure *proc, AstFile *file) {
|
|||||||
di->File.filename = filename;
|
di->File.filename = filename;
|
||||||
di->File.directory = directory;
|
di->File.directory = directory;
|
||||||
|
|
||||||
map_ir_debug_info_set(&proc->module->debug_info, hash_pointer(file), di);
|
map_set(&proc->module->debug_info, hash_pointer(file), di);
|
||||||
return di;
|
return di;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1424,7 +1415,7 @@ irDebugInfo *ir_add_debug_info_proc(irProcedure *proc, Entity *entity, String na
|
|||||||
di->Proc.file = file;
|
di->Proc.file = file;
|
||||||
di->Proc.pos = entity->token.pos;
|
di->Proc.pos = entity->token.pos;
|
||||||
|
|
||||||
map_ir_debug_info_set(&proc->module->debug_info, hash_pointer(entity), di);
|
map_set(&proc->module->debug_info, hash_pointer(entity), di);
|
||||||
return di;
|
return di;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1517,7 +1508,7 @@ irValue *ir_emit_call(irProcedure *p, irValue *value, irValue **args, isize arg_
|
|||||||
|
|
||||||
irValue *ir_emit_global_call(irProcedure *proc, char *name_, irValue **args, isize arg_count) {
|
irValue *ir_emit_global_call(irProcedure *proc, char *name_, irValue **args, isize arg_count) {
|
||||||
String name = make_string_c(name_);
|
String name = make_string_c(name_);
|
||||||
irValue **found = map_ir_value_get(&proc->module->members, hash_string(name));
|
irValue **found = map_get(&proc->module->members, hash_string(name));
|
||||||
GB_ASSERT_MSG(found != NULL, "%.*s", LIT(name));
|
GB_ASSERT_MSG(found != NULL, "%.*s", LIT(name));
|
||||||
irValue *gp = *found;
|
irValue *gp = *found;
|
||||||
return ir_emit_call(proc, gp, args, arg_count);
|
return ir_emit_call(proc, gp, args, arg_count);
|
||||||
@@ -3280,7 +3271,7 @@ isize ir_type_info_index(CheckerInfo *info, Type *type) {
|
|||||||
|
|
||||||
isize entry_index = -1;
|
isize entry_index = -1;
|
||||||
HashKey key = hash_pointer(type);
|
HashKey key = hash_pointer(type);
|
||||||
isize *found_entry_index = map_isize_get(&info->type_info_map, key);
|
isize *found_entry_index = map_get(&info->type_info_map, key);
|
||||||
if (found_entry_index) {
|
if (found_entry_index) {
|
||||||
entry_index = *found_entry_index;
|
entry_index = *found_entry_index;
|
||||||
}
|
}
|
||||||
@@ -3288,12 +3279,12 @@ isize ir_type_info_index(CheckerInfo *info, Type *type) {
|
|||||||
// NOTE(bill): Do manual search
|
// NOTE(bill): Do manual search
|
||||||
// TODO(bill): This is O(n) and can be very slow
|
// TODO(bill): This is O(n) and can be very slow
|
||||||
for_array(i, info->type_info_map.entries){
|
for_array(i, info->type_info_map.entries){
|
||||||
MapIsizeEntry *e = &info->type_info_map.entries[i];
|
auto *e = &info->type_info_map.entries[i];
|
||||||
Type *prev_type = cast(Type *)e->key.ptr;
|
Type *prev_type = cast(Type *)e->key.ptr;
|
||||||
if (are_types_identical(prev_type, type)) {
|
if (are_types_identical(prev_type, type)) {
|
||||||
entry_index = e->value;
|
entry_index = e->value;
|
||||||
// NOTE(bill): Add it to the search map
|
// NOTE(bill): Add it to the search map
|
||||||
map_isize_set(&info->type_info_map, key, entry_index);
|
map_set(&info->type_info_map, key, entry_index);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -3434,7 +3425,7 @@ String ir_mangle_name(irGen *s, String path, Entity *e) {
|
|||||||
irModule *m = &s->module;
|
irModule *m = &s->module;
|
||||||
CheckerInfo *info = m->info;
|
CheckerInfo *info = m->info;
|
||||||
gbAllocator a = m->allocator;
|
gbAllocator a = m->allocator;
|
||||||
AstFile *file = *map_ast_file_get(&info->files, hash_string(path));
|
AstFile *file = *map_get(&info->files, hash_string(path));
|
||||||
|
|
||||||
char *str = gb_alloc_array(a, char, path.len+1);
|
char *str = gb_alloc_array(a, char, path.len+1);
|
||||||
gb_memmove(str, path.text, path.len);
|
gb_memmove(str, path.text, path.len);
|
||||||
@@ -3496,14 +3487,14 @@ void ir_mangle_add_sub_type_name(irModule *m, Entity *field, String parent) {
|
|||||||
"%.*s.%.*s", LIT(parent), LIT(cn));
|
"%.*s.%.*s", LIT(parent), LIT(cn));
|
||||||
|
|
||||||
String child = {text, new_name_len-1};
|
String child = {text, new_name_len-1};
|
||||||
map_string_set(&m->entity_names, hash_pointer(field), child);
|
map_set(&m->entity_names, hash_pointer(field), child);
|
||||||
ir_gen_global_type_name(m, field, child);
|
ir_gen_global_type_name(m, field, child);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
irBranchBlocks ir_lookup_branch_blocks(irProcedure *proc, AstNode *ident) {
|
irBranchBlocks ir_lookup_branch_blocks(irProcedure *proc, AstNode *ident) {
|
||||||
GB_ASSERT(ident->kind == AstNode_Ident);
|
GB_ASSERT(ident->kind == AstNode_Ident);
|
||||||
Entity **found = map_entity_get(&proc->module->info->uses, hash_pointer(ident));
|
Entity **found = map_get(&proc->module->info->uses, hash_pointer(ident));
|
||||||
GB_ASSERT(found != NULL);
|
GB_ASSERT(found != NULL);
|
||||||
Entity *e = *found;
|
Entity *e = *found;
|
||||||
GB_ASSERT(e->kind == Entity_Label);
|
GB_ASSERT(e->kind == Entity_Label);
|
||||||
@@ -3553,7 +3544,7 @@ void ir_pop_target_list(irProcedure *proc) {
|
|||||||
void ir_gen_global_type_name(irModule *m, Entity *e, String name) {
|
void ir_gen_global_type_name(irModule *m, Entity *e, String name) {
|
||||||
irValue *t = ir_value_type_name(m->allocator, name, e->type);
|
irValue *t = ir_value_type_name(m->allocator, name, e->type);
|
||||||
ir_module_add_value(m, e, t);
|
ir_module_add_value(m, e, t);
|
||||||
map_ir_value_set(&m->members, hash_string(name), t);
|
map_set(&m->members, hash_string(name), t);
|
||||||
|
|
||||||
if (is_type_union(e->type)) {
|
if (is_type_union(e->type)) {
|
||||||
Type *bt = base_type(e->type);
|
Type *bt = base_type(e->type);
|
||||||
@@ -3602,7 +3593,7 @@ irValue *ir_emit_clamp(irProcedure *proc, Type *t, irValue *x, irValue *min, irV
|
|||||||
|
|
||||||
|
|
||||||
irValue *ir_find_global_variable(irProcedure *proc, String name) {
|
irValue *ir_find_global_variable(irProcedure *proc, String name) {
|
||||||
irValue **value = map_ir_value_get(&proc->module->members, hash_string(name));
|
irValue **value = map_get(&proc->module->members, hash_string(name));
|
||||||
GB_ASSERT_MSG(value != NULL, "Unable to find global variable `%.*s`", LIT(name));
|
GB_ASSERT_MSG(value != NULL, "Unable to find global variable `%.*s`", LIT(name));
|
||||||
return *value;
|
return *value;
|
||||||
}
|
}
|
||||||
@@ -3660,7 +3651,7 @@ irValue *ir_build_expr(irProcedure *proc, AstNode *expr) {
|
|||||||
case_end;
|
case_end;
|
||||||
|
|
||||||
case_ast_node(i, Ident, expr);
|
case_ast_node(i, Ident, expr);
|
||||||
Entity *e = *map_entity_get(&proc->module->info->uses, hash_pointer(expr));
|
Entity *e = *map_get(&proc->module->info->uses, hash_pointer(expr));
|
||||||
if (e->kind == Entity_Builtin) {
|
if (e->kind == Entity_Builtin) {
|
||||||
Token token = ast_node_token(expr);
|
Token token = ast_node_token(expr);
|
||||||
GB_PANIC("TODO(bill): ir_build_single_expr Entity_Builtin `%.*s`\n"
|
GB_PANIC("TODO(bill): ir_build_single_expr Entity_Builtin `%.*s`\n"
|
||||||
@@ -3671,7 +3662,7 @@ irValue *ir_build_expr(irProcedure *proc, AstNode *expr) {
|
|||||||
return ir_value_nil(proc->module->allocator, tv.type);
|
return ir_value_nil(proc->module->allocator, tv.type);
|
||||||
}
|
}
|
||||||
|
|
||||||
irValue **found = map_ir_value_get(&proc->module->values, hash_pointer(e));
|
irValue **found = map_get(&proc->module->values, hash_pointer(e));
|
||||||
if (found) {
|
if (found) {
|
||||||
irValue *v = *found;
|
irValue *v = *found;
|
||||||
if (v->kind == irValue_Proc) {
|
if (v->kind == irValue_Proc) {
|
||||||
@@ -3873,7 +3864,7 @@ irValue *ir_build_expr(irProcedure *proc, AstNode *expr) {
|
|||||||
|
|
||||||
|
|
||||||
case_ast_node(ce, CallExpr, expr);
|
case_ast_node(ce, CallExpr, expr);
|
||||||
if (map_tav_get(&proc->module->info->types, hash_pointer(ce->proc))->mode == Addressing_Type) {
|
if (map_get(&proc->module->info->types, hash_pointer(ce->proc))->mode == Addressing_Type) {
|
||||||
GB_ASSERT(ce->args.count == 1);
|
GB_ASSERT(ce->args.count == 1);
|
||||||
irValue *x = ir_build_expr(proc, ce->args[0]);
|
irValue *x = ir_build_expr(proc, ce->args[0]);
|
||||||
irValue *y = ir_emit_conv(proc, x, tv.type);
|
irValue *y = ir_emit_conv(proc, x, tv.type);
|
||||||
@@ -3882,7 +3873,7 @@ irValue *ir_build_expr(irProcedure *proc, AstNode *expr) {
|
|||||||
|
|
||||||
AstNode *p = unparen_expr(ce->proc);
|
AstNode *p = unparen_expr(ce->proc);
|
||||||
if (p->kind == AstNode_Ident) {
|
if (p->kind == AstNode_Ident) {
|
||||||
Entity **found = map_entity_get(&proc->module->info->uses, hash_pointer(p));
|
Entity **found = map_get(&proc->module->info->uses, hash_pointer(p));
|
||||||
if (found && (*found)->kind == Entity_Builtin) {
|
if (found && (*found)->kind == Entity_Builtin) {
|
||||||
Entity *e = *found;
|
Entity *e = *found;
|
||||||
switch (e->Builtin.id) {
|
switch (e->Builtin.id) {
|
||||||
@@ -4704,7 +4695,7 @@ irValue *ir_get_using_variable(irProcedure *proc, Entity *e) {
|
|||||||
Entity *parent = e->using_parent;
|
Entity *parent = e->using_parent;
|
||||||
Selection sel = lookup_field(proc->module->allocator, parent->type, name, false);
|
Selection sel = lookup_field(proc->module->allocator, parent->type, name, false);
|
||||||
GB_ASSERT(sel.entity != NULL);
|
GB_ASSERT(sel.entity != NULL);
|
||||||
irValue **pv = map_ir_value_get(&proc->module->values, hash_pointer(parent));
|
irValue **pv = map_get(&proc->module->values, hash_pointer(parent));
|
||||||
irValue *v = NULL;
|
irValue *v = NULL;
|
||||||
if (pv != NULL) {
|
if (pv != NULL) {
|
||||||
v = *pv;
|
v = *pv;
|
||||||
@@ -4719,7 +4710,7 @@ irValue *ir_get_using_variable(irProcedure *proc, Entity *e) {
|
|||||||
|
|
||||||
// irValue *ir_add_using_variable(irProcedure *proc, Entity *e) {
|
// irValue *ir_add_using_variable(irProcedure *proc, Entity *e) {
|
||||||
// irValue *var = ir_get_using_variable(proc, e);
|
// irValue *var = ir_get_using_variable(proc, e);
|
||||||
// map_ir_value_set(&proc->module->values, hash_pointer(e), var);
|
// map_set(&proc->module->values, hash_pointer(e), var);
|
||||||
// return var;
|
// return var;
|
||||||
// }
|
// }
|
||||||
|
|
||||||
@@ -4741,7 +4732,7 @@ irAddr ir_build_addr_from_entity(irProcedure *proc, Entity *e, AstNode *expr) {
|
|||||||
GB_ASSERT(e->kind != Entity_Constant);
|
GB_ASSERT(e->kind != Entity_Constant);
|
||||||
|
|
||||||
irValue *v = NULL;
|
irValue *v = NULL;
|
||||||
irValue **found = map_ir_value_get(&proc->module->values, hash_pointer(e));
|
irValue **found = map_get(&proc->module->values, hash_pointer(e));
|
||||||
if (found) {
|
if (found) {
|
||||||
v = *found;
|
v = *found;
|
||||||
} else if (e->kind == Entity_Variable && e->flags & EntityFlag_Using) {
|
} else if (e->kind == Entity_Variable && e->flags & EntityFlag_Using) {
|
||||||
@@ -5720,7 +5711,7 @@ void ir_build_range_interval(irProcedure *proc, AstNodeBinaryExpr *node, Type *v
|
|||||||
}
|
}
|
||||||
|
|
||||||
void ir_store_type_case_implicit(irProcedure *proc, AstNode *clause, irValue *value) {
|
void ir_store_type_case_implicit(irProcedure *proc, AstNode *clause, irValue *value) {
|
||||||
Entity **found = map_entity_get(&proc->module->info->implicits, hash_pointer(clause));
|
Entity **found = map_get(&proc->module->info->implicits, hash_pointer(clause));
|
||||||
GB_ASSERT(found != NULL);
|
GB_ASSERT(found != NULL);
|
||||||
Entity *e = *found; GB_ASSERT(e != NULL);
|
Entity *e = *found; GB_ASSERT(e != NULL);
|
||||||
irValue *x = ir_add_local(proc, e, NULL);
|
irValue *x = ir_add_local(proc, e, NULL);
|
||||||
@@ -5836,18 +5827,18 @@ void ir_build_stmt_internal(irProcedure *proc, AstNode *node) {
|
|||||||
|
|
||||||
irValue *value = ir_value_type_name(proc->module->allocator,
|
irValue *value = ir_value_type_name(proc->module->allocator,
|
||||||
name, e->type);
|
name, e->type);
|
||||||
map_string_set(&proc->module->entity_names, hash_pointer(e), name);
|
map_set(&proc->module->entity_names, hash_pointer(e), name);
|
||||||
ir_gen_global_type_name(proc->module, e, name);
|
ir_gen_global_type_name(proc->module, e, name);
|
||||||
} break;
|
} break;
|
||||||
case Entity_Procedure: {
|
case Entity_Procedure: {
|
||||||
DeclInfo **decl_info = map_decl_info_get(&proc->module->info->entities, hash_pointer(e));
|
DeclInfo **decl_info = map_get(&proc->module->info->entities, hash_pointer(e));
|
||||||
GB_ASSERT(decl_info != NULL);
|
GB_ASSERT(decl_info != NULL);
|
||||||
DeclInfo *dl = *decl_info;
|
DeclInfo *dl = *decl_info;
|
||||||
ast_node(pd, ProcLit, dl->proc_lit);
|
ast_node(pd, ProcLit, dl->proc_lit);
|
||||||
if (pd->body != NULL) {
|
if (pd->body != NULL) {
|
||||||
CheckerInfo *info = proc->module->info;
|
CheckerInfo *info = proc->module->info;
|
||||||
|
|
||||||
if (map_entity_get(&proc->module->min_dep_map, hash_pointer(e)) == NULL) {
|
if (map_get(&proc->module->min_dep_map, hash_pointer(e)) == NULL) {
|
||||||
// NOTE(bill): Nothing depends upon it so doesn't need to be built
|
// NOTE(bill): Nothing depends upon it so doesn't need to be built
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -5896,10 +5887,10 @@ void ir_build_stmt_internal(irProcedure *proc, AstNode *node) {
|
|||||||
|
|
||||||
if (value->Proc.tags & ProcTag_foreign) {
|
if (value->Proc.tags & ProcTag_foreign) {
|
||||||
HashKey key = hash_string(name);
|
HashKey key = hash_string(name);
|
||||||
irValue **prev_value = map_ir_value_get(&proc->module->members, key);
|
irValue **prev_value = map_get(&proc->module->members, key);
|
||||||
if (prev_value == NULL) {
|
if (prev_value == NULL) {
|
||||||
// NOTE(bill): Don't do mutliple declarations in the IR
|
// NOTE(bill): Don't do mutliple declarations in the IR
|
||||||
map_ir_value_set(&proc->module->members, key, value);
|
map_set(&proc->module->members, key, value);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
array_add(&proc->children, &value->Proc);
|
array_add(&proc->children, &value->Proc);
|
||||||
@@ -6509,7 +6500,7 @@ void ir_build_stmt_internal(irProcedure *proc, AstNode *node) {
|
|||||||
|
|
||||||
Entity *case_entity = NULL;
|
Entity *case_entity = NULL;
|
||||||
{
|
{
|
||||||
Entity **found = map_entity_get(&proc->module->info->implicits, hash_pointer(clause));
|
Entity **found = map_get(&proc->module->info->implicits, hash_pointer(clause));
|
||||||
GB_ASSERT(found != NULL);
|
GB_ASSERT(found != NULL);
|
||||||
case_entity = *found;
|
case_entity = *found;
|
||||||
}
|
}
|
||||||
@@ -6679,7 +6670,7 @@ void ir_begin_procedure_body(irProcedure *proc) {
|
|||||||
array_init(&proc->children, heap_allocator());
|
array_init(&proc->children, heap_allocator());
|
||||||
array_init(&proc->branch_blocks, heap_allocator());
|
array_init(&proc->branch_blocks, heap_allocator());
|
||||||
|
|
||||||
DeclInfo **found = map_decl_info_get(&proc->module->info->entities, hash_pointer(proc->entity));
|
DeclInfo **found = map_get(&proc->module->info->entities, hash_pointer(proc->entity));
|
||||||
if (found != NULL) {
|
if (found != NULL) {
|
||||||
DeclInfo *decl = *found;
|
DeclInfo *decl = *found;
|
||||||
for_array(i, decl->labels) {
|
for_array(i, decl->labels) {
|
||||||
@@ -6774,12 +6765,12 @@ void ir_build_proc(irValue *value, irProcedure *parent) {
|
|||||||
CheckerInfo *info = m->info;
|
CheckerInfo *info = m->info;
|
||||||
Entity *e = proc->entity;
|
Entity *e = proc->entity;
|
||||||
String filename = e->token.pos.file;
|
String filename = e->token.pos.file;
|
||||||
AstFile **found = map_ast_file_get(&info->files, hash_string(filename));
|
AstFile **found = map_get(&info->files, hash_string(filename));
|
||||||
GB_ASSERT(found != NULL);
|
GB_ASSERT(found != NULL);
|
||||||
AstFile *f = *found;
|
AstFile *f = *found;
|
||||||
irDebugInfo *di_file = NULL;
|
irDebugInfo *di_file = NULL;
|
||||||
|
|
||||||
irDebugInfo **di_file_found = map_ir_debug_info_get(&m->debug_info, hash_pointer(f));
|
irDebugInfo **di_file_found = map_get(&m->debug_info, hash_pointer(f));
|
||||||
if (di_file_found) {
|
if (di_file_found) {
|
||||||
di_file = *di_file_found;
|
di_file = *di_file_found;
|
||||||
GB_ASSERT(di_file->kind == irDebugInfo_File);
|
GB_ASSERT(di_file->kind == irDebugInfo_File);
|
||||||
@@ -6831,7 +6822,7 @@ void ir_build_proc(irValue *value, irProcedure *parent) {
|
|||||||
|
|
||||||
|
|
||||||
void ir_module_add_value(irModule *m, Entity *e, irValue *v) {
|
void ir_module_add_value(irModule *m, Entity *e, irValue *v) {
|
||||||
map_ir_value_set(&m->values, hash_pointer(e), v);
|
map_set(&m->values, hash_pointer(e), v);
|
||||||
}
|
}
|
||||||
|
|
||||||
void ir_init_module(irModule *m, Checker *c) {
|
void ir_init_module(irModule *m, Checker *c) {
|
||||||
@@ -6844,10 +6835,10 @@ void ir_init_module(irModule *m, Checker *c) {
|
|||||||
m->tmp_allocator = gb_arena_allocator(&m->tmp_arena);
|
m->tmp_allocator = gb_arena_allocator(&m->tmp_arena);
|
||||||
m->info = &c->info;
|
m->info = &c->info;
|
||||||
|
|
||||||
map_ir_value_init(&m->values, heap_allocator());
|
map_init(&m->values, heap_allocator());
|
||||||
map_ir_value_init(&m->members, heap_allocator());
|
map_init(&m->members, heap_allocator());
|
||||||
map_ir_debug_info_init(&m->debug_info, heap_allocator());
|
map_init(&m->debug_info, heap_allocator());
|
||||||
map_string_init(&m->entity_names, heap_allocator());
|
map_init(&m->entity_names, heap_allocator());
|
||||||
array_init(&m->procs, heap_allocator());
|
array_init(&m->procs, heap_allocator());
|
||||||
array_init(&m->procs_to_generate, heap_allocator());
|
array_init(&m->procs_to_generate, heap_allocator());
|
||||||
array_init(&m->foreign_library_paths, heap_allocator());
|
array_init(&m->foreign_library_paths, heap_allocator());
|
||||||
@@ -6861,7 +6852,7 @@ void ir_init_module(irModule *m, Checker *c) {
|
|||||||
{
|
{
|
||||||
isize max_index = -1;
|
isize max_index = -1;
|
||||||
for_array(type_info_map_index, m->info->type_info_map.entries) {
|
for_array(type_info_map_index, m->info->type_info_map.entries) {
|
||||||
MapIsizeEntry *entry = &m->info->type_info_map.entries[type_info_map_index];
|
auto *entry = &m->info->type_info_map.entries[type_info_map_index];
|
||||||
Type *t = cast(Type *)cast(uintptr)entry->key.key;
|
Type *t = cast(Type *)cast(uintptr)entry->key.key;
|
||||||
t = default_type(t);
|
t = default_type(t);
|
||||||
isize entry_index = ir_type_info_index(m->info, t);
|
isize entry_index = ir_type_info_index(m->info, t);
|
||||||
@@ -6876,7 +6867,7 @@ void ir_init_module(irModule *m, Checker *c) {
|
|||||||
irValue *g = ir_value_global(m->allocator, e, NULL);
|
irValue *g = ir_value_global(m->allocator, e, NULL);
|
||||||
g->Global.is_private = true;
|
g->Global.is_private = true;
|
||||||
ir_module_add_value(m, e, g);
|
ir_module_add_value(m, e, g);
|
||||||
map_ir_value_set(&m->members, hash_string(name), g);
|
map_set(&m->members, hash_string(name), g);
|
||||||
ir_global_type_info_data = g;
|
ir_global_type_info_data = g;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -6886,7 +6877,7 @@ void ir_init_module(irModule *m, Checker *c) {
|
|||||||
isize count = 0;
|
isize count = 0;
|
||||||
|
|
||||||
for_array(entry_index, m->info->type_info_map.entries) {
|
for_array(entry_index, m->info->type_info_map.entries) {
|
||||||
MapIsizeEntry *entry = &m->info->type_info_map.entries[entry_index];
|
auto *entry = &m->info->type_info_map.entries[entry_index];
|
||||||
Type *t = cast(Type *)cast(uintptr)entry->key.key;
|
Type *t = cast(Type *)cast(uintptr)entry->key.key;
|
||||||
|
|
||||||
switch (t->kind) {
|
switch (t->kind) {
|
||||||
@@ -6914,7 +6905,7 @@ void ir_init_module(irModule *m, Checker *c) {
|
|||||||
make_type_array(m->allocator, t_type_info_ptr, count), false);
|
make_type_array(m->allocator, t_type_info_ptr, count), false);
|
||||||
irValue *g = ir_value_global(m->allocator, e, NULL);
|
irValue *g = ir_value_global(m->allocator, e, NULL);
|
||||||
ir_module_add_value(m, e, g);
|
ir_module_add_value(m, e, g);
|
||||||
map_ir_value_set(&m->members, hash_string(name), g);
|
map_set(&m->members, hash_string(name), g);
|
||||||
ir_global_type_info_member_types = g;
|
ir_global_type_info_member_types = g;
|
||||||
}
|
}
|
||||||
{
|
{
|
||||||
@@ -6923,7 +6914,7 @@ void ir_init_module(irModule *m, Checker *c) {
|
|||||||
make_type_array(m->allocator, t_string, count), false);
|
make_type_array(m->allocator, t_string, count), false);
|
||||||
irValue *g = ir_value_global(m->allocator, e, NULL);
|
irValue *g = ir_value_global(m->allocator, e, NULL);
|
||||||
ir_module_add_value(m, e, g);
|
ir_module_add_value(m, e, g);
|
||||||
map_ir_value_set(&m->members, hash_string(name), g);
|
map_set(&m->members, hash_string(name), g);
|
||||||
ir_global_type_info_member_names = g;
|
ir_global_type_info_member_names = g;
|
||||||
}
|
}
|
||||||
{
|
{
|
||||||
@@ -6932,7 +6923,7 @@ void ir_init_module(irModule *m, Checker *c) {
|
|||||||
make_type_array(m->allocator, t_int, count), false);
|
make_type_array(m->allocator, t_int, count), false);
|
||||||
irValue *g = ir_value_global(m->allocator, e, NULL);
|
irValue *g = ir_value_global(m->allocator, e, NULL);
|
||||||
ir_module_add_value(m, e, g);
|
ir_module_add_value(m, e, g);
|
||||||
map_ir_value_set(&m->members, hash_string(name), g);
|
map_set(&m->members, hash_string(name), g);
|
||||||
ir_global_type_info_member_offsets = g;
|
ir_global_type_info_member_offsets = g;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -6942,7 +6933,7 @@ void ir_init_module(irModule *m, Checker *c) {
|
|||||||
make_type_array(m->allocator, t_bool, count), false);
|
make_type_array(m->allocator, t_bool, count), false);
|
||||||
irValue *g = ir_value_global(m->allocator, e, NULL);
|
irValue *g = ir_value_global(m->allocator, e, NULL);
|
||||||
ir_module_add_value(m, e, g);
|
ir_module_add_value(m, e, g);
|
||||||
map_ir_value_set(&m->members, hash_string(name), g);
|
map_set(&m->members, hash_string(name), g);
|
||||||
ir_global_type_info_member_usings = g;
|
ir_global_type_info_member_usings = g;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -6953,15 +6944,15 @@ void ir_init_module(irModule *m, Checker *c) {
|
|||||||
di->CompileUnit.file = m->info->files.entries[0].value; // Zeroth is the init file
|
di->CompileUnit.file = m->info->files.entries[0].value; // Zeroth is the init file
|
||||||
di->CompileUnit.producer = str_lit("odin");
|
di->CompileUnit.producer = str_lit("odin");
|
||||||
|
|
||||||
map_ir_debug_info_set(&m->debug_info, hash_pointer(m), di);
|
map_set(&m->debug_info, hash_pointer(m), di);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void ir_destroy_module(irModule *m) {
|
void ir_destroy_module(irModule *m) {
|
||||||
map_ir_value_destroy(&m->values);
|
map_destroy(&m->values);
|
||||||
map_ir_value_destroy(&m->members);
|
map_destroy(&m->members);
|
||||||
map_string_destroy(&m->entity_names);
|
map_destroy(&m->entity_names);
|
||||||
map_ir_debug_info_destroy(&m->debug_info);
|
map_destroy(&m->debug_info);
|
||||||
array_free(&m->procs);
|
array_free(&m->procs);
|
||||||
array_free(&m->procs_to_generate);
|
array_free(&m->procs_to_generate);
|
||||||
array_free(&m->foreign_library_paths);
|
array_free(&m->foreign_library_paths);
|
||||||
@@ -7089,7 +7080,7 @@ void ir_gen_tree(irGen *s) {
|
|||||||
bool has_win_main = false;
|
bool has_win_main = false;
|
||||||
|
|
||||||
for_array(i, info->entities.entries) {
|
for_array(i, info->entities.entries) {
|
||||||
MapDeclInfoEntry *entry = &info->entities.entries[i];
|
auto *entry = &info->entities.entries[i];
|
||||||
Entity *e = cast(Entity *)cast(uintptr)entry->key.key;
|
Entity *e = cast(Entity *)cast(uintptr)entry->key.key;
|
||||||
String name = e->token.string;
|
String name = e->token.string;
|
||||||
if (e->kind == Entity_Variable) {
|
if (e->kind == Entity_Variable) {
|
||||||
@@ -7121,7 +7112,7 @@ void ir_gen_tree(irGen *s) {
|
|||||||
m->min_dep_map = generate_minimum_dependency_map(info, entry_point);
|
m->min_dep_map = generate_minimum_dependency_map(info, entry_point);
|
||||||
|
|
||||||
for_array(i, info->entities.entries) {
|
for_array(i, info->entities.entries) {
|
||||||
MapDeclInfoEntry *entry = &info->entities.entries[i];
|
auto *entry = &info->entities.entries[i];
|
||||||
Entity *e = cast(Entity *)entry->key.ptr;
|
Entity *e = cast(Entity *)entry->key.ptr;
|
||||||
String name = e->token.string;
|
String name = e->token.string;
|
||||||
DeclInfo *decl = entry->value;
|
DeclInfo *decl = entry->value;
|
||||||
@@ -7131,7 +7122,7 @@ void ir_gen_tree(irGen *s) {
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (map_entity_get(&m->min_dep_map, hash_pointer(e)) == NULL) {
|
if (map_get(&m->min_dep_map, hash_pointer(e)) == NULL) {
|
||||||
// NOTE(bill): Nothing depends upon it so doesn't need to be built
|
// NOTE(bill): Nothing depends upon it so doesn't need to be built
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
@@ -7145,7 +7136,7 @@ void ir_gen_tree(irGen *s) {
|
|||||||
name = ir_mangle_name(s, e->token.pos.file, e);
|
name = ir_mangle_name(s, e->token.pos.file, e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
map_string_set(&m->entity_names, hash_pointer(e), name);
|
map_set(&m->entity_names, hash_pointer(e), name);
|
||||||
|
|
||||||
switch (e->kind) {
|
switch (e->kind) {
|
||||||
case Entity_TypeName:
|
case Entity_TypeName:
|
||||||
@@ -7183,7 +7174,7 @@ void ir_gen_tree(irGen *s) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
ir_module_add_value(m, e, g);
|
ir_module_add_value(m, e, g);
|
||||||
map_ir_value_set(&m->members, hash_string(name), g);
|
map_set(&m->members, hash_string(name), g);
|
||||||
} break;
|
} break;
|
||||||
|
|
||||||
case Entity_Procedure: {
|
case Entity_Procedure: {
|
||||||
@@ -7207,15 +7198,15 @@ void ir_gen_tree(irGen *s) {
|
|||||||
|
|
||||||
ir_module_add_value(m, e, p);
|
ir_module_add_value(m, e, p);
|
||||||
HashKey hash_name = hash_string(name);
|
HashKey hash_name = hash_string(name);
|
||||||
if (map_ir_value_get(&m->members, hash_name) == NULL) {
|
if (map_get(&m->members, hash_name) == NULL) {
|
||||||
map_ir_value_multi_insert(&m->members, hash_name, p);
|
multi_map_insert(&m->members, hash_name, p);
|
||||||
}
|
}
|
||||||
} break;
|
} break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
for_array(i, m->members.entries) {
|
for_array(i, m->members.entries) {
|
||||||
MapIrValueEntry *entry = &m->members.entries[i];
|
auto *entry = &m->members.entries[i];
|
||||||
irValue *v = entry->value;
|
irValue *v = entry->value;
|
||||||
if (v->kind == irValue_Proc) {
|
if (v->kind == irValue_Proc) {
|
||||||
ir_build_proc(v, NULL);
|
ir_build_proc(v, NULL);
|
||||||
@@ -7228,7 +7219,7 @@ void ir_gen_tree(irGen *s) {
|
|||||||
|
|
||||||
isize all_proc_max_count = 0;
|
isize all_proc_max_count = 0;
|
||||||
for_array(i, m->debug_info.entries) {
|
for_array(i, m->debug_info.entries) {
|
||||||
MapIrDebugInfoEntry *entry = &m->debug_info.entries[i];
|
auto *entry = &m->debug_info.entries[i];
|
||||||
irDebugInfo *di = entry->value;
|
irDebugInfo *di = entry->value;
|
||||||
di->id = i;
|
di->id = i;
|
||||||
if (di->kind == irDebugInfo_Proc) {
|
if (di->kind == irDebugInfo_Proc) {
|
||||||
@@ -7237,12 +7228,12 @@ void ir_gen_tree(irGen *s) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
array_init(&all_procs->AllProcs.procs, m->allocator, all_proc_max_count);
|
array_init(&all_procs->AllProcs.procs, m->allocator, all_proc_max_count);
|
||||||
map_ir_debug_info_set(&m->debug_info, hash_pointer(all_procs), all_procs); // NOTE(bill): This doesn't need to be mapped
|
map_set(&m->debug_info, hash_pointer(all_procs), all_procs); // NOTE(bill): This doesn't need to be mapped
|
||||||
compile_unit->CompileUnit.all_procs = all_procs;
|
compile_unit->CompileUnit.all_procs = all_procs;
|
||||||
|
|
||||||
|
|
||||||
for_array(i, m->debug_info.entries) {
|
for_array(i, m->debug_info.entries) {
|
||||||
MapIrDebugInfoEntry *entry = &m->debug_info.entries[i];
|
auto *entry = &m->debug_info.entries[i];
|
||||||
irDebugInfo *di = entry->value;
|
irDebugInfo *di = entry->value;
|
||||||
if (di->kind == irDebugInfo_Proc) {
|
if (di->kind == irDebugInfo_Proc) {
|
||||||
array_add(&all_procs->AllProcs.procs, di);
|
array_add(&all_procs->AllProcs.procs, di);
|
||||||
@@ -7279,8 +7270,8 @@ void ir_gen_tree(irGen *s) {
|
|||||||
Entity *e = make_entity_procedure(a, NULL, make_token_ident(name), proc_type, 0);
|
Entity *e = make_entity_procedure(a, NULL, make_token_ident(name), proc_type, 0);
|
||||||
irValue *p = ir_value_procedure(a, m, e, proc_type, NULL, body, name);
|
irValue *p = ir_value_procedure(a, m, e, proc_type, NULL, body, name);
|
||||||
|
|
||||||
map_ir_value_set(&m->values, hash_pointer(e), p);
|
map_set(&m->values, hash_pointer(e), p);
|
||||||
map_ir_value_set(&m->members, hash_string(name), p);
|
map_set(&m->members, hash_string(name), p);
|
||||||
|
|
||||||
irProcedure *proc = &p->Proc;
|
irProcedure *proc = &p->Proc;
|
||||||
proc->tags = ProcTag_no_inline; // TODO(bill): is no_inline a good idea?
|
proc->tags = ProcTag_no_inline; // TODO(bill): is no_inline a good idea?
|
||||||
@@ -7300,7 +7291,7 @@ void ir_gen_tree(irGen *s) {
|
|||||||
|
|
||||||
{
|
{
|
||||||
String main_name = str_lit("main");
|
String main_name = str_lit("main");
|
||||||
irValue **found = map_ir_value_get(&m->members, hash_string(main_name));
|
irValue **found = map_get(&m->members, hash_string(main_name));
|
||||||
if (found != NULL) {
|
if (found != NULL) {
|
||||||
ir_emit_call(proc, *found, NULL, 0);
|
ir_emit_call(proc, *found, NULL, 0);
|
||||||
} else {
|
} else {
|
||||||
@@ -7350,8 +7341,8 @@ void ir_gen_tree(irGen *s) {
|
|||||||
|
|
||||||
m->entry_point_entity = e;
|
m->entry_point_entity = e;
|
||||||
|
|
||||||
map_ir_value_set(&m->values, hash_pointer(e), p);
|
map_set(&m->values, hash_pointer(e), p);
|
||||||
map_ir_value_set(&m->members, hash_string(name), p);
|
map_set(&m->members, hash_string(name), p);
|
||||||
|
|
||||||
irProcedure *proc = &p->Proc;
|
irProcedure *proc = &p->Proc;
|
||||||
proc->tags = ProcTag_no_inline; // TODO(bill): is no_inline a good idea?
|
proc->tags = ProcTag_no_inline; // TODO(bill): is no_inline a good idea?
|
||||||
@@ -7373,8 +7364,8 @@ void ir_gen_tree(irGen *s) {
|
|||||||
Entity *e = make_entity_procedure(a, NULL, make_token_ident(name), proc_type, 0);
|
Entity *e = make_entity_procedure(a, NULL, make_token_ident(name), proc_type, 0);
|
||||||
irValue *p = ir_value_procedure(a, m, e, proc_type, NULL, body, name);
|
irValue *p = ir_value_procedure(a, m, e, proc_type, NULL, body, name);
|
||||||
|
|
||||||
map_ir_value_set(&m->values, hash_pointer(e), p);
|
map_set(&m->values, hash_pointer(e), p);
|
||||||
map_ir_value_set(&m->members, hash_string(name), p);
|
map_set(&m->members, hash_string(name), p);
|
||||||
|
|
||||||
|
|
||||||
irProcedure *proc = &p->Proc;
|
irProcedure *proc = &p->Proc;
|
||||||
@@ -7452,7 +7443,7 @@ void ir_gen_tree(irGen *s) {
|
|||||||
i32 type_info_member_offsets_index = 0;
|
i32 type_info_member_offsets_index = 0;
|
||||||
|
|
||||||
for_array(type_info_map_index, info->type_info_map.entries) {
|
for_array(type_info_map_index, info->type_info_map.entries) {
|
||||||
MapIsizeEntry *entry = &info->type_info_map.entries[type_info_map_index];
|
auto *entry = &info->type_info_map.entries[type_info_map_index];
|
||||||
Type *t = cast(Type *)cast(uintptr)entry->key.key;
|
Type *t = cast(Type *)cast(uintptr)entry->key.key;
|
||||||
t = default_type(t);
|
t = default_type(t);
|
||||||
isize entry_index = ir_type_info_index(info, t);
|
isize entry_index = ir_type_info_index(info, t);
|
||||||
@@ -7915,7 +7906,7 @@ void ir_gen_tree(irGen *s) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
for_array(type_info_map_index, info->type_info_map.entries) {
|
for_array(type_info_map_index, info->type_info_map.entries) {
|
||||||
MapIsizeEntry *entry = &info->type_info_map.entries[type_info_map_index];
|
auto *entry = &info->type_info_map.entries[type_info_map_index];
|
||||||
Type *t = cast(Type *)cast(uintptr)entry->key.key;
|
Type *t = cast(Type *)cast(uintptr)entry->key.key;
|
||||||
t = default_type(t);
|
t = default_type(t);
|
||||||
isize entry_index = entry->value;
|
isize entry_index = entry->value;
|
||||||
@@ -7934,7 +7925,7 @@ void ir_gen_tree(irGen *s) {
|
|||||||
|
|
||||||
// Number debug info
|
// Number debug info
|
||||||
for_array(i, m->debug_info.entries) {
|
for_array(i, m->debug_info.entries) {
|
||||||
MapIrDebugInfoEntry *entry = &m->debug_info.entries[i];
|
auto *entry = &m->debug_info.entries[i];
|
||||||
irDebugInfo *di = entry->value;
|
irDebugInfo *di = entry->value;
|
||||||
di->id = i;
|
di->id = i;
|
||||||
}
|
}
|
||||||
|
|||||||
+7
-7
@@ -306,7 +306,7 @@ void ir_print_type(irFileBuffer *f, irModule *m, Type *t) {
|
|||||||
|
|
||||||
case Type_Named:
|
case Type_Named:
|
||||||
if (is_type_struct(t) || is_type_union(t)) {
|
if (is_type_struct(t) || is_type_union(t)) {
|
||||||
String *name = map_string_get(&m->entity_names, hash_pointer(t->Named.type_name));
|
String *name = map_get(&m->entity_names, hash_pointer(t->Named.type_name));
|
||||||
GB_ASSERT_MSG(name != NULL, "%.*s", LIT(t->Named.name));
|
GB_ASSERT_MSG(name != NULL, "%.*s", LIT(t->Named.name));
|
||||||
ir_print_encoded_local(f, *name);
|
ir_print_encoded_local(f, *name);
|
||||||
} else {
|
} else {
|
||||||
@@ -1523,7 +1523,7 @@ void ir_print_proc(irFileBuffer *f, irModule *m, irProcedure *proc) {
|
|||||||
|
|
||||||
if (proc->entity != NULL) {
|
if (proc->entity != NULL) {
|
||||||
if (proc->body != NULL) {
|
if (proc->body != NULL) {
|
||||||
irDebugInfo **di_ = map_ir_debug_info_get(&proc->module->debug_info, hash_pointer(proc->entity));
|
irDebugInfo **di_ = map_get(&proc->module->debug_info, hash_pointer(proc->entity));
|
||||||
if (di_ != NULL) {
|
if (di_ != NULL) {
|
||||||
irDebugInfo *di = *di_;
|
irDebugInfo *di = *di_;
|
||||||
GB_ASSERT(di->kind == irDebugInfo_Proc);
|
GB_ASSERT(di->kind == irDebugInfo_Proc);
|
||||||
@@ -1606,7 +1606,7 @@ void print_llvm_ir(irGen *ir) {
|
|||||||
|
|
||||||
|
|
||||||
for_array(member_index, m->members.entries) {
|
for_array(member_index, m->members.entries) {
|
||||||
MapIrValueEntry *entry = &m->members.entries[member_index];
|
auto *entry = &m->members.entries[member_index];
|
||||||
irValue *v = entry->value;
|
irValue *v = entry->value;
|
||||||
if (v->kind != irValue_TypeName) {
|
if (v->kind != irValue_TypeName) {
|
||||||
continue;
|
continue;
|
||||||
@@ -1619,7 +1619,7 @@ void print_llvm_ir(irGen *ir) {
|
|||||||
bool dll_main_found = false;
|
bool dll_main_found = false;
|
||||||
|
|
||||||
for_array(member_index, m->members.entries) {
|
for_array(member_index, m->members.entries) {
|
||||||
MapIrValueEntry *entry = &m->members.entries[member_index];
|
auto *entry = &m->members.entries[member_index];
|
||||||
irValue *v = entry->value;
|
irValue *v = entry->value;
|
||||||
if (v->kind != irValue_Proc) {
|
if (v->kind != irValue_Proc) {
|
||||||
continue;
|
continue;
|
||||||
@@ -1631,7 +1631,7 @@ void print_llvm_ir(irGen *ir) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
for_array(member_index, m->members.entries) {
|
for_array(member_index, m->members.entries) {
|
||||||
MapIrValueEntry *entry = &m->members.entries[member_index];
|
auto *entry = &m->members.entries[member_index];
|
||||||
irValue *v = entry->value;
|
irValue *v = entry->value;
|
||||||
if (v->kind != irValue_Proc) {
|
if (v->kind != irValue_Proc) {
|
||||||
continue;
|
continue;
|
||||||
@@ -1643,7 +1643,7 @@ void print_llvm_ir(irGen *ir) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
for_array(member_index, m->members.entries) {
|
for_array(member_index, m->members.entries) {
|
||||||
MapIrValueEntry *entry = &m->members.entries[member_index];
|
auto *entry = &m->members.entries[member_index];
|
||||||
irValue *v = entry->value;
|
irValue *v = entry->value;
|
||||||
if (v->kind != irValue_Global) {
|
if (v->kind != irValue_Global) {
|
||||||
continue;
|
continue;
|
||||||
@@ -1713,7 +1713,7 @@ void print_llvm_ir(irGen *ir) {
|
|||||||
|
|
||||||
switch (di->kind) {
|
switch (di->kind) {
|
||||||
case irDebugInfo_CompileUnit: {
|
case irDebugInfo_CompileUnit: {
|
||||||
irDebugInfo *file = *map_ir_debug_info_get(&m->debug_info, hash_pointer(di->CompileUnit.file));
|
irDebugInfo *file = *map_get(&m->debug_info, hash_pointer(di->CompileUnit.file));
|
||||||
ir_fprintf(f,
|
ir_fprintf(f,
|
||||||
"distinct !DICompileUnit("
|
"distinct !DICompileUnit("
|
||||||
"language: DW_LANG_Go, " // Is this good enough?
|
"language: DW_LANG_Go, " // Is this good enough?
|
||||||
|
|||||||
+112
-113
@@ -1,38 +1,30 @@
|
|||||||
/*
|
|
||||||
Example of usage:
|
|
||||||
|
|
||||||
#define MAP_TYPE String
|
|
||||||
#define MAP_PROC map_string_
|
|
||||||
#define MAP_NAME MapString
|
|
||||||
#include "map.cpp"
|
|
||||||
*/
|
|
||||||
// A `Map` is an unordered hash table which can allow for a key to point to multiple values
|
// A `Map` is an unordered hash table which can allow for a key to point to multiple values
|
||||||
// with the use of the `multi_*` procedures.
|
// with the use of the `multi_*` procedures.
|
||||||
// TODO(bill): I should probably allow the `multi_*` stuff to be #ifdefed out
|
// TODO(bill): I should probably allow the `multi_map_*` stuff to be #ifdefed out
|
||||||
|
|
||||||
#ifndef MAP_UTIL_STUFF
|
#ifndef MAP_UTIL_STUFF
|
||||||
#define MAP_UTIL_STUFF
|
#define MAP_UTIL_STUFF
|
||||||
// NOTE(bill): This util stuff is the same for every `Map`
|
// NOTE(bill): This util stuff is the same for every `Map`
|
||||||
typedef struct MapFindResult {
|
struct MapFindResult {
|
||||||
isize hash_index;
|
isize hash_index;
|
||||||
isize entry_prev;
|
isize entry_prev;
|
||||||
isize entry_index;
|
isize entry_index;
|
||||||
} MapFindResult;
|
};
|
||||||
|
|
||||||
typedef enum HashKeyKind {
|
enum HashKeyKind {
|
||||||
HashKey_Default,
|
HashKey_Default,
|
||||||
HashKey_String,
|
HashKey_String,
|
||||||
HashKey_Pointer,
|
HashKey_Pointer,
|
||||||
} HashKeyKind;
|
};
|
||||||
|
|
||||||
typedef struct HashKey {
|
struct HashKey {
|
||||||
HashKeyKind kind;
|
HashKeyKind kind;
|
||||||
u64 key;
|
u64 key;
|
||||||
union {
|
union {
|
||||||
String string; // if String, s.len > 0
|
String string; // if String, s.len > 0
|
||||||
void * ptr;
|
void * ptr;
|
||||||
};
|
};
|
||||||
} HashKey;
|
};
|
||||||
|
|
||||||
gb_inline HashKey hashing_proc(void const *data, isize len) {
|
gb_inline HashKey hashing_proc(void const *data, isize len) {
|
||||||
HashKey h = {HashKey_Default};
|
HashKey h = {HashKey_Default};
|
||||||
@@ -73,75 +65,75 @@ bool hash_key_equal(HashKey a, HashKey b) {
|
|||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
bool operator==(HashKey a, HashKey b) { return hash_key_equal(a, b); }
|
||||||
|
bool operator!=(HashKey a, HashKey b) { return !hash_key_equal(a, b); }
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#define _J2_IND(a, b) a##b
|
template <typename T>
|
||||||
#define _J2(a, b) _J2_IND(a, b)
|
struct MapEntry {
|
||||||
|
|
||||||
/*
|
|
||||||
MAP_TYPE - Entry type
|
|
||||||
MAP_PROC - Function prefix (e.g. entity_map_)
|
|
||||||
MAP_NAME - Name of Map (e.g. EntityMap)
|
|
||||||
*/
|
|
||||||
#define MAP_ENTRY _J2(MAP_NAME,Entry)
|
|
||||||
|
|
||||||
typedef struct MAP_ENTRY {
|
|
||||||
HashKey key;
|
HashKey key;
|
||||||
isize next;
|
isize next;
|
||||||
MAP_TYPE value;
|
T value;
|
||||||
} MAP_ENTRY;
|
};
|
||||||
|
|
||||||
typedef struct MAP_NAME {
|
template <typename T>
|
||||||
Array<isize> hashes;
|
struct Map {
|
||||||
Array<MAP_ENTRY> entries;
|
Array<isize> hashes;
|
||||||
} MAP_NAME;
|
Array<MapEntry<T> > entries;
|
||||||
|
};
|
||||||
|
|
||||||
void _J2(MAP_PROC,init) (MAP_NAME *h, gbAllocator a);
|
|
||||||
void _J2(MAP_PROC,init_with_reserve)(MAP_NAME *h, gbAllocator a, isize capacity);
|
template <typename T> void map_init (Map<T> *h, gbAllocator a);
|
||||||
void _J2(MAP_PROC,destroy) (MAP_NAME *h);
|
template <typename T> void map_init_with_reserve(Map<T> *h, gbAllocator a, isize capacity);
|
||||||
MAP_TYPE *_J2(MAP_PROC,get) (MAP_NAME *h, HashKey key);
|
template <typename T> void map_destroy (Map<T> *h);
|
||||||
void _J2(MAP_PROC,set) (MAP_NAME *h, HashKey key, MAP_TYPE value);
|
template <typename T> T * map_get (Map<T> *h, HashKey key);
|
||||||
void _J2(MAP_PROC,remove) (MAP_NAME *h, HashKey key);
|
template <typename T> void map_set (Map<T> *h, HashKey key, T const &value);
|
||||||
void _J2(MAP_PROC,clear) (MAP_NAME *h);
|
template <typename T> void map_remove (Map<T> *h, HashKey key);
|
||||||
void _J2(MAP_PROC,grow) (MAP_NAME *h);
|
template <typename T> void map_clear (Map<T> *h);
|
||||||
void _J2(MAP_PROC,rehash) (MAP_NAME *h, isize new_count);
|
template <typename T> void map_grow (Map<T> *h);
|
||||||
|
template <typename T> void map_rehash (Map<T> *h, isize new_count);
|
||||||
|
|
||||||
// Mutlivalued map procedure
|
// Mutlivalued map procedure
|
||||||
MAP_ENTRY *_J2(MAP_PROC,multi_find_first)(MAP_NAME *h, HashKey key);
|
template <typename T> MapEntry<T> * multi_map_find_first(Map<T> *h, HashKey key);
|
||||||
MAP_ENTRY *_J2(MAP_PROC,multi_find_next) (MAP_NAME *h, MAP_ENTRY *e);
|
template <typename T> MapEntry<T> * multi_map_find_next (Map<T> *h, MapEntry<T> *e);
|
||||||
|
|
||||||
isize _J2(MAP_PROC,multi_count) (MAP_NAME *h, HashKey key);
|
template <typename T> isize multi_map_count (Map<T> *h, HashKey key);
|
||||||
void _J2(MAP_PROC,multi_get_all) (MAP_NAME *h, HashKey key, MAP_TYPE *items);
|
template <typename T> void multi_map_get_all (Map<T> *h, HashKey key, T *items);
|
||||||
void _J2(MAP_PROC,multi_insert) (MAP_NAME *h, HashKey key, MAP_TYPE value);
|
template <typename T> void multi_map_insert (Map<T> *h, HashKey key, T const &value);
|
||||||
void _J2(MAP_PROC,multi_remove) (MAP_NAME *h, HashKey key, MAP_ENTRY *e);
|
template <typename T> void multi_map_remove (Map<T> *h, HashKey key, MapEntry<T> *e);
|
||||||
void _J2(MAP_PROC,multi_remove_all)(MAP_NAME *h, HashKey key);
|
template <typename T> void multi_map_remove_all(Map<T> *h, HashKey key);
|
||||||
|
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
gb_inline void _J2(MAP_PROC,init)(MAP_NAME *h, gbAllocator a) {
|
gb_inline void map_init(Map<T> *h, gbAllocator a) {
|
||||||
array_init(&h->hashes, a);
|
array_init(&h->hashes, a);
|
||||||
array_init(&h->entries, a);
|
array_init(&h->entries, a);
|
||||||
}
|
}
|
||||||
|
|
||||||
gb_inline void _J2(MAP_PROC,init_with_reserve)(MAP_NAME *h, gbAllocator a, isize capacity) {
|
template <typename T>
|
||||||
|
gb_inline void map_init_with_reserve(Map<T> *h, gbAllocator a, isize capacity) {
|
||||||
array_init(&h->hashes, a, capacity);
|
array_init(&h->hashes, a, capacity);
|
||||||
array_init(&h->entries, a, capacity);
|
array_init(&h->entries, a, capacity);
|
||||||
}
|
}
|
||||||
|
|
||||||
gb_inline void _J2(MAP_PROC,destroy)(MAP_NAME *h) {
|
template <typename T>
|
||||||
|
gb_inline void map_destroy(Map<T> *h) {
|
||||||
array_free(&h->entries);
|
array_free(&h->entries);
|
||||||
array_free(&h->hashes);
|
array_free(&h->hashes);
|
||||||
}
|
}
|
||||||
|
|
||||||
gb_internal isize _J2(MAP_PROC,_add_entry)(MAP_NAME *h, HashKey key) {
|
template <typename T>
|
||||||
MAP_ENTRY e = {};
|
gb_internal isize map__add_entry(Map<T> *h, HashKey key) {
|
||||||
|
MapEntry<T> e = {};
|
||||||
e.key = key;
|
e.key = key;
|
||||||
e.next = -1;
|
e.next = -1;
|
||||||
array_add(&h->entries, e);
|
array_add(&h->entries, e);
|
||||||
return h->entries.count-1;
|
return h->entries.count-1;
|
||||||
}
|
}
|
||||||
|
|
||||||
gb_internal MapFindResult _J2(MAP_PROC,_find)(MAP_NAME *h, HashKey key) {
|
template <typename T>
|
||||||
|
gb_internal MapFindResult map__find(Map<T> *h, HashKey key) {
|
||||||
MapFindResult fr = {-1, -1, -1};
|
MapFindResult fr = {-1, -1, -1};
|
||||||
if (h->hashes.count > 0) {
|
if (h->hashes.count > 0) {
|
||||||
fr.hash_index = key.key % h->hashes.count;
|
fr.hash_index = key.key % h->hashes.count;
|
||||||
@@ -157,7 +149,8 @@ gb_internal MapFindResult _J2(MAP_PROC,_find)(MAP_NAME *h, HashKey key) {
|
|||||||
return fr;
|
return fr;
|
||||||
}
|
}
|
||||||
|
|
||||||
gb_internal MapFindResult _J2(MAP_PROC,_find_from_entry)(MAP_NAME *h, MAP_ENTRY *e) {
|
template <typename T>
|
||||||
|
gb_internal MapFindResult map__find_from_entry(Map<T> *h, MapEntry<T> *e) {
|
||||||
MapFindResult fr = {-1, -1, -1};
|
MapFindResult fr = {-1, -1, -1};
|
||||||
if (h->hashes.count > 0) {
|
if (h->hashes.count > 0) {
|
||||||
fr.hash_index = e->key.key % h->hashes.count;
|
fr.hash_index = e->key.key % h->hashes.count;
|
||||||
@@ -173,33 +166,35 @@ gb_internal MapFindResult _J2(MAP_PROC,_find_from_entry)(MAP_NAME *h, MAP_ENTRY
|
|||||||
return fr;
|
return fr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
gb_internal b32 _J2(MAP_PROC,_full)(MAP_NAME *h) {
|
gb_internal b32 map__full(Map<T> *h) {
|
||||||
return 0.75f * h->hashes.count <= h->entries.count;
|
return 0.75f * h->hashes.count <= h->entries.count;
|
||||||
}
|
}
|
||||||
|
|
||||||
gb_inline void _J2(MAP_PROC,grow)(MAP_NAME *h) {
|
template <typename T>
|
||||||
|
gb_inline void map_grow(Map<T> *h) {
|
||||||
isize new_count = ARRAY_GROW_FORMULA(h->entries.count);
|
isize new_count = ARRAY_GROW_FORMULA(h->entries.count);
|
||||||
_J2(MAP_PROC,rehash)(h, new_count);
|
map_rehash(h, new_count);
|
||||||
}
|
}
|
||||||
|
|
||||||
void _J2(MAP_PROC,rehash)(MAP_NAME *h, isize new_count) {
|
template <typename T>
|
||||||
|
void map_rehash(Map<T> *h, isize new_count) {
|
||||||
isize i, j;
|
isize i, j;
|
||||||
MAP_NAME nh = {};
|
Map<T> nh = {};
|
||||||
_J2(MAP_PROC,init)(&nh, h->hashes.allocator);
|
map_init(&nh, h->hashes.allocator);
|
||||||
array_resize(&nh.hashes, new_count);
|
array_resize(&nh.hashes, new_count);
|
||||||
array_reserve(&nh.entries, h->entries.count);
|
array_reserve(&nh.entries, h->entries.count);
|
||||||
for (i = 0; i < new_count; i++) {
|
for (i = 0; i < new_count; i++) {
|
||||||
nh.hashes[i] = -1;
|
nh.hashes[i] = -1;
|
||||||
}
|
}
|
||||||
for (i = 0; i < h->entries.count; i++) {
|
for (i = 0; i < h->entries.count; i++) {
|
||||||
MAP_ENTRY *e = &h->entries[i];
|
MapEntry<T> *e = &h->entries[i];
|
||||||
MapFindResult fr;
|
MapFindResult fr;
|
||||||
if (nh.hashes.count == 0) {
|
if (nh.hashes.count == 0) {
|
||||||
_J2(MAP_PROC,grow)(&nh);
|
map_grow(&nh);
|
||||||
}
|
}
|
||||||
fr = _J2(MAP_PROC,_find)(&nh, e->key);
|
fr = map__find(&nh, e->key);
|
||||||
j = _J2(MAP_PROC,_add_entry)(&nh, e->key);
|
j = map__add_entry(&nh, e->key);
|
||||||
if (fr.entry_prev < 0) {
|
if (fr.entry_prev < 0) {
|
||||||
nh.hashes[fr.hash_index] = j;
|
nh.hashes[fr.hash_index] = j;
|
||||||
} else {
|
} else {
|
||||||
@@ -207,32 +202,34 @@ void _J2(MAP_PROC,rehash)(MAP_NAME *h, isize new_count) {
|
|||||||
}
|
}
|
||||||
nh.entries[j].next = fr.entry_index;
|
nh.entries[j].next = fr.entry_index;
|
||||||
nh.entries[j].value = e->value;
|
nh.entries[j].value = e->value;
|
||||||
if (_J2(MAP_PROC,_full)(&nh)) {
|
if (map__full(&nh)) {
|
||||||
_J2(MAP_PROC,grow)(&nh);
|
map_grow(&nh);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
_J2(MAP_PROC,destroy)(h);
|
map_destroy(h);
|
||||||
*h = nh;
|
*h = nh;
|
||||||
}
|
}
|
||||||
|
|
||||||
gb_inline MAP_TYPE *_J2(MAP_PROC,get)(MAP_NAME *h, HashKey key) {
|
template <typename T>
|
||||||
isize index = _J2(MAP_PROC,_find)(h, key).entry_index;
|
gb_inline T *map_get(Map<T> *h, HashKey key) {
|
||||||
|
isize index = map__find(h, key).entry_index;
|
||||||
if (index >= 0) {
|
if (index >= 0) {
|
||||||
return &h->entries[index].value;
|
return &h->entries[index].value;
|
||||||
}
|
}
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
void _J2(MAP_PROC,set)(MAP_NAME *h, HashKey key, MAP_TYPE value) {
|
template <typename T>
|
||||||
|
void map_set(Map<T> *h, HashKey key, T const &value) {
|
||||||
isize index;
|
isize index;
|
||||||
MapFindResult fr;
|
MapFindResult fr;
|
||||||
if (h->hashes.count == 0)
|
if (h->hashes.count == 0)
|
||||||
_J2(MAP_PROC,grow)(h);
|
map_grow(h);
|
||||||
fr = _J2(MAP_PROC,_find)(h, key);
|
fr = map__find(h, key);
|
||||||
if (fr.entry_index >= 0) {
|
if (fr.entry_index >= 0) {
|
||||||
index = fr.entry_index;
|
index = fr.entry_index;
|
||||||
} else {
|
} else {
|
||||||
index = _J2(MAP_PROC,_add_entry)(h, key);
|
index = map__add_entry(h, key);
|
||||||
if (fr.entry_prev >= 0) {
|
if (fr.entry_prev >= 0) {
|
||||||
h->entries[fr.entry_prev].next = index;
|
h->entries[fr.entry_prev].next = index;
|
||||||
} else {
|
} else {
|
||||||
@@ -241,14 +238,14 @@ void _J2(MAP_PROC,set)(MAP_NAME *h, HashKey key, MAP_TYPE value) {
|
|||||||
}
|
}
|
||||||
h->entries[index].value = value;
|
h->entries[index].value = value;
|
||||||
|
|
||||||
if (_J2(MAP_PROC,_full)(h)) {
|
if (map__full(h)) {
|
||||||
_J2(MAP_PROC,grow)(h);
|
map_grow(h);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
void _J2(MAP_PROC,_erase)(MAP_NAME *h, MapFindResult fr) {
|
void map__erase(Map<T> *h, MapFindResult fr) {
|
||||||
MapFindResult last;
|
MapFindResult last;
|
||||||
if (fr.entry_prev < 0) {
|
if (fr.entry_prev < 0) {
|
||||||
h->hashes[fr.hash_index] = h->entries[fr.entry_index].next;
|
h->hashes[fr.hash_index] = h->entries[fr.entry_index].next;
|
||||||
@@ -260,7 +257,7 @@ void _J2(MAP_PROC,_erase)(MAP_NAME *h, MapFindResult fr) {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
h->entries[fr.entry_index] = h->entries[h->entries.count-1];
|
h->entries[fr.entry_index] = h->entries[h->entries.count-1];
|
||||||
last = _J2(MAP_PROC,_find)(h, h->entries[fr.entry_index].key);
|
last = map__find(h, h->entries[fr.entry_index].key);
|
||||||
if (last.entry_prev >= 0) {
|
if (last.entry_prev >= 0) {
|
||||||
h->entries[last.entry_prev].next = fr.entry_index;
|
h->entries[last.entry_prev].next = fr.entry_index;
|
||||||
} else {
|
} else {
|
||||||
@@ -268,29 +265,33 @@ void _J2(MAP_PROC,_erase)(MAP_NAME *h, MapFindResult fr) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void _J2(MAP_PROC,remove)(MAP_NAME *h, HashKey key) {
|
template <typename T>
|
||||||
MapFindResult fr = _J2(MAP_PROC,_find)(h, key);
|
void map_remove(Map<T> *h, HashKey key) {
|
||||||
|
MapFindResult fr = map__find(h, key);
|
||||||
if (fr.entry_index >= 0) {
|
if (fr.entry_index >= 0) {
|
||||||
_J2(MAP_PROC,_erase)(h, fr);
|
map__erase(h, fr);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
gb_inline void _J2(MAP_PROC,clear)(MAP_NAME *h) {
|
template <typename T>
|
||||||
|
gb_inline void map_clear(Map<T> *h) {
|
||||||
array_clear(&h->hashes);
|
array_clear(&h->hashes);
|
||||||
array_clear(&h->entries);
|
array_clear(&h->entries);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
#if 1
|
#if 1
|
||||||
MAP_ENTRY *_J2(MAP_PROC,multi_find_first)(MAP_NAME *h, HashKey key) {
|
template <typename T>
|
||||||
isize i = _J2(MAP_PROC,_find)(h, key).entry_index;
|
MapEntry<T> *multi_map_find_first(Map<T> *h, HashKey key) {
|
||||||
|
isize i = map__find(h, key).entry_index;
|
||||||
if (i < 0) {
|
if (i < 0) {
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
return &h->entries[i];
|
return &h->entries[i];
|
||||||
}
|
}
|
||||||
|
|
||||||
MAP_ENTRY *_J2(MAP_PROC,multi_find_next)(MAP_NAME *h, MAP_ENTRY *e) {
|
template <typename T>
|
||||||
|
MapEntry<T> *multi_map_find_next(Map<T> *h, MapEntry<T> *e) {
|
||||||
isize i = e->next;
|
isize i = e->next;
|
||||||
while (i >= 0) {
|
while (i >= 0) {
|
||||||
if (hash_key_equal(h->entries[i].key, e->key)) {
|
if (hash_key_equal(h->entries[i].key, e->key)) {
|
||||||
@@ -301,34 +302,37 @@ MAP_ENTRY *_J2(MAP_PROC,multi_find_next)(MAP_NAME *h, MAP_ENTRY *e) {
|
|||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
isize _J2(MAP_PROC,multi_count)(MAP_NAME *h, HashKey key) {
|
template <typename T>
|
||||||
|
isize multi_map_count(Map<T> *h, HashKey key) {
|
||||||
isize count = 0;
|
isize count = 0;
|
||||||
MAP_ENTRY *e = _J2(MAP_PROC,multi_find_first)(h, key);
|
MapEntry<T> *e = multi_map_find_first(h, key);
|
||||||
while (e != NULL) {
|
while (e != NULL) {
|
||||||
count++;
|
count++;
|
||||||
e = _J2(MAP_PROC,multi_find_next)(h, e);
|
e = multi_map_find_next(h, e);
|
||||||
}
|
}
|
||||||
return count;
|
return count;
|
||||||
}
|
}
|
||||||
|
|
||||||
void _J2(MAP_PROC,multi_get_all)(MAP_NAME *h, HashKey key, MAP_TYPE *items) {
|
template <typename T>
|
||||||
|
void multi_map_get_all(Map<T> *h, HashKey key, T *items) {
|
||||||
isize i = 0;
|
isize i = 0;
|
||||||
MAP_ENTRY *e = _J2(MAP_PROC,multi_find_first)(h, key);
|
MapEntry<T> *e = multi_map_find_first(h, key);
|
||||||
while (e != NULL) {
|
while (e != NULL) {
|
||||||
items[i++] = e->value;
|
items[i++] = e->value;
|
||||||
e = _J2(MAP_PROC,multi_find_next)(h, e);
|
e = multi_map_find_next(h, e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void _J2(MAP_PROC,multi_insert)(MAP_NAME *h, HashKey key, MAP_TYPE value) {
|
template <typename T>
|
||||||
|
void multi_map_insert(Map<T> *h, HashKey key, T const &value) {
|
||||||
MapFindResult fr;
|
MapFindResult fr;
|
||||||
isize i;
|
isize i;
|
||||||
if (h->hashes.count == 0) {
|
if (h->hashes.count == 0) {
|
||||||
_J2(MAP_PROC,grow)(h);
|
map_grow(h);
|
||||||
}
|
}
|
||||||
// Make
|
// Make
|
||||||
fr = _J2(MAP_PROC,_find)(h, key);
|
fr = map__find(h, key);
|
||||||
i = _J2(MAP_PROC,_add_entry)(h, key);
|
i = map__add_entry(h, key);
|
||||||
if (fr.entry_prev < 0) {
|
if (fr.entry_prev < 0) {
|
||||||
h->hashes[fr.hash_index] = i;
|
h->hashes[fr.hash_index] = i;
|
||||||
} else {
|
} else {
|
||||||
@@ -337,28 +341,23 @@ void _J2(MAP_PROC,multi_insert)(MAP_NAME *h, HashKey key, MAP_TYPE value) {
|
|||||||
h->entries[i].next = fr.entry_index;
|
h->entries[i].next = fr.entry_index;
|
||||||
h->entries[i].value = value;
|
h->entries[i].value = value;
|
||||||
// Grow if needed
|
// Grow if needed
|
||||||
if (_J2(MAP_PROC,_full)(h)) {
|
if (map__full(h)) {
|
||||||
_J2(MAP_PROC,grow)(h);
|
map_grow(h);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void _J2(MAP_PROC,multi_remove)(MAP_NAME *h, HashKey key, MAP_ENTRY *e) {
|
template <typename T>
|
||||||
MapFindResult fr = _J2(MAP_PROC,_find_from_entry)(h, e);
|
void multi_map_remove(Map<T> *h, HashKey key, MapEntry<T> *e) {
|
||||||
|
MapFindResult fr = map__find_from_entry(h, e);
|
||||||
if (fr.entry_index >= 0) {
|
if (fr.entry_index >= 0) {
|
||||||
_J2(MAP_PROC,_erase)(h, fr);
|
map__erase(h, fr);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void _J2(MAP_PROC,multi_remove_all)(MAP_NAME *h, HashKey key) {
|
template <typename T>
|
||||||
while (_J2(MAP_PROC,get)(h, key) != NULL) {
|
void multi_map_remove_all(Map<T> *h, HashKey key) {
|
||||||
_J2(MAP_PROC,remove)(h, key);
|
while (map_get(h, key) != NULL) {
|
||||||
|
map_remove(h, key);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
#undef _J2
|
|
||||||
#undef MAP_TYPE
|
|
||||||
#undef MAP_PROC
|
|
||||||
#undef MAP_NAME
|
|
||||||
#undef MAP_ENTRY
|
|
||||||
|
|||||||
+19
-23
@@ -14,10 +14,6 @@ enum ssaDeferExitKind;
|
|||||||
|
|
||||||
String ssa_mangle_name(ssaModule *m, String path, Entity *e);
|
String ssa_mangle_name(ssaModule *m, String path, Entity *e);
|
||||||
|
|
||||||
#define MAP_TYPE ssaValue *
|
|
||||||
#define MAP_PROC map_ssa_value_
|
|
||||||
#define MAP_NAME MapSsaValue
|
|
||||||
#include "map.cpp"
|
|
||||||
|
|
||||||
#include "ssa_op.cpp"
|
#include "ssa_op.cpp"
|
||||||
|
|
||||||
@@ -148,7 +144,7 @@ struct ssaProc {
|
|||||||
|
|
||||||
i32 block_id;
|
i32 block_id;
|
||||||
i32 value_id;
|
i32 value_id;
|
||||||
MapSsaValue values; // Key: Entity *
|
Map<ssaValue *> values; // Key: Entity *
|
||||||
|
|
||||||
Array<ssaDefer> defer_stmts;
|
Array<ssaDefer> defer_stmts;
|
||||||
i32 scope_level;
|
i32 scope_level;
|
||||||
@@ -166,8 +162,8 @@ struct ssaModule {
|
|||||||
gbAllocator tmp_allocator;
|
gbAllocator tmp_allocator;
|
||||||
gbArena tmp_arena;
|
gbArena tmp_arena;
|
||||||
|
|
||||||
MapEntity min_dep_map; // Key: Entity *
|
Map<Entity *> min_dep_map; // Key: Entity *
|
||||||
MapSsaValue values; // Key: Entity *
|
Map<ssaValue *> values; // Key: Entity *
|
||||||
// List of registers for the specific architecture
|
// List of registers for the specific architecture
|
||||||
Array<ssaRegister> registers;
|
Array<ssaRegister> registers;
|
||||||
|
|
||||||
@@ -584,7 +580,7 @@ ssaProc *ssa_new_proc(ssaModule *m, String name, Entity *entity, DeclInfo *decl_
|
|||||||
|
|
||||||
array_init(&p->blocks, heap_allocator());
|
array_init(&p->blocks, heap_allocator());
|
||||||
array_init(&p->defer_stmts, heap_allocator());
|
array_init(&p->defer_stmts, heap_allocator());
|
||||||
map_ssa_value_init(&p->values, heap_allocator());
|
map_init(&p->values, heap_allocator());
|
||||||
|
|
||||||
return p;
|
return p;
|
||||||
}
|
}
|
||||||
@@ -597,14 +593,14 @@ ssaAddr ssa_add_local(ssaProc *p, Entity *e, AstNode *expr) {
|
|||||||
ssaValue *local = ssa_new_value0(p, ssaOp_Local, t);
|
ssaValue *local = ssa_new_value0(p, ssaOp_Local, t);
|
||||||
p->curr_block = cb;
|
p->curr_block = cb;
|
||||||
|
|
||||||
map_ssa_value_set(&p->values, hash_pointer(e), local);
|
map_set(&p->values, hash_pointer(e), local);
|
||||||
map_ssa_value_set(&p->module->values, hash_pointer(e), local);
|
map_set(&p->module->values, hash_pointer(e), local);
|
||||||
local->comment_string = e->token.string;
|
local->comment_string = e->token.string;
|
||||||
ssa_new_value1(p, ssaOp_Zero, t, local);
|
ssa_new_value1(p, ssaOp_Zero, t, local);
|
||||||
return ssa_addr(local);
|
return ssa_addr(local);
|
||||||
}
|
}
|
||||||
ssaAddr ssa_add_local_for_ident(ssaProc *p, AstNode *name) {
|
ssaAddr ssa_add_local_for_ident(ssaProc *p, AstNode *name) {
|
||||||
Entity **found = map_entity_get(&p->module->info->definitions, hash_pointer(name));
|
Entity **found = map_get(&p->module->info->definitions, hash_pointer(name));
|
||||||
if (found) {
|
if (found) {
|
||||||
Entity *e = *found;
|
Entity *e = *found;
|
||||||
return ssa_add_local(p, e, name);
|
return ssa_add_local(p, e, name);
|
||||||
@@ -710,7 +706,7 @@ ssaValue *ssa_get_using_variable(ssaProc *p, Entity *e) {
|
|||||||
Entity *parent = e->using_parent;
|
Entity *parent = e->using_parent;
|
||||||
Selection sel = lookup_field(p->allocator, parent->type, name, false);
|
Selection sel = lookup_field(p->allocator, parent->type, name, false);
|
||||||
GB_ASSERT(sel.entity != NULL);
|
GB_ASSERT(sel.entity != NULL);
|
||||||
ssaValue **pv = map_ssa_value_get(&p->module->values, hash_pointer(parent));
|
ssaValue **pv = map_get(&p->module->values, hash_pointer(parent));
|
||||||
ssaValue *v = NULL;
|
ssaValue *v = NULL;
|
||||||
if (pv != NULL) {
|
if (pv != NULL) {
|
||||||
v = *pv;
|
v = *pv;
|
||||||
@@ -726,7 +722,7 @@ ssaAddr ssa_build_addr_from_entity(ssaProc *p, Entity *e, AstNode *expr) {
|
|||||||
GB_ASSERT(e != NULL);
|
GB_ASSERT(e != NULL);
|
||||||
|
|
||||||
ssaValue *v = NULL;
|
ssaValue *v = NULL;
|
||||||
ssaValue **found = map_ssa_value_get(&p->module->values, hash_pointer(e));
|
ssaValue **found = map_get(&p->module->values, hash_pointer(e));
|
||||||
if (found) {
|
if (found) {
|
||||||
v = *found;
|
v = *found;
|
||||||
} else if (e->kind == Entity_Variable && e->flags & EntityFlag_Using) {
|
} else if (e->kind == Entity_Variable && e->flags & EntityFlag_Using) {
|
||||||
@@ -1690,7 +1686,7 @@ ssaValue *ssa_build_expr(ssaProc *p, AstNode *expr) {
|
|||||||
case_end;
|
case_end;
|
||||||
|
|
||||||
case_ast_node(i, Ident, expr);
|
case_ast_node(i, Ident, expr);
|
||||||
Entity *e = *map_entity_get(&p->module->info->uses, hash_pointer(expr));
|
Entity *e = *map_get(&p->module->info->uses, hash_pointer(expr));
|
||||||
if (e->kind == Entity_Builtin) {
|
if (e->kind == Entity_Builtin) {
|
||||||
Token token = ast_node_token(expr);
|
Token token = ast_node_token(expr);
|
||||||
GB_PANIC("TODO(bill): ssa_build_expr Entity_Builtin `%.*s`\n"
|
GB_PANIC("TODO(bill): ssa_build_expr Entity_Builtin `%.*s`\n"
|
||||||
@@ -1702,7 +1698,7 @@ ssaValue *ssa_build_expr(ssaProc *p, AstNode *expr) {
|
|||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
ssaValue **found = map_ssa_value_get(&p->module->values, hash_pointer(e));
|
ssaValue **found = map_get(&p->module->values, hash_pointer(e));
|
||||||
if (found) {
|
if (found) {
|
||||||
ssaValue *v = *found;
|
ssaValue *v = *found;
|
||||||
if (v->op == ssaOp_Proc) {
|
if (v->op == ssaOp_Proc) {
|
||||||
@@ -1840,7 +1836,7 @@ ssaValue *ssa_build_expr(ssaProc *p, AstNode *expr) {
|
|||||||
|
|
||||||
|
|
||||||
case_ast_node(ce, CallExpr, expr);
|
case_ast_node(ce, CallExpr, expr);
|
||||||
if (map_tav_get(&p->module->info->types, hash_pointer(ce->proc))->mode == Addressing_Type) {
|
if (map_get(&p->module->info->types, hash_pointer(ce->proc))->mode == Addressing_Type) {
|
||||||
GB_ASSERT(ce->args.count == 1);
|
GB_ASSERT(ce->args.count == 1);
|
||||||
ssaValue *x = ssa_build_expr(p, ce->args[0]);
|
ssaValue *x = ssa_build_expr(p, ce->args[0]);
|
||||||
return ssa_emit_conv(p, x, tv.type);
|
return ssa_emit_conv(p, x, tv.type);
|
||||||
@@ -2484,7 +2480,7 @@ bool ssa_generate(Parser *parser, CheckerInfo *info) {
|
|||||||
m.tmp_allocator = gb_arena_allocator(&m.tmp_arena);
|
m.tmp_allocator = gb_arena_allocator(&m.tmp_arena);
|
||||||
m.allocator = gb_arena_allocator(&m.arena);
|
m.allocator = gb_arena_allocator(&m.arena);
|
||||||
|
|
||||||
map_ssa_value_init(&m.values, heap_allocator());
|
map_init(&m.values, heap_allocator());
|
||||||
array_init(&m.registers, heap_allocator());
|
array_init(&m.registers, heap_allocator());
|
||||||
array_init(&m.procs, heap_allocator());
|
array_init(&m.procs, heap_allocator());
|
||||||
array_init(&m.procs_to_generate, heap_allocator());
|
array_init(&m.procs_to_generate, heap_allocator());
|
||||||
@@ -2496,7 +2492,7 @@ bool ssa_generate(Parser *parser, CheckerInfo *info) {
|
|||||||
bool has_win_main = false;
|
bool has_win_main = false;
|
||||||
|
|
||||||
for_array(i, info->entities.entries) {
|
for_array(i, info->entities.entries) {
|
||||||
MapDeclInfoEntry *entry = &info->entities.entries[i];
|
auto *entry = &info->entities.entries[i];
|
||||||
Entity *e = cast(Entity *)cast(uintptr)entry->key.key;
|
Entity *e = cast(Entity *)cast(uintptr)entry->key.key;
|
||||||
String name = e->token.string;
|
String name = e->token.string;
|
||||||
if (e->kind == Entity_Variable) {
|
if (e->kind == Entity_Variable) {
|
||||||
@@ -2522,7 +2518,7 @@ bool ssa_generate(Parser *parser, CheckerInfo *info) {
|
|||||||
m.min_dep_map = generate_minimum_dependency_map(info, entry_point);
|
m.min_dep_map = generate_minimum_dependency_map(info, entry_point);
|
||||||
|
|
||||||
for_array(i, info->entities.entries) {
|
for_array(i, info->entities.entries) {
|
||||||
MapDeclInfoEntry *entry = &info->entities.entries[i];
|
auto *entry = &info->entities.entries[i];
|
||||||
Entity *e = cast(Entity *)entry->key.ptr;
|
Entity *e = cast(Entity *)entry->key.ptr;
|
||||||
String name = e->token.string;
|
String name = e->token.string;
|
||||||
DeclInfo *decl = entry->value;
|
DeclInfo *decl = entry->value;
|
||||||
@@ -2532,7 +2528,7 @@ bool ssa_generate(Parser *parser, CheckerInfo *info) {
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (map_entity_get(&m.min_dep_map, hash_pointer(e)) == NULL) {
|
if (map_get(&m.min_dep_map, hash_pointer(e)) == NULL) {
|
||||||
// NOTE(bill): Nothing depends upon it so doesn't need to be built
|
// NOTE(bill): Nothing depends upon it so doesn't need to be built
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
@@ -2579,8 +2575,8 @@ bool ssa_generate(Parser *parser, CheckerInfo *info) {
|
|||||||
|
|
||||||
// ssa_module_add_value(m, e, p);
|
// ssa_module_add_value(m, e, p);
|
||||||
// HashKey hash_name = hash_string(name);
|
// HashKey hash_name = hash_string(name);
|
||||||
// if (map_ssa_value_get(&m.members, hash_name) == NULL) {
|
// if (map_get(&m.members, hash_name) == NULL) {
|
||||||
// map_ssa_value_set(&m.members, hash_name, p);
|
// map_set(&m.members, hash_name, p);
|
||||||
// }
|
// }
|
||||||
} break;
|
} break;
|
||||||
}
|
}
|
||||||
@@ -2600,7 +2596,7 @@ String ssa_mangle_name(ssaModule *m, String path, Entity *e) {
|
|||||||
String name = e->token.string;
|
String name = e->token.string;
|
||||||
CheckerInfo *info = m->info;
|
CheckerInfo *info = m->info;
|
||||||
gbAllocator a = m->allocator;
|
gbAllocator a = m->allocator;
|
||||||
AstFile *file = *map_ast_file_get(&info->files, hash_string(path));
|
AstFile *file = *map_get(&info->files, hash_string(path));
|
||||||
|
|
||||||
char *str = gb_alloc_array(a, char, path.len+1);
|
char *str = gb_alloc_array(a, char, path.len+1);
|
||||||
gb_memmove(str, path.text, path.len);
|
gb_memmove(str, path.text, path.len);
|
||||||
|
|||||||
Reference in New Issue
Block a user