aboutsummaryrefslogtreecommitdiff
path: root/src/codegen/print_llvm.cpp
diff options
context:
space:
mode:
authorGinger Bill <bill@gingerbill.org>2016-09-30 20:38:46 +0100
committerGinger Bill <bill@gingerbill.org>2016-09-30 20:38:46 +0100
commitc6aac264fa8001ff5e55e5ac6f56289ff0a755ee (patch)
tree4ff0521b330e5a2b0183d3bab2f762a669b5efa5 /src/codegen/print_llvm.cpp
parent04b5d8c132e8aabb3bb5dff31683cb45d4dff9c0 (diff)
Begin work on const llvm aggregate literals
Diffstat (limited to 'src/codegen/print_llvm.cpp')
-rw-r--r--src/codegen/print_llvm.cpp118
1 files changed, 118 insertions, 0 deletions
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;