mirror of
https://github.com/odin-lang/Odin.git
synced 2026-01-02 11:12:31 +00:00
Update internals of a Union and Tuple
This commit is contained in:
@@ -44,15 +44,6 @@ TypeInfo :: struct #ordered {
|
||||
u8, u16, u32, u64, u128, uint,
|
||||
f32, f64,
|
||||
};
|
||||
Record :: struct #ordered {
|
||||
types: []^TypeInfo;
|
||||
names: []string;
|
||||
offsets: []int; // offsets may not be used in tuples
|
||||
usings: []bool; // usings may not be used in tuples
|
||||
packed: bool;
|
||||
ordered: bool;
|
||||
custom_align: bool;
|
||||
}
|
||||
|
||||
// Variant Types
|
||||
Named :: struct #ordered {name: string; base: ^TypeInfo};
|
||||
@@ -80,9 +71,20 @@ TypeInfo :: struct #ordered {
|
||||
DynamicArray :: struct #ordered {elem: ^TypeInfo; elem_size: int};
|
||||
Slice :: struct #ordered {elem: ^TypeInfo; elem_size: int};
|
||||
Vector :: struct #ordered {elem: ^TypeInfo; elem_size, count: int};
|
||||
Tuple :: Record; // Only really used for procedures
|
||||
Struct :: Record;
|
||||
RawUnion :: Record;
|
||||
Tuple :: struct #ordered { // Only really used for procedures
|
||||
types: []^TypeInfo;
|
||||
names: []string;
|
||||
};
|
||||
Struct :: struct #ordered {
|
||||
types: []^TypeInfo;
|
||||
names: []string;
|
||||
offsets: []int; // offsets may not be used in tuples
|
||||
usings: []bool; // usings may not be used in tuples
|
||||
is_packed: bool;
|
||||
is_ordered: bool;
|
||||
is_raw_union: bool;
|
||||
custom_align: bool;
|
||||
};
|
||||
Union :: struct #ordered {
|
||||
variants: []^TypeInfo;
|
||||
tag_offset: int;
|
||||
@@ -126,7 +128,6 @@ TypeInfo :: struct #ordered {
|
||||
Vector,
|
||||
Tuple,
|
||||
Struct,
|
||||
RawUnion,
|
||||
Union,
|
||||
Enum,
|
||||
Map,
|
||||
|
||||
@@ -274,8 +274,9 @@ write_type :: proc(buf: ^StringBuffer, ti: ^TypeInfo) {
|
||||
|
||||
case Struct:
|
||||
write_string(buf, "struct ");
|
||||
if info.packed do write_string(buf, "#packed ");
|
||||
if info.ordered do write_string(buf, "#ordered ");
|
||||
if info.is_packed do write_string(buf, "#packed ");
|
||||
if info.is_ordered do write_string(buf, "#ordered ");
|
||||
if info.is_raw_union do write_string(buf, "#raw_union ");
|
||||
if info.custom_align {
|
||||
write_string(buf, "#align ");
|
||||
write_int(buf, i64(ti.align), 10);
|
||||
@@ -298,16 +299,6 @@ write_type :: proc(buf: ^StringBuffer, ti: ^TypeInfo) {
|
||||
}
|
||||
write_string(buf, "}");
|
||||
|
||||
case RawUnion:
|
||||
write_string(buf, "raw_union {");
|
||||
for name, i in info.names {
|
||||
if i > 0 do write_string(buf, ", ");
|
||||
write_string(buf, name);
|
||||
write_string(buf, ": ");
|
||||
write_type(buf, info.types[i]);
|
||||
}
|
||||
write_string(buf, "}");
|
||||
|
||||
case Enum:
|
||||
write_string(buf, "enum ");
|
||||
write_type(buf, info.base);
|
||||
@@ -317,6 +308,7 @@ write_type :: proc(buf: ^StringBuffer, ti: ^TypeInfo) {
|
||||
write_string(buf, name);
|
||||
}
|
||||
write_string(buf, "}");
|
||||
|
||||
case BitField:
|
||||
write_string(buf, "bit_field ");
|
||||
if ti.align != 1 {
|
||||
@@ -864,6 +856,11 @@ fmt_value :: proc(fi: ^FmtInfo, v: any, verb: rune) {
|
||||
|
||||
|
||||
case Struct:
|
||||
if info.is_raw_union {
|
||||
write_string(fi.buf, "(raw_union)");
|
||||
return;
|
||||
}
|
||||
|
||||
write_byte(fi.buf, '{');
|
||||
defer write_byte(fi.buf, '}');
|
||||
|
||||
@@ -891,10 +888,6 @@ fmt_value :: proc(fi: ^FmtInfo, v: any, verb: rune) {
|
||||
fmt_arg(fi, any{data, ti}, verb);
|
||||
}
|
||||
|
||||
|
||||
case RawUnion:
|
||||
write_string(fi.buf, "(raw_union)");
|
||||
|
||||
case Enum:
|
||||
fmt_enum(fi, v, verb);
|
||||
|
||||
|
||||
@@ -245,8 +245,6 @@ align_of_type_info :: proc(type_info: ^TypeInfo) -> int {
|
||||
return type_info.align;
|
||||
case Union:
|
||||
return type_info.align;
|
||||
case RawUnion:
|
||||
return type_info.align;
|
||||
case Enum:
|
||||
return align_of_type_info(info.base);
|
||||
case Map:
|
||||
@@ -305,8 +303,6 @@ size_of_type_info :: proc(type_info: ^TypeInfo) -> int {
|
||||
return type_info.size;
|
||||
case Union:
|
||||
return type_info.size;
|
||||
case RawUnion:
|
||||
return type_info.size;
|
||||
case Enum:
|
||||
return size_of_type_info(info.base);
|
||||
case Map:
|
||||
|
||||
@@ -83,19 +83,19 @@ is_tuple :: proc(info: ^TypeInfo) -> bool {
|
||||
}
|
||||
is_struct :: proc(info: ^TypeInfo) -> bool {
|
||||
if info == nil do return false;
|
||||
_, ok := type_info_base(info).variant.(TypeInfo.Struct);
|
||||
return ok;
|
||||
s, ok := type_info_base(info).variant.(TypeInfo.Struct);
|
||||
return ok && !s.is_raw_union;
|
||||
}
|
||||
is_raw_union :: proc(info: ^TypeInfo) -> bool {
|
||||
if info == nil do return false;
|
||||
s, ok := type_info_base(info).variant.(TypeInfo.Struct);
|
||||
return ok && s.is_raw_union;
|
||||
}
|
||||
is_union :: proc(info: ^TypeInfo) -> bool {
|
||||
if info == nil do return false;
|
||||
_, ok := type_info_base(info).variant.(TypeInfo.Union);
|
||||
return ok;
|
||||
}
|
||||
is_raw_union :: proc(info: ^TypeInfo) -> bool {
|
||||
if info == nil do return false;
|
||||
_, ok := type_info_base(info).variant.(TypeInfo.RawUnion);
|
||||
return ok;
|
||||
}
|
||||
is_enum :: proc(info: ^TypeInfo) -> bool {
|
||||
if info == nil do return false;
|
||||
_, ok := type_info_base(info).variant.(TypeInfo.Enum);
|
||||
|
||||
@@ -686,7 +686,7 @@ void check_proc_body(Checker *c, Token token, DeclInfo *decl, Type *type, AstNod
|
||||
GB_ASSERT(type->kind == Type_Proc);
|
||||
if (type->Proc.param_count > 0) {
|
||||
TypeTuple *params = &type->Proc.params->Tuple;
|
||||
for (isize i = 0; i < params->variable_count; i++) {
|
||||
for_array(i, params->variables) {
|
||||
Entity *e = params->variables[i];
|
||||
if (e->kind != Entity_Variable) {
|
||||
continue;
|
||||
|
||||
@@ -519,7 +519,7 @@ i64 check_distance_between_types(Checker *c, Operand *operand, Type *type) {
|
||||
}
|
||||
|
||||
if (is_type_union(dst)) {
|
||||
for (isize i = 0; i < dst->Union.variant_count; i++) {
|
||||
for_array(i, dst->Union.variants) {
|
||||
Type *vt = dst->Union.variants[i];
|
||||
if (are_types_identical(vt, s)) {
|
||||
return 1;
|
||||
@@ -851,8 +851,7 @@ void check_record_field_decl(Checker *c, AstNode *decl, Array<Entity *> *fields,
|
||||
} else {
|
||||
if (o.mode == Addressing_Value && o.type->kind == Type_Tuple) {
|
||||
// NOTE(bill): Tuples are not first class thus never named
|
||||
isize count = o.type->Tuple.variable_count;
|
||||
for (isize index = 0; index < count; index++) {
|
||||
for_array(index, o.type->Tuple.variables) {
|
||||
Operand single = {Addressing_Value};
|
||||
single.type = o.type->Tuple.variables[index]->type;
|
||||
single.expr = v;
|
||||
@@ -1200,9 +1199,7 @@ void check_struct_type(Checker *c, Type *struct_type, AstNode *node, Array<Opera
|
||||
|
||||
if (entities.count > 0) {
|
||||
Type *tuple = make_type_tuple(c->allocator);
|
||||
tuple->Tuple.variables = entities.data;
|
||||
tuple->Tuple.variable_count = entities.count;
|
||||
|
||||
tuple->Tuple.variables = entities;
|
||||
polymorphic_params = tuple;
|
||||
}
|
||||
}
|
||||
@@ -1314,7 +1311,7 @@ void check_union_type(Checker *c, Type *named_type, Type *union_type, AstNode *n
|
||||
GB_ASSERT(is_type_union(union_type));
|
||||
ast_node(ut, UnionType, node);
|
||||
|
||||
isize variant_count = ut->variants.count+1;
|
||||
isize variant_count = ut->variants.count;
|
||||
|
||||
gbTempArenaMemory tmp = gb_temp_arena_memory_begin(&c->tmp_arena);
|
||||
defer (gb_temp_arena_memory_end(tmp));
|
||||
@@ -1323,9 +1320,8 @@ void check_union_type(Checker *c, Type *named_type, Type *union_type, AstNode *n
|
||||
|
||||
Array<Type *> variants = {};
|
||||
array_init(&variants, c->allocator, variant_count);
|
||||
array_add(&variants, t_invalid);
|
||||
|
||||
union_type->Union.scope = c->context.scope;
|
||||
union_type->Union.scope = c->context.scope;
|
||||
|
||||
for_array(i, ut->variants) {
|
||||
AstNode *node = ut->variants[i];
|
||||
@@ -1356,8 +1352,7 @@ void check_union_type(Checker *c, Type *named_type, Type *union_type, AstNode *n
|
||||
}
|
||||
}
|
||||
|
||||
union_type->Union.variants = variants.data;
|
||||
union_type->Union.variant_count = variants.count;
|
||||
union_type->Union.variants = variants;
|
||||
}
|
||||
|
||||
// void check_raw_union_type(Checker *c, Type *union_type, AstNode *node) {
|
||||
@@ -1655,8 +1650,8 @@ bool check_type_specialization_to(Checker *c, Type *specialization, Type *type,
|
||||
|
||||
TypeTuple *s_tuple = &s->Record.polymorphic_params->Tuple;
|
||||
TypeTuple *t_tuple = &t->Record.polymorphic_params->Tuple;
|
||||
GB_ASSERT(t_tuple->variable_count == s_tuple->variable_count);
|
||||
for (isize i = 0; i < s_tuple->variable_count; i++) {
|
||||
GB_ASSERT(t_tuple->variables.count == s_tuple->variables.count);
|
||||
for_array(i, s_tuple->variables) {
|
||||
Entity *s_e = s_tuple->variables[i];
|
||||
Entity *t_e = t_tuple->variables[i];
|
||||
Type *st = s_e->type;
|
||||
@@ -1748,10 +1743,10 @@ bool is_polymorphic_type_assignable(Checker *c, Type *poly, Type *source, bool c
|
||||
if (source->kind == Type_Union) {
|
||||
TypeUnion *x = &poly->Union;
|
||||
TypeUnion *y = &source->Union;
|
||||
if (x->variant_count != y->variant_count) {
|
||||
if (x->variants.count != y->variants.count) {
|
||||
return false;
|
||||
}
|
||||
for (isize i = 1; i < x->variant_count; i++) {
|
||||
for_array(i, x->variants) {
|
||||
Type *a = x->variants[i];
|
||||
Type *b = y->variants[i];
|
||||
bool ok = is_polymorphic_type_assignable(c, a, b, false, modify_type);
|
||||
@@ -1887,8 +1882,8 @@ Type *check_get_params(Checker *c, Scope *scope, AstNode *_params, bool *is_vari
|
||||
|
||||
bool is_variadic = false;
|
||||
bool is_c_vararg = false;
|
||||
Entity **variables = gb_alloc_array(c->allocator, Entity *, variable_count);
|
||||
isize variable_index = 0;
|
||||
Array<Entity *> variables = {};
|
||||
array_init(&variables, c->allocator, variable_count);
|
||||
for_array(i, params) {
|
||||
AstNode *param = params[i];
|
||||
if (param->kind != AstNode_Field) {
|
||||
@@ -2033,7 +2028,7 @@ Type *check_get_params(Checker *c, Scope *scope, AstNode *_params, bool *is_vari
|
||||
Entity *param = nullptr;
|
||||
if (is_type_param) {
|
||||
if (operands != nullptr) {
|
||||
Operand o = (*operands)[variable_index];
|
||||
Operand o = (*operands)[variables.count];
|
||||
if (o.mode == Addressing_Type) {
|
||||
type = o.type;
|
||||
} else {
|
||||
@@ -2067,7 +2062,7 @@ Type *check_get_params(Checker *c, Scope *scope, AstNode *_params, bool *is_vari
|
||||
param->TypeName.is_type_alias = true;
|
||||
} else {
|
||||
if (operands != nullptr && is_type_polymorphic_type) {
|
||||
Operand op = (*operands)[variable_index];
|
||||
Operand op = (*operands)[variables.count];
|
||||
type = determine_type_from_polymorphic(c, type, op);
|
||||
if (type == t_invalid) {
|
||||
success = false;
|
||||
@@ -2093,11 +2088,10 @@ Type *check_get_params(Checker *c, Scope *scope, AstNode *_params, bool *is_vari
|
||||
}
|
||||
|
||||
add_entity(c, scope, name, param);
|
||||
variables[variable_index++] = param;
|
||||
array_add(&variables, param);
|
||||
}
|
||||
}
|
||||
|
||||
variable_count = variable_index;
|
||||
|
||||
if (is_variadic) {
|
||||
GB_ASSERT(params.count > 0);
|
||||
@@ -2113,7 +2107,6 @@ Type *check_get_params(Checker *c, Scope *scope, AstNode *_params, bool *is_vari
|
||||
|
||||
Type *tuple = make_type_tuple(c->allocator);
|
||||
tuple->Tuple.variables = variables;
|
||||
tuple->Tuple.variable_count = variable_count;
|
||||
|
||||
if (success_) *success_ = success;
|
||||
if (is_variadic_) *is_variadic_ = is_variadic;
|
||||
@@ -2142,8 +2135,8 @@ Type *check_get_results(Checker *c, Scope *scope, AstNode *_results) {
|
||||
}
|
||||
}
|
||||
|
||||
Entity **variables = gb_alloc_array(c->allocator, Entity *, variable_count);
|
||||
isize variable_index = 0;
|
||||
Array<Entity *> variables = {};
|
||||
array_init(&variables, c->allocator, variable_count);
|
||||
for_array(i, results) {
|
||||
ast_node(field, Field, results[i]);
|
||||
AstNode *default_value = unparen_expr(field->default_value);
|
||||
@@ -2197,7 +2190,7 @@ Type *check_get_results(Checker *c, Scope *scope, AstNode *_results) {
|
||||
Entity *param = make_entity_param(c->allocator, scope, token, type, false, false);
|
||||
param->Variable.default_value = value;
|
||||
param->Variable.default_is_nil = default_is_nil;
|
||||
variables[variable_index++] = param;
|
||||
array_add(&variables, param);
|
||||
} else {
|
||||
for_array(j, field->names) {
|
||||
Token token = ast_node_token(results[i]);
|
||||
@@ -2216,17 +2209,17 @@ Type *check_get_results(Checker *c, Scope *scope, AstNode *_results) {
|
||||
Entity *param = make_entity_param(c->allocator, scope, token, type, false, false);
|
||||
param->Variable.default_value = value;
|
||||
param->Variable.default_is_nil = default_is_nil;
|
||||
variables[variable_index++] = param;
|
||||
array_add(&variables, param);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (isize i = 0; i < variable_index; i++) {
|
||||
for_array(i, variables) {
|
||||
String x = variables[i]->token.string;
|
||||
if (x.len == 0 || is_blank_ident(x)) {
|
||||
continue;
|
||||
}
|
||||
for (isize j = i+1; j < variable_index; j++) {
|
||||
for (isize j = i+1; j < variables.count; j++) {
|
||||
String y = variables[j]->token.string;
|
||||
if (y.len == 0 || is_blank_ident(y)) {
|
||||
continue;
|
||||
@@ -2238,7 +2231,6 @@ Type *check_get_results(Checker *c, Scope *scope, AstNode *_results) {
|
||||
}
|
||||
|
||||
tuple->Tuple.variables = variables;
|
||||
tuple->Tuple.variable_count = variable_index;
|
||||
|
||||
return tuple;
|
||||
}
|
||||
@@ -2335,7 +2327,7 @@ Type *type_to_abi_compat_param_type(gbAllocator a, Type *original_type) {
|
||||
Type *reduce_tuple_to_single_type(Type *original_type) {
|
||||
if (original_type != nullptr) {
|
||||
Type *t = core_type(original_type);
|
||||
if (t->kind == Type_Tuple && t->Tuple.variable_count == 1) {
|
||||
if (t->kind == Type_Tuple && t->Tuple.variables.count == 1) {
|
||||
return t->Tuple.variables[0]->type;
|
||||
}
|
||||
}
|
||||
@@ -2384,9 +2376,10 @@ Type *type_to_abi_compat_result_type(gbAllocator a, Type *original_type) {
|
||||
|
||||
if (new_type != original_type) {
|
||||
Type *tuple = make_type_tuple(a);
|
||||
tuple->Tuple.variable_count = 1;
|
||||
tuple->Tuple.variables = gb_alloc_array(a, Entity *, 1);
|
||||
tuple->Tuple.variables[0] = make_entity_param(a, original_type->Tuple.variables[0]->scope, empty_token, new_type, false, false);
|
||||
Array<Entity *> variables = {};
|
||||
array_init(&variables, a, 1);
|
||||
array_add(&variables, make_entity_param(a, original_type->Tuple.variables[0]->scope, empty_token, new_type, false, false));
|
||||
tuple->Tuple.variables = variables;
|
||||
new_type = tuple;
|
||||
}
|
||||
|
||||
@@ -2437,8 +2430,8 @@ bool check_procedure_type(Checker *c, Type *type, AstNode *proc_type_node, Array
|
||||
|
||||
isize param_count = 0;
|
||||
isize result_count = 0;
|
||||
if (params) param_count = params ->Tuple.variable_count;
|
||||
if (results) result_count = results->Tuple.variable_count;
|
||||
if (params) param_count = params ->Tuple.variables.count;
|
||||
if (results) result_count = results->Tuple.variables.count;
|
||||
|
||||
type->Proc.node = proc_type_node;
|
||||
type->Proc.scope = c->context.scope;
|
||||
@@ -2719,10 +2712,9 @@ i64 check_array_or_map_count(Checker *c, AstNode *e, bool is_map) {
|
||||
Type *make_optional_ok_type(gbAllocator a, Type *value) {
|
||||
bool typed = true;
|
||||
Type *t = make_type_tuple(a);
|
||||
t->Tuple.variables = gb_alloc_array(a, Entity *, 2);
|
||||
t->Tuple.variable_count = 2;
|
||||
t->Tuple.variables[0] = make_entity_field(a, nullptr, blank_token, value, false, 0);
|
||||
t->Tuple.variables[1] = make_entity_field(a, nullptr, blank_token, typed ? t_bool : t_untyped_bool, false, 1);
|
||||
array_init(&t->Tuple.variables, a, 2);
|
||||
array_add (&t->Tuple.variables, make_entity_field(a, nullptr, blank_token, value, false, 0));
|
||||
array_add (&t->Tuple.variables, make_entity_field(a, nullptr, blank_token, typed ? t_bool : t_untyped_bool, false, 1));
|
||||
return t;
|
||||
}
|
||||
|
||||
@@ -4304,11 +4296,11 @@ void convert_to_typed(Checker *c, Operand *operand, Type *target_type, i32 level
|
||||
{
|
||||
gbTempArenaMemory tmp = gb_temp_arena_memory_begin(&c->tmp_arena);
|
||||
defer (gb_temp_arena_memory_end(tmp));
|
||||
i32 count = t->Union.variant_count;
|
||||
isize count = t->Union.variants.count;
|
||||
i64 *scores = gb_alloc_array(c->tmp_allocator, i64, count);
|
||||
i32 success_count = 0;
|
||||
i32 first_success_index = -1;
|
||||
for (i32 i = 1; i < count; i++) {
|
||||
for_array(i, t->Union.variants) {
|
||||
Type *vt = t->Union.variants[i];
|
||||
i64 score = 0;
|
||||
if (check_is_assignable_to_with_score(c, operand, vt, &score)) {
|
||||
@@ -4358,14 +4350,14 @@ void convert_to_typed(Checker *c, Operand *operand, Type *target_type, i32 level
|
||||
} else if (!is_type_untyped_nil(operand->type) || !type_has_nil(target_type)) {
|
||||
operand->mode = Addressing_Invalid;
|
||||
convert_untyped_error(c, operand, target_type);
|
||||
if (count > 1) {
|
||||
if (count > 0) {
|
||||
gb_printf_err("`%s` is a union which only excepts the following types:\n", type_str);
|
||||
gb_printf_err("\t");
|
||||
for (i32 i = 1; i < count; i++) {
|
||||
for (i32 i = 0; i < count; i++) {
|
||||
Type *v = t->Union.variants[i];
|
||||
if (i > 1 && count > 3) gb_printf_err(", ");
|
||||
if (i > 0 && count > 2) gb_printf_err(", ");
|
||||
if (i == count-1) {
|
||||
if (count == 3) {
|
||||
if (count == 2) {
|
||||
gb_printf_err(" or ");
|
||||
} else {
|
||||
gb_printf_err("or ");
|
||||
@@ -4692,7 +4684,7 @@ Entity *check_selector(Checker *c, Operand *operand, AstNode *node, Type *type_h
|
||||
i64 max_count = 0;
|
||||
switch (type->kind) {
|
||||
case Type_Record: max_count = type->Record.field_count; break;
|
||||
case Type_Tuple: max_count = type->Tuple.variable_count; break;
|
||||
case Type_Tuple: max_count = type->Tuple.variables.count; break;
|
||||
}
|
||||
|
||||
if (index >= max_count) {
|
||||
@@ -5591,11 +5583,9 @@ bool check_builtin_procedure(Checker *c, Operand *operand, AstNode *call, i32 id
|
||||
|
||||
Type *tuple = make_type_tuple(a);
|
||||
i32 variable_count = type->Record.field_count;
|
||||
tuple->Tuple.variables = gb_alloc_array(a, Entity *, variable_count);
|
||||
tuple->Tuple.variable_count = variable_count;
|
||||
|
||||
array_init_count(&tuple->Tuple.variables, a, variable_count);
|
||||
// TODO(bill): Should I copy each of the entities or is this good enough?
|
||||
gb_memcopy_array(tuple->Tuple.variables, type->Record.fields_in_src_order, variable_count);
|
||||
gb_memcopy_array(tuple->Tuple.variables.data, type->Record.fields_in_src_order, variable_count);
|
||||
|
||||
operand->type = tuple;
|
||||
operand->mode = Addressing_Value;
|
||||
@@ -5957,7 +5947,7 @@ bool check_unpack_arguments(Checker *c, isize lhs_count, Array<Operand> *operand
|
||||
}
|
||||
} else {
|
||||
TypeTuple *tuple = &o.type->Tuple;
|
||||
for (isize j = 0; j < tuple->variable_count; j++) {
|
||||
for_array(j, tuple->variables) {
|
||||
o.type = tuple->variables[j]->type;
|
||||
array_add(operands, o);
|
||||
}
|
||||
@@ -5988,7 +5978,7 @@ CALL_ARGUMENT_CHECKER(check_call_arguments_internal) {
|
||||
if (pt->params != nullptr) {
|
||||
param_tuple = &pt->params->Tuple;
|
||||
|
||||
param_count = param_tuple->variable_count;
|
||||
param_count = param_tuple->variables.count;
|
||||
if (variadic) {
|
||||
param_count--;
|
||||
}
|
||||
@@ -6069,7 +6059,7 @@ CALL_ARGUMENT_CHECKER(check_call_arguments_internal) {
|
||||
TypeProc *pt = &final_proc_type->Proc;
|
||||
|
||||
GB_ASSERT(pt->params != nullptr);
|
||||
Entity **sig_params = pt->params->Tuple.variables;
|
||||
auto sig_params = pt->params->Tuple.variables;
|
||||
isize operand_index = 0;
|
||||
isize max_operand_count = gb_min(param_count, operands.count);
|
||||
for (; operand_index < max_operand_count; operand_index++) {
|
||||
@@ -6564,8 +6554,7 @@ isize lookup_polymorphic_struct_parameter(TypeRecord *st, String parameter_name)
|
||||
if (!st->is_polymorphic) return -1;
|
||||
|
||||
TypeTuple *params = &st->polymorphic_params->Tuple;
|
||||
isize param_count = params->variable_count;
|
||||
for (isize i = 0; i < param_count; i++) {
|
||||
for_array(i, params->variables) {
|
||||
Entity *e = params->variables[i];
|
||||
String name = e->token.string;
|
||||
if (is_blank_ident(name)) {
|
||||
@@ -6617,7 +6606,7 @@ CallArgumentError check_polymorphic_struct_type(Checker *c, Operand *operand, As
|
||||
CallArgumentError err = CallArgumentError_None;
|
||||
|
||||
TypeTuple *tuple = &st->polymorphic_params->Tuple;
|
||||
isize param_count = tuple->variable_count;
|
||||
isize param_count = tuple->variables.count;
|
||||
|
||||
Array<Operand> ordered_operands = operands;
|
||||
if (named_fields) {
|
||||
@@ -6749,7 +6738,7 @@ CallArgumentError check_polymorphic_struct_type(Checker *c, Operand *operand, As
|
||||
Type *t = base_type(e->type);
|
||||
TypeTuple *tuple = &t->Record.polymorphic_params->Tuple;
|
||||
bool ok = true;
|
||||
GB_ASSERT(param_count == tuple->variable_count);
|
||||
GB_ASSERT(param_count == tuple->variables.count);
|
||||
for (isize j = 0; j < param_count; j++) {
|
||||
Entity *p = tuple->variables[j];
|
||||
Operand o = ordered_operands[j];
|
||||
@@ -6968,7 +6957,7 @@ ExprKind check_call_expr(Checker *c, Operand *operand, AstNode *call) {
|
||||
operand->mode = Addressing_NoValue;
|
||||
} else {
|
||||
GB_ASSERT(is_type_tuple(result_type));
|
||||
switch (result_type->Tuple.variable_count) {
|
||||
switch (result_type->Tuple.variables.count) {
|
||||
case 0:
|
||||
operand->mode = Addressing_NoValue;
|
||||
break;
|
||||
@@ -7736,7 +7725,7 @@ ExprKind check_expr_base_internal(Checker *c, Operand *o, AstNode *node, Type *t
|
||||
|
||||
if (is_type_union(src)) {
|
||||
bool ok = false;
|
||||
for (isize i = 1; i < bsrc->Union.variant_count; i++) {
|
||||
for_array(i, bsrc->Union.variants) {
|
||||
Type *vt = bsrc->Union.variants[i];
|
||||
if (are_types_identical(vt, dst)) {
|
||||
ok = true;
|
||||
@@ -8120,7 +8109,7 @@ void check_not_tuple(Checker *c, Operand *o) {
|
||||
if (o->mode == Addressing_Value) {
|
||||
// NOTE(bill): Tuples are not first class thus never named
|
||||
if (o->type->kind == Type_Tuple) {
|
||||
isize count = o->type->Tuple.variable_count;
|
||||
isize count = o->type->Tuple.variables.count;
|
||||
GB_ASSERT(count != 1);
|
||||
error(o->expr,
|
||||
"%td-valued tuple found where single value expected", count);
|
||||
@@ -8192,6 +8181,10 @@ gbString write_expr_to_string(gbString str, AstNode *node) {
|
||||
str = gb_string_append_length(str, &bd->name[0], bd->name.len);
|
||||
case_end;
|
||||
|
||||
case_ast_node(ud, Undef, node);
|
||||
str = gb_string_appendc(str, "---");
|
||||
case_end;
|
||||
|
||||
case_ast_node(pl, ProcLit, node);
|
||||
str = write_expr_to_string(str, pl->type);
|
||||
case_end;
|
||||
|
||||
@@ -817,7 +817,7 @@ void check_stmt_internal(Checker *c, AstNode *node, u32 flags) {
|
||||
TypeProc *pt = &proc_type->Proc;
|
||||
isize result_count = 0;
|
||||
if (pt->results) {
|
||||
result_count = proc_type->Proc.results->Tuple.variable_count;
|
||||
result_count = proc_type->Proc.results->Tuple.variables.count;
|
||||
}
|
||||
|
||||
|
||||
@@ -1474,7 +1474,7 @@ void check_stmt_internal(Checker *c, AstNode *node, u32 flags) {
|
||||
if (match_type_kind == MatchType_Union) {
|
||||
GB_ASSERT(is_type_union(bt));
|
||||
bool tag_type_found = false;
|
||||
for (isize i = 0; i < bt->Union.variant_count; i++) {
|
||||
for_array(i, bt->Union.variants) {
|
||||
Type *vt = bt->Union.variants[i];
|
||||
if (are_types_identical(vt, y.type)) {
|
||||
tag_type_found = true;
|
||||
|
||||
@@ -1169,7 +1169,7 @@ void add_type_info_type(Checker *c, Type *t) {
|
||||
|
||||
case Type_Union:
|
||||
add_type_info_type(c, t_int);
|
||||
for (isize i = 0; i < bt->Union.variant_count; i++) {
|
||||
for_array(i, bt->Union.variants) {
|
||||
add_type_info_type(c, bt->Union.variants[i]);
|
||||
}
|
||||
break;
|
||||
@@ -1188,7 +1188,7 @@ void add_type_info_type(Checker *c, Type *t) {
|
||||
} break;
|
||||
|
||||
case Type_Tuple:
|
||||
for (isize i = 0; i < bt->Tuple.variable_count; i++) {
|
||||
for_array(i, bt->Tuple.variables) {
|
||||
Entity *var = bt->Tuple.variables[i];
|
||||
add_type_info_type(c, var->type);
|
||||
}
|
||||
@@ -1341,12 +1341,8 @@ void init_preload(Checker *c) {
|
||||
GB_ASSERT(is_type_struct(type_info_entity->type));
|
||||
TypeRecord *record = &base_type(type_info_entity->type)->Record;
|
||||
|
||||
Entity *type_info_record = find_sub_core_entity(record, str_lit("Record"));
|
||||
Entity *type_info_enum_value = find_sub_core_entity(record, str_lit("EnumValue"));
|
||||
|
||||
|
||||
t_type_info_record = type_info_record->type;
|
||||
t_type_info_record_ptr = make_type_pointer(c->allocator, t_type_info_record);
|
||||
t_type_info_enum_value = type_info_enum_value->type;
|
||||
t_type_info_enum_value_ptr = make_type_pointer(c->allocator, t_type_info_enum_value);
|
||||
|
||||
@@ -1357,30 +1353,29 @@ void init_preload(Checker *c) {
|
||||
GB_ASSERT(is_type_union(tiv_type));
|
||||
TypeUnion *tiv = &tiv_type->Union;
|
||||
|
||||
if (tiv->variant_count != 22) {
|
||||
if (tiv->variants.count != 20) {
|
||||
compiler_error("Invalid `TypeInfo` layout");
|
||||
}
|
||||
t_type_info_named = tiv->variants[ 1];
|
||||
t_type_info_integer = tiv->variants[ 2];
|
||||
t_type_info_rune = tiv->variants[ 3];
|
||||
t_type_info_float = tiv->variants[ 4];
|
||||
t_type_info_complex = tiv->variants[ 5];
|
||||
t_type_info_string = tiv->variants[ 6];
|
||||
t_type_info_boolean = tiv->variants[ 7];
|
||||
t_type_info_any = tiv->variants[ 8];
|
||||
t_type_info_pointer = tiv->variants[ 9];
|
||||
t_type_info_procedure = tiv->variants[10];
|
||||
t_type_info_array = tiv->variants[11];
|
||||
t_type_info_dynamic_array = tiv->variants[12];
|
||||
t_type_info_slice = tiv->variants[13];
|
||||
t_type_info_vector = tiv->variants[14];
|
||||
t_type_info_tuple = tiv->variants[15];
|
||||
t_type_info_struct = tiv->variants[16];
|
||||
t_type_info_raw_union = tiv->variants[17];
|
||||
t_type_info_union = tiv->variants[18];
|
||||
t_type_info_enum = tiv->variants[19];
|
||||
t_type_info_map = tiv->variants[20];
|
||||
t_type_info_bit_field = tiv->variants[21];
|
||||
t_type_info_named = tiv->variants[ 0];
|
||||
t_type_info_integer = tiv->variants[ 1];
|
||||
t_type_info_rune = tiv->variants[ 2];
|
||||
t_type_info_float = tiv->variants[ 3];
|
||||
t_type_info_complex = tiv->variants[ 4];
|
||||
t_type_info_string = tiv->variants[ 5];
|
||||
t_type_info_boolean = tiv->variants[ 6];
|
||||
t_type_info_any = tiv->variants[ 7];
|
||||
t_type_info_pointer = tiv->variants[ 8];
|
||||
t_type_info_procedure = tiv->variants[ 9];
|
||||
t_type_info_array = tiv->variants[10];
|
||||
t_type_info_dynamic_array = tiv->variants[11];
|
||||
t_type_info_slice = tiv->variants[12];
|
||||
t_type_info_vector = tiv->variants[13];
|
||||
t_type_info_tuple = tiv->variants[14];
|
||||
t_type_info_struct = tiv->variants[15];
|
||||
t_type_info_union = tiv->variants[16];
|
||||
t_type_info_enum = tiv->variants[17];
|
||||
t_type_info_map = tiv->variants[18];
|
||||
t_type_info_bit_field = tiv->variants[19];
|
||||
|
||||
t_type_info_named_ptr = make_type_pointer(c->allocator, t_type_info_named);
|
||||
t_type_info_integer_ptr = make_type_pointer(c->allocator, t_type_info_integer);
|
||||
@@ -1398,7 +1393,6 @@ void init_preload(Checker *c) {
|
||||
t_type_info_vector_ptr = make_type_pointer(c->allocator, t_type_info_vector);
|
||||
t_type_info_tuple_ptr = make_type_pointer(c->allocator, t_type_info_tuple);
|
||||
t_type_info_struct_ptr = make_type_pointer(c->allocator, t_type_info_struct);
|
||||
t_type_info_raw_union_ptr = make_type_pointer(c->allocator, t_type_info_raw_union);
|
||||
t_type_info_union_ptr = make_type_pointer(c->allocator, t_type_info_union);
|
||||
t_type_info_enum_ptr = make_type_pointer(c->allocator, t_type_info_enum);
|
||||
t_type_info_map_ptr = make_type_pointer(c->allocator, t_type_info_map);
|
||||
|
||||
167
src/ir.cpp
167
src/ir.cpp
@@ -617,7 +617,7 @@ Type *ir_instr_type(irInstr *instr) {
|
||||
case irInstr_Call: {
|
||||
Type *pt = base_type(instr->Call.type);
|
||||
if (pt != nullptr) {
|
||||
if (pt->kind == Type_Tuple && pt->Tuple.variable_count == 1) {
|
||||
if (pt->kind == Type_Tuple && pt->Tuple.variables.count == 1) {
|
||||
return pt->Tuple.variables[0]->type;
|
||||
}
|
||||
return pt;
|
||||
@@ -2382,8 +2382,7 @@ irValue *ir_emit_struct_ep(irProcedure *proc, irValue *s, i32 index) {
|
||||
GB_ASSERT(index == -1);
|
||||
return ir_emit_union_tag_ptr(proc, s);
|
||||
} else if (is_type_tuple(t)) {
|
||||
GB_ASSERT(t->Tuple.variable_count > 0);
|
||||
GB_ASSERT(gb_is_between(index, 0, t->Tuple.variable_count-1));
|
||||
GB_ASSERT(t->Tuple.variables.count > 0);
|
||||
result_type = make_type_pointer(a, t->Tuple.variables[index]->type);
|
||||
} else if (is_type_complex(t)) {
|
||||
Type *ft = base_complex_elem_type(t);
|
||||
@@ -2445,8 +2444,7 @@ irValue *ir_emit_struct_ev(irProcedure *proc, irValue *s, i32 index) {
|
||||
GB_ASSERT(index == -1);
|
||||
return ir_emit_union_tag_value(proc, s);
|
||||
} else if (is_type_tuple(t)) {
|
||||
GB_ASSERT(t->Tuple.variable_count > 0);
|
||||
GB_ASSERT(gb_is_between(index, 0, t->Tuple.variable_count-1));
|
||||
GB_ASSERT(t->Tuple.variables.count > 0);
|
||||
result_type = t->Tuple.variables[index]->type;
|
||||
} else if (is_type_complex(t)) {
|
||||
Type *ft = base_complex_elem_type(t);
|
||||
@@ -2960,7 +2958,7 @@ irValue *ir_emit_conv(irProcedure *proc, irValue *value, Type *t) {
|
||||
}
|
||||
|
||||
if (is_type_union(dst)) {
|
||||
for (isize i = 1; i < dst->Union.variant_count; i++) {
|
||||
for_array(i, dst->Union.variants) {
|
||||
Type *vt = dst->Union.variants[i];
|
||||
if (are_types_identical(vt, src_type)) {
|
||||
ir_emit_comment(proc, str_lit("union - child to parent"));
|
||||
@@ -4861,7 +4859,7 @@ irValue *ir_build_expr(irProcedure *proc, AstNode *expr) {
|
||||
AstNode *a = ce->args[i];
|
||||
Type *at = base_type(type_of_expr(proc->module->info, a));
|
||||
if (at->kind == Type_Tuple) {
|
||||
arg_count += at->Tuple.variable_count;
|
||||
arg_count += at->Tuple.variables.count;
|
||||
} else {
|
||||
arg_count++;
|
||||
}
|
||||
@@ -4882,7 +4880,7 @@ irValue *ir_build_expr(irProcedure *proc, AstNode *expr) {
|
||||
irValue *a = ir_build_expr(proc, arg);
|
||||
Type *at = ir_type(a);
|
||||
if (at->kind == Type_Tuple) {
|
||||
for (isize i = 0; i < at->Tuple.variable_count; i++) {
|
||||
for_array(i, at->Tuple.variables) {
|
||||
Entity *e = at->Tuple.variables[i];
|
||||
irValue *v = ir_emit_struct_ev(proc, a, i);
|
||||
args[arg_index++] = v;
|
||||
@@ -5129,7 +5127,7 @@ irAddr ir_build_addr(irProcedure *proc, AstNode *expr) {
|
||||
irValue *enum_info = ir_emit_conv(proc, ti_ptr, t_type_info_enum_ptr);
|
||||
names_ptr = ir_emit_struct_ep(proc, enum_info, 3);
|
||||
} else if (type->kind == Type_Record) {
|
||||
irValue *record_info = ir_emit_conv(proc, ti_ptr, t_type_info_record_ptr);
|
||||
irValue *record_info = ir_emit_conv(proc, ti_ptr, t_type_info_struct_ptr);
|
||||
names_ptr = ir_emit_struct_ep(proc, record_info, 3);
|
||||
}
|
||||
return ir_addr(names_ptr);
|
||||
@@ -6266,7 +6264,7 @@ void ir_build_stmt_internal(irProcedure *proc, AstNode *node) {
|
||||
irValue *init = ir_build_expr(proc, vd->values[i]);
|
||||
Type *t = ir_type(init);
|
||||
if (t->kind == Type_Tuple) {
|
||||
for (isize i = 0; i < t->Tuple.variable_count; i++) {
|
||||
for_array(i, t->Tuple.variables) {
|
||||
Entity *e = t->Tuple.variables[i];
|
||||
irValue *v = ir_emit_struct_ev(proc, init, i);
|
||||
array_add(&inits, v);
|
||||
@@ -6331,7 +6329,7 @@ void ir_build_stmt_internal(irProcedure *proc, AstNode *node) {
|
||||
Type *t = ir_type(init);
|
||||
// TODO(bill): refactor for code reuse as this is repeated a bit
|
||||
if (t->kind == Type_Tuple) {
|
||||
for (isize i = 0; i < t->Tuple.variable_count; i++) {
|
||||
for_array(i, t->Tuple.variables) {
|
||||
Entity *e = t->Tuple.variables[i];
|
||||
irValue *v = ir_emit_struct_ev(proc, init, i);
|
||||
array_add(&inits, v);
|
||||
@@ -6463,7 +6461,7 @@ void ir_build_stmt_internal(irProcedure *proc, AstNode *node) {
|
||||
irValue *res = ir_build_expr(proc, rs->results[res_index]);
|
||||
Type *t = ir_type(res);
|
||||
if (t->kind == Type_Tuple) {
|
||||
for (isize i = 0; i < t->Tuple.variable_count; i++) {
|
||||
for_array(i, t->Tuple.variables) {
|
||||
Entity *e = t->Tuple.variables[i];
|
||||
irValue *v = ir_emit_struct_ev(proc, res, i);
|
||||
array_add(&results, v);
|
||||
@@ -6934,7 +6932,7 @@ void ir_build_stmt_internal(irProcedure *proc, AstNode *node) {
|
||||
irValue *variant_tag = nullptr;
|
||||
Type *ut = base_type(type_deref(parent_type));
|
||||
GB_ASSERT(ut->kind == Type_Union);
|
||||
for (isize variant_index = 1; variant_index < ut->Union.variant_count; variant_index++) {
|
||||
for_array(variant_index, ut->Union.variants) {
|
||||
Type *vt = ut->Union.variants[variant_index];
|
||||
if (are_types_identical(vt, bt)) {
|
||||
variant_tag = ir_type_info(proc, vt);
|
||||
@@ -7154,7 +7152,7 @@ void ir_begin_procedure_body(irProcedure *proc) {
|
||||
isize q_index = 0;
|
||||
|
||||
TypeTuple *params = &proc->type->Proc.params->Tuple;
|
||||
for (isize i = 0; i < params->variable_count; i++) {
|
||||
for_array(i, params->variables) {
|
||||
ast_node(fl, FieldList, pt->params);
|
||||
GB_ASSERT(fl->list.count > 0);
|
||||
GB_ASSERT(fl->list[0]->kind == AstNode_Field);
|
||||
@@ -7340,13 +7338,13 @@ void ir_init_module(irModule *m, Checker *c) {
|
||||
|
||||
switch (t->kind) {
|
||||
case Type_Union:
|
||||
count += t->Union.variant_count;
|
||||
count += t->Union.variants.count;
|
||||
break;
|
||||
case Type_Record:
|
||||
count += t->Record.field_count;
|
||||
break;
|
||||
case Type_Tuple:
|
||||
count += t->Tuple.variable_count;
|
||||
count += t->Tuple.variables.count;
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -7718,11 +7716,8 @@ void ir_gen_tree(irGen *s) {
|
||||
|
||||
Scope *proc_scope = gb_alloc_item(a, Scope);
|
||||
|
||||
proc_params->Tuple.variables = gb_alloc_array(a, Entity *, 3);
|
||||
proc_params->Tuple.variable_count = 3;
|
||||
|
||||
proc_results->Tuple.variables = gb_alloc_array(a, Entity *, 1);
|
||||
proc_results->Tuple.variable_count = 1;
|
||||
array_init_count(&proc_params->Tuple.variables, a, 3);
|
||||
array_init_count(&proc_results->Tuple.variables, a, 1);
|
||||
|
||||
proc_params->Tuple.variables[0] = make_entity_param(a, proc_scope, blank_token, t_rawptr, false, false);
|
||||
proc_params->Tuple.variables[1] = make_entity_param(a, proc_scope, make_token_ident(str_lit("reason")), t_i32, false, false);
|
||||
@@ -8078,10 +8073,10 @@ void ir_gen_tree(irGen *s) {
|
||||
ir_emit_comment(proc, str_lit("TypeInfoTuple"));
|
||||
tag = ir_emit_conv(proc, variant_ptr, t_type_info_tuple_ptr);
|
||||
|
||||
irValue *memory_types = ir_type_info_member_types_offset(proc, t->Tuple.variable_count);
|
||||
irValue *memory_names = ir_type_info_member_names_offset(proc, t->Tuple.variable_count);
|
||||
irValue *memory_types = ir_type_info_member_types_offset(proc, t->Tuple.variables.count);
|
||||
irValue *memory_names = ir_type_info_member_names_offset(proc, t->Tuple.variables.count);
|
||||
|
||||
for (isize i = 0; i < t->Tuple.variable_count; i++) {
|
||||
for_array(i, t->Tuple.variables) {
|
||||
// NOTE(bill): offset is not used for tuples
|
||||
Entity *f = t->Tuple.variables[i];
|
||||
|
||||
@@ -8095,7 +8090,7 @@ void ir_gen_tree(irGen *s) {
|
||||
}
|
||||
}
|
||||
|
||||
irValue *count = ir_const_int(a, t->Tuple.variable_count);
|
||||
irValue *count = ir_const_int(a, t->Tuple.variables.count);
|
||||
ir_fill_slice(proc, ir_emit_struct_ep(proc, tag, 0), memory_types, count, count);
|
||||
ir_fill_slice(proc, ir_emit_struct_ep(proc, tag, 1), memory_names, count, count);
|
||||
} break;
|
||||
@@ -8152,12 +8147,12 @@ void ir_gen_tree(irGen *s) {
|
||||
irValue *variant_types = ir_emit_struct_ep(proc, tag, 0);
|
||||
irValue *tag_offset_ptr = ir_emit_struct_ep(proc, tag, 1);
|
||||
|
||||
isize variant_count = gb_max(0, t->Union.variant_count-1);
|
||||
isize variant_count = gb_max(0, t->Union.variants.count);
|
||||
irValue *memory_types = ir_type_info_member_types_offset(proc, variant_count);
|
||||
|
||||
// NOTE(bill): Zeroth is nil so ignore it
|
||||
for (isize variant_index = 0; variant_index < variant_count; variant_index++) {
|
||||
Type *vt = t->Union.variants[variant_index+1]; // Skip zeroth
|
||||
Type *vt = t->Union.variants[variant_index];
|
||||
irValue *tip = ir_get_type_info_ptr(proc, vt);
|
||||
|
||||
irValue *index = ir_const_int(a, variant_index);
|
||||
@@ -8175,77 +8170,57 @@ void ir_gen_tree(irGen *s) {
|
||||
} break;
|
||||
|
||||
case Type_Record: {
|
||||
if (t->Record.is_raw_union) {
|
||||
ir_emit_comment(proc, str_lit("TypeInfoRawUnion"));
|
||||
tag = ir_emit_conv(proc, variant_ptr, t_type_info_raw_union_ptr);
|
||||
ir_emit_comment(proc, str_lit("TypeInfoStruct"));
|
||||
tag = ir_emit_conv(proc, variant_ptr, t_type_info_struct_ptr);
|
||||
|
||||
irValue *memory_types = ir_type_info_member_types_offset(proc, t->Record.field_count);
|
||||
irValue *memory_names = ir_type_info_member_names_offset(proc, t->Record.field_count);
|
||||
irValue *memory_offsets = ir_type_info_member_offsets_offset(proc, t->Record.field_count);
|
||||
|
||||
for (isize i = 0; i < t->Record.field_count; i++) {
|
||||
Entity *f = t->Record.fields[i];
|
||||
irValue *index = ir_const_int(a, i);
|
||||
irValue *type_info = ir_emit_ptr_offset(proc, memory_types, index);
|
||||
// NOTE(bill): Offsets are always 0
|
||||
|
||||
ir_emit_store(proc, type_info, ir_type_info(proc, f->type));
|
||||
if (f->token.string.len > 0) {
|
||||
irValue *name = ir_emit_ptr_offset(proc, memory_names, index);
|
||||
ir_emit_store(proc, name, ir_const_string(a, f->token.string));
|
||||
}
|
||||
}
|
||||
|
||||
irValue *count = ir_const_int(a, t->Record.field_count);
|
||||
ir_fill_slice(proc, ir_emit_struct_ep(proc, tag, 0), memory_types, count, count);
|
||||
ir_fill_slice(proc, ir_emit_struct_ep(proc, tag, 1), memory_names, count, count);
|
||||
ir_fill_slice(proc, ir_emit_struct_ep(proc, tag, 2), memory_offsets, count, count);
|
||||
} else {
|
||||
ir_emit_comment(proc, str_lit("TypeInfoStruct"));
|
||||
tag = ir_emit_conv(proc, variant_ptr, t_type_info_struct_ptr);
|
||||
|
||||
{
|
||||
irValue *packed = ir_const_bool(a, t->Record.is_packed);
|
||||
irValue *ordered = ir_const_bool(a, t->Record.is_ordered);
|
||||
irValue *custom_align = ir_const_bool(a, t->Record.custom_align != 0);
|
||||
ir_emit_store(proc, ir_emit_struct_ep(proc, tag, 4), packed);
|
||||
ir_emit_store(proc, ir_emit_struct_ep(proc, tag, 5), ordered);
|
||||
ir_emit_store(proc, ir_emit_struct_ep(proc, tag, 6), custom_align);
|
||||
}
|
||||
|
||||
irValue *memory_types = ir_type_info_member_types_offset(proc, t->Record.field_count);
|
||||
irValue *memory_names = ir_type_info_member_names_offset(proc, t->Record.field_count);
|
||||
irValue *memory_offsets = ir_type_info_member_offsets_offset(proc, t->Record.field_count);
|
||||
irValue *memory_usings = ir_type_info_member_usings_offset(proc, t->Record.field_count);
|
||||
|
||||
type_set_offsets(a, t); // NOTE(bill): Just incase the offsets have not been set yet
|
||||
for (isize source_index = 0; source_index < t->Record.field_count; source_index++) {
|
||||
// TODO(bill): Order fields in source order not layout order
|
||||
Entity *f = t->Record.fields_in_src_order[source_index];
|
||||
irValue *tip = ir_get_type_info_ptr(proc, f->type);
|
||||
i64 foffset = t->Record.offsets[f->Variable.field_index];
|
||||
GB_ASSERT(f->kind == Entity_Variable && f->flags & EntityFlag_Field);
|
||||
|
||||
irValue *index = ir_const_int(a, source_index);
|
||||
irValue *type_info = ir_emit_ptr_offset(proc, memory_types, index);
|
||||
irValue *offset = ir_emit_ptr_offset(proc, memory_offsets, index);
|
||||
irValue *is_using = ir_emit_ptr_offset(proc, memory_usings, index);
|
||||
|
||||
ir_emit_store(proc, type_info, ir_type_info(proc, f->type));
|
||||
if (f->token.string.len > 0) {
|
||||
irValue *name = ir_emit_ptr_offset(proc, memory_names, index);
|
||||
ir_emit_store(proc, name, ir_const_string(a, f->token.string));
|
||||
}
|
||||
ir_emit_store(proc, offset, ir_const_int(a, foffset));
|
||||
ir_emit_store(proc, is_using, ir_const_bool(a, (f->flags&EntityFlag_Using) != 0));
|
||||
}
|
||||
|
||||
irValue *count = ir_const_int(a, t->Record.field_count);
|
||||
ir_fill_slice(proc, ir_emit_struct_ep(proc, tag, 0), memory_types, count, count);
|
||||
ir_fill_slice(proc, ir_emit_struct_ep(proc, tag, 1), memory_names, count, count);
|
||||
ir_fill_slice(proc, ir_emit_struct_ep(proc, tag, 2), memory_offsets, count, count);
|
||||
ir_fill_slice(proc, ir_emit_struct_ep(proc, tag, 3), memory_usings, count, count);
|
||||
{
|
||||
irValue *is_packed = ir_const_bool(a, t->Record.is_packed);
|
||||
irValue *is_ordered = ir_const_bool(a, t->Record.is_ordered);
|
||||
irValue *is_raw_union = ir_const_bool(a, t->Record.is_raw_union);
|
||||
irValue *is_custom_align = ir_const_bool(a, t->Record.custom_align != 0);
|
||||
ir_emit_store(proc, ir_emit_struct_ep(proc, tag, 4), is_packed);
|
||||
ir_emit_store(proc, ir_emit_struct_ep(proc, tag, 5), is_ordered);
|
||||
ir_emit_store(proc, ir_emit_struct_ep(proc, tag, 6), is_raw_union);
|
||||
ir_emit_store(proc, ir_emit_struct_ep(proc, tag, 7), is_custom_align);
|
||||
}
|
||||
|
||||
i32 count = t->Record.field_count;
|
||||
|
||||
irValue *memory_types = ir_type_info_member_types_offset (proc, count);
|
||||
irValue *memory_names = ir_type_info_member_names_offset (proc, count);
|
||||
irValue *memory_offsets = ir_type_info_member_offsets_offset(proc, count);
|
||||
irValue *memory_usings = ir_type_info_member_usings_offset (proc, count);
|
||||
|
||||
type_set_offsets(a, t); // NOTE(bill): Just incase the offsets have not been set yet
|
||||
for (isize source_index = 0; source_index < count; source_index++) {
|
||||
// TODO(bill): Order fields in source order not layout order
|
||||
Entity *f = t->Record.fields_in_src_order[source_index];
|
||||
irValue *tip = ir_get_type_info_ptr(proc, f->type);
|
||||
i64 foffset = 0;
|
||||
if (!t->Record.is_raw_union) {
|
||||
foffset = t->Record.offsets[f->Variable.field_index];
|
||||
}
|
||||
GB_ASSERT(f->kind == Entity_Variable && f->flags & EntityFlag_Field);
|
||||
|
||||
irValue *index = ir_const_int(a, source_index);
|
||||
irValue *type_info = ir_emit_ptr_offset(proc, memory_types, index);
|
||||
irValue *offset = ir_emit_ptr_offset(proc, memory_offsets, index);
|
||||
irValue *is_using = ir_emit_ptr_offset(proc, memory_usings, index);
|
||||
|
||||
ir_emit_store(proc, type_info, ir_type_info(proc, f->type));
|
||||
if (f->token.string.len > 0) {
|
||||
irValue *name = ir_emit_ptr_offset(proc, memory_names, index);
|
||||
ir_emit_store(proc, name, ir_const_string(a, f->token.string));
|
||||
}
|
||||
ir_emit_store(proc, offset, ir_const_int(a, foffset));
|
||||
ir_emit_store(proc, is_using, ir_const_bool(a, (f->flags&EntityFlag_Using) != 0));
|
||||
}
|
||||
|
||||
irValue *cv = ir_const_int(a, count);
|
||||
ir_fill_slice(proc, ir_emit_struct_ep(proc, tag, 0), memory_types, cv, cv);
|
||||
ir_fill_slice(proc, ir_emit_struct_ep(proc, tag, 1), memory_names, cv, cv);
|
||||
ir_fill_slice(proc, ir_emit_struct_ep(proc, tag, 2), memory_offsets, cv, cv);
|
||||
ir_fill_slice(proc, ir_emit_struct_ep(proc, tag, 3), memory_usings, cv, cv);
|
||||
} break;
|
||||
case Type_Map: {
|
||||
ir_emit_comment(proc, str_lit("TypeInfoMap"));
|
||||
|
||||
@@ -155,12 +155,11 @@ void ir_print_proc_results(irFileBuffer *f, irModule *m, Type *t) {
|
||||
Type *rt = t->Proc.abi_compat_result_type;
|
||||
if (!is_type_tuple(rt)) {
|
||||
ir_print_type(f, m, rt);
|
||||
} else if (rt->Tuple.variable_count == 1) {
|
||||
} else if (rt->Tuple.variables.count == 1) {
|
||||
ir_print_type(f, m, rt->Tuple.variables[0]->type);
|
||||
} else {
|
||||
isize count = rt->Tuple.variable_count;
|
||||
ir_fprintf(f, "{");
|
||||
for (isize i = 0; i < count; i++) {
|
||||
for_array(i, rt->Tuple.variables) {
|
||||
Entity *e = rt->Tuple.variables[i];
|
||||
if (i > 0) {
|
||||
ir_fprintf(f, ", ");
|
||||
@@ -344,15 +343,13 @@ void ir_print_type(irFileBuffer *f, irModule *m, Type *t) {
|
||||
}
|
||||
return;
|
||||
case Type_Tuple:
|
||||
if (t->Tuple.variable_count == 1) {
|
||||
if (t->Tuple.variables.count == 1) {
|
||||
ir_print_type(f, m, t->Tuple.variables[0]->type);
|
||||
} else {
|
||||
ir_fprintf(f, "{");
|
||||
isize index = 0;
|
||||
for (isize i = 0; i < t->Tuple.variable_count; i++) {
|
||||
if (index > 0) {
|
||||
ir_fprintf(f, ", ");
|
||||
}
|
||||
for_array(i, t->Tuple.variables) {
|
||||
if (index > 0) ir_fprintf(f, ", ");
|
||||
Entity *e = t->Tuple.variables[i];
|
||||
if (e->kind == Entity_Variable) {
|
||||
ir_print_type(f, m, e->type);
|
||||
@@ -1352,7 +1349,7 @@ void ir_print_instr(irFileBuffer *f, irModule *m, irValue *value) {
|
||||
TypeTuple *params = &proc_type->Proc.params->Tuple;
|
||||
if (proc_type->Proc.c_vararg) {
|
||||
isize i = 0;
|
||||
for (; i < params->variable_count-1; i++) {
|
||||
for (; i < params->variables.count-1; i++) {
|
||||
Entity *e = params->variables[i];
|
||||
GB_ASSERT(e != nullptr);
|
||||
if (e->kind != Entity_Variable) continue;
|
||||
@@ -1380,9 +1377,8 @@ void ir_print_instr(irFileBuffer *f, irModule *m, irValue *value) {
|
||||
param_index++;
|
||||
}
|
||||
} else {
|
||||
GB_ASSERT(call->arg_count == params->variable_count);
|
||||
isize param_count = params->variable_count;
|
||||
for (isize i = 0; i < param_count; i++) {
|
||||
GB_ASSERT(call->arg_count == params->variables.count);
|
||||
for_array(i, params->variables) {
|
||||
Entity *e = params->variables[i];
|
||||
GB_ASSERT(e != nullptr);
|
||||
if (e->kind != Entity_Variable) continue;
|
||||
@@ -1645,7 +1641,7 @@ void ir_print_proc(irFileBuffer *f, irModule *m, irProcedure *proc) {
|
||||
if (e->kind != Entity_Variable) continue;
|
||||
if (param_index > 0) ir_fprintf(f, ", ");
|
||||
|
||||
if (i+1 == params->variable_count && proc_type->c_vararg) {
|
||||
if (i+1 == params->variables.count && proc_type->c_vararg) {
|
||||
ir_fprintf(f, " ...");
|
||||
} else {
|
||||
ir_print_type(f, m, abi_type);
|
||||
|
||||
@@ -2291,34 +2291,37 @@ AstNode *parse_operand(AstFile *f, bool lhs) {
|
||||
Token token = expect_token(f, Token_proc);
|
||||
String link_name = {};
|
||||
AstNode *type = parse_proc_type(f, token, &link_name);
|
||||
|
||||
if (f->allow_type && f->expr_level < 0) {
|
||||
return type;
|
||||
}
|
||||
|
||||
u64 tags = type->ProcType.tags;
|
||||
|
||||
if (allow_token(f, Token_Undef)) {
|
||||
return ast_proc_lit(f, type, nullptr, tags, link_name);
|
||||
} else if (!f->allow_type || f->expr_level >= 0) {
|
||||
if (f->curr_token.kind == Token_OpenBrace) {
|
||||
if ((tags & ProcTag_foreign) != 0) {
|
||||
syntax_error(token, "A procedure tagged as `#foreign` cannot have a body");
|
||||
}
|
||||
AstNode *curr_proc = f->curr_proc;
|
||||
AstNode *body = nullptr;
|
||||
f->curr_proc = type;
|
||||
body = parse_body(f);
|
||||
f->curr_proc = curr_proc;
|
||||
|
||||
return ast_proc_lit(f, type, body, tags, link_name);
|
||||
} else if (allow_token(f, Token_do)) {
|
||||
if ((tags & ProcTag_foreign) != 0) {
|
||||
syntax_error(token, "A procedure tagged as `#foreign` cannot have a body");
|
||||
}
|
||||
AstNode *curr_proc = f->curr_proc;
|
||||
AstNode *body = nullptr;
|
||||
f->curr_proc = type;
|
||||
body = convert_stmt_to_body(f, parse_stmt(f));
|
||||
f->curr_proc = curr_proc;
|
||||
|
||||
return ast_proc_lit(f, type, body, tags, link_name);
|
||||
} else if (f->curr_token.kind == Token_OpenBrace) {
|
||||
if ((tags & ProcTag_foreign) != 0) {
|
||||
syntax_error(token, "A procedure tagged as `#foreign` cannot have a body");
|
||||
}
|
||||
AstNode *curr_proc = f->curr_proc;
|
||||
AstNode *body = nullptr;
|
||||
f->curr_proc = type;
|
||||
body = parse_body(f);
|
||||
f->curr_proc = curr_proc;
|
||||
|
||||
return ast_proc_lit(f, type, body, tags, link_name);
|
||||
} else if (allow_token(f, Token_do)) {
|
||||
if ((tags & ProcTag_foreign) != 0) {
|
||||
syntax_error(token, "A procedure tagged as `#foreign` cannot have a body");
|
||||
}
|
||||
AstNode *curr_proc = f->curr_proc;
|
||||
AstNode *body = nullptr;
|
||||
f->curr_proc = type;
|
||||
body = convert_stmt_to_body(f, parse_stmt(f));
|
||||
f->curr_proc = curr_proc;
|
||||
|
||||
return ast_proc_lit(f, type, body, tags, link_name);
|
||||
}
|
||||
|
||||
if ((tags & ProcTag_foreign) != 0) {
|
||||
|
||||
18
src/ssa.cpp
18
src/ssa.cpp
@@ -639,10 +639,10 @@ bool can_ssa_type(Type *t) {
|
||||
case Type_Map:
|
||||
return false;
|
||||
case Type_Tuple:
|
||||
if (t->Tuple.variable_count > SSA_MAX_STRUCT_FIELD_COUNT) {
|
||||
if (t->Tuple.variables.count > SSA_MAX_STRUCT_FIELD_COUNT) {
|
||||
return false;
|
||||
}
|
||||
for (isize i = 0; i < t->Tuple.variable_count; i++) {
|
||||
for_array(i, t->Tuple.variables) {
|
||||
if (!can_ssa_type(t->Tuple.variables[i]->type)) {
|
||||
return false;
|
||||
}
|
||||
@@ -813,14 +813,9 @@ ssaValue *ssa_emit_ptr_index(ssaProc *p, ssaValue *s, i64 index) {
|
||||
GB_ASSERT(t->Record.field_count > 0);
|
||||
GB_ASSERT(gb_is_between(index, 0, t->Record.field_count-1));
|
||||
result_type = make_type_pointer(a, t->Record.fields[index]->type);
|
||||
} else if (is_type_union(t)) {
|
||||
type_set_offsets(a, t);
|
||||
GB_ASSERT(t->Record.field_count > 0);
|
||||
GB_ASSERT(gb_is_between(index, 0, t->Record.field_count-1));
|
||||
result_type = make_type_pointer(a, t->Record.fields[index]->type);
|
||||
} else if (is_type_tuple(t)) {
|
||||
GB_ASSERT(t->Tuple.variable_count > 0);
|
||||
GB_ASSERT(gb_is_between(index, 0, t->Tuple.variable_count-1));
|
||||
GB_ASSERT(t->Tuple.variables.count > 0);
|
||||
GB_ASSERT(gb_is_between(index, 0, t->Tuple.variables.count-1));
|
||||
result_type = make_type_pointer(a, t->Tuple.variables[index]->type);
|
||||
} else if (is_type_slice(t)) {
|
||||
switch (index) {
|
||||
@@ -882,8 +877,7 @@ ssaValue *ssa_emit_value_index(ssaProc *p, ssaValue *s, i64 index) {
|
||||
GB_ASSERT(gb_is_between(index, 0, t->Record.field_count-1));
|
||||
result_type = t->Record.fields[index]->type;
|
||||
} else if (is_type_tuple(t)) {
|
||||
GB_ASSERT(t->Tuple.variable_count > 0);
|
||||
GB_ASSERT(gb_is_between(index, 0, t->Tuple.variable_count-1));
|
||||
GB_ASSERT(t->Tuple.variables.count > 0);
|
||||
result_type = t->Tuple.variables[index]->type;
|
||||
} else if (is_type_slice(t)) {
|
||||
switch (index) {
|
||||
@@ -2015,7 +2009,7 @@ void ssa_build_stmt_internal(ssaProc *p, AstNode *node) {
|
||||
Type *t = base_type(init->type);
|
||||
// TODO(bill): refactor for code reuse as this is repeated a bit
|
||||
if (t->kind == Type_Tuple) {
|
||||
for (isize i = 0; i < t->Tuple.variable_count; i++) {
|
||||
for_array(i, t->Tuple.variables) {
|
||||
Entity *e = t->Tuple.variables[i];
|
||||
ssaValue *v = ssa_emit_value_index(p, init, i);
|
||||
array_add(&inits, v);
|
||||
|
||||
@@ -119,8 +119,7 @@ struct TypeRecord {
|
||||
Entity * max_value; \
|
||||
}) \
|
||||
TYPE_KIND(Union, struct { \
|
||||
Type ** variants; \
|
||||
i32 variant_count; \
|
||||
Array<Type *> variants; \
|
||||
AstNode *node; \
|
||||
Scope * scope; \
|
||||
Entity * union__type_info; \
|
||||
@@ -133,8 +132,7 @@ struct TypeRecord {
|
||||
Entity *type_name; /* Entity_TypeName */ \
|
||||
}) \
|
||||
TYPE_KIND(Tuple, struct { \
|
||||
Entity **variables; /* Entity_Variable */ \
|
||||
i32 variable_count; \
|
||||
Array<Entity *> variables; /* Entity_Variable */ \
|
||||
bool are_offsets_set; \
|
||||
i64 * offsets; \
|
||||
}) \
|
||||
@@ -330,10 +328,8 @@ gb_global Type *t_string_slice = nullptr;
|
||||
|
||||
// Type generated for the "preload" file
|
||||
gb_global Type *t_type_info = nullptr;
|
||||
gb_global Type *t_type_info_record = nullptr;
|
||||
gb_global Type *t_type_info_enum_value = nullptr;
|
||||
gb_global Type *t_type_info_ptr = nullptr;
|
||||
gb_global Type *t_type_info_record_ptr = nullptr;
|
||||
gb_global Type *t_type_info_enum_value_ptr = nullptr;
|
||||
|
||||
gb_global Type *t_type_info_named = nullptr;
|
||||
@@ -352,7 +348,6 @@ gb_global Type *t_type_info_slice = nullptr;
|
||||
gb_global Type *t_type_info_vector = nullptr;
|
||||
gb_global Type *t_type_info_tuple = nullptr;
|
||||
gb_global Type *t_type_info_struct = nullptr;
|
||||
gb_global Type *t_type_info_raw_union = nullptr;
|
||||
gb_global Type *t_type_info_union = nullptr;
|
||||
gb_global Type *t_type_info_enum = nullptr;
|
||||
gb_global Type *t_type_info_map = nullptr;
|
||||
@@ -375,7 +370,6 @@ gb_global Type *t_type_info_slice_ptr = nullptr;
|
||||
gb_global Type *t_type_info_vector_ptr = nullptr;
|
||||
gb_global Type *t_type_info_tuple_ptr = nullptr;
|
||||
gb_global Type *t_type_info_struct_ptr = nullptr;
|
||||
gb_global Type *t_type_info_raw_union_ptr = nullptr;
|
||||
gb_global Type *t_type_info_union_ptr = nullptr;
|
||||
gb_global Type *t_type_info_enum_ptr = nullptr;
|
||||
gb_global Type *t_type_info_map_ptr = nullptr;
|
||||
@@ -951,7 +945,7 @@ bool is_type_polymorphic(Type *t) {
|
||||
return is_type_polymorphic(t->Slice.elem);
|
||||
|
||||
case Type_Tuple:
|
||||
for (isize i = 0; i < t->Tuple.variable_count; i++) {
|
||||
for_array(i, t->Tuple.variables) {
|
||||
if (is_type_polymorphic(t->Tuple.variables[i]->type)) {
|
||||
return true;
|
||||
}
|
||||
@@ -983,7 +977,7 @@ bool is_type_polymorphic(Type *t) {
|
||||
}
|
||||
break;
|
||||
case Type_Union:
|
||||
for (isize i = 1; i < t->Union.variant_count; i++) {
|
||||
for_array(i, t->Union.variants) {
|
||||
if (is_type_polymorphic(t->Union.variants[i])) {
|
||||
return true;
|
||||
}
|
||||
@@ -1125,10 +1119,10 @@ bool are_types_identical(Type *x, Type *y) {
|
||||
|
||||
case Type_Union:
|
||||
if (y->kind == Type_Union) {
|
||||
if (x->Union.variant_count == y->Union.variant_count &&
|
||||
if (x->Union.variants.count == y->Union.variants.count &&
|
||||
x->Union.custom_align == y->Union.custom_align) {
|
||||
// NOTE(bill): zeroth variant is nullptr
|
||||
for (isize i = 1; i < x->Union.variant_count; i++) {
|
||||
for_array(i, x->Union.variants) {
|
||||
if (!are_types_identical(x->Union.variants[i], y->Union.variants[i])) {
|
||||
return false;
|
||||
}
|
||||
@@ -1180,8 +1174,8 @@ bool are_types_identical(Type *x, Type *y) {
|
||||
|
||||
case Type_Tuple:
|
||||
if (y->kind == Type_Tuple) {
|
||||
if (x->Tuple.variable_count == y->Tuple.variable_count) {
|
||||
for (isize i = 0; i < x->Tuple.variable_count; i++) {
|
||||
if (x->Tuple.variables.count == y->Tuple.variables.count) {
|
||||
for_array(i, x->Tuple.variables) {
|
||||
Entity *xe = x->Tuple.variables[i];
|
||||
Entity *ye = y->Tuple.variables[i];
|
||||
if (xe->kind != ye->kind || !are_types_identical(xe->type, ye->type)) {
|
||||
@@ -1299,7 +1293,7 @@ bool is_type_cte_safe(Type *type) {
|
||||
}
|
||||
|
||||
case Type_Tuple: {
|
||||
for (isize i = 0; i < type->Tuple.variable_count; i++) {
|
||||
for_array(i, type->Tuple.variables) {
|
||||
Entity *v = type->Tuple.variables[i];
|
||||
if (!is_type_cte_safe(v->type)) {
|
||||
return false;
|
||||
@@ -1411,9 +1405,9 @@ Selection lookup_field_from_index(gbAllocator a, Type *type, i64 index) {
|
||||
|
||||
i64 max_count = 0;
|
||||
switch (type->kind) {
|
||||
case Type_Record: max_count = type->Record.field_count; break;
|
||||
case Type_Tuple: max_count = type->Tuple.variable_count; break;
|
||||
case Type_BitField: max_count = type->BitField.field_count; break;
|
||||
case Type_Record: max_count = type->Record.field_count; break;
|
||||
case Type_Tuple: max_count = type->Tuple.variables.count; break;
|
||||
case Type_BitField: max_count = type->BitField.field_count; break;
|
||||
}
|
||||
|
||||
if (index >= max_count) {
|
||||
@@ -1813,7 +1807,7 @@ i64 type_align_of_internal(gbAllocator allocator, Type *t, TypePath *path) {
|
||||
|
||||
case Type_Tuple: {
|
||||
i64 max = 1;
|
||||
for (isize i = 0; i < t->Tuple.variable_count; i++) {
|
||||
for_array(i, t->Tuple.variables) {
|
||||
i64 align = type_align_of_internal(allocator, t->Tuple.variables[i]->type, path);
|
||||
if (max < align) {
|
||||
max = align;
|
||||
@@ -1834,8 +1828,7 @@ i64 type_align_of_internal(gbAllocator allocator, Type *t, TypePath *path) {
|
||||
|
||||
case Type_Union: {
|
||||
i64 max = build_context.word_size;
|
||||
// NOTE(bill): field zero is null
|
||||
for (isize i = 1; i < t->Union.variant_count; i++) {
|
||||
for_array(i, t->Union.variants) {
|
||||
Type *variant = t->Union.variants[i];
|
||||
type_path_push(path, variant);
|
||||
if (path->failure) {
|
||||
@@ -1944,7 +1937,7 @@ bool type_set_offsets(gbAllocator allocator, Type *t) {
|
||||
} else if (is_type_tuple(t)) {
|
||||
if (!t->Tuple.are_offsets_set) {
|
||||
t->Record.are_offsets_being_processed = true;
|
||||
t->Tuple.offsets = type_set_offsets_of(allocator, t->Tuple.variables, t->Tuple.variable_count, false, false);
|
||||
t->Tuple.offsets = type_set_offsets_of(allocator, t->Tuple.variables.data, t->Tuple.variables.count, false, false);
|
||||
t->Tuple.are_offsets_set = true;
|
||||
return true;
|
||||
}
|
||||
@@ -2054,7 +2047,7 @@ i64 type_size_of_internal(gbAllocator allocator, Type *t, TypePath *path) {
|
||||
|
||||
case Type_Tuple: {
|
||||
i64 count, align, size;
|
||||
count = t->Tuple.variable_count;
|
||||
count = t->Tuple.variables.count;
|
||||
if (count == 0) {
|
||||
return 0;
|
||||
}
|
||||
@@ -2075,10 +2068,8 @@ i64 type_size_of_internal(gbAllocator allocator, Type *t, TypePath *path) {
|
||||
|
||||
i64 max = 0;
|
||||
i64 field_size = 0;
|
||||
isize variant_count = t->Union.variant_count;
|
||||
|
||||
|
||||
for (isize i = 1; i < variant_count; i++) {
|
||||
for_array(i, t->Union.variants) {
|
||||
Type *variant_type = t->Union.variants[i];
|
||||
i64 size = type_size_of_internal(allocator, variant_type, path);
|
||||
if (max < size) {
|
||||
@@ -2158,7 +2149,7 @@ i64 type_offset_of(gbAllocator allocator, Type *t, i32 index) {
|
||||
}
|
||||
} else if (t->kind == Type_Tuple) {
|
||||
type_set_offsets(allocator, t);
|
||||
if (gb_is_between(index, 0, t->Tuple.variable_count-1)) {
|
||||
if (gb_is_between(index, 0, t->Tuple.variables.count-1)) {
|
||||
return t->Tuple.offsets[index];
|
||||
}
|
||||
} else if (t->kind == Type_Basic) {
|
||||
@@ -2309,9 +2300,9 @@ gbString write_type_to_string(gbString str, Type *type) {
|
||||
|
||||
case Type_Union:
|
||||
str = gb_string_appendc(str, "union{");
|
||||
for (isize i = 1; i < type->Union.variant_count; i++) {
|
||||
for_array(i, type->Union.variants) {
|
||||
Type *t = type->Union.variants[i];
|
||||
if (i > 1) str = gb_string_appendc(str, ", ");
|
||||
if (i > 0) str = gb_string_appendc(str, ", ");
|
||||
str = write_type_to_string(str, t);
|
||||
}
|
||||
str = gb_string_appendc(str, "}");
|
||||
@@ -2374,8 +2365,8 @@ gbString write_type_to_string(gbString str, Type *type) {
|
||||
break;
|
||||
|
||||
case Type_Tuple:
|
||||
if (type->Tuple.variable_count > 0) {
|
||||
for (isize i = 0; i < type->Tuple.variable_count; i++) {
|
||||
if (type->Tuple.variables.count > 0) {
|
||||
for_array(i, type->Tuple.variables) {
|
||||
Entity *var = type->Tuple.variables[i];
|
||||
if (var != nullptr) {
|
||||
if (i > 0) {
|
||||
|
||||
Reference in New Issue
Block a user