mirror of
https://github.com/odin-lang/Odin.git
synced 2026-02-13 23:03:16 +00:00
Fix union_tag_size; Fix constant array of array literal printing with scalar contents
This commit is contained in:
48
src/ir.cpp
48
src/ir.cpp
@@ -989,7 +989,7 @@ irValue *ir_instr_union_tag_ptr(irProcedure *p, irValue *address) {
|
||||
i->UnionTagPtr.address = address;
|
||||
// i->UnionTagPtr.type = make_type_pointer(p->module->allocator, t_type_info_ptr);
|
||||
Type *u = type_deref(ir_type(address));
|
||||
i->UnionTagPtr.type = make_type_pointer(p->module->allocator, union_tag_type(u));
|
||||
i->UnionTagPtr.type = make_type_pointer(p->module->allocator, union_tag_type(p->module->allocator, u));
|
||||
return v;
|
||||
}
|
||||
|
||||
@@ -1000,7 +1000,7 @@ irValue *ir_instr_union_tag_value(irProcedure *p, irValue *address) {
|
||||
// i->UnionTagValue.type = t_type_info_ptr;
|
||||
// i->UnionTagValue.type = t_int;
|
||||
Type *u = type_deref(ir_type(address));
|
||||
i->UnionTagPtr.type = union_tag_type(u);
|
||||
i->UnionTagPtr.type = union_tag_type(p->module->allocator, u);
|
||||
return v;
|
||||
}
|
||||
|
||||
@@ -2751,10 +2751,6 @@ irValue *ir_array_len(irProcedure *proc, irValue *array) {
|
||||
return ir_const_int(proc->module->allocator, t->Array.count);
|
||||
}
|
||||
|
||||
irValue *ir_vector_elem(irProcedure *proc, irValue *vector) {
|
||||
return ir_emit_array_ep(proc, vector, v_one32);
|
||||
}
|
||||
|
||||
|
||||
irValue *ir_slice_elem(irProcedure *proc, irValue *slice) {
|
||||
GB_ASSERT(is_type_slice(ir_type(slice)));
|
||||
@@ -2869,7 +2865,7 @@ irValue *ir_find_or_add_entity_string(irModule *m, String str) {
|
||||
|
||||
|
||||
irValue *ir_const_union_tag(gbAllocator a, Type *u, Type *v) {
|
||||
return ir_value_constant(a, union_tag_type(u), exact_value_i64(union_variant_index(u, v)));
|
||||
return ir_value_constant(a, union_tag_type(a, u), exact_value_i64(union_variant_index(u, v)));
|
||||
}
|
||||
|
||||
|
||||
@@ -4474,12 +4470,12 @@ irValue *ir_build_builtin_proc(irProcedure *proc, AstNode *expr, TypeAndValue tv
|
||||
|
||||
case BuiltinProc_swizzle: {
|
||||
ir_emit_comment(proc, str_lit("swizzle.begin"));
|
||||
irAddr vector_addr = ir_build_addr(proc, ce->args[0]);
|
||||
irAddr addr = ir_build_addr(proc, ce->args[0]);
|
||||
isize index_count = ce->args.count-1;
|
||||
if (index_count == 0) {
|
||||
return ir_addr_load(proc, vector_addr);
|
||||
return ir_addr_load(proc, addr);
|
||||
}
|
||||
irValue *src = ir_addr_get_ptr(proc, vector_addr);
|
||||
irValue *src = ir_addr_get_ptr(proc, addr);
|
||||
irValue *dst = ir_add_local_generated(proc, tv.type);
|
||||
|
||||
for (i32 i = 1; i < ce->args.count; i++) {
|
||||
@@ -4497,8 +4493,6 @@ irValue *ir_build_builtin_proc(irProcedure *proc, AstNode *expr, TypeAndValue tv
|
||||
}
|
||||
ir_emit_comment(proc, str_lit("swizzle.end"));
|
||||
return ir_emit_load(proc, dst);
|
||||
// return ir_emit(proc, ir_instr_vector_shuffle(proc, vector, indices, index_count));
|
||||
break;
|
||||
}
|
||||
|
||||
case BuiltinProc_complex: {
|
||||
@@ -7810,7 +7804,7 @@ void ir_setup_type_info_data(irProcedure *proc) { // NOTE(bill): Setup type_info
|
||||
|
||||
switch (t->kind) {
|
||||
case Type_Named: {
|
||||
ir_emit_comment(proc, str_lit("TypeInfoNamed"));
|
||||
ir_emit_comment(proc, str_lit("Type_Info_Named"));
|
||||
tag = ir_emit_conv(proc, variant_ptr, t_type_info_named_ptr);
|
||||
|
||||
// TODO(bill): Which is better? The mangled name or actual name?
|
||||
@@ -7823,7 +7817,7 @@ void ir_setup_type_info_data(irProcedure *proc) { // NOTE(bill): Setup type_info
|
||||
}
|
||||
|
||||
case Type_Basic:
|
||||
ir_emit_comment(proc, str_lit("TypeInfoBasic"));
|
||||
ir_emit_comment(proc, str_lit("Type_Info_Basic"));
|
||||
switch (t->Basic.kind) {
|
||||
case Basic_bool:
|
||||
tag = ir_emit_conv(proc, variant_ptr, t_type_info_boolean_ptr);
|
||||
@@ -7879,14 +7873,14 @@ void ir_setup_type_info_data(irProcedure *proc) { // NOTE(bill): Setup type_info
|
||||
break;
|
||||
|
||||
case Type_Pointer: {
|
||||
ir_emit_comment(proc, str_lit("TypeInfoPointer"));
|
||||
ir_emit_comment(proc, str_lit("Type_Info_Pointer"));
|
||||
tag = ir_emit_conv(proc, variant_ptr, t_type_info_pointer_ptr);
|
||||
irValue *gep = ir_get_type_info_ptr(proc, t->Pointer.elem);
|
||||
ir_emit_store(proc, ir_emit_struct_ep(proc, tag, 0), gep);
|
||||
break;
|
||||
}
|
||||
case Type_Array: {
|
||||
ir_emit_comment(proc, str_lit("TypeInfoArray"));
|
||||
ir_emit_comment(proc, str_lit("Type_Info_Array"));
|
||||
tag = ir_emit_conv(proc, variant_ptr, t_type_info_array_ptr);
|
||||
irValue *gep = ir_get_type_info_ptr(proc, t->Array.elem);
|
||||
ir_emit_store(proc, ir_emit_struct_ep(proc, tag, 0), gep);
|
||||
@@ -7901,7 +7895,7 @@ void ir_setup_type_info_data(irProcedure *proc) { // NOTE(bill): Setup type_info
|
||||
break;
|
||||
}
|
||||
case Type_DynamicArray: {
|
||||
ir_emit_comment(proc, str_lit("TypeInfoDynamicArray"));
|
||||
ir_emit_comment(proc, str_lit("Type_Info_Dynamic_Array"));
|
||||
tag = ir_emit_conv(proc, variant_ptr, t_type_info_dynamic_array_ptr);
|
||||
irValue *gep = ir_get_type_info_ptr(proc, t->DynamicArray.elem);
|
||||
ir_emit_store(proc, ir_emit_struct_ep(proc, tag, 0), gep);
|
||||
@@ -7912,7 +7906,7 @@ void ir_setup_type_info_data(irProcedure *proc) { // NOTE(bill): Setup type_info
|
||||
break;
|
||||
}
|
||||
case Type_Slice: {
|
||||
ir_emit_comment(proc, str_lit("TypeInfoSlice"));
|
||||
ir_emit_comment(proc, str_lit("Type_Info_Slice"));
|
||||
tag = ir_emit_conv(proc, variant_ptr, t_type_info_slice_ptr);
|
||||
irValue *gep = ir_get_type_info_ptr(proc, t->Slice.elem);
|
||||
ir_emit_store(proc, ir_emit_struct_ep(proc, tag, 0), gep);
|
||||
@@ -7923,7 +7917,7 @@ void ir_setup_type_info_data(irProcedure *proc) { // NOTE(bill): Setup type_info
|
||||
break;
|
||||
}
|
||||
case Type_Proc: {
|
||||
ir_emit_comment(proc, str_lit("TypeInfoProc"));
|
||||
ir_emit_comment(proc, str_lit("Type_Info_Proc"));
|
||||
tag = ir_emit_conv(proc, variant_ptr, t_type_info_procedure_ptr);
|
||||
|
||||
irValue *params = ir_emit_struct_ep(proc, tag, 0);
|
||||
@@ -7944,7 +7938,7 @@ void ir_setup_type_info_data(irProcedure *proc) { // NOTE(bill): Setup type_info
|
||||
break;
|
||||
}
|
||||
case Type_Tuple: {
|
||||
ir_emit_comment(proc, str_lit("TypeInfoTuple"));
|
||||
ir_emit_comment(proc, str_lit("Type_Info_Tuple"));
|
||||
tag = ir_emit_conv(proc, variant_ptr, t_type_info_tuple_ptr);
|
||||
|
||||
irValue *memory_types = ir_type_info_member_types_offset(proc, t->Tuple.variables.count);
|
||||
@@ -7970,7 +7964,7 @@ void ir_setup_type_info_data(irProcedure *proc) { // NOTE(bill): Setup type_info
|
||||
break;
|
||||
}
|
||||
case Type_Enum:
|
||||
ir_emit_comment(proc, str_lit("TypeInfoEnum"));
|
||||
ir_emit_comment(proc, str_lit("Type_Info_Enum"));
|
||||
tag = ir_emit_conv(proc, variant_ptr, t_type_info_enum_ptr);
|
||||
{
|
||||
GB_ASSERT(t->Enum.base_type != nullptr);
|
||||
@@ -8015,7 +8009,7 @@ void ir_setup_type_info_data(irProcedure *proc) { // NOTE(bill): Setup type_info
|
||||
break;
|
||||
|
||||
case Type_Union: {
|
||||
ir_emit_comment(proc, str_lit("TypeInfoUnion"));
|
||||
ir_emit_comment(proc, str_lit("Type_Info_Union"));
|
||||
tag = ir_emit_conv(proc, variant_ptr, t_type_info_union_ptr);
|
||||
|
||||
{
|
||||
@@ -8039,17 +8033,17 @@ void ir_setup_type_info_data(irProcedure *proc) { // NOTE(bill): Setup type_info
|
||||
irValue *count = ir_const_int(a, variant_count);
|
||||
ir_fill_slice(proc, variant_types, memory_types, count);
|
||||
|
||||
i64 tag_size = union_tag_size(t);
|
||||
i64 tag_size = union_tag_size(a, t);
|
||||
i64 tag_offset = align_formula(t->Union.variant_block_size, tag_size);
|
||||
ir_emit_store(proc, tag_offset_ptr, ir_const_uintptr(a, tag_offset));
|
||||
ir_emit_store(proc, tag_type_ptr, ir_type_info(proc, union_tag_type(t)));
|
||||
ir_emit_store(proc, tag_type_ptr, ir_type_info(proc, union_tag_type(a, t)));
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
case Type_Struct: {
|
||||
ir_emit_comment(proc, str_lit("TypeInfoStruct"));
|
||||
ir_emit_comment(proc, str_lit("Type_Info_Struct"));
|
||||
tag = ir_emit_conv(proc, variant_ptr, t_type_info_struct_ptr);
|
||||
|
||||
{
|
||||
@@ -8103,7 +8097,7 @@ void ir_setup_type_info_data(irProcedure *proc) { // NOTE(bill): Setup type_info
|
||||
break;
|
||||
}
|
||||
case Type_Map: {
|
||||
ir_emit_comment(proc, str_lit("TypeInfoMap"));
|
||||
ir_emit_comment(proc, str_lit("Type_Info_Map"));
|
||||
tag = ir_emit_conv(proc, variant_ptr, t_type_info_map_ptr);
|
||||
generate_map_internal_types(a, t);
|
||||
|
||||
@@ -8118,7 +8112,7 @@ void ir_setup_type_info_data(irProcedure *proc) { // NOTE(bill): Setup type_info
|
||||
}
|
||||
|
||||
case Type_BitField: {
|
||||
ir_emit_comment(proc, str_lit("TypeInfoBitField"));
|
||||
ir_emit_comment(proc, str_lit("Type_Info_Bit_Field"));
|
||||
tag = ir_emit_conv(proc, variant_ptr, t_type_info_bit_field_ptr);
|
||||
// names: []string;
|
||||
// bits: []u32;
|
||||
|
||||
@@ -342,7 +342,7 @@ void ir_print_type(irFileBuffer *f, irModule *m, Type *t) {
|
||||
ir_fprintf(f, "{[0 x <%lld x i8>], ", align);
|
||||
ir_fprintf(f, "[%lld x i8], ", block_size);
|
||||
// ir_print_type(f, m, t_type_info_ptr);
|
||||
ir_print_type(f, m, union_tag_type(t));
|
||||
ir_print_type(f, m, union_tag_type(m->allocator, t));
|
||||
ir_write_byte(f, '}');
|
||||
}
|
||||
} return;
|
||||
@@ -463,6 +463,26 @@ void ir_print_exact_value(irFileBuffer *f, irModule *m, ExactValue value, Type *
|
||||
type = core_type(type);
|
||||
value = convert_exact_value_for_type(value, type);
|
||||
|
||||
// NOTE(bill): Is this correct? Does this handle all cases regarding arrays?
|
||||
if (is_type_array(type) &&
|
||||
value.kind != ExactValue_Invalid &&
|
||||
value.kind != ExactValue_Compound) {
|
||||
i64 count = type->Array.count;
|
||||
Type *elem = type->Array.elem;
|
||||
ir_write_byte(f, '[');
|
||||
|
||||
for (i64 i = 0; i < count; i++) {
|
||||
if (i > 0) ir_write_string(f, ", ");
|
||||
ir_print_type(f, m, elem);
|
||||
ir_write_byte(f, ' ');
|
||||
ir_print_exact_value(f, m, value, elem);
|
||||
}
|
||||
|
||||
ir_write_byte(f, ']');
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
switch (value.kind) {
|
||||
case ExactValue_Bool:
|
||||
if (value.value_bool) {
|
||||
@@ -548,7 +568,6 @@ void ir_print_exact_value(irFileBuffer *f, irModule *m, ExactValue value, Type *
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case ExactValue_Complex: {
|
||||
type = core_type(type);
|
||||
GB_ASSERT_MSG(is_type_complex(type), "%s", type_to_string(type));
|
||||
@@ -562,7 +581,6 @@ void ir_print_exact_value(irFileBuffer *f, irModule *m, ExactValue value, Type *
|
||||
ir_write_byte(f, '}');
|
||||
break;
|
||||
}
|
||||
|
||||
case ExactValue_Pointer:
|
||||
if (value.value_pointer == 0) {
|
||||
ir_write_string(f, "null");
|
||||
@@ -574,7 +592,6 @@ void ir_print_exact_value(irFileBuffer *f, irModule *m, ExactValue value, Type *
|
||||
ir_write_byte(f, ')');
|
||||
}
|
||||
break;
|
||||
|
||||
case ExactValue_Compound: {
|
||||
type = base_type(type);
|
||||
if (is_type_slice(type)) {
|
||||
@@ -700,7 +717,6 @@ void ir_print_exact_value(irFileBuffer *f, irModule *m, ExactValue value, Type *
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
case ExactValue_Procedure: {
|
||||
irValue **found = nullptr;
|
||||
AstNode *expr = value.value_procedure;
|
||||
@@ -719,7 +735,6 @@ void ir_print_exact_value(irFileBuffer *f, irModule *m, ExactValue value, Type *
|
||||
ir_print_value(f, m, val, type);
|
||||
break;
|
||||
}
|
||||
|
||||
default: {
|
||||
bool has_defaults = ir_type_has_default_values(type);
|
||||
if (!has_defaults) {
|
||||
|
||||
@@ -126,6 +126,7 @@ struct TypeStruct {
|
||||
Scope * scope; \
|
||||
i64 variant_block_size; \
|
||||
i64 custom_align; \
|
||||
i64 tag_size; \
|
||||
}) \
|
||||
TYPE_KIND(Named, struct { \
|
||||
String name; \
|
||||
@@ -1361,16 +1362,23 @@ i64 union_variant_index(Type *u, Type *v) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
i64 union_tag_size(Type *u) {
|
||||
i64 union_tag_size(gbAllocator a, Type *u) {
|
||||
u = base_type(u);
|
||||
GB_ASSERT(u->kind == Type_Union);
|
||||
u64 cl2 = ceil_log2(cast(u64)u->Union.variants.count);
|
||||
i64 s = (next_pow2(cast(i64)cl2) + 7)/8;
|
||||
return gb_clamp(s, 1, build_context.word_size);
|
||||
if (u->Union.tag_size > 0) {
|
||||
return u->Union.tag_size;
|
||||
}
|
||||
|
||||
i64 tag_size = type_align_of(a, u);
|
||||
if (tag_size < 1) {
|
||||
tag_size = build_context.word_size;
|
||||
}
|
||||
u->Union.tag_size = tag_size;
|
||||
return tag_size;
|
||||
}
|
||||
|
||||
Type *union_tag_type(Type *u) {
|
||||
i64 s = union_tag_size(u);
|
||||
Type *union_tag_type(gbAllocator a, Type *u) {
|
||||
i64 s = union_tag_size(a, u);
|
||||
switch (s) {
|
||||
case 1: return t_u8;
|
||||
case 2: return t_u16;
|
||||
@@ -1879,7 +1887,7 @@ i64 type_align_of_internal(gbAllocator allocator, Type *t, TypePath *path) {
|
||||
return gb_clamp(t->Union.custom_align, 1, build_context.max_align);
|
||||
}
|
||||
|
||||
i64 max = union_tag_size(t);
|
||||
i64 max = 1;
|
||||
for_array(i, t->Union.variants) {
|
||||
Type *variant = t->Union.variants[i];
|
||||
bool pop = type_path_push(path, variant);
|
||||
@@ -2091,9 +2099,10 @@ i64 type_size_of_internal(gbAllocator allocator, Type *t, TypePath *path) {
|
||||
}
|
||||
|
||||
// NOTE(bill): Align to tag
|
||||
i64 tag_size = union_tag_size(t);
|
||||
i64 tag_size = gb_max(align, 1);
|
||||
i64 size = align_formula(max, tag_size);
|
||||
// NOTE(bill): Calculate the padding between the common fields and the tag
|
||||
t->Union.tag_size = tag_size;
|
||||
t->Union.variant_block_size = size - field_size;
|
||||
|
||||
size += tag_size;
|
||||
|
||||
Reference in New Issue
Block a user