aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorGinger Bill <bill@gingerbill.org>2017-07-20 15:17:04 +0100
committerGinger Bill <bill@gingerbill.org>2017-07-20 15:17:04 +0100
commit6d37ed12d2e9914bd308dbf2fd3dec166cc78af1 (patch)
tree50597ee875a84c1ec2f8c64d031cb9857c0c233f /src
parenteab23cd5b74b9df2f5158138510b45c83bbf1bc8 (diff)
Update internals of a Union and Tuple
Diffstat (limited to 'src')
-rw-r--r--src/check_decl.cpp2
-rw-r--r--src/check_expr.cpp113
-rw-r--r--src/check_stmt.cpp4
-rw-r--r--src/checker.cpp52
-rw-r--r--src/ir.cpp157
-rw-r--r--src/ir_print.cpp22
-rw-r--r--src/parser.cpp49
-rw-r--r--src/ssa.cpp18
-rw-r--r--src/types.cpp53
9 files changed, 208 insertions, 262 deletions
diff --git a/src/check_decl.cpp b/src/check_decl.cpp
index 38923e494..6e47a2554 100644
--- a/src/check_decl.cpp
+++ b/src/check_decl.cpp
@@ -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;
diff --git a/src/check_expr.cpp b/src/check_expr.cpp
index ef65409c1..9f30575a2 100644
--- a/src/check_expr.cpp
+++ b/src/check_expr.cpp
@@ -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;
diff --git a/src/check_stmt.cpp b/src/check_stmt.cpp
index 751e9759e..cf8fa2933 100644
--- a/src/check_stmt.cpp
+++ b/src/check_stmt.cpp
@@ -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;
diff --git a/src/checker.cpp b/src/checker.cpp
index 98e47c86a..26022b7f2 100644
--- a/src/checker.cpp
+++ b/src/checker.cpp
@@ -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);
diff --git a/src/ir.cpp b/src/ir.cpp
index 61f8d8ffa..dc0bc9f59 100644
--- a/src/ir.cpp
+++ b/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);
-
- 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);
+ ir_emit_comment(proc, str_lit("TypeInfoStruct"));
+ tag = ir_emit_conv(proc, variant_ptr, t_type_info_struct_ptr);
- 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
+ {
+ 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);
+ }
- 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));
- }
+ 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 *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 *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);
- 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));
+ 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);
- ir_fill_slice(proc, ir_emit_struct_ep(proc, tag, 3), memory_usings, count, count);
+ 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"));
diff --git a/src/ir_print.cpp b/src/ir_print.cpp
index deb5b9e34..1b65112f1 100644
--- a/src/ir_print.cpp
+++ b/src/ir_print.cpp
@@ -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);
diff --git a/src/parser.cpp b/src/parser.cpp
index 48169f4d6..090d3a46e 100644
--- a/src/parser.cpp
+++ b/src/parser.cpp
@@ -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) {
diff --git a/src/ssa.cpp b/src/ssa.cpp
index a1b5c3827..ef9b03dce 100644
--- a/src/ssa.cpp
+++ b/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);
diff --git a/src/types.cpp b/src/types.cpp
index 29a06528d..010d8aec2 100644
--- a/src/types.cpp
+++ b/src/types.cpp
@@ -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) {