enum_to_string

This commit is contained in:
Ginger Bill
2016-09-19 21:33:52 +01:00
parent bbc9739f5c
commit 9561dc33ce
17 changed files with 660 additions and 214 deletions

View File

@@ -67,16 +67,6 @@ String ssa_mangle_name(ssaGen *s, String path, String name) {
}
void ssa_gen_tree(ssaGen *s) {
if (v_zero == NULL) {
v_zero = ssa_make_const_int (gb_heap_allocator(), 0);
v_one = ssa_make_const_int (gb_heap_allocator(), 1);
v_zero32 = ssa_make_const_i32 (gb_heap_allocator(), 0);
v_one32 = ssa_make_const_i32 (gb_heap_allocator(), 1);
v_two32 = ssa_make_const_i32 (gb_heap_allocator(), 2);
v_false = ssa_make_const_bool(gb_heap_allocator(), false);
v_true = ssa_make_const_bool(gb_heap_allocator(), true);
}
struct ssaGlobalVariable {
ssaValue *var, *init;
DeclInfo *decl;
@@ -85,9 +75,35 @@ void ssa_gen_tree(ssaGen *s) {
ssaModule *m = &s->module;
CheckerInfo *info = m->info;
gbAllocator a = m->allocator;
if (v_zero == NULL) {
v_zero = ssa_make_const_int (m->allocator, 0);
v_one = ssa_make_const_int (m->allocator, 1);
v_zero32 = ssa_make_const_i32 (m->allocator, 0);
v_one32 = ssa_make_const_i32 (m->allocator, 1);
v_two32 = ssa_make_const_i32 (m->allocator, 2);
v_false = ssa_make_const_bool(m->allocator, false);
v_true = ssa_make_const_bool(m->allocator, true);
}
isize global_variable_max_count = 0;
gb_for_array(i, info->entities.entries) {
auto *entry = &info->entities.entries[i];
Entity *e = cast(Entity *)cast(uintptr)entry->key.key;
if (e->kind == Entity_Variable) {
global_variable_max_count++;
}
}
gbTempArenaMemory tmp = gb_temp_arena_memory_begin(&m->tmp_arena);
defer (gb_temp_arena_memory_end(tmp));
gbArray(ssaGlobalVariable) global_variables;
gb_array_init(global_variables, gb_heap_allocator());
defer (gb_array_free(global_variables));
gb_array_init_reserve(global_variables, m->tmp_allocator, global_variable_max_count);
gb_for_array(i, info->entities.entries) {
auto *entry = &info->entities.entries[i];
@@ -123,7 +139,7 @@ void ssa_gen_tree(ssaGen *s) {
ExactValue v = tav->value;
if (v.kind == ExactValue_String) {
// NOTE(bill): The printer will fix the value correctly
g->Global.value = ssa_add_global_string_array(m, v.value_string);
// g->Global.value = ssa_add_global_string_array(m, v.value_string);
} else {
g->Global.value = ssa_make_value_constant(a, tav->type, v);
}
@@ -147,6 +163,8 @@ void ssa_gen_tree(ssaGen *s) {
}
if (pd->foreign_name.len > 0) {
name = pd->foreign_name;
} else if (pd->link_name.len > 0) {
name = pd->link_name;
}
ssaValue *p = ssa_make_value_procedure(a, m, e, e->type, decl->type_expr, body, name);
@@ -171,7 +189,18 @@ void ssa_gen_tree(ssaGen *s) {
ssaDebugInfo *compile_unit = m->debug_info.entries[0].value;
GB_ASSERT(compile_unit->kind == ssaDebugInfo_CompileUnit);
ssaDebugInfo *all_procs = ssa_alloc_debug_info(m->allocator, ssaDebugInfo_AllProcs);
gb_array_init(all_procs->AllProcs.procs, gb_heap_allocator());
isize all_proc_max_count = 0;
gb_for_array(i, m->debug_info.entries) {
auto *entry = &m->debug_info.entries[i];
ssaDebugInfo *di = entry->value;
di->id = i;
if (di->kind == ssaDebugInfo_Proc) {
all_proc_max_count++;
}
}
gb_array_init_reserve(all_procs->AllProcs.procs, m->allocator, all_proc_max_count);
map_set(&m->debug_info, hash_pointer(all_procs), all_procs); // NOTE(bill): This doesn't need to be mapped
compile_unit->CompileUnit.all_procs = all_procs;
@@ -250,10 +279,12 @@ void ssa_gen_tree(ssaGen *s) {
// Useful types
Type *t_int_ptr = make_type_pointer(a, t_int);
Type *t_i64_ptr = make_type_pointer(a, t_i64);
Type *t_bool_ptr = make_type_pointer(a, t_bool);
Type *t_string_ptr = make_type_pointer(a, t_string);
Type *t_type_info_ptr_ptr = make_type_pointer(a, t_type_info_ptr);
Type *t_i64_slice_ptr = make_type_pointer(a, make_type_slice(a, t_i64));
Type *t_string_slice_ptr = make_type_pointer(a, make_type_slice(a, t_string));
auto get_type_info_ptr = [](ssaProcedure *proc, ssaValue *type_info_data, Type *type) -> ssaValue * {
return ssa_emit_struct_gep(proc, type_info_data,
@@ -302,12 +333,12 @@ void ssa_gen_tree(ssaGen *s) {
case Basic_i16:
case Basic_i32:
case Basic_i64:
case Basic_i128:
// case Basic_i128:
case Basic_u8:
case Basic_u16:
case Basic_u32:
case Basic_u64:
case Basic_u128:
// case Basic_u128:
case Basic_int:
case Basic_uint: {
tag = ssa_add_local_generated(proc, t_type_info_integer);
@@ -467,8 +498,72 @@ void ssa_gen_tree(ssaGen *s) {
if (enum_base == NULL) {
enum_base = t_int;
}
ssaValue *gep = get_type_info_ptr(proc, type_info_data, enum_base);
ssa_emit_store(proc, ssa_emit_struct_gep(proc, tag, v_zero32, t_type_info_ptr_ptr), gep);
ssaValue *base = ssa_emit_struct_gep(proc, tag, v_zero32, t_type_info_ptr_ptr);
ssa_emit_store(proc, base, get_type_info_ptr(proc, type_info_data, enum_base));
if (t->Record.other_field_count > 0) {
Entity **fields = t->Record.other_fields;
isize count = t->Record.other_field_count;
ssaValue *value_array = NULL;
ssaValue *name_array = NULL;
{
Token token = {Token_Identifier};
i32 id = cast(i32)entry_index;
char name_base[] = "__$enum_values";
isize name_len = gb_size_of(name_base) + 10;
token.string.text = gb_alloc_array(a, u8, name_len);
token.string.len = gb_snprintf(cast(char *)token.string.text, name_len,
"%s-%d", name_base, id)-1;
Entity *e = make_entity_variable(a, NULL, token, make_type_array(a, t_i64, count));
value_array = ssa_make_value_global(a, e, NULL);
value_array->Global.is_private = true;
ssa_module_add_value(m, e, value_array);
map_set(&m->members, hash_string(token.string), value_array);
}
{
Token token = {Token_Identifier};
i32 id = cast(i32)entry_index;
char name_base[] = "__$enum_names";
isize name_len = gb_size_of(name_base) + 10;
token.string.text = gb_alloc_array(a, u8, name_len);
token.string.len = gb_snprintf(cast(char *)token.string.text, name_len,
"%s-%d", name_base, id)-1;
Entity *e = make_entity_variable(a, NULL, token, make_type_array(a, t_string, count));
name_array = ssa_make_value_global(a, e, NULL);
name_array->Global.is_private = true;
ssa_module_add_value(m, e, name_array);
map_set(&m->members, hash_string(token.string), name_array);
}
for (isize i = 0; i < count; i++) {
ssaValue *value_gep = ssa_emit_struct_gep(proc, value_array, i, t_i64_ptr);
ssaValue *name_gep = ssa_emit_struct_gep(proc, name_array, i, t_string_ptr);
ssa_emit_store(proc, value_gep, ssa_make_const_i64(a, fields[i]->Constant.value.value_integer));
ssa_emit_store(proc, name_gep, ssa_emit_global_string(proc, fields[i]->token.string));
}
ssaValue *v_count = ssa_make_const_int(a, count);
ssaValue *values = ssa_emit_struct_gep(proc, tag, v_one32, t_i64_slice_ptr);
ssaValue *names = ssa_emit_struct_gep(proc, tag, v_two32, t_string_slice_ptr);
ssaValue *value_slice = ssa_add_local_generated(proc, type_deref(t_i64_slice_ptr));
ssaValue *name_slice = ssa_add_local_generated(proc, type_deref(t_string_slice_ptr));
ssa_emit_store(proc, ssa_emit_struct_gep(proc, value_slice, v_zero32, t_i64_ptr), ssa_array_elem(proc, value_array));
ssa_emit_store(proc, ssa_emit_struct_gep(proc, value_slice, v_one32, t_int_ptr), v_count);
ssa_emit_store(proc, ssa_emit_struct_gep(proc, value_slice, v_two32, t_int_ptr), v_count);
ssa_emit_store(proc, ssa_emit_struct_gep(proc, name_slice, v_zero32, t_string_ptr), ssa_array_elem(proc, name_array));
ssa_emit_store(proc, ssa_emit_struct_gep(proc, name_slice, v_one32, t_int_ptr), v_count);
ssa_emit_store(proc, ssa_emit_struct_gep(proc, name_slice, v_two32, t_int_ptr), v_count);
ssa_emit_store(proc, values, ssa_emit_load(proc, value_slice));
ssa_emit_store(proc, names, ssa_emit_load(proc, name_slice));
}
} break;
}
} break;
@@ -515,10 +610,10 @@ void ssa_gen_tree(ssaGen *s) {
ssaValue *variadic = ssa_emit_struct_gep(proc, tag, v_two32, t_bool_ptr);
if (t->Proc.params) {
ssa_emit_store(proc, params, get_type_info_ptr(proc, type_info_data, t->Proc.params));
ssa_emit_store(proc, params, get_type_info_ptr(proc, type_info_data, t->Proc.params));
}
if (t->Proc.results) {
ssa_emit_store(proc, results, get_type_info_ptr(proc, type_info_data, t->Proc.results));
ssa_emit_store(proc, results, get_type_info_ptr(proc, type_info_data, t->Proc.results));
}
ssa_emit_store(proc, variadic, ssa_make_const_bool(a, t->Proc.variadic));