diff --git a/core/runtime/core.odin b/core/runtime/core.odin index dfbe0d053..2989c4700 100644 --- a/core/runtime/core.odin +++ b/core/runtime/core.odin @@ -149,9 +149,16 @@ Type_Info_Relative_Slice :: struct { base_integer: ^Type_Info, }; +Type_Info_Flag :: enum u8 { + Comparable = 0, + Simple_Compare = 1, +}; +Type_Info_Flags :: distinct bit_set[Type_Info_Flag; u32]; + Type_Info :: struct { size: int, align: int, + flags: Type_Info_Flags, id: typeid, variant: union { diff --git a/src/checker.cpp b/src/checker.cpp index 1a5a75152..bba790cb2 100644 --- a/src/checker.cpp +++ b/src/checker.cpp @@ -899,6 +899,7 @@ bool init_checker(Checker *c, Parser *parser) { gbAllocator a = heap_allocator(); init_checker_info(&c->info); + c->info.checker = c; array_init(&c->procs_to_check, a); array_init(&c->procs_with_deferred_to_check, a); @@ -2179,9 +2180,9 @@ void init_core_type_info(Checker *c) { t_type_info_enum_value = type_info_enum_value->type; t_type_info_enum_value_ptr = alloc_type_pointer(t_type_info_enum_value); - GB_ASSERT(tis->fields.count == 4); + GB_ASSERT(tis->fields.count == 5); - Entity *type_info_variant = tis->fields[3]; + Entity *type_info_variant = tis->fields[4]; Type *tiv_type = type_info_variant->type; GB_ASSERT(is_type_union(tiv_type)); diff --git a/src/checker.hpp b/src/checker.hpp index 72c4b148c..168c00d33 100644 --- a/src/checker.hpp +++ b/src/checker.hpp @@ -252,8 +252,12 @@ struct AtomOpMapEntry { }; +struct CheckerContext; + // CheckerInfo stores all the symbol information for a type-checked program struct CheckerInfo { + Checker *checker; + Map untyped; // Key: Ast * | Expression -> ExprInfo // NOTE(bill): This needs to be a map and not on the Ast // as it needs to be iterated across diff --git a/src/ir.cpp b/src/ir.cpp index 2d244f62c..ce5dea86d 100644 --- a/src/ir.cpp +++ b/src/ir.cpp @@ -11974,6 +11974,8 @@ void ir_setup_type_info_data(irProcedure *proc) { // NOTE(bill): Setup type_info // Useful types Type *t_i64_slice_ptr = alloc_type_pointer(alloc_type_slice(t_i64)); Type *t_string_slice_ptr = alloc_type_pointer(alloc_type_slice(t_string)); + Entity *type_info_flags_entity = find_core_entity(info->checker, str_lit("Type_Info_Flags")); + Type *t_type_info_flags = type_info_flags_entity->type; i32 type_info_member_types_index = 0; i32 type_info_member_names_index = 0; @@ -11993,11 +11995,14 @@ void ir_setup_type_info_data(irProcedure *proc) { // NOTE(bill): Setup type_info irValue *tag = nullptr; irValue *ti_ptr = ir_emit_array_epi(proc, ir_global_type_info_data, cast(i32)entry_index); - irValue *variant_ptr = ir_emit_struct_ep(proc, ti_ptr, 3); + irValue *variant_ptr = ir_emit_struct_ep(proc, ti_ptr, 4); + + irValue *type_info_flags = ir_value_constant(t_type_info_flags, exact_value_i64(type_info_flags_of_type(t))); ir_emit_store(proc, ir_emit_struct_ep(proc, ti_ptr, 0), ir_const_int(type_size_of(t))); ir_emit_store(proc, ir_emit_struct_ep(proc, ti_ptr, 1), ir_const_int(type_align_of(t))); - ir_emit_store(proc, ir_emit_struct_ep(proc, ti_ptr, 2), ir_typeid(proc->module, t)); + ir_emit_store(proc, ir_emit_struct_ep(proc, ti_ptr, 2), type_info_flags); + ir_emit_store(proc, ir_emit_struct_ep(proc, ti_ptr, 3), ir_typeid(proc->module, t)); switch (t->kind) { diff --git a/src/llvm_backend.cpp b/src/llvm_backend.cpp index 665f9570a..a2727b012 100644 --- a/src/llvm_backend.cpp +++ b/src/llvm_backend.cpp @@ -11732,6 +11732,9 @@ void lb_setup_type_info_data(lbProcedure *p) { // NOTE(bill): Setup type_info da // Useful types Type *t_i64_slice_ptr = alloc_type_pointer(alloc_type_slice(t_i64)); Type *t_string_slice_ptr = alloc_type_pointer(alloc_type_slice(t_string)); + Entity *type_info_flags_entity = find_core_entity(info->checker, str_lit("Type_Info_Flags")); + Type *t_type_info_flags = type_info_flags_entity->type; + i32 type_info_member_types_index = 0; i32 type_info_member_names_index = 0; @@ -11751,11 +11754,14 @@ void lb_setup_type_info_data(lbProcedure *p) { // NOTE(bill): Setup type_info da lbValue tag = {}; lbValue ti_ptr = lb_emit_array_epi(p, lb_global_type_info_data.addr, cast(i32)entry_index); - lbValue variant_ptr = lb_emit_struct_ep(p, ti_ptr, 3); + lbValue variant_ptr = lb_emit_struct_ep(p, ti_ptr, 4); + + lbValue type_info_flags = lb_const_int(p->module, t_type_info_flags, type_info_flags_of_type(t)); lb_emit_store(p, lb_emit_struct_ep(p, ti_ptr, 0), lb_const_int(m, t_int, type_size_of(t))); lb_emit_store(p, lb_emit_struct_ep(p, ti_ptr, 1), lb_const_int(m, t_int, type_align_of(t))); - lb_emit_store(p, lb_emit_struct_ep(p, ti_ptr, 2), lb_typeid(m, t)); + lb_emit_store(p, lb_emit_struct_ep(p, ti_ptr, 2), type_info_flags); + lb_emit_store(p, lb_emit_struct_ep(p, ti_ptr, 3), lb_typeid(m, t)); switch (t->kind) { diff --git a/src/types.cpp b/src/types.cpp index 80812e94b..09888f878 100644 --- a/src/types.cpp +++ b/src/types.cpp @@ -373,7 +373,28 @@ enum Typeid_Kind : u8 { Typeid_Relative_Slice, }; +// IMPORTANT NOTE(bill): This must match the same as the in core.odin +enum TypeInfoFlag : u32 { + TypeInfoFlag_Comparable = 1<<0, + TypeInfoFlag_Simple_Compare = 1<<1, +}; +bool is_type_comparable(Type *t); +bool is_type_simple_compare(Type *t); + +u32 type_info_flags_of_type(Type *type) { + if (type == nullptr) { + return 0; + } + u32 flags = 0; + if (is_type_comparable(type)) { + flags |= TypeInfoFlag_Comparable; + } + if (is_type_simple_compare(type)) { + flags |= TypeInfoFlag_Comparable; + } + return flags; +} // TODO(bill): Should I add extra information here specifying the kind of selection? @@ -1348,6 +1369,8 @@ bool is_type_simple_compare(Type *t) { return false; } + + Type *base_complex_elem_type(Type *t) { t = core_type(t); if (t->kind == Type_Basic) {