diff --git a/src/tilde.cpp b/src/tilde.cpp index 89075da75..7574ea6b9 100644 --- a/src/tilde.cpp +++ b/src/tilde.cpp @@ -243,6 +243,24 @@ gb_internal isize cg_type_info_index(CheckerInfo *info, Type *type, bool err_on_ return -1; } +gb_internal cgValue cg_global_type_info_data_ptr(cgProcedure *p) { + cgValue v = cg_find_value_from_entity(p->module, cg_global_type_info_data_entity); + return cg_flatten_value(p, v); +} + + +gb_internal cgValue cg_type_info(cgProcedure *p, Type *type) { + GB_ASSERT(!build_context.no_rtti); + + type = default_type(type); + + isize index = cg_type_info_index(p->module->info, type); + GB_ASSERT(index >= 0); + + cgValue data = cg_global_type_info_data_ptr(p); + return cg_emit_array_epi(p, data, index); +} + gb_internal u64 cg_typeid_as_u64(cgModule *m, Type *type) { GB_ASSERT(!build_context.no_rtti); diff --git a/src/tilde.hpp b/src/tilde.hpp index a548252d9..2d7b2e1c3 100644 --- a/src/tilde.hpp +++ b/src/tilde.hpp @@ -301,7 +301,7 @@ gb_internal void cg_build_return_stmt(cgProcedure *p, Slice const &return gb_internal void cg_build_return_stmt_internal(cgProcedure *p, Slice const &results); gb_internal void cg_build_range_stmt(cgProcedure *p, Ast *node); - +gb_internal cgValue cg_find_value_from_entity(cgModule *m, Entity *e); gb_internal cgValue cg_find_procedure_value_from_entity(cgModule *m, Entity *e); gb_internal TB_DebugType *cg_debug_type(cgModule *m, Type *type); @@ -322,6 +322,9 @@ gb_internal cgValue cg_emit_comp_against_nil(cgProcedure *p, TokenKind op_kind, gb_internal cgValue cg_emit_comp(cgProcedure *p, TokenKind op_kind, cgValue left, cgValue right); gb_internal cgValue cg_emit_arith(cgProcedure *p, TokenKind op, cgValue lhs, cgValue rhs, Type *type); +gb_internal cgValue cg_emit_call(cgProcedure * p, cgValue value, Slice const &args); +gb_internal cgValue cg_emit_runtime_call(cgProcedure *p, char const *name, Slice const &args); + gb_internal bool cg_emit_goto(cgProcedure *p, TB_Node *control_region); gb_internal TB_Node *cg_control_region(cgProcedure *p, char const *name); diff --git a/src/tilde_builtin.cpp b/src/tilde_builtin.cpp index b40eacc7f..e30ff1cb0 100644 --- a/src/tilde_builtin.cpp +++ b/src/tilde_builtin.cpp @@ -236,7 +236,6 @@ gb_internal cgValue cg_builtin_mem_copy_non_overlapping(cgProcedure *p, cgValue } - gb_internal cgValue cg_build_builtin(cgProcedure *p, BuiltinProcId id, Ast *expr) { ast_node(ce, CallExpr, expr); @@ -419,6 +418,21 @@ gb_internal cgValue cg_build_builtin(cgProcedure *p, BuiltinProcId id, Ast *expr return cg_emit_arith(p, Token_Quo, diff, cg_const_int(p, t_int, type_size_of(elem)), t_int); } + case BuiltinProc_type_info_of: + { + Ast *arg = ce->args[0]; + TypeAndValue tav = type_and_value_of_expr(arg); + if (tav.mode == Addressing_Type) { + Type *t = default_type(type_of_expr(arg)); + return cg_type_info(p, t); + } + GB_ASSERT(is_type_typeid(tav.type)); + + auto args = slice_make(permanent_allocator(), 1); + args[0] = cg_build_expr(p, arg); + return cg_emit_runtime_call(p, "__type_info_of", args); + } + } diff --git a/src/tilde_expr.cpp b/src/tilde_expr.cpp index 993270c14..8737e75cd 100644 --- a/src/tilde_expr.cpp +++ b/src/tilde_expr.cpp @@ -191,7 +191,46 @@ gb_internal cgValue cg_emit_transmute(cgProcedure *p, cgValue value, Type *type) GB_ASSERT_MSG(!TB_IS_VOID_TYPE(dt), "%d %s -> %s", dt.type, type_to_string(value.type), type_to_string(type)); value.type = type; if (value.node->dt.raw != dt.raw) { - value.node = tb_inst_bitcast(p->func, value.node, dt); + switch (value.node->dt.type) { + case TB_INT: + switch (value.node->dt.type) { + case TB_INT: + break; + case TB_FLOAT: + value.node = tb_inst_bitcast(p->func, value.node, dt); + break; + case TB_PTR: + value.node = tb_inst_int2ptr(p->func, value.node); + break; + } + break; + case TB_FLOAT: + switch (value.node->dt.type) { + case TB_INT: + value.node = tb_inst_bitcast(p->func, value.node, dt); + break; + case TB_FLOAT: + break; + case TB_PTR: + value.node = tb_inst_bitcast(p->func, value.node, TB_TYPE_INTPTR); + value.node = tb_inst_int2ptr(p->func, value.node); + break; + } + break; + case TB_PTR: + switch (value.node->dt.type) { + case TB_INT: + value.node = tb_inst_ptr2int(p->func, value.node, dt); + break; + case TB_FLOAT: + value.node = tb_inst_ptr2int(p->func, value.node, TB_TYPE_INTPTR); + value.node = tb_inst_bitcast(p->func, value.node, dt); + break; + case TB_PTR: + break; + } + break; + } } return value; case cgValue_Addr: diff --git a/src/tilde_proc.cpp b/src/tilde_proc.cpp index ed28f5016..acc31ce67 100644 --- a/src/tilde_proc.cpp +++ b/src/tilde_proc.cpp @@ -677,6 +677,12 @@ gb_internal cgValue cg_emit_call(cgProcedure * p, cgValue value, Slice return cg_value_multi(multi, pt->results); } +gb_internal cgValue cg_emit_runtime_call(cgProcedure *p, char const *name, Slice const &args) { + AstPackage *pkg = p->module->info->runtime_package; + Entity *e = scope_lookup_current(pkg->scope, make_string_c(name)); + cgValue value = cg_find_procedure_value_from_entity(p->module, e); + return cg_emit_call(p, value, args); +} gb_internal cgValue cg_handle_param_value(cgProcedure *p, Type *parameter_type, ParameterValue const ¶m_value, TokenPos const &pos) { switch (param_value.kind) { diff --git a/src/tilde_stmt.cpp b/src/tilde_stmt.cpp index f89dbdf03..8b577dfeb 100644 --- a/src/tilde_stmt.cpp +++ b/src/tilde_stmt.cpp @@ -1630,8 +1630,7 @@ gb_internal void cg_build_range_stmt(cgProcedure *p, Ast *node) { array = cg_emit_load(p, array); } count_ptr = cg_emit_struct_ep(p, array, 1); - GB_PANIC("TODO(bill): cg_build_range_stmt_indexed"); - // cg_build_range_stmt_indexed(p, array, val0_type, count_ptr, &val, &key, &loop, &done, rs->reverse); + cg_build_range_stmt_indexed(p, array, val0_type, count_ptr, &val, &key, &loop, &done, rs->reverse); break; } case Type_Slice: {