aboutsummaryrefslogtreecommitdiff
path: root/src/codegen
diff options
context:
space:
mode:
authorGinger Bill <bill@gingerbill.org>2016-09-07 15:15:10 +0100
committerGinger Bill <bill@gingerbill.org>2016-09-07 15:15:10 +0100
commit2c4193a24226b084797af61e29c8355835c179a8 (patch)
tree4a580168b5f094010e93047c0439bb770b45272b /src/codegen
parent61fcfd6f3d3c6cffd7e610abab83445b4cd1950d (diff)
`any` type
Diffstat (limited to 'src/codegen')
-rw-r--r--src/codegen/print_llvm.cpp7
-rw-r--r--src/codegen/ssa.cpp79
2 files changed, 78 insertions, 8 deletions
diff --git a/src/codegen/print_llvm.cpp b/src/codegen/print_llvm.cpp
index c8dff6d6b..ea30d910c 100644
--- a/src/codegen/print_llvm.cpp
+++ b/src/codegen/print_llvm.cpp
@@ -153,6 +153,13 @@ void ssa_print_type(ssaFileBuffer *f, BaseTypeSizes s, Type *t) {
case Basic_string: ssa_fprintf(f, "%%..string"); break;
case Basic_uint: ssa_fprintf(f, "i%lld", word_bits); break;
case Basic_int: ssa_fprintf(f, "i%lld", word_bits); break;
+ case Basic_any:
+ ssa_fprintf(f, "{");
+ ssa_print_type(f, s, t_type_info_ptr);
+ ssa_fprintf(f, ", ");
+ ssa_print_type(f, s, t_rawptr);
+ ssa_fprintf(f, "}");
+ break;
}
break;
case Type_Array:
diff --git a/src/codegen/ssa.cpp b/src/codegen/ssa.cpp
index 5bff4a344..a5fe3c566 100644
--- a/src/codegen/ssa.cpp
+++ b/src/codegen/ssa.cpp
@@ -1053,9 +1053,26 @@ ssaValue *ssa_emit_deep_field_gep(ssaProcedure *proc, Type *type, ssaValue *e, S
if (is_type_raw_union(type)) {
type = type->Record.fields[index]->type;
e = ssa_emit_conv(proc, e, make_type_pointer(proc->module->allocator, type));
- } else {
+ } else if (type->kind == Type_Record) {
type = type->Record.fields[index]->type;
e = ssa_emit_struct_gep(proc, e, index, make_type_pointer(proc->module->allocator, type));
+ } else if (type->kind == Type_Basic) {
+ switch (type->Basic.kind) {
+ case Basic_any: {
+ if (index == 0) {
+ type = t_type_info_ptr;
+ } else if (index == 1) {
+ type = t_rawptr;
+ }
+ e = ssa_emit_struct_gep(proc, e, index, make_type_pointer(proc->module->allocator, type));
+ } break;
+
+ default:
+ GB_PANIC("un-gep-able type");
+ break;
+ }
+ } else {
+ GB_PANIC("un-gep-able type");
}
}
@@ -1079,9 +1096,26 @@ ssaValue *ssa_emit_deep_field_ev(ssaProcedure *proc, Type *type, ssaValue *e, Se
if (is_type_raw_union(type)) {
type = type->Record.fields[index]->type;
e = ssa_emit_conv(proc, e, make_type_pointer(proc->module->allocator, type));
- } else {
+ } else if (type->kind == Type_Record) {
type = type->Record.fields[index]->type;
e = ssa_emit_struct_ev(proc, e, index, type);
+ } else if (type->kind == Type_Basic) {
+ switch (type->Basic.kind) {
+ case Basic_any: {
+ if (index == 0) {
+ type = t_type_info_ptr;
+ } else if (index == 1) {
+ type = t_rawptr;
+ }
+ e = ssa_emit_struct_ev(proc, e, index, type);
+ } break;
+
+ default:
+ GB_PANIC("un-ev-able type");
+ break;
+ }
+ } else {
+ GB_PANIC("un-ev-able type");
}
}
@@ -1303,12 +1337,17 @@ ssaValue *ssa_emit_conv(ssaProcedure *proc, ssaValue *value, Type *t, b32 is_arg
}
if (value->kind == ssaValue_Constant) {
- if (dst->kind == Type_Basic) {
+ if (is_type_any(dst)) {
+ Type *dt = default_type(src);
+ ssaValue *default_value = ssa_add_local_generated(proc, dt);
+ ssa_emit_store(proc, default_value, value);
+ return ssa_emit_conv(proc, ssa_emit_load(proc, default_value), t_any, is_argument);
+ } else if (dst->kind == Type_Basic) {
ExactValue ev = value->Constant.value;
if (is_type_float(dst)) {
ev = exact_value_to_float(ev);
} else if (is_type_string(dst)) {
- //
+ // Handled elsewhere
} else if (is_type_integer(dst)) {
ev = exact_value_to_integer(ev);
} else if (is_type_pointer(dst)) {
@@ -1487,6 +1526,33 @@ ssaValue *ssa_emit_conv(ssaProcedure *proc, ssaValue *value, Type *t, b32 is_arg
return v;
}
+ if (is_type_any(dst)) {
+ ssaValue **found = map_get(&proc->module->members, hash_string(make_string("__type_info_data")));
+ GB_ASSERT(found != NULL);
+ ssaValue *type_info_data = *found;
+ CheckerInfo *info = proc->module->info;
+
+
+ ssaValue *result = ssa_add_local_generated(proc, t_any);
+
+ // NOTE(bill): Make copy on stack so I can reference it later
+ ssaValue *data = ssa_add_local_generated(proc, src_type);
+ ssa_emit_store(proc, data, value);
+ data = ssa_emit_conv(proc, data, t_rawptr);
+
+
+ MapFindResult fr = map__find(&info->type_info_types, hash_pointer(src_type));
+ GB_ASSERT(fr.entry_index >= 0);
+ ssaValue *ti = ssa_emit_struct_gep(proc, type_info_data, fr.entry_index, t_type_info_ptr);
+
+ ssaValue *gep0 = ssa_emit_struct_gep(proc, result, v_zero32, make_type_pointer(proc->module->allocator, t_type_info_ptr));
+ ssaValue *gep1 = ssa_emit_struct_gep(proc, result, v_one32, make_type_pointer(proc->module->allocator, t_rawptr));
+ ssa_emit_store(proc, gep0, ti);
+ ssa_emit_store(proc, gep1, data);
+
+ return ssa_emit_load(proc, result);
+ }
+
gb_printf_err("Not Identical %s != %s\n", type_to_string(src_type), type_to_string(t));
gb_printf_err("Not Identical %s != %s\n", type_to_string(src), type_to_string(dst));
@@ -3194,10 +3260,7 @@ void ssa_build_stmt(ssaProcedure *proc, AstNode *node) {
ssaBlock *default_block = NULL;
isize case_count = body->list_count;
- isize i = 0;
- for (AstNode *clause = body->list;
- clause != NULL;
- clause = clause->next, i++) {
+ for (AstNode *clause = body->list; clause != NULL; clause = clause->next) {
ast_node(cc, CaseClause, clause);
if (cc->list == NULL) {