Begin work on const llvm aggregate literals

This commit is contained in:
Ginger Bill
2016-09-30 20:38:46 +01:00
parent 04b5d8c132
commit c6aac264fa
12 changed files with 320 additions and 109 deletions

View File

@@ -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;