Use templated Map for extra type safety

This commit is contained in:
Ginger Bill
2017-06-08 13:26:48 +01:00
parent 2b96be0ae8
commit 5cad7d44a6
10 changed files with 359 additions and 425 deletions
+9 -9
View File
@@ -319,7 +319,7 @@ void check_proc_lit(Checker *c, Entity *e, DeclInfo *d) {
}
if (is_foreign) {
MapEntity *fp = &c->info.foreigns;
auto *fp = &c->info.foreigns;
String name = e->token.string;
if (pd->foreign_name.len > 0) {
name = pd->foreign_name;
@@ -352,7 +352,7 @@ void check_proc_lit(Checker *c, Entity *e, DeclInfo *d) {
e->Procedure.foreign_name = name;
HashKey key = hash_string(name);
Entity **found = map_entity_get(fp, key);
Entity **found = map_get(fp, key);
if (found) {
Entity *f = *found;
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);
}
} else {
map_entity_set(fp, key, e);
map_set(fp, key, e);
}
} else {
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) {
MapEntity *fp = &c->info.foreigns;
auto *fp = &c->info.foreigns;
e->Procedure.link_name = name;
HashKey key = hash_string(name);
Entity **found = map_entity_get(fp, key);
Entity **found = map_get(fp, key);
if (found) {
Entity *f = *found;
TokenPos pos = f->token.pos;
@@ -389,7 +389,7 @@ void check_proc_lit(Checker *c, Entity *e, DeclInfo *d) {
"\tother at %.*s(%td:%td)",
LIT(name), LIT(pos.file), pos.line, pos.column);
} 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) {
DeclInfo **found = map_decl_info_get(&c->info.entities, hash_pointer(e));
DeclInfo **found = map_get(&c->info.entities, hash_pointer(e));
if (found) {
d = *found;
} else {
@@ -511,7 +511,7 @@ void check_proc_body(Checker *c, Token token, DeclInfo *decl, Type *type, AstNod
String name = e->token.string;
Type *t = base_type(type_deref(e->type));
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);
for_array(i, (*found)->elements.entries) {
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) {
HashKey key = decl->deps.entries[i].key;
Entity *e = cast(Entity *)key.ptr;
map_bool_set(&decl->parent->deps, key, true);
map_set(&decl->parent->deps, key, true);
}
}
}
+33 -33
View File
@@ -62,7 +62,7 @@ void check_scope_decls(Checker *c, Array<AstNode *> nodes, isize reserve_size) {
default:
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) {
DeclInfo *d = *found;
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));
gbString str = 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);
String name = f->token.string;
HashKey key = hash_string(name);
Entity **found = map_entity_get(entity_map, key);
Entity **found = map_get(entity_map, key);
if (found != NULL) {
Entity *e = *found;
// 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));
}
} else {
map_entity_set(entity_map, key, f);
map_set(entity_map, key, f);
add_entity(c, c->context.scope, NULL, f);
if (f->flags & EntityFlag_Using) {
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) {
gbTempArenaMemory tmp = gb_temp_arena_memory_begin(&c->tmp_arena);
MapEntity entity_map = {};
map_entity_init_with_reserve(&entity_map, c->tmp_allocator, 2*field_count);
Map<Entity *> entity_map = {};
map_init_with_reserve(&entity_map, c->tmp_allocator, 2*field_count);
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");
} else {
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) {
Entity *e = *found;
// 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(e->token, "\tpreviously declared");
} else {
map_entity_set(&entity_map, key, e);
map_set(&entity_map, key, e);
fields[field_index++] = 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);
MapEntity entity_map = {}; // Key: String
map_entity_init_with_reserve(&entity_map, c->tmp_allocator, 2*variant_count);
Map<Entity *> entity_map = {}; // Key: String
map_init_with_reserve(&entity_map, c->tmp_allocator, 2*variant_count);
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++) {
Entity *f = fields[i];
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;
@@ -735,11 +735,11 @@ void check_union_type(Checker *c, Type *union_type, AstNode *node) {
}
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
error(name_token, "`%.*s` is already declared in this union", LIT(name_token.string));
} else {
map_entity_set(&entity_map, key, e);
map_set(&entity_map, key, e);
variants[variant_index++] = 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
enum_type->Record.enum_base_type = base_type;
MapEntity entity_map = {}; // Key: String
map_entity_init_with_reserve(&entity_map, c->tmp_allocator, 2*(et->fields.count));
Map<Entity *> entity_map = {}; // Key: String
map_init_with_reserve(&entity_map, c->tmp_allocator, 2*(et->fields.count));
Entity **fields = gb_alloc_array(c->allocator, Entity *, et->fields.count);
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;
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));
} else {
map_entity_set(&entity_map, key, e);
map_set(&entity_map, key, e);
add_entity(c, c->context.scope, NULL, e);
fields[field_count++] = 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);
MapEntity entity_map = {}; // Key: String
map_entity_init_with_reserve(&entity_map, c->tmp_allocator, 2*(bft->fields.count));
Map<Entity *> entity_map = {}; // Key: String
map_init_with_reserve(&entity_map, c->tmp_allocator, 2*(bft->fields.count));
isize field_count = 0;
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);
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));
} else {
map_entity_set(&entity_map, key, e);
map_set(&entity_map, key, e);
add_entity(c, c->context.scope, NULL, 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) {
// NOTE(bill): Overloads are only allowed with the same 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) {
is_overloaded = true;
}
@@ -1429,7 +1429,7 @@ Entity *check_ident(Checker *c, Operand *o, AstNode *n, Type *named_type, Type *
bool skip = false;
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) {
gbTempArenaMemory tmp = gb_temp_arena_memory_begin(&c->tmp_arena);
// 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;
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) {
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) {
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) {
return;
}
@@ -2983,12 +2983,12 @@ void update_expr_type(Checker *c, AstNode *e, Type *type, bool final) {
if (!final && is_type_untyped(type)) {
old.type = base_type(type);
map_expr_info_set(&c->info.untyped, key, old);
map_set(&c->info.untyped, key, old);
return;
}
// 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)) {
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) {
ExprInfo *found = map_expr_info_get(&c->info.untyped, hash_pointer(e));
ExprInfo *found = map_get(&c->info.untyped, hash_pointer(e));
if (found) {
found->value = value;
}
@@ -3206,7 +3206,7 @@ isize entity_overload_count(Scope *s, String name) {
}
if (e->kind == Entity_Procedure) {
// 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;
}
@@ -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);
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);
if (!implicit_is_found) {
is_not_exported = false;
@@ -3320,7 +3320,7 @@ Entity *check_selector(Checker *c, Operand *operand, AstNode *node, Type *type_h
bool skip = false;
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++) {
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
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]);
overload_count--;
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++) {
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);
DeclInfo *d = *found;
check_entity_decl(c, e, d, NULL);
+14 -19
View File
@@ -389,11 +389,6 @@ struct TypeAndToken {
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) {
flags &= ~Stmt_CheckScopeDecls;
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));
if (is_type_struct(t) || is_type_raw_union(t) || is_type_union(t)) {
// 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);
Scope *found = *found_;
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_type_and_token_init(&seen, heap_allocator());
Map<TypeAndToken> seen = {}; // NOTE(bill): Multimap
map_init(&seen, heap_allocator());
for_array(i, bs->stmts) {
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) {
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) {
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);
map_type_and_token_multi_get_all(&seen, key, taps);
multi_map_get_all(&seen, key, taps);
bool continue_outer = false;
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)};
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);
}
map_type_and_token_destroy(&seen);
map_destroy(&seen);
check_close_scope(c);
case_end;
@@ -1346,8 +1341,8 @@ void check_stmt_internal(Checker *c, AstNode *node, u32 flags) {
}
MapBool seen = {}; // Multimap
map_bool_init(&seen, heap_allocator());
Map<bool> seen = {}; // Multimap
map_init(&seen, heap_allocator());
for_array(i, bs->stmts) {
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);
bool *found = map_bool_get(&seen, key);
bool *found = map_get(&seen, key);
if (found) {
TokenPos pos = cc->token.pos;
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);
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_close_scope(c);
}
map_bool_destroy(&seen);
map_destroy(&seen);
check_close_scope(c);
case_end;
@@ -1635,7 +1630,7 @@ void check_stmt_internal(Checker *c, AstNode *node, u32 flags) {
Type *t = base_type(type_deref(e->type));
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);
for_array(i, (*found)->elements.entries) {
Entity *f = (*found)->elements.entries[i].value;
+84 -114
View File
@@ -195,7 +195,7 @@ struct DeclInfo {
AstNode * init_expr;
AstNode * proc_lit; // AstNode_ProcLit
MapBool deps; // Key: Entity *
Map<bool> deps; // Key: Entity *
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 {
Scope * parent;
Scope * prev, *next;
Scope * first_child;
Scope * last_child;
MapEntity elements; // Key: String
MapBool implicit; // Key: Entity *
Map<Entity *> elements; // Key: String
Map<bool> implicit; // Key: Entity *
Array<Scope *> shared;
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 {
Scope * parent;
AstNode *decl;
@@ -304,16 +274,16 @@ struct CheckerContext {
// CheckerInfo stores all the symbol information for a type-checked program
struct CheckerInfo {
MapTypeAndValue types; // Key: AstNode * | Expression -> Type (and value)
MapEntity definitions; // Key: AstNode * | Identifier -> Entity
MapEntity uses; // Key: AstNode * | Identifier -> Entity
MapScope scopes; // Key: AstNode * | Node -> Scope
MapExprInfo untyped; // Key: AstNode * | Expression -> ExprInfo
MapEntity implicits; // Key: AstNode *
MapDeclInfo entities; // Key: Entity *
MapEntity foreigns; // Key: String
MapAstFile files; // Key: String (full path)
MapIsize type_info_map; // Key: Type *
Map<TypeAndValue> types; // Key: AstNode * | Expression -> Type (and value)
Map<Entity *> definitions; // Key: AstNode * | Identifier -> Entity
Map<Entity *> uses; // Key: AstNode * | Identifier -> Entity
Map<Scope *> scopes; // Key: AstNode * | Node -> Scope
Map<ExprInfo> untyped; // Key: AstNode * | Expression -> ExprInfo
Map<Entity *> implicits; // Key: AstNode *
Map<DeclInfo *> entities; // Key: Entity *
Map<Entity *> foreigns; // Key: String
Map<AstFile *> files; // Key: String (full path)
Map<isize> type_info_map; // Key: Type *
isize type_info_count;
};
@@ -352,7 +322,7 @@ struct DelayedEntity {
void init_declaration_info(DeclInfo *d, Scope *scope, DeclInfo *parent) {
d->parent = parent;
d->scope = scope;
map_bool_init(&d->deps, heap_allocator());
map_init(&d->deps, 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) {
map_bool_destroy(&d->deps);
map_destroy(&d->deps);
}
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 *s = gb_alloc_item(allocator, Scope);
s->parent = parent;
map_entity_init(&s->elements, heap_allocator());
map_bool_init(&s->implicit, heap_allocator());
map_init(&s->elements, heap_allocator());
map_init(&s->implicit, heap_allocator());
array_init(&s->shared, heap_allocator());
array_init(&s->imported, heap_allocator());
@@ -417,8 +387,8 @@ void destroy_scope(Scope *scope) {
destroy_scope(child);
}
map_entity_destroy(&scope->elements);
map_bool_destroy(&scope->implicit);
map_destroy(&scope->elements);
map_destroy(&scope->implicit);
array_free(&scope->shared);
array_free(&scope->imported);
@@ -428,7 +398,7 @@ void destroy_scope(Scope *scope) {
void add_scope(Checker *c, AstNode *node, Scope *scope) {
GB_ASSERT(node != 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) {
HashKey key = hash_string(name);
Entity **found = map_entity_get(&s->elements, key);
Entity **found = map_get(&s->elements, key);
if (found) {
return *found;
}
for_array(i, s->shared) {
Scope *shared = s->shared[i];
Entity **found = map_entity_get(&shared->elements, key);
Entity **found = map_get(&shared->elements, key);
if (found) {
Entity *e = *found;
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;
HashKey key = hash_string(name);
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) {
Entity *e = *found;
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
for_array(i, s->shared) {
Scope *shared = s->shared[i];
Entity **found = map_entity_get(&shared->elements, key);
Entity **found = map_get(&shared->elements, key);
if (found) {
Entity *e = *found;
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) {
String name = entity->token.string;
HashKey key = hash_string(name);
Entity **found = map_entity_get(&s->elements, key);
Entity **found = map_get(&s->elements, key);
#if 1
// IMPORTANT NOTE(bill): Procedure overloading code
@@ -576,15 +546,15 @@ Entity *scope_insert_entity(Scope *s, Entity *entity) {
if (s->is_global) {
return prev;
}
map_entity_multi_insert(&s->elements, key, entity);
multi_map_insert(&s->elements, key, entity);
} else {
map_entity_set(&s->elements, key, entity);
map_set(&s->elements, key, entity);
}
#else
if (found) {
return *found;
}
map_entity_set(&s->elements, key, entity);
map_set(&s->elements, key, entity);
#endif
if (entity->scope == NULL) {
entity->scope = s;
@@ -599,7 +569,7 @@ void check_scope_usage(Checker *c, Scope *scope) {
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) {
@@ -607,7 +577,7 @@ void add_declaration_dependency(Checker *c, Entity *e) {
return;
}
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) {
add_dependency(c->context.decl, e);
}
@@ -705,31 +675,31 @@ void init_universal_scope(void) {
void init_checker_info(CheckerInfo *i) {
gbAllocator a = heap_allocator();
map_tav_init(&i->types, a);
map_entity_init(&i->definitions, a);
map_entity_init(&i->uses, a);
map_scope_init(&i->scopes, a);
map_decl_info_init(&i->entities, a);
map_expr_info_init(&i->untyped, a);
map_entity_init(&i->foreigns, a);
map_entity_init(&i->implicits, a);
map_isize_init(&i->type_info_map, a);
map_ast_file_init(&i->files, a);
map_init(&i->types, a);
map_init(&i->definitions, a);
map_init(&i->uses, a);
map_init(&i->scopes, a);
map_init(&i->entities, a);
map_init(&i->untyped, a);
map_init(&i->foreigns, a);
map_init(&i->implicits, a);
map_init(&i->type_info_map, a);
map_init(&i->files, a);
i->type_info_count = 0;
}
void destroy_checker_info(CheckerInfo *i) {
map_tav_destroy(&i->types);
map_entity_destroy(&i->definitions);
map_entity_destroy(&i->uses);
map_scope_destroy(&i->scopes);
map_decl_info_destroy(&i->entities);
map_expr_info_destroy(&i->untyped);
map_entity_destroy(&i->foreigns);
map_entity_destroy(&i->implicits);
map_isize_destroy(&i->type_info_map);
map_ast_file_destroy(&i->files);
map_destroy(&i->types);
map_destroy(&i->definitions);
map_destroy(&i->uses);
map_destroy(&i->scopes);
map_destroy(&i->entities);
map_destroy(&i->untyped);
map_destroy(&i->foreigns);
map_destroy(&i->implicits);
map_destroy(&i->type_info_map);
map_destroy(&i->files);
}
@@ -793,11 +763,11 @@ void destroy_checker(Checker *c) {
Entity *entity_of_ident(CheckerInfo *i, AstNode *identifier) {
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) {
return *found;
}
found = map_entity_get(&i->uses, hash_pointer(identifier));
found = map_get(&i->uses, hash_pointer(identifier));
if (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 result = {};
TypeAndValue *found = map_tav_get(&i->types, hash_pointer(expression));
TypeAndValue *found = map_get(&i->types, hash_pointer(expression));
if (found) result = *found;
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) {
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) {
@@ -858,7 +828,7 @@ void add_type_and_value(CheckerInfo *i, AstNode *expression, AddressingMode mode
tv.type = type;
tv.value = value;
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) {
@@ -868,7 +838,7 @@ void add_entity_definition(CheckerInfo *i, AstNode *identifier, Entity *entity)
return;
}
HashKey key = hash_pointer(identifier);
map_entity_set(&i->definitions, key, entity);
map_set(&i->definitions, key, entity);
} else {
// NOTE(bill): Error should handled elsewhere
}
@@ -918,7 +888,7 @@ void add_entity_use(Checker *c, AstNode *identifier, Entity *entity) {
return;
}
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?
}
@@ -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(identifier->Ident.string == e->token.string);
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) {
GB_ASSERT(node != 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
}
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
return;
}
isize ti_index = -1;
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;
if (are_types_identical(t, prev_type)) {
// Duplicate entry
@@ -972,7 +942,7 @@ void add_type_info_type(Checker *c, Type *t) {
ti_index = 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) {
return;
}
if (map_entity_get(map, hash_pointer(node)) != NULL) {
if (map_get(map, hash_pointer(node)) != NULL) {
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) {
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) {
MapEntity map = {}; // Key: Entity *
map_entity_init(&map, heap_allocator());
Map<Entity *> generate_minimum_dependency_map(CheckerInfo *info, Entity *start) {
Map<Entity *> map = {}; // Key: Entity *
map_init(&map, heap_allocator());
for_array(i, info->definitions.entries) {
Entity *e = info->definitions.entries[i].value;
@@ -1289,7 +1259,7 @@ bool check_is_entity_overloaded(Entity *e) {
}
Scope *s = e->scope;
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;
}
@@ -1309,7 +1279,7 @@ void check_procedure_overloading(Checker *c, Entity *e) {
String name = e->token.string;
HashKey key = hash_string(name);
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);
if (overload_count == 1) {
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);
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++) {
Entity *p = procs[j];
@@ -1660,7 +1630,7 @@ void check_all_global_entities(Checker *c) {
Scope *prev_file = {};
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;
DeclInfo *d = entry->value;
@@ -1698,7 +1668,7 @@ void check_all_global_entities(Checker *c) {
}
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;
if (e->kind != Entity_Procedure) {
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
// 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);
Scope **found = map_scope_get(file_scopes, key);
Scope **found = map_get(file_scopes, key);
if (found == NULL) {
for_array(scope_index, file_scopes->entries) {
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);
Scope **found = map_scope_get(file_scopes, key);
Scope **found = map_get(file_scopes, key);
if (found == NULL) {
for_array(scope_index, file_scopes->entries) {
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?
bool ok = add_entity(c, parent_scope, e->identifier, e);
if (ok) {
map_bool_set(&parent_scope->implicit, hash_pointer(e), true);
map_set(&parent_scope->implicit, hash_pointer(e), true);
}
}
} else {
@@ -2021,8 +1991,8 @@ void check_import_entities(Checker *c, MapScope *file_scopes) {
void check_parsed_files(Checker *c) {
MapScope file_scopes; // Key: String (fullpath)
map_scope_init(&file_scopes, heap_allocator());
Map<Scope *> file_scopes; // Key: String (fullpath)
map_init(&file_scopes, heap_allocator());
// Map full filepaths to Scopes
for_array(i, c->parser->files) {
@@ -2047,8 +2017,8 @@ void check_parsed_files(Checker *c) {
f->scope = scope;
f->decl_info = make_declaration_info(c->allocator, f->scope, c->context.decl);
HashKey key = hash_string(f->tokenizer.fullpath);
map_scope_set(&file_scopes, key, scope);
map_ast_file_set(&c->info.files, key, f);
map_set(&file_scopes, key, scope);
map_set(&c->info.files, key, f);
}
// Collect Entities
@@ -2091,7 +2061,7 @@ void check_parsed_files(Checker *c) {
// Add untyped expression values
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;
AstNode *expr = cast(AstNode *)cast(uintptr)key.key;
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
View File
@@ -18,6 +18,7 @@ gbAllocator heap_allocator(void) {
#include "array.cpp"
#include "integer128.cpp"
#include "murmurhash3.cpp"
#include "map.cpp"
u128 fnv128a(void const *data, isize len) {
u128 o = u128_lo_hi(0x13bull, 0x1000000ull);
@@ -234,23 +235,4 @@ f64 gb_sqrt(f64 x) {
} \
} 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"
+1
View File
@@ -4,6 +4,7 @@
// IMPORTANT TODO(bill): This needs to be completely fixed!!!!!!!!
struct AstNode;
struct HashKey;
struct Complex128 {
f64 real, imag;
+79 -88
View File
@@ -3,15 +3,6 @@ struct irBlock;
struct irValue;
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 {
@@ -28,11 +19,11 @@ struct irModule {
String layout;
// String triple;
MapEntity min_dep_map; // Key: Entity *
MapIrValue values; // Key: Entity *
MapIrValue members; // Key: String
MapString entity_names; // Key: Entity * of the typename
MapIrDebugInfo debug_info; // Key: Unique pointer
Map<Entity *> min_dep_map; // Key: Entity *
Map<irValue *> values; // Key: Entity *
Map<irValue *> members; // Key: String
Map<String> entity_names; // Key: Entity * of the typename
Map<irDebugInfo *> debug_info; // Key: Unique pointer
i32 global_string_index;
i32 global_array_index; // For ConstantSlice
i32 global_generated_index;
@@ -811,7 +802,7 @@ String ir_get_global_name(irModule *m, irValue *v) {
irValueGlobal *g = &v->Global;
Entity *e = g->entity;
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) {
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);
value->Global.is_private = true;
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;
}
irBlock *ir_new_block(irProcedure *proc, AstNode *node, char *label) {
Scope *scope = 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) {
scope = *found;
} 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);
irValue *g = ir_value_global(a, e, backing_array);
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);
}
@@ -1270,7 +1261,7 @@ irValue *ir_add_global_string_array(irModule *m, String string) {
// g->Global.is_constant = true;
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;
}
@@ -1291,7 +1282,7 @@ irValue *ir_add_local(irProcedure *proc, Entity *e, AstNode *expr) {
// }
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));
}
@@ -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) {
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) {
Entity *e = *found;
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);
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;
}
@@ -1407,7 +1398,7 @@ irDebugInfo *ir_add_debug_info_file(irProcedure *proc, AstFile *file) {
di->File.filename = filename;
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;
}
@@ -1424,7 +1415,7 @@ irDebugInfo *ir_add_debug_info_proc(irProcedure *proc, Entity *entity, String na
di->Proc.file = file;
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;
}
@@ -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) {
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));
irValue *gp = *found;
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;
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) {
entry_index = *found_entry_index;
}
@@ -3288,12 +3279,12 @@ isize ir_type_info_index(CheckerInfo *info, Type *type) {
// NOTE(bill): Do manual search
// TODO(bill): This is O(n) and can be very slow
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;
if (are_types_identical(prev_type, type)) {
entry_index = e->value;
// 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;
}
}
@@ -3434,7 +3425,7 @@ String ir_mangle_name(irGen *s, String path, Entity *e) {
irModule *m = &s->module;
CheckerInfo *info = m->info;
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);
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));
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);
}
irBranchBlocks ir_lookup_branch_blocks(irProcedure *proc, 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);
Entity *e = *found;
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) {
irValue *t = ir_value_type_name(m->allocator, name, e->type);
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)) {
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 **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));
return *value;
}
@@ -3660,7 +3651,7 @@ irValue *ir_build_expr(irProcedure *proc, AstNode *expr) {
case_end;
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) {
Token token = ast_node_token(expr);
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);
}
irValue **found = map_ir_value_get(&proc->module->values, hash_pointer(e));
irValue **found = map_get(&proc->module->values, hash_pointer(e));
if (found) {
irValue *v = *found;
if (v->kind == irValue_Proc) {
@@ -3873,7 +3864,7 @@ irValue *ir_build_expr(irProcedure *proc, AstNode *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);
irValue *x = ir_build_expr(proc, ce->args[0]);
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);
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) {
Entity *e = *found;
switch (e->Builtin.id) {
@@ -4704,7 +4695,7 @@ irValue *ir_get_using_variable(irProcedure *proc, Entity *e) {
Entity *parent = e->using_parent;
Selection sel = lookup_field(proc->module->allocator, parent->type, name, false);
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;
if (pv != NULL) {
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 *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;
// }
@@ -4741,7 +4732,7 @@ irAddr ir_build_addr_from_entity(irProcedure *proc, Entity *e, AstNode *expr) {
GB_ASSERT(e->kind != Entity_Constant);
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) {
v = *found;
} 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) {
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);
Entity *e = *found; GB_ASSERT(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,
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);
} break;
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);
DeclInfo *dl = *decl_info;
ast_node(pd, ProcLit, dl->proc_lit);
if (pd->body != NULL) {
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
break;
}
@@ -5896,10 +5887,10 @@ void ir_build_stmt_internal(irProcedure *proc, AstNode *node) {
if (value->Proc.tags & ProcTag_foreign) {
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) {
// 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 {
array_add(&proc->children, &value->Proc);
@@ -6509,7 +6500,7 @@ void ir_build_stmt_internal(irProcedure *proc, AstNode *node) {
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);
case_entity = *found;
}
@@ -6679,7 +6670,7 @@ void ir_begin_procedure_body(irProcedure *proc) {
array_init(&proc->children, 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) {
DeclInfo *decl = *found;
for_array(i, decl->labels) {
@@ -6774,12 +6765,12 @@ void ir_build_proc(irValue *value, irProcedure *parent) {
CheckerInfo *info = m->info;
Entity *e = proc->entity;
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);
AstFile *f = *found;
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) {
di_file = *di_file_found;
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) {
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) {
@@ -6844,10 +6835,10 @@ void ir_init_module(irModule *m, Checker *c) {
m->tmp_allocator = gb_arena_allocator(&m->tmp_arena);
m->info = &c->info;
map_ir_value_init(&m->values, heap_allocator());
map_ir_value_init(&m->members, heap_allocator());
map_ir_debug_info_init(&m->debug_info, heap_allocator());
map_string_init(&m->entity_names, heap_allocator());
map_init(&m->values, heap_allocator());
map_init(&m->members, heap_allocator());
map_init(&m->debug_info, heap_allocator());
map_init(&m->entity_names, heap_allocator());
array_init(&m->procs, heap_allocator());
array_init(&m->procs_to_generate, 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;
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;
t = default_type(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);
g->Global.is_private = true;
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;
}
@@ -6886,7 +6877,7 @@ void ir_init_module(irModule *m, Checker *c) {
isize count = 0;
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;
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);
irValue *g = ir_value_global(m->allocator, e, NULL);
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;
}
{
@@ -6923,7 +6914,7 @@ void ir_init_module(irModule *m, Checker *c) {
make_type_array(m->allocator, t_string, count), false);
irValue *g = ir_value_global(m->allocator, e, NULL);
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;
}
{
@@ -6932,7 +6923,7 @@ void ir_init_module(irModule *m, Checker *c) {
make_type_array(m->allocator, t_int, count), false);
irValue *g = ir_value_global(m->allocator, e, NULL);
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;
}
@@ -6942,7 +6933,7 @@ void ir_init_module(irModule *m, Checker *c) {
make_type_array(m->allocator, t_bool, count), false);
irValue *g = ir_value_global(m->allocator, e, NULL);
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;
}
}
@@ -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.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) {
map_ir_value_destroy(&m->values);
map_ir_value_destroy(&m->members);
map_string_destroy(&m->entity_names);
map_ir_debug_info_destroy(&m->debug_info);
map_destroy(&m->values);
map_destroy(&m->members);
map_destroy(&m->entity_names);
map_destroy(&m->debug_info);
array_free(&m->procs);
array_free(&m->procs_to_generate);
array_free(&m->foreign_library_paths);
@@ -7089,7 +7080,7 @@ void ir_gen_tree(irGen *s) {
bool has_win_main = false;
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;
String name = e->token.string;
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);
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;
String name = e->token.string;
DeclInfo *decl = entry->value;
@@ -7131,7 +7122,7 @@ void ir_gen_tree(irGen *s) {
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
continue;
}
@@ -7145,7 +7136,7 @@ void ir_gen_tree(irGen *s) {
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) {
case Entity_TypeName:
@@ -7183,7 +7174,7 @@ void ir_gen_tree(irGen *s) {
}
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;
case Entity_Procedure: {
@@ -7207,15 +7198,15 @@ void ir_gen_tree(irGen *s) {
ir_module_add_value(m, e, p);
HashKey hash_name = hash_string(name);
if (map_ir_value_get(&m->members, hash_name) == NULL) {
map_ir_value_multi_insert(&m->members, hash_name, p);
if (map_get(&m->members, hash_name) == NULL) {
multi_map_insert(&m->members, hash_name, p);
}
} break;
}
}
for_array(i, m->members.entries) {
MapIrValueEntry *entry = &m->members.entries[i];
auto *entry = &m->members.entries[i];
irValue *v = entry->value;
if (v->kind == irValue_Proc) {
ir_build_proc(v, NULL);
@@ -7228,7 +7219,7 @@ void ir_gen_tree(irGen *s) {
isize all_proc_max_count = 0;
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;
di->id = i;
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);
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;
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;
if (di->kind == irDebugInfo_Proc) {
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);
irValue *p = ir_value_procedure(a, m, e, proc_type, NULL, body, name);
map_ir_value_set(&m->values, hash_pointer(e), p);
map_ir_value_set(&m->members, hash_string(name), p);
map_set(&m->values, hash_pointer(e), p);
map_set(&m->members, hash_string(name), p);
irProcedure *proc = &p->Proc;
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");
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) {
ir_emit_call(proc, *found, NULL, 0);
} else {
@@ -7350,8 +7341,8 @@ void ir_gen_tree(irGen *s) {
m->entry_point_entity = e;
map_ir_value_set(&m->values, hash_pointer(e), p);
map_ir_value_set(&m->members, hash_string(name), p);
map_set(&m->values, hash_pointer(e), p);
map_set(&m->members, hash_string(name), p);
irProcedure *proc = &p->Proc;
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);
irValue *p = ir_value_procedure(a, m, e, proc_type, NULL, body, name);
map_ir_value_set(&m->values, hash_pointer(e), p);
map_ir_value_set(&m->members, hash_string(name), p);
map_set(&m->values, hash_pointer(e), p);
map_set(&m->members, hash_string(name), p);
irProcedure *proc = &p->Proc;
@@ -7452,7 +7443,7 @@ void ir_gen_tree(irGen *s) {
i32 type_info_member_offsets_index = 0;
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;
t = default_type(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) {
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;
t = default_type(t);
isize entry_index = entry->value;
@@ -7934,7 +7925,7 @@ void ir_gen_tree(irGen *s) {
// Number debug info
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;
di->id = i;
}
+7 -7
View File
@@ -306,7 +306,7 @@ void ir_print_type(irFileBuffer *f, irModule *m, Type *t) {
case Type_Named:
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));
ir_print_encoded_local(f, *name);
} else {
@@ -1523,7 +1523,7 @@ void ir_print_proc(irFileBuffer *f, irModule *m, irProcedure *proc) {
if (proc->entity != 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) {
irDebugInfo *di = *di_;
GB_ASSERT(di->kind == irDebugInfo_Proc);
@@ -1606,7 +1606,7 @@ void print_llvm_ir(irGen *ir) {
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;
if (v->kind != irValue_TypeName) {
continue;
@@ -1619,7 +1619,7 @@ void print_llvm_ir(irGen *ir) {
bool dll_main_found = false;
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;
if (v->kind != irValue_Proc) {
continue;
@@ -1631,7 +1631,7 @@ void print_llvm_ir(irGen *ir) {
}
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;
if (v->kind != irValue_Proc) {
continue;
@@ -1643,7 +1643,7 @@ void print_llvm_ir(irGen *ir) {
}
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;
if (v->kind != irValue_Global) {
continue;
@@ -1713,7 +1713,7 @@ void print_llvm_ir(irGen *ir) {
switch (di->kind) {
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,
"distinct !DICompileUnit("
"language: DW_LANG_Go, " // Is this good enough?
+112 -113
View File
@@ -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
// 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
#define MAP_UTIL_STUFF
// NOTE(bill): This util stuff is the same for every `Map`
typedef struct MapFindResult {
struct MapFindResult {
isize hash_index;
isize entry_prev;
isize entry_index;
} MapFindResult;
};
typedef enum HashKeyKind {
enum HashKeyKind {
HashKey_Default,
HashKey_String,
HashKey_Pointer,
} HashKeyKind;
};
typedef struct HashKey {
struct HashKey {
HashKeyKind kind;
u64 key;
union {
String string; // if String, s.len > 0
void * ptr;
};
} HashKey;
};
gb_inline HashKey hashing_proc(void const *data, isize len) {
HashKey h = {HashKey_Default};
@@ -73,75 +65,75 @@ bool hash_key_equal(HashKey a, HashKey b) {
}
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
#define _J2_IND(a, b) a##b
#define _J2(a, b) _J2_IND(a, b)
/*
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 {
template <typename T>
struct MapEntry {
HashKey key;
isize next;
MAP_TYPE value;
} MAP_ENTRY;
T value;
};
typedef struct MAP_NAME {
Array<isize> hashes;
Array<MAP_ENTRY> entries;
} MAP_NAME;
template <typename T>
struct Map {
Array<isize> hashes;
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);
void _J2(MAP_PROC,destroy) (MAP_NAME *h);
MAP_TYPE *_J2(MAP_PROC,get) (MAP_NAME *h, HashKey key);
void _J2(MAP_PROC,set) (MAP_NAME *h, HashKey key, MAP_TYPE value);
void _J2(MAP_PROC,remove) (MAP_NAME *h, HashKey key);
void _J2(MAP_PROC,clear) (MAP_NAME *h);
void _J2(MAP_PROC,grow) (MAP_NAME *h);
void _J2(MAP_PROC,rehash) (MAP_NAME *h, isize new_count);
template <typename T> void map_init (Map<T> *h, gbAllocator a);
template <typename T> void map_init_with_reserve(Map<T> *h, gbAllocator a, isize capacity);
template <typename T> void map_destroy (Map<T> *h);
template <typename T> T * map_get (Map<T> *h, HashKey key);
template <typename T> void map_set (Map<T> *h, HashKey key, T const &value);
template <typename T> void map_remove (Map<T> *h, HashKey key);
template <typename T> void map_clear (Map<T> *h);
template <typename T> void map_grow (Map<T> *h);
template <typename T> void map_rehash (Map<T> *h, isize new_count);
// Mutlivalued map procedure
MAP_ENTRY *_J2(MAP_PROC,multi_find_first)(MAP_NAME *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_first(Map<T> *h, HashKey key);
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);
void _J2(MAP_PROC,multi_get_all) (MAP_NAME *h, HashKey key, MAP_TYPE *items);
void _J2(MAP_PROC,multi_insert) (MAP_NAME *h, HashKey key, MAP_TYPE value);
void _J2(MAP_PROC,multi_remove) (MAP_NAME *h, HashKey key, MAP_ENTRY *e);
void _J2(MAP_PROC,multi_remove_all)(MAP_NAME *h, HashKey key);
template <typename T> isize multi_map_count (Map<T> *h, HashKey key);
template <typename T> void multi_map_get_all (Map<T> *h, HashKey key, T *items);
template <typename T> void multi_map_insert (Map<T> *h, HashKey key, T const &value);
template <typename T> void multi_map_remove (Map<T> *h, HashKey key, MapEntry<T> *e);
template <typename T> void multi_map_remove_all(Map<T> *h, HashKey key);
gb_inline void _J2(MAP_PROC,init)(MAP_NAME *h, gbAllocator a) {
template <typename T>
gb_inline void map_init(Map<T> *h, gbAllocator a) {
array_init(&h->hashes, 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->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->hashes);
}
gb_internal isize _J2(MAP_PROC,_add_entry)(MAP_NAME *h, HashKey key) {
MAP_ENTRY e = {};
template <typename T>
gb_internal isize map__add_entry(Map<T> *h, HashKey key) {
MapEntry<T> e = {};
e.key = key;
e.next = -1;
array_add(&h->entries, e);
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};
if (h->hashes.count > 0) {
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;
}
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};
if (h->hashes.count > 0) {
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;
}
gb_internal b32 _J2(MAP_PROC,_full)(MAP_NAME *h) {
template <typename T>
gb_internal b32 map__full(Map<T> *h) {
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);
_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;
MAP_NAME nh = {};
_J2(MAP_PROC,init)(&nh, h->hashes.allocator);
Map<T> nh = {};
map_init(&nh, h->hashes.allocator);
array_resize(&nh.hashes, new_count);
array_reserve(&nh.entries, h->entries.count);
for (i = 0; i < new_count; i++) {
nh.hashes[i] = -1;
}
for (i = 0; i < h->entries.count; i++) {
MAP_ENTRY *e = &h->entries[i];
MapEntry<T> *e = &h->entries[i];
MapFindResult fr;
if (nh.hashes.count == 0) {
_J2(MAP_PROC,grow)(&nh);
map_grow(&nh);
}
fr = _J2(MAP_PROC,_find)(&nh, e->key);
j = _J2(MAP_PROC,_add_entry)(&nh, e->key);
fr = map__find(&nh, e->key);
j = map__add_entry(&nh, e->key);
if (fr.entry_prev < 0) {
nh.hashes[fr.hash_index] = j;
} 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].value = e->value;
if (_J2(MAP_PROC,_full)(&nh)) {
_J2(MAP_PROC,grow)(&nh);
if (map__full(&nh)) {
map_grow(&nh);
}
}
_J2(MAP_PROC,destroy)(h);
map_destroy(h);
*h = nh;
}
gb_inline MAP_TYPE *_J2(MAP_PROC,get)(MAP_NAME *h, HashKey key) {
isize index = _J2(MAP_PROC,_find)(h, key).entry_index;
template <typename T>
gb_inline T *map_get(Map<T> *h, HashKey key) {
isize index = map__find(h, key).entry_index;
if (index >= 0) {
return &h->entries[index].value;
}
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;
MapFindResult fr;
if (h->hashes.count == 0)
_J2(MAP_PROC,grow)(h);
fr = _J2(MAP_PROC,_find)(h, key);
map_grow(h);
fr = map__find(h, key);
if (fr.entry_index >= 0) {
index = fr.entry_index;
} else {
index = _J2(MAP_PROC,_add_entry)(h, key);
index = map__add_entry(h, key);
if (fr.entry_prev >= 0) {
h->entries[fr.entry_prev].next = index;
} else {
@@ -241,14 +238,14 @@ void _J2(MAP_PROC,set)(MAP_NAME *h, HashKey key, MAP_TYPE value) {
}
h->entries[index].value = value;
if (_J2(MAP_PROC,_full)(h)) {
_J2(MAP_PROC,grow)(h);
if (map__full(h)) {
map_grow(h);
}
}
void _J2(MAP_PROC,_erase)(MAP_NAME *h, MapFindResult fr) {
template <typename T>
void map__erase(Map<T> *h, MapFindResult fr) {
MapFindResult last;
if (fr.entry_prev < 0) {
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;
}
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) {
h->entries[last.entry_prev].next = fr.entry_index;
} 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) {
MapFindResult fr = _J2(MAP_PROC,_find)(h, key);
template <typename T>
void map_remove(Map<T> *h, HashKey key) {
MapFindResult fr = map__find(h, key);
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->entries);
}
#if 1
MAP_ENTRY *_J2(MAP_PROC,multi_find_first)(MAP_NAME *h, HashKey key) {
isize i = _J2(MAP_PROC,_find)(h, key).entry_index;
template <typename T>
MapEntry<T> *multi_map_find_first(Map<T> *h, HashKey key) {
isize i = map__find(h, key).entry_index;
if (i < 0) {
return NULL;
}
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;
while (i >= 0) {
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;
}
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;
MAP_ENTRY *e = _J2(MAP_PROC,multi_find_first)(h, key);
MapEntry<T> *e = multi_map_find_first(h, key);
while (e != NULL) {
count++;
e = _J2(MAP_PROC,multi_find_next)(h, e);
e = multi_map_find_next(h, e);
}
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;
MAP_ENTRY *e = _J2(MAP_PROC,multi_find_first)(h, key);
MapEntry<T> *e = multi_map_find_first(h, key);
while (e != NULL) {
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;
isize i;
if (h->hashes.count == 0) {
_J2(MAP_PROC,grow)(h);
map_grow(h);
}
// Make
fr = _J2(MAP_PROC,_find)(h, key);
i = _J2(MAP_PROC,_add_entry)(h, key);
fr = map__find(h, key);
i = map__add_entry(h, key);
if (fr.entry_prev < 0) {
h->hashes[fr.hash_index] = i;
} 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].value = value;
// Grow if needed
if (_J2(MAP_PROC,_full)(h)) {
_J2(MAP_PROC,grow)(h);
if (map__full(h)) {
map_grow(h);
}
}
void _J2(MAP_PROC,multi_remove)(MAP_NAME *h, HashKey key, MAP_ENTRY *e) {
MapFindResult fr = _J2(MAP_PROC,_find_from_entry)(h, e);
template <typename T>
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) {
_J2(MAP_PROC,_erase)(h, fr);
map__erase(h, fr);
}
}
void _J2(MAP_PROC,multi_remove_all)(MAP_NAME *h, HashKey key) {
while (_J2(MAP_PROC,get)(h, key) != NULL) {
_J2(MAP_PROC,remove)(h, key);
template <typename T>
void multi_map_remove_all(Map<T> *h, HashKey key) {
while (map_get(h, key) != NULL) {
map_remove(h, key);
}
}
#endif
#undef _J2
#undef MAP_TYPE
#undef MAP_PROC
#undef MAP_NAME
#undef MAP_ENTRY
+19 -23
View File
@@ -14,10 +14,6 @@ enum ssaDeferExitKind;
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"
@@ -148,7 +144,7 @@ struct ssaProc {
i32 block_id;
i32 value_id;
MapSsaValue values; // Key: Entity *
Map<ssaValue *> values; // Key: Entity *
Array<ssaDefer> defer_stmts;
i32 scope_level;
@@ -166,8 +162,8 @@ struct ssaModule {
gbAllocator tmp_allocator;
gbArena tmp_arena;
MapEntity min_dep_map; // Key: Entity *
MapSsaValue values; // Key: Entity *
Map<Entity *> min_dep_map; // Key: Entity *
Map<ssaValue *> values; // Key: Entity *
// List of registers for the specific architecture
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->defer_stmts, heap_allocator());
map_ssa_value_init(&p->values, heap_allocator());
map_init(&p->values, heap_allocator());
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);
p->curr_block = cb;
map_ssa_value_set(&p->values, hash_pointer(e), local);
map_ssa_value_set(&p->module->values, hash_pointer(e), local);
map_set(&p->values, hash_pointer(e), local);
map_set(&p->module->values, hash_pointer(e), local);
local->comment_string = e->token.string;
ssa_new_value1(p, ssaOp_Zero, t, local);
return ssa_addr(local);
}
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) {
Entity *e = *found;
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;
Selection sel = lookup_field(p->allocator, parent->type, name, false);
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;
if (pv != NULL) {
v = *pv;
@@ -726,7 +722,7 @@ ssaAddr ssa_build_addr_from_entity(ssaProc *p, Entity *e, AstNode *expr) {
GB_ASSERT(e != 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) {
v = *found;
} 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_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) {
Token token = ast_node_token(expr);
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;
}
ssaValue **found = map_ssa_value_get(&p->module->values, hash_pointer(e));
ssaValue **found = map_get(&p->module->values, hash_pointer(e));
if (found) {
ssaValue *v = *found;
if (v->op == ssaOp_Proc) {
@@ -1840,7 +1836,7 @@ ssaValue *ssa_build_expr(ssaProc *p, AstNode *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);
ssaValue *x = ssa_build_expr(p, ce->args[0]);
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.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.procs, 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;
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;
String name = e->token.string;
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);
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;
String name = e->token.string;
DeclInfo *decl = entry->value;
@@ -2532,7 +2528,7 @@ bool ssa_generate(Parser *parser, CheckerInfo *info) {
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
continue;
}
@@ -2579,8 +2575,8 @@ bool ssa_generate(Parser *parser, CheckerInfo *info) {
// ssa_module_add_value(m, e, p);
// HashKey hash_name = hash_string(name);
// if (map_ssa_value_get(&m.members, hash_name) == NULL) {
// map_ssa_value_set(&m.members, hash_name, p);
// if (map_get(&m.members, hash_name) == NULL) {
// map_set(&m.members, hash_name, p);
// }
} break;
}
@@ -2600,7 +2596,7 @@ String ssa_mangle_name(ssaModule *m, String path, Entity *e) {
String name = e->token.string;
CheckerInfo *info = m->info;
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);
gb_memmove(str, path.text, path.len);