Update internals of a Union and Tuple

This commit is contained in:
Ginger Bill
2017-07-20 15:17:04 +01:00
parent eab23cd5b7
commit 6d37ed12d2
13 changed files with 243 additions and 307 deletions

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@@ -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) {

View File

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

View File

@@ -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) {