mirror of
https://github.com/Ed94/Odin.git
synced 2026-08-05 15:18:49 +00:00
Amend Checker API
This commit is contained in:
+1
-1
@@ -3409,7 +3409,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_get(&e->ImportName.scope->implicit, hash_pointer(entity)) != NULL;
|
bool implicit_is_found = is_entity_implicitly_imported(e, entity);
|
||||||
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;
|
||||||
|
|||||||
+50
-5
@@ -308,25 +308,26 @@ struct DelayedEntity {
|
|||||||
DeclInfo * decl;
|
DeclInfo * decl;
|
||||||
};
|
};
|
||||||
|
|
||||||
Entity * entity_of_ident (CheckerInfo *i, AstNode *identifier);
|
// CheckerInfo API
|
||||||
TypeAndValue type_and_value_of_expr (CheckerInfo *i, AstNode *expr);
|
TypeAndValue type_and_value_of_expr (CheckerInfo *i, AstNode *expr);
|
||||||
Type * type_of_expr (CheckerInfo *i, AstNode *expr);
|
Type * type_of_expr (CheckerInfo *i, AstNode *expr);
|
||||||
|
Entity * entity_of_ident (CheckerInfo *i, AstNode *identifier);
|
||||||
Entity * implicit_entity_of_node(CheckerInfo *i, AstNode *clause);
|
Entity * implicit_entity_of_node(CheckerInfo *i, AstNode *clause);
|
||||||
DeclInfo * decl_info_of_entity (CheckerInfo *i, Entity * e);
|
DeclInfo * decl_info_of_entity (CheckerInfo *i, Entity * e);
|
||||||
DeclInfo * decl_info_of_ident (CheckerInfo *i, AstNode *ident);
|
DeclInfo * decl_info_of_ident (CheckerInfo *i, AstNode *ident);
|
||||||
AstFile * ast_file_of_filename (CheckerInfo *i, String filename);
|
AstFile * ast_file_of_filename (CheckerInfo *i, String filename);
|
||||||
Scope * scope_of_node (CheckerInfo *i, AstNode *node);
|
Scope * scope_of_node (CheckerInfo *i, AstNode *node);
|
||||||
ExprInfo * check_get_expr_info (CheckerInfo *i, AstNode *expr);
|
isize type_info_index (CheckerInfo *i, Type *type); // Only to use once checking is done
|
||||||
void check_set_expr_info (CheckerInfo *i, AstNode *expr, ExprInfo info);
|
|
||||||
void check_remove_expr_info (CheckerInfo *i, AstNode *expr);
|
|
||||||
|
|
||||||
Entity *current_scope_lookup_entity(Scope *s, String name);
|
Entity *current_scope_lookup_entity(Scope *s, String name);
|
||||||
void scope_lookup_parent_entity (Scope *s, String name, Scope **scope_, Entity **entity_);
|
|
||||||
Entity *scope_lookup_entity (Scope *s, String name);
|
Entity *scope_lookup_entity (Scope *s, String name);
|
||||||
|
void scope_lookup_parent_entity (Scope *s, String name, Scope **scope_, Entity **entity_);
|
||||||
Entity *scope_insert_entity (Scope *s, Entity *entity);
|
Entity *scope_insert_entity (Scope *s, Entity *entity);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
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;
|
||||||
@@ -812,6 +813,11 @@ Entity *implicit_entity_of_node(CheckerInfo *i, AstNode *clause) {
|
|||||||
}
|
}
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
bool is_entity_implicitly_imported(Entity *import_name, Entity *e) {
|
||||||
|
GB_ASSERT(import_name->kind == Entity_ImportName);
|
||||||
|
return map_get(&import_name->ImportName.scope->implicit, hash_pointer(e)) != NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
DeclInfo *decl_info_of_entity(CheckerInfo *i, Entity *e) {
|
DeclInfo *decl_info_of_entity(CheckerInfo *i, Entity *e) {
|
||||||
if (e != NULL) {
|
if (e != NULL) {
|
||||||
@@ -853,6 +859,35 @@ void check_remove_expr_info(CheckerInfo *i, AstNode *expr) {
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
isize type_info_index(CheckerInfo *info, Type *type) {
|
||||||
|
type = default_type(type);
|
||||||
|
|
||||||
|
isize entry_index = -1;
|
||||||
|
HashKey key = hash_pointer(type);
|
||||||
|
isize *found_entry_index = map_get(&info->type_info_map, key);
|
||||||
|
if (found_entry_index) {
|
||||||
|
entry_index = *found_entry_index;
|
||||||
|
}
|
||||||
|
if (entry_index < 0) {
|
||||||
|
// NOTE(bill): Do manual search
|
||||||
|
// TODO(bill): This is O(n) and can be very slow
|
||||||
|
for_array(i, info->type_info_map.entries){
|
||||||
|
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_set(&info->type_info_map, key, entry_index);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (entry_index < 0) {
|
||||||
|
compiler_error("TypeInfo for `%s` could not be found", type_to_string(type));
|
||||||
|
}
|
||||||
|
return entry_index;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
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) {
|
||||||
@@ -1194,6 +1229,12 @@ Map<Entity *> generate_minimum_dependency_map(CheckerInfo *info, Entity *start)
|
|||||||
return map;
|
return map;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool is_entity_in_dependency_map(Map<Entity *> *map, Entity *e) {
|
||||||
|
return map_get(map, hash_pointer(e)) != NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
Entity *find_core_entity(Checker *c, String name) {
|
Entity *find_core_entity(Checker *c, String name) {
|
||||||
Entity *e = current_scope_lookup_entity(c->global_scope, name);
|
Entity *e = current_scope_lookup_entity(c->global_scope, name);
|
||||||
@@ -1368,6 +1409,10 @@ void check_procedure_overloading(Checker *c, Entity *e) {
|
|||||||
|
|
||||||
TokenPos pos = q->token.pos;
|
TokenPos pos = q->token.pos;
|
||||||
|
|
||||||
|
if (q->type == NULL) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
if (is_type_proc(q->type)) {
|
if (is_type_proc(q->type)) {
|
||||||
TypeProc *ptq = &base_type(q->type)->Proc;
|
TypeProc *ptq = &base_type(q->type)->Proc;
|
||||||
if (ptq->is_generic) {
|
if (ptq->is_generic) {
|
||||||
|
|||||||
+8
-46
@@ -1653,7 +1653,6 @@ irValue *ir_gen_map_header(irProcedure *proc, irValue *map_val, Type *map_type)
|
|||||||
ir_emit_store(proc, gep0, m);
|
ir_emit_store(proc, gep0, m);
|
||||||
|
|
||||||
if (is_type_string(key_type)) {
|
if (is_type_string(key_type)) {
|
||||||
// GB_PANIC("TODO(bill): string map keys");
|
|
||||||
ir_emit_store(proc, ir_emit_struct_ep(proc, h, 1), v_true);
|
ir_emit_store(proc, ir_emit_struct_ep(proc, h, 1), v_true);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -2111,13 +2110,6 @@ irValue *ir_emit_arith(irProcedure *proc, TokenKind op, irValue *left, irValue *
|
|||||||
case Token_Shl:
|
case Token_Shl:
|
||||||
case Token_Shr:
|
case Token_Shr:
|
||||||
left = ir_emit_conv(proc, left, type);
|
left = ir_emit_conv(proc, left, type);
|
||||||
// if (!is_type_unsigned(ir_type(right))) {
|
|
||||||
// Type *t = t_u64;
|
|
||||||
// if (build_context.word_size == 32) {
|
|
||||||
// t = t_u32;
|
|
||||||
// }
|
|
||||||
// right = ir_emit_conv(proc, right, t);
|
|
||||||
// }
|
|
||||||
right = ir_emit_conv(proc, right, type);
|
right = ir_emit_conv(proc, right, type);
|
||||||
|
|
||||||
break;
|
break;
|
||||||
@@ -2149,6 +2141,9 @@ irValue *ir_emit_arith(irProcedure *proc, TokenKind op, irValue *left, irValue *
|
|||||||
if (op == Token_ModMod) {
|
if (op == Token_ModMod) {
|
||||||
irValue *n = left;
|
irValue *n = left;
|
||||||
irValue *m = right;
|
irValue *m = right;
|
||||||
|
if (is_type_unsigned(type)) {
|
||||||
|
return ir_emit_arith(proc, Token_Mod, n, m, type);
|
||||||
|
}
|
||||||
irValue *a = ir_emit_arith(proc, Token_Mod, n, m, type);
|
irValue *a = ir_emit_arith(proc, Token_Mod, n, m, type);
|
||||||
irValue *b = ir_emit_arith(proc, Token_Add, a, m, type);
|
irValue *b = ir_emit_arith(proc, Token_Add, a, m, type);
|
||||||
return ir_emit_arith(proc, Token_Mod, b, m, type);
|
return ir_emit_arith(proc, Token_Mod, b, m, type);
|
||||||
@@ -3321,39 +3316,6 @@ irValue *ir_emit_any_cast(irProcedure *proc, irValue *value, Type *type, TokenPo
|
|||||||
return ir_addr_load(proc, ir_emit_any_cast_addr(proc, value, type, pos));
|
return ir_addr_load(proc, ir_emit_any_cast_addr(proc, value, type, pos));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
isize ir_type_info_index(CheckerInfo *info, Type *type) {
|
|
||||||
type = default_type(type);
|
|
||||||
|
|
||||||
isize entry_index = -1;
|
|
||||||
HashKey key = hash_pointer(type);
|
|
||||||
isize *found_entry_index = map_get(&info->type_info_map, key);
|
|
||||||
if (found_entry_index) {
|
|
||||||
entry_index = *found_entry_index;
|
|
||||||
}
|
|
||||||
if (entry_index < 0) {
|
|
||||||
// NOTE(bill): Do manual search
|
|
||||||
// TODO(bill): This is O(n) and can be very slow
|
|
||||||
for_array(i, info->type_info_map.entries){
|
|
||||||
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_set(&info->type_info_map, key, entry_index);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (entry_index < 0) {
|
|
||||||
compiler_error("TypeInfo for `%s` could not be found", type_to_string(type));
|
|
||||||
}
|
|
||||||
return entry_index;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// TODO(bill): Try and make a lot of this constant aggregate literals in LLVM IR
|
// TODO(bill): Try and make a lot of this constant aggregate literals in LLVM IR
|
||||||
gb_global irValue *ir_global_type_info_data = NULL;
|
gb_global irValue *ir_global_type_info_data = NULL;
|
||||||
gb_global irValue *ir_global_type_info_member_types = NULL;
|
gb_global irValue *ir_global_type_info_member_types = NULL;
|
||||||
@@ -3373,7 +3335,7 @@ irValue *ir_type_info(irProcedure *proc, Type *type) {
|
|||||||
|
|
||||||
type = default_type(type);
|
type = default_type(type);
|
||||||
|
|
||||||
i32 entry_index = ir_type_info_index(info, type);
|
i32 entry_index = type_info_index(info, type);
|
||||||
|
|
||||||
// gb_printf_err("%d %s\n", entry_index, type_to_string(type));
|
// gb_printf_err("%d %s\n", entry_index, type_to_string(type));
|
||||||
|
|
||||||
@@ -5997,7 +5959,7 @@ void ir_build_stmt_internal(irProcedure *proc, AstNode *node) {
|
|||||||
if (pd->body != NULL) {
|
if (pd->body != NULL) {
|
||||||
CheckerInfo *info = proc->module->info;
|
CheckerInfo *info = proc->module->info;
|
||||||
|
|
||||||
if (map_get(&proc->module->min_dep_map, hash_pointer(e)) == NULL) {
|
if (is_entity_in_dependency_map(&proc->module->min_dep_map, e) == false) {
|
||||||
// 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;
|
||||||
}
|
}
|
||||||
@@ -7009,7 +6971,7 @@ void ir_init_module(irModule *m, Checker *c) {
|
|||||||
auto *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 *)entry->key.ptr;
|
Type *t = cast(Type *)entry->key.ptr;
|
||||||
t = default_type(t);
|
t = default_type(t);
|
||||||
isize entry_index = ir_type_info_index(m->info, t);
|
isize entry_index = type_info_index(m->info, t);
|
||||||
if (max_index < entry_index) {
|
if (max_index < entry_index) {
|
||||||
max_index = entry_index;
|
max_index = entry_index;
|
||||||
}
|
}
|
||||||
@@ -7161,7 +7123,7 @@ void ir_gen_destroy(irGen *s) {
|
|||||||
// Type Info stuff
|
// Type Info stuff
|
||||||
//
|
//
|
||||||
irValue *ir_get_type_info_ptr(irProcedure *proc, Type *type) {
|
irValue *ir_get_type_info_ptr(irProcedure *proc, Type *type) {
|
||||||
i32 index = cast(i32)ir_type_info_index(proc->module->info, type);
|
i32 index = cast(i32)type_info_index(proc->module->info, type);
|
||||||
// gb_printf_err("%d %s\n", index, type_to_string(type));
|
// gb_printf_err("%d %s\n", index, type_to_string(type));
|
||||||
irValue *ptr = ir_emit_array_epi(proc, ir_global_type_info_data, index);
|
irValue *ptr = ir_emit_array_epi(proc, ir_global_type_info_data, index);
|
||||||
return ir_emit_bitcast(proc, ptr, t_type_info_ptr);
|
return ir_emit_bitcast(proc, ptr, t_type_info_ptr);
|
||||||
@@ -7608,7 +7570,7 @@ void ir_gen_tree(irGen *s) {
|
|||||||
auto *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 *)entry->key.ptr;
|
Type *t = cast(Type *)entry->key.ptr;
|
||||||
t = default_type(t);
|
t = default_type(t);
|
||||||
isize entry_index = ir_type_info_index(info, t);
|
isize entry_index = type_info_index(info, t);
|
||||||
|
|
||||||
irValue *tag = NULL;
|
irValue *tag = NULL;
|
||||||
irValue *ti_ptr = ir_emit_array_epi(proc, ir_global_type_info_data, entry_index);
|
irValue *ti_ptr = ir_emit_array_epi(proc, ir_global_type_info_data, entry_index);
|
||||||
|
|||||||
+22
-5
@@ -15,6 +15,12 @@ enum HashKeyKind {
|
|||||||
HashKey_Default,
|
HashKey_Default,
|
||||||
HashKey_String,
|
HashKey_String,
|
||||||
HashKey_Pointer,
|
HashKey_Pointer,
|
||||||
|
HashKey_PointerAndId,
|
||||||
|
};
|
||||||
|
|
||||||
|
struct PointerAndId {
|
||||||
|
void *ptr;
|
||||||
|
u32 id;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct HashKey {
|
struct HashKey {
|
||||||
@@ -22,8 +28,9 @@ struct HashKey {
|
|||||||
// u128 key;
|
// u128 key;
|
||||||
u64 key;
|
u64 key;
|
||||||
union {
|
union {
|
||||||
String string; // if String, s.len > 0
|
String string; // if String, s.len > 0
|
||||||
void * ptr;
|
void * ptr;
|
||||||
|
PointerAndId ptr_and_id;
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -44,11 +51,16 @@ gb_inline HashKey hash_string(String s) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
gb_inline HashKey hash_pointer(void *ptr) {
|
gb_inline HashKey hash_pointer(void *ptr) {
|
||||||
HashKey h = {HashKey_Default};
|
HashKey h = {HashKey_Pointer};
|
||||||
// h.key = u128_from_u64(cast(u64)cast(uintptr)ptr);
|
|
||||||
h.key = cast(u64)cast(uintptr)ptr;
|
h.key = cast(u64)cast(uintptr)ptr;
|
||||||
h.ptr = ptr;
|
h.ptr = ptr;
|
||||||
h.kind = HashKey_Default;
|
return h;
|
||||||
|
}
|
||||||
|
gb_inline HashKey hash_ptr_and_id(void *ptr, u32 id) {
|
||||||
|
HashKey h = {HashKey_PointerAndId};
|
||||||
|
h.key = cast(u64)cast(uintptr)ptr;
|
||||||
|
h.ptr_and_id.ptr = ptr;
|
||||||
|
h.ptr_and_id.id = id;
|
||||||
return h;
|
return h;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -60,6 +72,11 @@ bool hash_key_equal(HashKey a, HashKey b) {
|
|||||||
return a.string == b.string;
|
return a.string == b.string;
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
|
} else if (a.kind == HashKey_PointerAndId) {
|
||||||
|
if (b.kind == HashKey_PointerAndId) {
|
||||||
|
return a.ptr_and_id.id == b.ptr_and_id.id;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user