Browse Source

Add `flags: Type_Info_Flags,` to `runtime.Type_Info`

gingerBill 4 years ago
parent
commit
0b30c3dc5a
6 changed files with 52 additions and 6 deletions
  1. 7 0
      core/runtime/core.odin
  2. 3 2
      src/checker.cpp
  3. 4 0
      src/checker.hpp
  4. 7 2
      src/ir.cpp
  5. 8 2
      src/llvm_backend.cpp
  6. 23 0
      src/types.cpp

+ 7 - 0
core/runtime/core.odin

@@ -149,9 +149,16 @@ Type_Info_Relative_Slice :: struct {
 	base_integer: ^Type_Info,
 	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 {
 Type_Info :: struct {
 	size:  int,
 	size:  int,
 	align: int,
 	align: int,
+	flags: Type_Info_Flags,
 	id:    typeid,
 	id:    typeid,
 
 
 	variant: union {
 	variant: union {

+ 3 - 2
src/checker.cpp

@@ -899,6 +899,7 @@ bool init_checker(Checker *c, Parser *parser) {
 	gbAllocator a = heap_allocator();
 	gbAllocator a = heap_allocator();
 
 
 	init_checker_info(&c->info);
 	init_checker_info(&c->info);
+	c->info.checker = c;
 
 
 	array_init(&c->procs_to_check, a);
 	array_init(&c->procs_to_check, a);
 	array_init(&c->procs_with_deferred_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 = type_info_enum_value->type;
 	t_type_info_enum_value_ptr = alloc_type_pointer(t_type_info_enum_value);
 	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;
 	Type *tiv_type = type_info_variant->type;
 	GB_ASSERT(is_type_union(tiv_type));
 	GB_ASSERT(is_type_union(tiv_type));
 
 

+ 4 - 0
src/checker.hpp

@@ -252,8 +252,12 @@ struct AtomOpMapEntry {
 };
 };
 
 
 
 
+struct CheckerContext;
+
 // CheckerInfo stores all the symbol information for a type-checked program
 // CheckerInfo stores all the symbol information for a type-checked program
 struct CheckerInfo {
 struct CheckerInfo {
+	Checker *checker;
+
 	Map<ExprInfo>         untyped; // Key: Ast * | Expression -> ExprInfo
 	Map<ExprInfo>         untyped; // Key: Ast * | Expression -> ExprInfo
 	                               // NOTE(bill): This needs to be a map and not on the Ast
 	                               // NOTE(bill): This needs to be a map and not on the Ast
 	                               // as it needs to be iterated across
 	                               // as it needs to be iterated across

+ 7 - 2
src/ir.cpp

@@ -11974,6 +11974,8 @@ void ir_setup_type_info_data(irProcedure *proc) { // NOTE(bill): Setup type_info
 	// Useful types
 	// Useful types
 	Type *t_i64_slice_ptr    = alloc_type_pointer(alloc_type_slice(t_i64));
 	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));
 	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_types_index = 0;
 	i32 type_info_member_names_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 *tag = nullptr;
 		irValue *ti_ptr = ir_emit_array_epi(proc, ir_global_type_info_data, cast(i32)entry_index);
 		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, 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, 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) {
 		switch (t->kind) {

+ 8 - 2
src/llvm_backend.cpp

@@ -11732,6 +11732,9 @@ void lb_setup_type_info_data(lbProcedure *p) { // NOTE(bill): Setup type_info da
 	// Useful types
 	// Useful types
 	Type *t_i64_slice_ptr    = alloc_type_pointer(alloc_type_slice(t_i64));
 	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));
 	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_types_index = 0;
 	i32 type_info_member_names_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 tag = {};
 		lbValue ti_ptr = lb_emit_array_epi(p, lb_global_type_info_data.addr, cast(i32)entry_index);
 		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, 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, 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) {
 		switch (t->kind) {

+ 23 - 0
src/types.cpp

@@ -373,7 +373,28 @@ enum Typeid_Kind : u8 {
 	Typeid_Relative_Slice,
 	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?
 // 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;
 	return false;
 }
 }
 
 
+
+
 Type *base_complex_elem_type(Type *t) {
 Type *base_complex_elem_type(Type *t) {
 	t = core_type(t);
 	t = core_type(t);
 	if (t->kind == Type_Basic) {
 	if (t->kind == Type_Basic) {