mirror of
https://github.com/Ed94/Odin.git
synced 2026-08-06 23:58:50 +00:00
Simplify type info table construction
This commit is contained in:
+100
-60
@@ -828,9 +828,15 @@ gb_internal void add_dependency(CheckerInfo *info, DeclInfo *d, Entity *e) {
|
|||||||
rw_mutex_unlock(&d->deps_mutex);
|
rw_mutex_unlock(&d->deps_mutex);
|
||||||
}
|
}
|
||||||
gb_internal void add_type_info_dependency(CheckerInfo *info, DeclInfo *d, Type *type) {
|
gb_internal void add_type_info_dependency(CheckerInfo *info, DeclInfo *d, Type *type) {
|
||||||
if (d == nullptr) {
|
if (d == nullptr || type == nullptr) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
if (type->kind == Type_Named) {
|
||||||
|
Entity *e = type->Named.type_name;
|
||||||
|
if (e->TypeName.is_type_alias) {
|
||||||
|
type = type->Named.base;
|
||||||
|
}
|
||||||
|
}
|
||||||
rw_mutex_lock(&d->type_info_deps_mutex);
|
rw_mutex_lock(&d->type_info_deps_mutex);
|
||||||
ptr_set_add(&d->type_info_deps, type);
|
ptr_set_add(&d->type_info_deps, type);
|
||||||
rw_mutex_unlock(&d->type_info_deps_mutex);
|
rw_mutex_unlock(&d->type_info_deps_mutex);
|
||||||
@@ -1361,9 +1367,12 @@ gb_internal void init_checker_info(CheckerInfo *i) {
|
|||||||
string_map_init(&i->foreigns);
|
string_map_init(&i->foreigns);
|
||||||
// map_init(&i->gen_procs);
|
// map_init(&i->gen_procs);
|
||||||
map_init(&i->gen_types);
|
map_init(&i->gen_types);
|
||||||
|
|
||||||
array_init(&i->type_info_types, a);
|
array_init(&i->type_info_types, a);
|
||||||
map_init(&i->type_info_map);
|
type_set_init(&i->min_dep_type_info_set);
|
||||||
type_set_init(&i->type_info_set);
|
map_init(&i->minimum_dependency_type_info_index_map);
|
||||||
|
|
||||||
|
// map_init(&i->type_info_map);
|
||||||
string_map_init(&i->files);
|
string_map_init(&i->files);
|
||||||
string_map_init(&i->packages);
|
string_map_init(&i->packages);
|
||||||
array_init(&i->variable_init_order, a);
|
array_init(&i->variable_init_order, a);
|
||||||
@@ -1396,9 +1405,11 @@ gb_internal void destroy_checker_info(CheckerInfo *i) {
|
|||||||
string_map_destroy(&i->foreigns);
|
string_map_destroy(&i->foreigns);
|
||||||
// map_destroy(&i->gen_procs);
|
// map_destroy(&i->gen_procs);
|
||||||
map_destroy(&i->gen_types);
|
map_destroy(&i->gen_types);
|
||||||
|
|
||||||
array_free(&i->type_info_types);
|
array_free(&i->type_info_types);
|
||||||
map_destroy(&i->type_info_map);
|
type_set_destroy(&i->min_dep_type_info_set);
|
||||||
type_set_destroy(&i->type_info_set);
|
map_destroy(&i->minimum_dependency_type_info_index_map);
|
||||||
|
|
||||||
string_map_destroy(&i->files);
|
string_map_destroy(&i->files);
|
||||||
string_map_destroy(&i->packages);
|
string_map_destroy(&i->packages);
|
||||||
array_free(&i->variable_init_order);
|
array_free(&i->variable_init_order);
|
||||||
@@ -1632,6 +1643,23 @@ gb_internal void check_remove_expr_info(CheckerContext *c, Ast *e) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
gb_internal isize type_info_index(CheckerInfo *info, TypeInfoPair pair, bool error_on_failure) {
|
||||||
|
mutex_lock(&info->minimum_dependency_type_info_mutex);
|
||||||
|
|
||||||
|
isize entry_index = -1;
|
||||||
|
uintptr hash = cast(uintptr)pair.hash;
|
||||||
|
isize *found_entry_index = map_get(&info->minimum_dependency_type_info_index_map, hash);
|
||||||
|
if (found_entry_index) {
|
||||||
|
entry_index = *found_entry_index;
|
||||||
|
}
|
||||||
|
mutex_unlock(&info->minimum_dependency_type_info_mutex);
|
||||||
|
|
||||||
|
if (error_on_failure && entry_index < 0) {
|
||||||
|
compiler_error("Type_Info for '%s' could not be found", type_to_string(pair.type));
|
||||||
|
}
|
||||||
|
return entry_index;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
gb_internal isize type_info_index(CheckerInfo *info, Type *type, bool error_on_failure) {
|
gb_internal isize type_info_index(CheckerInfo *info, Type *type, bool error_on_failure) {
|
||||||
type = default_type(type);
|
type = default_type(type);
|
||||||
@@ -1639,32 +1667,10 @@ gb_internal isize type_info_index(CheckerInfo *info, Type *type, bool error_on_f
|
|||||||
type = t_bool;
|
type = t_bool;
|
||||||
}
|
}
|
||||||
|
|
||||||
mutex_lock(&info->type_info_mutex);
|
u64 hash = type_hash_canonical_type(type);
|
||||||
|
return type_info_index(info, {type, hash}, error_on_failure);
|
||||||
isize entry_index = -1;
|
|
||||||
isize *found_entry_index = map_get(&info->type_info_map, type);
|
|
||||||
if (found_entry_index) {
|
|
||||||
entry_index = *found_entry_index;
|
|
||||||
}
|
|
||||||
if (entry_index < 0) {
|
|
||||||
// NOTE(bill): Do manual linear search
|
|
||||||
for (auto const &e : info->type_info_map) {
|
|
||||||
if (are_types_identical_unique_tuples(e.key, type)) {
|
|
||||||
entry_index = e.value;
|
|
||||||
// NOTE(bill): Add it to the search map
|
|
||||||
map_set(&info->type_info_map, type, entry_index);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
mutex_unlock(&info->type_info_mutex);
|
|
||||||
|
|
||||||
if (error_on_failure && entry_index < 0) {
|
|
||||||
compiler_error("Type_Info for '%s' could not be found", type_to_string(type));
|
|
||||||
}
|
|
||||||
return entry_index;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
gb_internal void add_untyped(CheckerContext *c, Ast *expr, AddressingMode mode, Type *type, ExactValue const &value) {
|
gb_internal void add_untyped(CheckerContext *c, Ast *expr, AddressingMode mode, Type *type, ExactValue const &value) {
|
||||||
@@ -2018,8 +2024,12 @@ gb_internal void add_type_info_type_internal(CheckerContext *c, Type *t) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
add_type_info_dependency(c->info, c->decl, t);
|
add_type_info_dependency(c->info, c->decl, t);
|
||||||
|
#if 0
|
||||||
MUTEX_GUARD_BLOCK(&c->info->type_info_mutex) {
|
MUTEX_GUARD_BLOCK(&c->info->type_info_mutex) {
|
||||||
|
if (type_set_update(&c->info->type_info_set, t)) {
|
||||||
|
// return;
|
||||||
|
}
|
||||||
|
|
||||||
auto found = map_get(&c->info->type_info_map, t);
|
auto found = map_get(&c->info->type_info_map, t);
|
||||||
if (found != nullptr) {
|
if (found != nullptr) {
|
||||||
// Types have already been added
|
// Types have already been added
|
||||||
@@ -2238,6 +2248,7 @@ gb_internal void add_type_info_type_internal(CheckerContext *c, Type *t) {
|
|||||||
GB_PANIC("Unhandled type: %*.s %d", LIT(type_strings[bt->kind]), bt->kind);
|
GB_PANIC("Unhandled type: %*.s %d", LIT(type_strings[bt->kind]), bt->kind);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -2295,11 +2306,10 @@ gb_internal void add_min_dep_type_info(Checker *c, Type *t) {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (type_set_update(&c->info.type_info_set, t)) {
|
if (type_set_update(&c->info.min_dep_type_info_set, t)) {
|
||||||
// return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// Add nested types
|
// Add nested types
|
||||||
if (t->kind == Type_Named) {
|
if (t->kind == Type_Named) {
|
||||||
// NOTE(bill): Just in case
|
// NOTE(bill): Just in case
|
||||||
@@ -2697,7 +2707,6 @@ gb_internal void generate_minimum_dependency_set(Checker *c, Entity *start) {
|
|||||||
isize min_dep_set_cap = next_pow2_isize(entity_count*4); // empirically determined factor
|
isize min_dep_set_cap = next_pow2_isize(entity_count*4); // empirically determined factor
|
||||||
|
|
||||||
ptr_set_init(&c->info.minimum_dependency_set, min_dep_set_cap);
|
ptr_set_init(&c->info.minimum_dependency_set, min_dep_set_cap);
|
||||||
map_init(&c->info.minimum_dependency_type_info_set);
|
|
||||||
|
|
||||||
#define FORCE_ADD_RUNTIME_ENTITIES(condition, ...) do { \
|
#define FORCE_ADD_RUNTIME_ENTITIES(condition, ...) do { \
|
||||||
if (condition) { \
|
if (condition) { \
|
||||||
@@ -6720,40 +6729,71 @@ gb_internal void check_parsed_files(Checker *c) {
|
|||||||
add_type_and_value(&c->builtin_ctx, u.expr, u.info->mode, u.info->type, u.info->value);
|
add_type_and_value(&c->builtin_ctx, u.expr, u.info->mode, u.info->type, u.info->value);
|
||||||
}
|
}
|
||||||
|
|
||||||
TIME_SECTION("check for type hash collisions");
|
TIME_SECTION("initilize type info array");
|
||||||
{
|
{
|
||||||
PtrSet<uintptr> found = {};
|
for (auto const &tt : c->info.min_dep_type_info_set) {
|
||||||
ptr_set_init(&found, c->info.type_info_types.count);
|
array_add(&c->info.type_info_types, tt);
|
||||||
defer (ptr_set_destroy(&found));
|
|
||||||
for (auto const &tt : c->info.type_info_types) {
|
|
||||||
if (ptr_set_update(&found, cast(uintptr)tt.hash)) {
|
|
||||||
Type *other_type = nullptr;
|
|
||||||
for (auto const &other : c->info.type_info_types) {
|
|
||||||
if (&tt == &other) {
|
|
||||||
continue;
|
|
||||||
}
|
}
|
||||||
if (cast(uintptr)other.hash == cast(uintptr)tt.hash &&
|
array_sort(c->info.type_info_types, type_info_pair_cmp);
|
||||||
!are_types_identical(tt.type, other.type)) {
|
|
||||||
other_type = other.type;
|
map_reserve(&c->info.minimum_dependency_type_info_index_map, c->info.type_info_types.count);
|
||||||
break;
|
|
||||||
}
|
for_array(i, c->info.type_info_types) {
|
||||||
}
|
auto const &tt = c->info.type_info_types[i];
|
||||||
if (other_type != nullptr) {
|
bool exists = map_set_if_not_previously_exists(&c->info.minimum_dependency_type_info_index_map, cast(uintptr)tt.hash, i);
|
||||||
String ts = type_to_canonical_string(temporary_allocator(), tt.type);
|
if (exists) {
|
||||||
String os = type_to_canonical_string(temporary_allocator(), other_type);
|
for (auto const &entry : c->info.minimum_dependency_type_info_index_map) {
|
||||||
if (ts != os) {
|
if (entry.key == cast(uintptr)tt.hash) {
|
||||||
compiler_error("%s found type hash collision with %s (hash = %llu)\n"
|
auto const &other = c->info.type_info_types[entry.value];
|
||||||
"%s vs %s\n",
|
if (!are_types_identical_unique_tuples(tt.type, other.type)) {
|
||||||
type_to_string(tt.type), type_to_string(other_type), cast(unsigned long long)tt.hash,
|
gbString t = temp_canonical_string(tt.type);
|
||||||
temp_canonical_string(tt.type),
|
gbString o = temp_canonical_string(other.type);
|
||||||
temp_canonical_string(other_type)
|
GB_PANIC("%s (%s) %llu vs %s (%s) %llu",
|
||||||
);
|
type_to_string(tt.type, false), t, cast(unsigned long long)tt.hash,
|
||||||
|
type_to_string(other.type, false), o, cast(unsigned long long)other.hash);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
GB_ASSERT(c->info.minimum_dependency_type_info_index_map.count <= c->info.type_info_types.count);
|
||||||
|
}
|
||||||
|
|
||||||
|
// TIME_SECTION("check for type hash collisions");
|
||||||
|
// {
|
||||||
|
// PtrSet<uintptr> found = {};
|
||||||
|
// ptr_set_init(&found, c->info.type_info_types.count);
|
||||||
|
// defer (ptr_set_destroy(&found));
|
||||||
|
// for (auto const &tt : c->info.type_info_types) {
|
||||||
|
// if (ptr_set_update(&found, cast(uintptr)tt.hash)) {
|
||||||
|
// Type *other_type = nullptr;
|
||||||
|
// for (auto const &other : c->info.type_info_types) {
|
||||||
|
// if (&tt == &other) {
|
||||||
|
// continue;
|
||||||
|
// }
|
||||||
|
// if (cast(uintptr)other.hash == cast(uintptr)tt.hash &&
|
||||||
|
// !are_types_identical(tt.type, other.type)) {
|
||||||
|
// other_type = other.type;
|
||||||
|
// break;
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// if (other_type != nullptr) {
|
||||||
|
// String ts = type_to_canonical_string(temporary_allocator(), tt.type);
|
||||||
|
// String os = type_to_canonical_string(temporary_allocator(), other_type);
|
||||||
|
// if (ts != os) {
|
||||||
|
// compiler_error("%s found type hash collision with %s (hash = %llu)\n"
|
||||||
|
// "%s vs %s\n",
|
||||||
|
// type_to_string(tt.type), type_to_string(other_type), cast(unsigned long long)tt.hash,
|
||||||
|
// temp_canonical_string(tt.type),
|
||||||
|
// temp_canonical_string(other_type)
|
||||||
|
// );
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
TIME_SECTION("sort init and fini procedures");
|
TIME_SECTION("sort init and fini procedures");
|
||||||
|
|||||||
+10
-7
@@ -222,7 +222,7 @@ struct DeclInfo {
|
|||||||
PtrSet<Entity *> deps;
|
PtrSet<Entity *> deps;
|
||||||
|
|
||||||
RwMutex type_info_deps_mutex;
|
RwMutex type_info_deps_mutex;
|
||||||
PtrSet<Type *> type_info_deps;
|
PtrSet<Type *> type_info_deps; // TODO(bill): Use TypeSet
|
||||||
|
|
||||||
BlockingMutex type_and_value_mutex;
|
BlockingMutex type_and_value_mutex;
|
||||||
|
|
||||||
@@ -444,8 +444,10 @@ struct CheckerInfo {
|
|||||||
Scope * init_scope;
|
Scope * init_scope;
|
||||||
Entity * entry_point;
|
Entity * entry_point;
|
||||||
PtrSet<Entity *> minimum_dependency_set;
|
PtrSet<Entity *> minimum_dependency_set;
|
||||||
PtrMap</*type info index*/isize, /*min dep index*/isize> minimum_dependency_type_info_set;
|
BlockingMutex minimum_dependency_type_info_mutex;
|
||||||
|
PtrMap</*type info hash*/uintptr, /*min dep index*/isize> minimum_dependency_type_info_index_map;
|
||||||
|
TypeSet min_dep_type_info_set;
|
||||||
|
Array<TypeInfoPair> type_info_types; // sorted after filled
|
||||||
|
|
||||||
|
|
||||||
Array<Entity *> testing_procedures;
|
Array<Entity *> testing_procedures;
|
||||||
@@ -473,10 +475,10 @@ struct CheckerInfo {
|
|||||||
BlockingMutex gen_types_mutex;
|
BlockingMutex gen_types_mutex;
|
||||||
PtrMap<Type *, GenTypesData *> gen_types;
|
PtrMap<Type *, GenTypesData *> gen_types;
|
||||||
|
|
||||||
BlockingMutex type_info_mutex; // NOT recursive
|
// BlockingMutex type_info_mutex; // NOT recursive
|
||||||
Array<TypeInfoPair> type_info_types;
|
// Array<TypeInfoPair> type_info_types;
|
||||||
PtrMap<Type *, isize> type_info_map;
|
// PtrMap<Type *, isize> type_info_map;
|
||||||
TypeSet type_info_set;
|
// TypeSet type_info_set;
|
||||||
|
|
||||||
BlockingMutex foreign_mutex; // NOT recursive
|
BlockingMutex foreign_mutex; // NOT recursive
|
||||||
StringMap<Entity *> foreigns;
|
StringMap<Entity *> foreigns;
|
||||||
@@ -595,6 +597,7 @@ gb_internal DeclInfo * decl_info_of_entity (Entity * e);
|
|||||||
gb_internal AstFile * ast_file_of_filename (CheckerInfo *i, String filename);
|
gb_internal AstFile * ast_file_of_filename (CheckerInfo *i, String filename);
|
||||||
// IMPORTANT: Only to use once checking is done
|
// IMPORTANT: Only to use once checking is done
|
||||||
gb_internal isize type_info_index (CheckerInfo *i, Type *type, bool error_on_failure);
|
gb_internal isize type_info_index (CheckerInfo *i, Type *type, bool error_on_failure);
|
||||||
|
gb_internal isize type_info_index (CheckerInfo *info, TypeInfoPair pair, bool error_on_failure);
|
||||||
|
|
||||||
// Will return nullptr if not found
|
// Will return nullptr if not found
|
||||||
gb_internal Entity *entity_of_node(Ast *expr);
|
gb_internal Entity *entity_of_node(Ast *expr);
|
||||||
|
|||||||
@@ -3154,7 +3154,9 @@ gb_internal bool lb_generate_code(lbGenerator *gen) {
|
|||||||
lbModule *m = default_module;
|
lbModule *m = default_module;
|
||||||
|
|
||||||
{ // Add type info data
|
{ // Add type info data
|
||||||
isize max_type_info_count = info->minimum_dependency_type_info_set.count+1;
|
GB_ASSERT_MSG(info->minimum_dependency_type_info_index_map.count == info->type_info_types.count, "%tu vs %tu", info->minimum_dependency_type_info_index_map.count, info->type_info_types.count);
|
||||||
|
|
||||||
|
isize max_type_info_count = info->minimum_dependency_type_info_index_map.count+1;
|
||||||
Type *t = alloc_type_array(t_type_info_ptr, max_type_info_count);
|
Type *t = alloc_type_array(t_type_info_ptr, max_type_info_count);
|
||||||
|
|
||||||
// IMPORTANT NOTE(bill): As LLVM does not have a union type, an array of unions cannot be initialized
|
// IMPORTANT NOTE(bill): As LLVM does not have a union type, an array of unions cannot be initialized
|
||||||
|
|||||||
+13
-12
@@ -1,16 +1,12 @@
|
|||||||
gb_internal isize lb_type_info_index(CheckerInfo *info, Type *type, bool err_on_not_found=true) {
|
|
||||||
auto *set = &info->minimum_dependency_type_info_set;
|
gb_internal isize lb_type_info_index(CheckerInfo *info, TypeInfoPair pair, bool err_on_not_found=true) {
|
||||||
isize index = type_info_index(info, type, err_on_not_found);
|
isize index = type_info_index(info, pair, err_on_not_found);
|
||||||
if (index >= 0) {
|
if (index >= 0) {
|
||||||
auto *found = map_get(set, index+1);
|
return index+1;
|
||||||
if (found) {
|
|
||||||
GB_ASSERT(*found >= 0);
|
|
||||||
return *found + 1;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
if (err_on_not_found) {
|
if (err_on_not_found) {
|
||||||
gb_printf_err("NOT FOUND lb_type_info_index:\n\t%s\n\t@ index %td\n\tmax count: %u\nFound:\n", type_to_string(type), index, set->count);
|
gb_printf_err("NOT FOUND lb_type_info_index:\n\t%s\n\t@ index %td\n\tmax count: %u\nFound:\n", type_to_string(pair.type), index, info->minimum_dependency_type_info_index_map.count);
|
||||||
for (auto const &entry : *set) {
|
for (auto const &entry : info->minimum_dependency_type_info_index_map) {
|
||||||
isize type_info_index = entry.key;
|
isize type_info_index = entry.key;
|
||||||
gb_printf_err("\t%s\n", type_to_string(info->type_info_types[type_info_index].type));
|
gb_printf_err("\t%s\n", type_to_string(info->type_info_types[type_info_index].type));
|
||||||
}
|
}
|
||||||
@@ -19,6 +15,10 @@ gb_internal isize lb_type_info_index(CheckerInfo *info, Type *type, bool err_on_
|
|||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
gb_internal isize lb_type_info_index(CheckerInfo *info, Type *type, bool err_on_not_found=true) {
|
||||||
|
return lb_type_info_index(info, {type, type_hash_canonical_type(type)}, err_on_not_found);
|
||||||
|
}
|
||||||
|
|
||||||
gb_internal u64 lb_typeid_kind(lbModule *m, Type *type, u64 id=0) {
|
gb_internal u64 lb_typeid_kind(lbModule *m, Type *type, u64 id=0) {
|
||||||
GB_ASSERT(!build_context.no_rtti);
|
GB_ASSERT(!build_context.no_rtti);
|
||||||
|
|
||||||
@@ -280,12 +280,13 @@ gb_internal void lb_setup_type_info_data_giant_array(lbModule *m, i64 global_typ
|
|||||||
LLVMTypeRef *modified_types = lb_setup_modified_types_for_type_info(m, global_type_info_data_entity_count);
|
LLVMTypeRef *modified_types = lb_setup_modified_types_for_type_info(m, global_type_info_data_entity_count);
|
||||||
defer (gb_free(heap_allocator(), modified_types));
|
defer (gb_free(heap_allocator(), modified_types));
|
||||||
for_array(type_info_type_index, info->type_info_types) {
|
for_array(type_info_type_index, info->type_info_types) {
|
||||||
Type *t = info->type_info_types[type_info_type_index].type;
|
auto const &tt = info->type_info_types[type_info_type_index];
|
||||||
|
Type *t = tt.type;
|
||||||
if (t == nullptr || t == t_invalid) {
|
if (t == nullptr || t == t_invalid) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
isize entry_index = lb_type_info_index(info, t, false);
|
isize entry_index = lb_type_info_index(info, tt, false);
|
||||||
if (entry_index <= 0) {
|
if (entry_index <= 0) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -48,6 +48,15 @@ gb_internal gbString temp_canonical_string(Type *type);
|
|||||||
struct TypeInfoPair;
|
struct TypeInfoPair;
|
||||||
struct TypeSet;
|
struct TypeSet;
|
||||||
|
|
||||||
|
gb_internal GB_COMPARE_PROC(type_info_pair_cmp) {
|
||||||
|
TypeInfoPair *x = cast(TypeInfoPair *)a;
|
||||||
|
TypeInfoPair *y = cast(TypeInfoPair *)b;
|
||||||
|
if (x->hash == y->hash) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
return x->hash < y->hash ? -1 : +1;
|
||||||
|
}
|
||||||
|
|
||||||
static constexpr u64 TYPE_SET_TOMBSTONE = ~(u64)(0ull);
|
static constexpr u64 TYPE_SET_TOMBSTONE = ~(u64)(0ull);
|
||||||
|
|
||||||
gb_internal void type_set_init (TypeSet *s, isize capacity);
|
gb_internal void type_set_init (TypeSet *s, isize capacity);
|
||||||
@@ -136,7 +145,7 @@ gb_internal isize type_set__find(TypeSet *s, TypeInfoPair pair) {
|
|||||||
usize hash_index = cast(usize)hash & mask;
|
usize hash_index = cast(usize)hash & mask;
|
||||||
for (usize i = 0; i < s->capacity; i++) {
|
for (usize i = 0; i < s->capacity; i++) {
|
||||||
Type *key = s->keys[hash_index].type;
|
Type *key = s->keys[hash_index].type;
|
||||||
if (are_types_identical(key, pair.type)) {
|
if (are_types_identical_unique_tuples(key, pair.type)) {
|
||||||
return hash_index;
|
return hash_index;
|
||||||
} else if (key == 0) {
|
} else if (key == 0) {
|
||||||
return -1;
|
return -1;
|
||||||
@@ -154,7 +163,7 @@ gb_internal isize type_set__find(TypeSet *s, Type *ptr) {
|
|||||||
usize hash_index = cast(usize)hash & mask;
|
usize hash_index = cast(usize)hash & mask;
|
||||||
for (usize i = 0; i < s->capacity; i++) {
|
for (usize i = 0; i < s->capacity; i++) {
|
||||||
Type *key = s->keys[hash_index].type;
|
Type *key = s->keys[hash_index].type;
|
||||||
if (are_types_identical(key, ptr)) {
|
if (are_types_identical_unique_tuples(key, ptr)) {
|
||||||
return hash_index;
|
return hash_index;
|
||||||
} else if (key == 0) {
|
} else if (key == 0) {
|
||||||
return -1;
|
return -1;
|
||||||
@@ -224,7 +233,7 @@ gb_internal bool type_set_update(TypeSet *s, TypeInfoPair pair) { // returns tru
|
|||||||
GB_ASSERT(hash_index < s->capacity);
|
GB_ASSERT(hash_index < s->capacity);
|
||||||
for (usize i = 0; i < s->capacity; i++) {
|
for (usize i = 0; i < s->capacity; i++) {
|
||||||
TypeInfoPair *key = &s->keys[hash_index];
|
TypeInfoPair *key = &s->keys[hash_index];
|
||||||
GB_ASSERT(!are_types_identical(key->type, pair.type));
|
GB_ASSERT(!are_types_identical_unique_tuples(key->type, pair.type));
|
||||||
if (key->hash == TYPE_SET_TOMBSTONE || key->hash == 0) {
|
if (key->hash == TYPE_SET_TOMBSTONE || key->hash == 0) {
|
||||||
*key = pair;
|
*key = pair;
|
||||||
s->count++;
|
s->count++;
|
||||||
@@ -274,6 +283,9 @@ gb_internal gbString write_canonical_params(gbString w, Type *params) {
|
|||||||
if (i > 0) {
|
if (i > 0) {
|
||||||
w = gb_string_appendc(w, CANONICAL_PARAM_SEPARATOR);
|
w = gb_string_appendc(w, CANONICAL_PARAM_SEPARATOR);
|
||||||
}
|
}
|
||||||
|
w = gb_string_append_length(w, v->token.string.text, v->token.string.len);
|
||||||
|
w = gb_string_appendc(w, CANONICAL_TYPE_SEPARATOR);
|
||||||
|
|
||||||
if (v->kind == Entity_Variable) {
|
if (v->kind == Entity_Variable) {
|
||||||
if (v->flags&EntityFlag_CVarArg) {
|
if (v->flags&EntityFlag_CVarArg) {
|
||||||
w = gb_string_appendc(w, CANONICAL_PARAM_C_VARARG);
|
w = gb_string_appendc(w, CANONICAL_PARAM_C_VARARG);
|
||||||
@@ -466,14 +478,17 @@ write_base_name:
|
|||||||
switch (e->kind) {
|
switch (e->kind) {
|
||||||
case Entity_TypeName:
|
case Entity_TypeName:
|
||||||
{
|
{
|
||||||
|
|
||||||
Type *params = nullptr;
|
Type *params = nullptr;
|
||||||
Entity *parent = type_get_polymorphic_parent(e->type, ¶ms);
|
Entity *parent = type_get_polymorphic_parent(e->type, ¶ms);
|
||||||
if (parent) {
|
if (parent && (parent->token.string == e->token.string)) {
|
||||||
w = gb_string_append_length(w, parent->token.string.text, parent->token.string.len);
|
w = gb_string_append_length(w, parent->token.string.text, parent->token.string.len);
|
||||||
w = write_canonical_params(w, params);
|
w = write_canonical_params(w, params);
|
||||||
} else {
|
} else {
|
||||||
w = gb_string_append_length(w, e->token.string.text, e->token.string.len);
|
w = gb_string_append_length(w, e->token.string.text, e->token.string.len);
|
||||||
}
|
}
|
||||||
|
gb_unused(parent);
|
||||||
|
|
||||||
}
|
}
|
||||||
// Handle parapoly stuff here?
|
// Handle parapoly stuff here?
|
||||||
return w;
|
return w;
|
||||||
|
|||||||
Reference in New Issue
Block a user