mirror of
https://github.com/Ed94/Odin.git
synced 2026-07-20 16:36:46 +00:00
Make any use typeid rather than ^Type_Info
This commit is contained in:
+2
-2
@@ -3428,7 +3428,7 @@ bool check_builtin_procedure(Checker *c, Operand *operand, AstNode *call, i32 id
|
||||
}
|
||||
|
||||
case BuiltinProc_typeid_of: {
|
||||
// proc typeid_of(Type) -> ^Type_Info
|
||||
// proc typeid_of(Type) -> typeid
|
||||
if (c->context.scope->is_global) {
|
||||
compiler_error("'typeid_of' Cannot be declared within a #shared_global_scope due to how the internals of the compiler works");
|
||||
}
|
||||
@@ -5701,7 +5701,7 @@ ExprKind check_expr_base_internal(Checker *c, Operand *o, AstNode *node, Type *t
|
||||
break; // NOTE(bill): No need to init
|
||||
}
|
||||
{ // Checker values
|
||||
Type *field_types[2] = {t_rawptr, t_type_info_ptr};
|
||||
Type *field_types[2] = {t_rawptr, t_typeid};
|
||||
isize field_count = 2;
|
||||
if (cl->elems[0]->kind == AstNode_FieldValue) {
|
||||
bool fields_visited[2] = {};
|
||||
|
||||
+43
-35
@@ -784,6 +784,7 @@ irValue *ir_emit_load (irProcedure *p, irValue *address);
|
||||
void ir_emit_jump (irProcedure *proc, irBlock *block);
|
||||
irValue *ir_emit_conv (irProcedure *proc, irValue *value, Type *t);
|
||||
irValue *ir_type_info (irProcedure *proc, Type *type);
|
||||
irValue *ir_typeid (irProcedure *proc, Type *type);
|
||||
irValue *ir_build_expr (irProcedure *proc, AstNode *expr);
|
||||
void ir_build_stmt (irProcedure *proc, AstNode *node);
|
||||
irValue *ir_build_cond (irProcedure *proc, AstNode *cond, irBlock *true_block, irBlock *false_block);
|
||||
@@ -2456,6 +2457,9 @@ irValue *ir_emit_comp_against_nil(irProcedure *proc, TokenKind op_kind, irValue
|
||||
} else if (is_type_union(t)) {
|
||||
irValue *tag = ir_emit_union_tag_value(proc, x);
|
||||
return ir_emit_comp(proc, op_kind, tag, v_zero);
|
||||
} else if (is_type_typeid(t)) {
|
||||
irValue *invalid_typeid = ir_value_constant(proc->module->allocator, t_typeid, exact_value_i64(0));
|
||||
return ir_emit_comp(proc, op_kind, x, invalid_typeid);
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
@@ -2619,8 +2623,8 @@ irValue *ir_emit_struct_ep(irProcedure *proc, irValue *s, i32 index) {
|
||||
}
|
||||
} else if (is_type_any(t)) {
|
||||
switch (index) {
|
||||
case 0: result_type = alloc_type_pointer(t_rawptr); break;
|
||||
case 1: result_type = alloc_type_pointer(t_type_info_ptr); break;
|
||||
case 0: result_type = alloc_type_pointer(t_rawptr); break;
|
||||
case 1: result_type = alloc_type_pointer(t_typeid); break;
|
||||
}
|
||||
} else if (is_type_dynamic_array(t)) {
|
||||
switch (index) {
|
||||
@@ -2668,8 +2672,8 @@ irValue *ir_emit_struct_ev(irProcedure *proc, irValue *s, i32 index) {
|
||||
break;
|
||||
case Basic_any:
|
||||
switch (index) {
|
||||
case 0: result_type = t_rawptr; break;
|
||||
case 1: result_type = t_type_info_ptr; break;
|
||||
case 0: result_type = t_rawptr; break;
|
||||
case 1: result_type = t_typeid; break;
|
||||
}
|
||||
break;
|
||||
case Basic_complex64: case Basic_complex128:
|
||||
@@ -3350,10 +3354,10 @@ irValue *ir_emit_conv(irProcedure *proc, irValue *value, Type *t) {
|
||||
data = ir_emit_conv(proc, data, t_rawptr);
|
||||
|
||||
|
||||
irValue *ti = ir_type_info(proc, st);
|
||||
irValue *id = ir_typeid(proc, st);
|
||||
|
||||
ir_emit_store(proc, ir_emit_struct_ep(proc, result, 0), data);
|
||||
ir_emit_store(proc, ir_emit_struct_ep(proc, result, 1), ti);
|
||||
ir_emit_store(proc, ir_emit_struct_ep(proc, result, 1), id);
|
||||
|
||||
return ir_emit_load(proc, result);
|
||||
}
|
||||
@@ -3501,8 +3505,8 @@ irValue *ir_emit_union_cast(irProcedure *proc, irValue *value, Type *type, Token
|
||||
args[2] = ir_const_int(a, pos.line);
|
||||
args[3] = ir_const_int(a, pos.column);
|
||||
|
||||
args[4] = ir_type_info(proc, src_type);
|
||||
args[5] = ir_type_info(proc, dst_type);
|
||||
args[4] = ir_typeid(proc, src_type);
|
||||
args[5] = ir_typeid(proc, dst_type);
|
||||
ir_emit_global_call(proc, "__type_assertion_check", args);
|
||||
}
|
||||
|
||||
@@ -3529,13 +3533,13 @@ irAddr ir_emit_any_cast_addr(irProcedure *proc, irValue *value, Type *type, Toke
|
||||
|
||||
irValue *v = ir_add_local_generated(proc, tuple);
|
||||
|
||||
irValue *ti_ptr = ir_type_info(proc, dst_type);
|
||||
irValue *any_ti = ir_emit_struct_ev(proc, value, 1);
|
||||
irValue *dst_typeid = ir_typeid(proc, dst_type);
|
||||
irValue *any_typeid = ir_emit_struct_ev(proc, value, 1);
|
||||
|
||||
|
||||
irBlock *ok_block = ir_new_block(proc, nullptr, "any_cast.ok");
|
||||
irBlock *end_block = ir_new_block(proc, nullptr, "any_cast.end");
|
||||
irValue *cond = ir_emit_comp(proc, Token_CmpEq, any_ti, ti_ptr);
|
||||
irValue *cond = ir_emit_comp(proc, Token_CmpEq, any_typeid, dst_typeid);
|
||||
ir_emit_if(proc, cond, ok_block, end_block);
|
||||
ir_start_block(proc, ok_block);
|
||||
|
||||
@@ -3561,8 +3565,8 @@ irAddr ir_emit_any_cast_addr(irProcedure *proc, irValue *value, Type *type, Toke
|
||||
args[2] = ir_const_int(a, pos.line);
|
||||
args[3] = ir_const_int(a, pos.column);
|
||||
|
||||
args[4] = any_ti;
|
||||
args[5] = ti_ptr;
|
||||
args[4] = any_typeid;
|
||||
args[5] = dst_typeid;
|
||||
ir_emit_global_call(proc, "__type_assertion_check", args);
|
||||
|
||||
return ir_addr(ir_emit_struct_ep(proc, v, 0));
|
||||
@@ -3617,17 +3621,23 @@ isize ir_type_info_index(CheckerInfo *info, Type *type) {
|
||||
|
||||
irValue *ir_type_info(irProcedure *proc, Type *type) {
|
||||
CheckerInfo *info = proc->module->info;
|
||||
|
||||
type = default_type(type);
|
||||
|
||||
i32 entry_index = cast(i32)ir_type_info_index(info, type);
|
||||
GB_ASSERT(entry_index >= 0);
|
||||
|
||||
// gb_printf_err("%d %s\n", entry_index, type_to_string(type));
|
||||
|
||||
return ir_emit_array_ep(proc, ir_global_type_info_data, ir_const_i32(proc->module->allocator, entry_index));
|
||||
i32 id = cast(i32)ir_type_info_index(info, type);
|
||||
GB_ASSERT(id >= 0);
|
||||
return ir_emit_array_ep(proc, ir_global_type_info_data, ir_const_i32(proc->module->allocator, id));
|
||||
}
|
||||
|
||||
irValue *ir_typeid(irProcedure *proc, Type *type) {
|
||||
CheckerInfo *info = proc->module->info;
|
||||
type = default_type(type);
|
||||
|
||||
isize id = ir_type_info_index(info, type);
|
||||
GB_ASSERT(id >= 0);
|
||||
return ir_value_constant(proc->module->allocator, t_typeid, exact_value_i64(id));
|
||||
}
|
||||
|
||||
|
||||
irValue *ir_emit_logical_binary_expr(irProcedure *proc, TokenKind op, AstNode *left, AstNode *right, Type *type) {
|
||||
irBlock *rhs = ir_new_block(proc, nullptr, "logical.cmp.rhs");
|
||||
irBlock *done = ir_new_block(proc, nullptr, "logical.cmp.done");
|
||||
@@ -4205,9 +4215,7 @@ irValue *ir_build_builtin_proc(irProcedure *proc, AstNode *expr, TypeAndValue tv
|
||||
|
||||
case BuiltinProc_typeid_of: {
|
||||
Type *t = default_type(type_of_expr(proc->module->info, ce->args[0]));
|
||||
i32 entry_index = cast(i32)ir_type_info_index(proc->module->info, t);
|
||||
GB_ASSERT(entry_index >= 0);
|
||||
return ir_value_constant(proc->module->allocator, t_typeid, exact_value_i64(entry_index));
|
||||
return ir_typeid(proc, t);
|
||||
}
|
||||
|
||||
case BuiltinProc_len: {
|
||||
@@ -5032,8 +5040,8 @@ irValue *ir_build_expr_internal(irProcedure *proc, AstNode *expr) {
|
||||
args[2] = ir_const_int(a, pos.line);
|
||||
args[3] = ir_const_int(a, pos.column);
|
||||
|
||||
args[4] = ir_type_info(proc, src_type);
|
||||
args[5] = ir_type_info(proc, dst_type);
|
||||
args[4] = ir_typeid(proc, src_type);
|
||||
args[5] = ir_typeid(proc, dst_type);
|
||||
ir_emit_global_call(proc, "__type_assertion_check", args);
|
||||
|
||||
irValue *data_ptr = v;
|
||||
@@ -5045,11 +5053,11 @@ irValue *ir_build_expr_internal(irProcedure *proc, AstNode *expr) {
|
||||
}
|
||||
|
||||
irValue *data_ptr = ir_emit_struct_ev(proc, v, 0);
|
||||
irValue *any_ti = ir_emit_struct_ev(proc, v, 1);
|
||||
irValue *ti_ptr = ir_type_info(proc, type);
|
||||
irValue *any_id = ir_emit_struct_ev(proc, v, 1);
|
||||
irValue *id = ir_typeid(proc, type);
|
||||
|
||||
|
||||
irValue *ok = ir_emit_comp(proc, Token_CmpEq, any_ti, ti_ptr);
|
||||
irValue *ok = ir_emit_comp(proc, Token_CmpEq, any_id, id);
|
||||
auto args = array_make<irValue *>(proc->module->allocator, 6);
|
||||
args[0] = ok;
|
||||
|
||||
@@ -5057,8 +5065,8 @@ irValue *ir_build_expr_internal(irProcedure *proc, AstNode *expr) {
|
||||
args[2] = ir_const_int(a, pos.line);
|
||||
args[3] = ir_const_int(a, pos.column);
|
||||
|
||||
args[4] = any_ti;
|
||||
args[5] = ti_ptr;
|
||||
args[4] = any_id;
|
||||
args[5] = id;
|
||||
ir_emit_global_call(proc, "__type_assertion_check", args);
|
||||
|
||||
return ir_emit_conv(proc, data_ptr, tv.type);
|
||||
@@ -6006,11 +6014,11 @@ irAddr ir_build_addr(irProcedure *proc, AstNode *expr) {
|
||||
ir_emit_store(proc, v, ir_add_module_constant(proc->module, type, exact_value_compound(expr)));
|
||||
String field_names[2] = {
|
||||
str_lit("data"),
|
||||
str_lit("type_info"),
|
||||
str_lit("typeid"),
|
||||
};
|
||||
Type *field_types[2] = {
|
||||
t_rawptr,
|
||||
t_type_info_ptr,
|
||||
t_typeid,
|
||||
};
|
||||
|
||||
for_array(field_index, cl->elems) {
|
||||
@@ -7237,9 +7245,9 @@ void ir_build_stmt_internal(irProcedure *proc, AstNode *node) {
|
||||
irValue *variant_tag = ir_const_union_tag(proc->module->allocator, ut, case_type);
|
||||
cond = ir_emit_comp(proc, Token_CmpEq, tag_index, variant_tag);
|
||||
} else if (switch_kind == TypeSwitch_Any) {
|
||||
irValue *any_ti = ir_emit_load(proc, ir_emit_struct_ep(proc, parent_ptr, 1));
|
||||
irValue *case_ti = ir_type_info(proc, case_type);
|
||||
cond = ir_emit_comp(proc, Token_CmpEq, any_ti, case_ti);
|
||||
irValue *any_typeid = ir_emit_load(proc, ir_emit_struct_ep(proc, parent_ptr, 1));
|
||||
irValue *case_typeid = ir_typeid(proc, case_type);
|
||||
cond = ir_emit_comp(proc, Token_CmpEq, any_typeid, case_typeid);
|
||||
}
|
||||
GB_ASSERT(cond != nullptr);
|
||||
|
||||
|
||||
+8
-11
@@ -319,6 +319,8 @@ void ir_print_type(irFileBuffer *f, irModule *m, Type *t, bool in_struct) {
|
||||
|
||||
case Basic_rune: ir_write_str_lit(f, "i32"); return;
|
||||
|
||||
case Basic_typeid:
|
||||
/* fallthrough */
|
||||
case Basic_int:
|
||||
case Basic_uint:
|
||||
case Basic_uintptr:
|
||||
@@ -341,8 +343,6 @@ void ir_print_type(irFileBuffer *f, irModule *m, Type *t, bool in_struct) {
|
||||
case Basic_rawptr: ir_write_str_lit(f, "%..rawptr"); return;
|
||||
case Basic_string: ir_write_str_lit(f, "%..string"); return;
|
||||
case Basic_cstring: ir_write_str_lit(f, "i8*"); return;
|
||||
|
||||
case Basic_typeid: ir_write_str_lit(f, "%..typeid"); return;
|
||||
}
|
||||
break;
|
||||
|
||||
@@ -538,7 +538,6 @@ void ir_print_exact_value(irFileBuffer *f, irModule *m, ExactValue value, Type *
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
switch (value.kind) {
|
||||
case ExactValue_Bool:
|
||||
if (value.value_bool) {
|
||||
@@ -653,7 +652,11 @@ void ir_print_exact_value(irFileBuffer *f, irModule *m, ExactValue value, Type *
|
||||
}
|
||||
case ExactValue_Pointer:
|
||||
if (value.value_pointer == 0) {
|
||||
ir_write_str_lit(f, "null");
|
||||
if (is_type_typeid(type)) {
|
||||
ir_write_str_lit(f, "0");
|
||||
} else {
|
||||
ir_write_str_lit(f, "null");
|
||||
}
|
||||
} else {
|
||||
ir_write_str_lit(f, "inttoptr (");
|
||||
ir_print_type(f, m, t_int);
|
||||
@@ -1748,15 +1751,9 @@ void print_llvm_ir(irGen *ir) {
|
||||
ir_write_str_lit(f, " = type {");
|
||||
ir_print_type(f, m, t_rawptr);
|
||||
ir_write_str_lit(f, ", ");
|
||||
ir_print_type(f, m, t_type_info_ptr);
|
||||
ir_print_type(f, m, t_typeid);
|
||||
ir_write_str_lit(f, "} ; Basic_any\n");
|
||||
|
||||
ir_print_encoded_local(f, str_lit("..typeid"));
|
||||
ir_write_str_lit(f, " = type ");
|
||||
ir_print_type(f, m, t_uintptr);
|
||||
ir_write_str_lit(f, "; Basic_typeid\n");
|
||||
|
||||
|
||||
ir_write_str_lit(f, "declare void @llvm.dbg.declare(metadata, metadata, metadata) nounwind readnone \n");
|
||||
ir_write_byte(f, '\n');
|
||||
|
||||
|
||||
+11
-12
@@ -911,6 +911,10 @@ bool is_type_any(Type *t) {
|
||||
t = base_type(t);
|
||||
return (t->kind == Type_Basic && t->Basic.kind == Basic_any);
|
||||
}
|
||||
bool is_type_typeid(Type *t) {
|
||||
t = base_type(t);
|
||||
return (t->kind == Type_Basic && t->Basic.kind == Basic_typeid);
|
||||
}
|
||||
bool is_type_untyped_nil(Type *t) {
|
||||
t = base_type(t);
|
||||
return (t->kind == Type_Basic && t->Basic.kind == Basic_UntypedNil);
|
||||
@@ -1095,6 +1099,8 @@ bool type_has_nil(Type *t) {
|
||||
return true;
|
||||
case Basic_cstring:
|
||||
return true;
|
||||
case Basic_typeid:
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
} break;
|
||||
@@ -1590,9 +1596,6 @@ Selection lookup_field_from_index(Type *type, i64 index) {
|
||||
}
|
||||
|
||||
|
||||
gb_global Entity *entity__any_data = nullptr;
|
||||
gb_global Entity *entity__any_type_info = nullptr;
|
||||
|
||||
Entity *current_scope_lookup_entity(Scope *s, String name);
|
||||
|
||||
Selection lookup_field_with_selection(Type *type_, String field_name, bool is_type, Selection sel) {
|
||||
@@ -1616,21 +1619,17 @@ Selection lookup_field_with_selection(Type *type_, String field_name, bool is_ty
|
||||
// IMPORTANT TODO(bill): Should these members be available to should I only allow them with
|
||||
// `Raw_Any` type?
|
||||
String data_str = str_lit("data");
|
||||
String type_info_str = str_lit("type_info");
|
||||
if (entity__any_data == nullptr) {
|
||||
entity__any_data = alloc_entity_field(nullptr, make_token_ident(data_str), t_rawptr, false, 0);
|
||||
}
|
||||
if (entity__any_type_info == nullptr) {
|
||||
entity__any_type_info = alloc_entity_field(nullptr, make_token_ident(type_info_str), t_type_info_ptr, false, 1);
|
||||
}
|
||||
String typeid_str = str_lit("typeid");
|
||||
gb_local_persist Entity *entity__any_data = alloc_entity_field(nullptr, make_token_ident(data_str), t_rawptr, false, 0);
|
||||
gb_local_persist Entity *entity__any_typeid = alloc_entity_field(nullptr, make_token_ident(typeid_str), t_typeid, false, 1);
|
||||
|
||||
if (field_name == data_str) {
|
||||
selection_add_index(&sel, 0);
|
||||
sel.entity = entity__any_data;;
|
||||
return sel;
|
||||
} else if (field_name == type_info_str) {
|
||||
} else if (field_name == typeid_str) {
|
||||
selection_add_index(&sel, 1);
|
||||
sel.entity = entity__any_type_info;
|
||||
sel.entity = entity__any_typeid;
|
||||
return sel;
|
||||
}
|
||||
#endif
|
||||
|
||||
Reference in New Issue
Block a user