From c6aac264fa8001ff5e55e5ac6f56289ff0a755ee Mon Sep 17 00:00:00 2001 From: Ginger Bill Date: Fri, 30 Sep 2016 20:38:46 +0100 Subject: Begin work on const llvm aggregate literals --- src/codegen/print_llvm.cpp | 118 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 118 insertions(+) (limited to 'src/codegen/print_llvm.cpp') diff --git a/src/codegen/print_llvm.cpp b/src/codegen/print_llvm.cpp index 420bb112f..3957b0e36 100644 --- a/src/codegen/print_llvm.cpp +++ b/src/codegen/print_llvm.cpp @@ -263,6 +263,8 @@ void ssa_print_type(ssaFileBuffer *f, ssaModule *m, Type *t) { } } +void ssa_print_value(ssaFileBuffer *f, ssaModule *m, ssaValue *value, Type *type_hint); + void ssa_print_exact_value(ssaFileBuffer *f, ssaModule *m, ExactValue value, Type *type) { type = base_type(type); if (is_type_float(type)) { @@ -320,6 +322,122 @@ void ssa_print_exact_value(ssaFileBuffer *f, ssaModule *m, ExactValue value, Typ ssa_fprintf(f, ")"); } break; + + case ExactValue_Compound: { + // ssa_fprintf(f, "%s", (value.value_bool ? "true" : "false")); + type = base_type(type); + if (is_type_array(type)) { + ssa_fprintf(f, "["); + Type *elem_type = type->Array.elem; + ast_node(cl, CompoundLit, value.value_compound); + + for (isize i = 0; i < type->Array.count; i++) { + if (i > 0) { + ssa_fprintf(f, ", "); + } + ssa_print_type(f, m, elem_type); + ssa_fprintf(f, " "); + + TypeAndValue *tav = type_and_value_of_expression(m->info, cl->elems[i]); + GB_ASSERT(tav != NULL); + ssa_print_exact_value(f, m, tav->value, elem_type); + } + + ssa_fprintf(f, "]"); + } else if (is_type_struct(type)) { + gbTempArenaMemory tmp = gb_temp_arena_memory_begin(&m->tmp_arena); + defer (gb_temp_arena_memory_end(tmp)); + + ast_node(cl, CompoundLit, value.value_compound); + + if (cl->elems == NULL || gb_array_count(cl->elems) == 0) { + ssa_fprintf(f, "zeroinitializer"); + break; + } + + + isize value_count = type->Record.field_count; + ExactValue *values = gb_alloc_array(m->tmp_allocator, ExactValue, value_count); + + + if (cl->elems[0]->kind == AstNode_FieldValue) { + isize elem_count = gb_array_count(cl->elems); + for (isize i = 0; i < elem_count; i++) { + ast_node(fv, FieldValue, cl->elems[i]); + String name = fv->field->Ident.string; + + TypeAndValue *tav = type_and_value_of_expression(m->info, fv->value); + GB_ASSERT(tav != NULL); + + Selection sel = lookup_field(m->allocator, type, name, false); + Entity *f = type->Record.fields[sel.index[0]]; + + values[f->Variable.field_index] = tav->value; + } + } else { + for (isize i = 0; i < value_count; i++) { + TypeAndValue *tav = type_and_value_of_expression(m->info, cl->elems[i]); + GB_ASSERT(tav != NULL); + + Entity *f = type->Record.fields_in_src_order[i]; + + values[f->Variable.field_index] = tav->value; + } + } + + + + if (type->Record.struct_is_packed) { + ssa_fprintf(f, "<"); + } + ssa_fprintf(f, "{"); + + + for (isize i = 0; i < value_count; i++) { + if (i > 0) { + ssa_fprintf(f, ", "); + } + Type *elem_type = type->Record.fields[i]->type; + + ssa_print_type(f, m, elem_type); + ssa_fprintf(f, " "); + + ExactValue v = values[i]; + if (v.kind == ExactValue_Invalid) { + ssa_fprintf(f, "zeroinitializer"); + } else if (v.kind == ExactValue_String) { + // HACK NOTE(bill): This is a hack but it works because strings are created at the very end + // of the .ll file + ssaValue *str_array = ssa_add_global_string_array(m, v.value_string); + + ssa_fprintf(f, "{i8* getelementptr inbounds ("); + ssa_print_type(f, m, str_array->Global.entity->type); + ssa_fprintf(f, ", "); + ssa_print_type(f, m, str_array->Global.entity->type); + ssa_fprintf(f, "* "); + ssa_print_encoded_global(f, str_array->Global.entity->token.string, false); + ssa_fprintf(f, ", "); + ssa_print_type(f, m, t_int); + ssa_fprintf(f, " 0, i32 0), "); + ssa_print_type(f, m, t_int); + ssa_fprintf(f, " %lld}", cast(i64)v.value_string.len); + + } else { + ssa_print_exact_value(f, m, v, elem_type); + } + } + + + ssa_fprintf(f, "}"); + if (type->Record.struct_is_packed) { + ssa_fprintf(f, ">"); + } + } else { + ssa_fprintf(f, "zeroinitializer"); + } + + } break; + default: GB_PANIC("Invalid ExactValue: %d", value.kind); break; -- cgit v1.2.3