aboutsummaryrefslogtreecommitdiff
path: root/src/ir.cpp
diff options
context:
space:
mode:
authorGinger Bill <bill@gingerbill.org>2017-06-29 15:13:41 +0100
committerGinger Bill <bill@gingerbill.org>2017-06-29 15:13:41 +0100
commit001baf4419da9c43d4ef68d7ec1eac638d6fb742 (patch)
tree5d685a869cee84487a860e616034ed1e2428f50d /src/ir.cpp
parentd167290b280c2dfcb764ff1e8f48df975444962d (diff)
Add `Type` -- Runtime type for comparing types (similar to TypeInfo but simpler)
Diffstat (limited to 'src/ir.cpp')
-rw-r--r--src/ir.cpp54
1 files changed, 48 insertions, 6 deletions
diff --git a/src/ir.cpp b/src/ir.cpp
index 4267b6434..64dc71684 100644
--- a/src/ir.cpp
+++ b/src/ir.cpp
@@ -749,6 +749,7 @@ void ir_build_defer_stmt (irProcedure *proc, irDefer d);
irAddr ir_build_addr (irProcedure *proc, AstNode *expr);
void ir_build_proc (irValue *value, irProcedure *parent);
void ir_gen_global_type_name(irModule *m, Entity *e, String name);
+irValue *ir_get_type_info_ptr (irProcedure *proc, Type *type);
@@ -2771,6 +2772,23 @@ String ir_lookup_subtype_polymorphic_field(CheckerInfo *info, Type *dst, Type *s
}
+irValue *ir_emit_ptr_to_int(irProcedure *proc, irValue *value, Type *t, bool allow_type_type = false) {
+ Type *vt = core_type(ir_type(value));
+ GB_ASSERT(is_type_pointer(vt));
+ if (allow_type_type) {
+ GB_ASSERT(is_type_int_or_uint(core_type(t)) || is_type_type(t));
+ } else {
+ GB_ASSERT(is_type_int_or_uint(core_type(t)));
+ }
+ return ir_emit(proc, ir_instr_conv(proc, irConv_ptrtoint, value, vt, t));
+}
+irValue *ir_emit_int_to_ptr(irProcedure *proc, irValue *value, Type *t) {
+ Type *vt = core_type(ir_type(value));
+ GB_ASSERT(is_type_int_or_uint(vt));
+ GB_ASSERT(is_type_pointer(core_type(t)));
+ return ir_emit(proc, ir_instr_conv(proc, irConv_inttoptr, value, vt, t));
+}
+
irValue *ir_emit_conv(irProcedure *proc, irValue *value, Type *t) {
Type *src_type = ir_type(value);
@@ -2925,10 +2943,10 @@ irValue *ir_emit_conv(irProcedure *proc, irValue *value, Type *t) {
// Pointer <-> int
if (is_type_pointer(src) && is_type_int_or_uint(dst)) {
- return ir_emit(proc, ir_instr_conv(proc, irConv_ptrtoint, value, src_type, t));
+ return ir_emit_ptr_to_int(proc, value, t);
}
if (is_type_int_or_uint(src) && is_type_pointer(dst)) {
- return ir_emit(proc, ir_instr_conv(proc, irConv_inttoptr, value, src_type, t));
+ return ir_emit_int_to_ptr(proc, value, t);
}
if (is_type_union(dst)) {
@@ -4388,7 +4406,14 @@ irValue *ir_build_expr(irProcedure *proc, AstNode *expr) {
if (tv.mode == Addressing_Type) {
// TODO(bill): Handle this correctly
- return ir_value_nil(proc->module->allocator, tv.type);
+ i32 entry_index = type_info_index(proc->module->info, tv.type, false);
+ if (entry_index >= 0) {
+ irValue *ptr = ir_get_type_info_ptr(proc, tv.type);
+ return ir_emit_ptr_to_int(proc, ptr, t_type, true);
+ // i32 id = entry_index+1;
+ // return ir_value_constant(proc->module->allocator, t_int, exact_value_i64(id));
+ }
+ return v_raw_nil;
}
if (tv.value.kind != ExactValue_Invalid) {
@@ -4766,7 +4791,10 @@ irValue *ir_build_expr(irProcedure *proc, AstNode *expr) {
GB_ASSERT(!vari_expand);
isize i = 0;
for (; i < type->param_count-1; i++) {
- args[i] = ir_emit_conv(proc, args[i], pt->variables[i]->type);
+ Entity *e = pt->variables[i];
+ if (e->kind == Entity_Variable) {
+ args[i] = ir_emit_conv(proc, args[i], e->type);
+ }
}
Type *variadic_type = pt->variables[i]->type;
GB_ASSERT(is_type_slice(variadic_type));
@@ -4783,7 +4811,10 @@ irValue *ir_build_expr(irProcedure *proc, AstNode *expr) {
} else if (variadic) {
isize i = 0;
for (; i < type->param_count-1; i++) {
- args[i] = ir_emit_conv(proc, args[i], pt->variables[i]->type);
+ Entity *e = pt->variables[i];
+ if (e->kind == Entity_Variable) {
+ args[i] = ir_emit_conv(proc, args[i], e->type);
+ }
}
if (!vari_expand) {
Type *variadic_type = pt->variables[i]->type;
@@ -4795,7 +4826,10 @@ irValue *ir_build_expr(irProcedure *proc, AstNode *expr) {
}
} else {
for (isize i = 0; i < type->param_count; i++) {
- args[i] = ir_emit_conv(proc, args[i], pt->variables[i]->type);
+ Entity *e = pt->variables[i];
+ if (e->kind == Entity_Variable) {
+ args[i] = ir_emit_conv(proc, args[i], e->type);
+ }
}
}
@@ -7698,6 +7732,10 @@ void ir_gen_tree(irGen *s) {
auto *entry = &info->type_info_map.entries[type_info_map_index];
Type *t = cast(Type *)entry->key.ptr;
t = default_type(t);
+ if (t == t_invalid) {
+ continue;
+ }
+
isize entry_index = type_info_index(info, t);
irValue *tag = NULL;
@@ -7771,6 +7809,10 @@ void ir_gen_tree(irGen *s) {
case Basic_any:
tag = ir_emit_conv(proc, ti_ptr, t_type_info_any_ptr);
break;
+
+ case Basic_Type:
+ tag = ir_emit_conv(proc, ti_ptr, t_type_info_type_ptr);
+ break;
}
break;