diff options
| author | Ginger Bill <bill@gingerbill.org> | 2017-04-14 21:47:59 +0100 |
|---|---|---|
| committer | Ginger Bill <bill@gingerbill.org> | 2017-04-14 21:47:59 +0100 |
| commit | 23a0a6de4b78bc5447d70cebfd792319ea2b7059 (patch) | |
| tree | f41b0832edbd64d2de80166e72c7c5df2f769774 /src/types.c | |
| parent | 0d2dbee84e937ccf411787f9dda72e541db3fd20 (diff) | |
Add parse_int; Fix union bugs with size, alignment, and recursive definition checking
Diffstat (limited to 'src/types.c')
| -rw-r--r-- | src/types.c | 59 |
1 files changed, 50 insertions, 9 deletions
diff --git a/src/types.c b/src/types.c index a12432747..02c01d4c9 100644 --- a/src/types.c +++ b/src/types.c @@ -402,6 +402,7 @@ void set_base_type(Type *t, Type *base) { Type *alloc_type(gbAllocator a, TypeKind kind) { Type *t = gb_alloc_item(a, Type); + gb_zero_item(t); t->kind = kind; return t; } @@ -837,6 +838,12 @@ bool type_has_nil(Type *t) { case Type_DynamicArray: case Type_Map: return true; + case Type_Record: + switch (t->Record.kind) { + case TypeRecord_Union: + return true; + } + return false; } return false; } @@ -1138,7 +1145,6 @@ ProcTypeOverloadKind are_proc_types_overload_safe(Type *x, Type *y) { Entity *ey = py.params->Tuple.variables[0]; bool ok = are_types_identical(ex->type, ey->type); if (ok) { - gb_printf_err("Here\n"); } } @@ -1520,7 +1526,7 @@ void type_path_free(TypePath *tp) { TypePath *type_path_push(TypePath *tp, Type *t) { GB_ASSERT(tp != NULL); - for_array(i, tp->path) { + for (isize i = 0; i < tp->path.count; i++) { if (tp->path.e[i] == t) { // TODO(bill): GB_ASSERT(is_type_named(t)); @@ -1601,6 +1607,7 @@ i64 type_align_of_internal(gbAllocator allocator, Type *t, TypePath *path) { if (t->failure) { return FAILURE_ALIGNMENT; } + t = base_type(t); switch (t->kind) { @@ -1705,6 +1712,18 @@ i64 type_align_of_internal(gbAllocator allocator, Type *t, TypePath *path) { break; case TypeRecord_Union: { i64 max = 1; + if (t->Record.field_count > 0) { + Type *field_type = t->Record.fields[0]->type; + type_path_push(path, field_type); + if (path->failure) { + return FAILURE_ALIGNMENT; + } + i64 align = type_align_of_internal(allocator, field_type, path); + type_path_pop(path); + if (max < align) { + max = align; + } + } // NOTE(bill): field zero is null for (isize i = 1; i < t->Record.variant_count; i++) { Type *variant = t->Record.variants[i]->type; @@ -1795,8 +1814,18 @@ i64 type_size_of_internal(gbAllocator allocator, Type *t, TypePath *path) { if (t->failure) { return FAILURE_SIZE; } - t = base_type(t); + switch (t->kind) { + case Type_Named: { + type_path_push(path, t); + if (path->failure) { + return FAILURE_ALIGNMENT; + } + i64 size = type_size_of_internal(allocator, t->Named.base, path); + type_path_pop(path); + return size; + } break; + case Type_Basic: { GB_ASSERT(is_type_typed(t)); BasicKind kind = t->Basic.kind; @@ -1907,15 +1936,26 @@ i64 type_size_of_internal(gbAllocator allocator, Type *t, TypePath *path) { } break; case TypeRecord_Union: { - i64 count = t->Record.variant_count; i64 align = type_align_of_internal(allocator, t, path); if (path->failure) { return FAILURE_SIZE; } - i64 max = 0; // NOTE(bill): Zeroth field is invalid - for (isize i = 1; i < count; i++) { - i64 size = type_size_of_internal(allocator, t->Record.variants[i]->type, path); + type_set_offsets(allocator, t); + + i64 max = 0; + isize field_count = t->Record.field_count; + isize variant_count = t->Record.variant_count; + if (field_count > 0) { + Type *end_type = t->Record.fields[field_count-1]->type; + i64 end_offset = t->Record.offsets[field_count-1]; + i64 end_size = type_size_of_internal(allocator, end_type, path); + max = end_offset + end_size ; + } + + for (isize i = 1; i < variant_count; i++) { + Type *variant_type = t->Record.variants[i]->type; + i64 size = type_size_of_internal(allocator, variant_type, path); if (max < size) { max = size; } @@ -1923,7 +1963,8 @@ i64 type_size_of_internal(gbAllocator allocator, Type *t, TypePath *path) { // NOTE(bill): Align to int i64 size = align_formula(max, build_context.word_size); size += type_size_of_internal(allocator, t_int, path); - return align_formula(size, align); + size = align_formula(size, align); + return size; } break; case TypeRecord_RawUnion: { @@ -2111,7 +2152,7 @@ gbString write_type_to_string(gbString str, Type *type) { } str = gb_string_append_length(str, f->token.string.text, f->token.string.len); str = gb_string_appendc(str, ": "); - str = write_type_to_string(str, base_type(f->type)); + str = write_type_to_string(str, f->type); } for (isize i = 1; i < type->Record.variant_count; i++) { Entity *f = type->Record.variants[i]; |