diff --git a/src/array.cpp b/src/array.cpp index 0f0f3c7de..67e87166c 100644 --- a/src/array.cpp +++ b/src/array.cpp @@ -1,5 +1,104 @@ #define ARRAY_GROW_FORMULA(x) (2*(x) + 8) +GB_STATIC_ASSERT(ARRAY_GROW_FORMULA(0) > 0); +#define Array(Type_) struct { \ + gbAllocator allocator; \ + Type_ * e; \ + isize count; \ + isize capacity; \ +} + +typedef Array(void) ArrayVoid; + +#define array_init_reserve(x_, allocator_, init_capacity_) do { \ + GB_ASSERT((x_) != NULL); \ + void **e = cast(void **)&((x_)->e); \ + (x_)->allocator = (allocator_); \ + (x_)->count = 0; \ + (x_)->capacity = (init_capacity_); \ + *e = gb_alloc((allocator_), gb_size_of(*(x_)->e)*(init_capacity_)); \ +} while (0) + +#define array_init_count(x_, allocator_, init_count_) do { \ + GB_ASSERT((x_) != NULL); \ + void **e = cast(void **)&((x_)->e); \ + (x_)->allocator = (allocator_); \ + (x_)->count = (init_count_); \ + (x_)->capacity = (init_count_); \ + *e = gb_alloc((allocator_), gb_size_of(*(x_)->e)*(init_count_)); \ +} while (0) + +#define array_init(x_, allocator_) do { array_init_reserve(x_, allocator_, ARRAY_GROW_FORMULA(0)); } while (0) +#define array_free(x_) do { gb_free((x_)->allocator, (x_)->e); } while (0) +#define array_set_capacity(x_, capacity_) do { array__set_capacity((x_), (capacity_), gb_size_of(*(x_)->e)); } while (0) + +#define array_grow(x_, min_capacity_) do { \ + isize new_capacity = ARRAY_GROW_FORMULA((x_)->capacity); \ + if (new_capacity < (min_capacity_)) { \ + new_capacity = (min_capacity_); \ + } \ + array_set_capacity(x_, new_capacity); \ +} while (0) + +#define array_add(x_, item_) do { \ + if ((x_)->capacity < (x_)->count+1) { \ + array_grow(x_, 0); \ + } \ + (x_)->e[(x_)->count++] = item_; \ +} while (0) + +#define array_pop(x_) do { GB_ASSERT((x_)->count > 0); (x_)->count--; } while (0) +#define array_clear(x_) do { (x_)->count = 0; } while (0) + +#define array_resize(x_, new_count_) do { \ + if ((x_)->capacity < (new_count_)) { \ + array_grow((x_), (new_count_)); \ + } \ + (x_)->count = (new_count_); \ +} while (0) + +#define array_reserve(x_, new_capacity_) do { \ + if ((x_)->capacity < (new_capacity_)) { \ + array_set_capacity((x_), (new_capacity_)); \ + } \ +} while (0) + + + + +void array__set_capacity(void *ptr, isize capacity, isize element_size) { + GB_ASSERT(ptr != NULL); + ArrayVoid *x = cast(ArrayVoid *)ptr; + + GB_ASSERT(element_size > 0); + + if (capacity == x->capacity) { + return; + } + + if (capacity < x->count) { + if (x->capacity < capacity) { + isize new_capacity = ARRAY_GROW_FORMULA(x->capacity); + if (new_capacity < capacity) { + new_capacity = capacity; + } + array__set_capacity(ptr, new_capacity, element_size); + } + x->count = capacity; + } + + { + // TODO(bill): Resize rather than copy and delete + void *new_data = gb_alloc(x->allocator, element_size*capacity); + gb_memmove(new_data, x->e, element_size*x->count); + gb_free(x->allocator, x->e); + x->capacity = capacity; + x->e = new_data; + } +} + + +#if 0 template struct Array { gbAllocator allocator; @@ -133,3 +232,4 @@ void array_set_capacity(Array *array, isize capacity) { +#endif diff --git a/src/checker/checker.cpp b/src/checker/checker.cpp index 9e6330325..ee99a4713 100644 --- a/src/checker/checker.cpp +++ b/src/checker/checker.cpp @@ -70,8 +70,8 @@ struct Scope { Map elements; // Key: String Map implicit; // Key: String - Array shared; - Array imported; + Array(Scope *) shared; + Array(Scope *) imported; b32 is_proc; b32 is_global; b32 is_file; @@ -211,7 +211,7 @@ struct Checker { AstFile * curr_ast_file; BaseTypeSizes sizes; Scope * global_scope; - Array procs; // NOTE(bill): Procedures to check + Array(ProcedureInfo) procs; // NOTE(bill): Procedures to check gbArena arena; gbArena tmp_arena; @@ -220,12 +220,12 @@ struct Checker { CheckerContext context; - Array proc_stack; + Array(Type *) proc_stack; b32 in_defer; // TODO(bill): Actually handle correctly }; struct CycleChecker { - Array path; // Entity_TypeName + Array(Entity *) path; // Entity_TypeName }; @@ -235,7 +235,7 @@ CycleChecker *cycle_checker_add(CycleChecker *cc, Entity *e) { if (cc == NULL) { return NULL; } - if (cc->path.data == NULL) { + if (cc->path.e == NULL) { array_init(&cc->path, heap_allocator()); } GB_ASSERT(e != NULL && e->kind == Entity_TypeName); @@ -244,7 +244,7 @@ CycleChecker *cycle_checker_add(CycleChecker *cc, Entity *e) { } void cycle_checker_destroy(CycleChecker *cc) { - if (cc != NULL && cc->path.data != NULL) { + if (cc != NULL && cc->path.e != NULL) { array_free(&cc->path); } } @@ -299,7 +299,7 @@ Scope *make_scope(Scope *parent, gbAllocator allocator) { void destroy_scope(Scope *scope) { for_array(i, scope->elements.entries) { - Entity *e =scope->elements.entries[i].value; + Entity *e =scope->elements.entries.e[i].value; if (e->kind == Entity_Variable) { if (!(e->flags & EntityFlag_Used)) { #if 0 @@ -371,7 +371,7 @@ void scope_lookup_parent_entity(Scope *scope, String name, Scope **scope_, Entit } else { // Check shared scopes - i.e. other files @ global scope for_array(i, s->shared) { - Scope *shared = s->shared[i]; + Scope *shared = s->shared.e[i]; Entity **found = map_get(&shared->elements, key); if (found) { Entity *e = *found; @@ -414,7 +414,7 @@ Entity *current_scope_lookup_entity(Scope *s, String name) { return *found; } for_array(i, s->shared) { - Entity **found = map_get(&s->shared[i]->elements, key); + Entity **found = map_get(&s->shared.e[i]->elements, key); if (found) { return *found; } @@ -572,7 +572,7 @@ void init_checker(Checker *c, Parser *parser, BaseTypeSizes sizes) { isize item_size = gb_max3(gb_size_of(Entity), gb_size_of(Type), gb_size_of(Scope)); isize total_token_count = 0; for_array(i, c->parser->files) { - AstFile *f = &c->parser->files[i]; + AstFile *f = &c->parser->files.e[i]; total_token_count += f->tokens.count; } isize arena_size = 2 * item_size * total_token_count; @@ -735,7 +735,7 @@ void add_type_info_type(Checker *c, Type *t) { isize ti_index = -1; for_array(i, c->info.type_info_map.entries) { - auto *e = &c->info.type_info_map.entries[i]; + auto *e = &c->info.type_info_map.entries.e[i]; Type *prev_type = cast(Type *)e->key.ptr; if (are_types_identical(t, prev_type)) { // Duplicate entry @@ -858,7 +858,7 @@ void pop_procedure(Checker *c) { Type *const curr_procedure(Checker *c) { isize count = c->proc_stack.count; if (count > 0) { - return c->proc_stack[count-1]; + return c->proc_stack.e[count-1]; } return NULL; } @@ -890,7 +890,7 @@ void add_dependency_to_map(Map *map, CheckerInfo *info, Entity *node) DeclInfo *decl = *found; for_array(i, decl->deps.entries) { - Entity *e = cast(Entity *)decl->deps.entries[i].key.ptr; + Entity *e = cast(Entity *)decl->deps.entries.e[i].key.ptr; add_dependency_to_map(map, info, e); } } @@ -900,7 +900,7 @@ Map generate_minimum_dependency_map(CheckerInfo *info, Entity *start) map_init(&map, heap_allocator()); for_array(i, info->entities.entries) { - auto *entry = &info->entities.entries[i]; + auto *entry = &info->entities.entries.e[i]; Entity *e = cast(Entity *)cast(uintptr)entry->key.key; if (e->scope->is_global) { // NOTE(bill): Require runtime stuff @@ -996,7 +996,7 @@ void add_implicit_value(Checker *c, ImplicitValueId id, String name, String back void check_global_entity(Checker *c, EntityKind kind) { PROF_SCOPED("check_global_entity"); for_array(i, c->info.entities.entries) { - auto *entry = &c->info.entities.entries[i]; + auto *entry = &c->info.entities.entries.e[i]; Entity *e = cast(Entity *)cast(uintptr)entry->key.key; if (e->kind == kind) { DeclInfo *d = entry->value; @@ -1023,7 +1023,7 @@ void check_global_entity(Checker *c, EntityKind kind) { } void check_parsed_files(Checker *c) { - Array import_decls; + AstNodeArray import_decls; array_init(&import_decls, heap_allocator()); Map file_scopes; // Key: String (fullpath) @@ -1031,7 +1031,7 @@ void check_parsed_files(Checker *c) { // Map full filepaths to Scopes for_array(i, c->parser->files) { - AstFile *f = &c->parser->files[i]; + AstFile *f = &c->parser->files.e[i]; Scope *scope = NULL; scope = make_scope(c->global_scope, c->allocator); scope->is_global = f->is_global_scope; @@ -1058,13 +1058,13 @@ void check_parsed_files(Checker *c) { for_array(i, c->parser->files) { PROF_SCOPED("Collect Entities"); - AstFile *f = &c->parser->files[i]; + AstFile *f = &c->parser->files.e[i]; add_curr_ast_file(c, f); Scope *file_scope = f->scope; for_array(decl_index, f->decls) { - AstNode *decl = f->decls[decl_index]; + AstNode *decl = f->decls.e[decl_index]; if (!is_ast_node_decl(decl)) { continue; } @@ -1081,8 +1081,8 @@ void check_parsed_files(Checker *c) { case_ast_node(cd, ConstDecl, decl); for_array(i, cd->values) { - AstNode *name = cd->names[i]; - AstNode *value = cd->values[i]; + AstNode *name = cd->names.e[i]; + AstNode *value = cd->values.e[i]; ExactValue v = {ExactValue_Invalid}; Entity *e = make_entity_constant(c->allocator, file_scope, name->Ident, NULL, v); e->identifier = name; @@ -1112,14 +1112,14 @@ void check_parsed_files(Checker *c) { di->entities = entities; di->entity_count = entity_count; di->type_expr = vd->type; - di->init_expr = vd->values[0]; + di->init_expr = vd->values.e[0]; } for_array(i, vd->names) { - AstNode *name = vd->names[i]; + AstNode *name = vd->names.e[i]; AstNode *value = NULL; if (i < vd->values.count) { - value = vd->values[i]; + value = vd->values.e[i]; } Entity *e = make_entity_variable(c->allocator, file_scope, name->Ident, NULL); e->identifier = name; @@ -1167,13 +1167,13 @@ void check_parsed_files(Checker *c) { for_array(i, c->parser->files) { PROF_SCOPED("Import Entities"); - AstFile *f = &c->parser->files[i]; + AstFile *f = &c->parser->files.e[i]; add_curr_ast_file(c, f); Scope *file_scope = f->scope; for_array(decl_index, f->decls) { - AstNode *decl = f->decls[decl_index]; + AstNode *decl = f->decls.e[decl_index]; if (decl->kind != AstNode_ImportDecl) { continue; } @@ -1191,7 +1191,7 @@ void check_parsed_files(Checker *c) { b32 previously_added = false; for_array(import_index, file_scope->imported) { - Scope *prev = file_scope->imported[import_index]; + Scope *prev = file_scope->imported.e[import_index]; if (prev == scope) { previously_added = true; break; @@ -1207,7 +1207,7 @@ void check_parsed_files(Checker *c) { if (str_eq(id->import_name.string, str_lit("."))) { // NOTE(bill): Add imported entities to this file's scope for_array(elem_index, scope->elements.entries) { - Entity *e = scope->elements.entries[elem_index].value; + Entity *e = scope->elements.entries.e[elem_index].value; if (e->scope == file_scope) { continue; } @@ -1292,7 +1292,7 @@ void check_parsed_files(Checker *c) { // Check procedure bodies for_array(i, c->procs) { - ProcedureInfo *pi = &c->procs[i]; + ProcedureInfo *pi = &c->procs.e[i]; add_curr_ast_file(c, pi->file); b32 bounds_check = (pi->tags & ProcTag_bounds_check) != 0; @@ -1317,7 +1317,7 @@ void check_parsed_files(Checker *c) { for_array(i, c->info.untyped.entries) { PROF_SCOPED("Untyped expr values"); - auto *entry = &c->info.untyped.entries[i]; + auto *entry = &c->info.untyped.entries.e[i]; HashKey key = entry->key; AstNode *expr = cast(AstNode *)cast(uintptr)key.key; ExpressionInfo *info = &entry->value; diff --git a/src/checker/decl.cpp b/src/checker/decl.cpp index 37a832b9a..79b712522 100644 --- a/src/checker/decl.cpp +++ b/src/checker/decl.cpp @@ -68,11 +68,11 @@ void check_init_variables(Checker *c, Entity **lhs, isize lhs_count, AstNodeArra // NOTE(bill): If there is a bad syntax error, rhs > lhs which would mean there would need to be // an extra allocation - Array operands; - array_init(&operands, c->tmp_allocator, 2*lhs_count); + Array(Operand) operands; + array_init_reserve(&operands, c->tmp_allocator, 2*lhs_count); for_array(i, inits) { - AstNode *rhs = inits[i]; + AstNode *rhs = inits.e[i]; Operand o = {}; check_multi_expr(c, &o, rhs); if (o.type->kind != Type_Tuple) { @@ -88,7 +88,7 @@ void check_init_variables(Checker *c, Entity **lhs, isize lhs_count, AstNodeArra isize rhs_count = operands.count; for_array(i, operands) { - if (operands[i].mode == Addressing_Invalid) { + if (operands.e[i].mode == Addressing_Invalid) { rhs_count--; } } @@ -96,7 +96,7 @@ void check_init_variables(Checker *c, Entity **lhs, isize lhs_count, AstNodeArra isize max = gb_min(lhs_count, rhs_count); for (isize i = 0; i < max; i++) { - check_init_variable(c, lhs[i], &operands[i], context_name); + check_init_variable(c, lhs[i], &operands.e[i], context_name); } if (rhs_count > 0 && lhs_count != rhs_count) { @@ -161,7 +161,7 @@ void check_var_decl_node(Checker *c, AstNode *node) { Entity **entities = gb_alloc_array(c->allocator, Entity *, entity_count); for_array(i, vd->names) { - AstNode *name = vd->names[i]; + AstNode *name = vd->names.e[i]; Entity *entity = NULL; if (name->kind == AstNode_Ident) { Token token = name->Ident; @@ -215,7 +215,7 @@ void check_var_decl_node(Checker *c, AstNode *node) { for_array(i, vd->names) { if (entities[i] != NULL) { - add_entity(c, c->context.scope, vd->names[i], entities[i]); + add_entity(c, c->context.scope, vd->names.e[i], entities[i]); } } @@ -496,7 +496,7 @@ void check_var_decl(Checker *c, Entity *e, Entity **entities, isize entity_count } AstNodeArray inits; - array_init(&inits, c->allocator, 1); + array_init_reserve(&inits, c->allocator, 1); array_add(&inits, init_expr); check_init_variables(c, entities, entity_count, inits, str_lit("variable declaration")); } @@ -523,7 +523,7 @@ void check_proc_body(Checker *c, Token token, DeclInfo *decl, Type *type, AstNod Scope **found = map_get(&c->info.scopes, hash_pointer(t->Record.node)); GB_ASSERT(found != NULL); for_array(i, (*found)->elements.entries) { - Entity *f = (*found)->elements.entries[i].value; + Entity *f = (*found)->elements.entries.e[i].value; if (f->kind == Entity_Variable) { Entity *uvar = make_entity_using_variable(c->allocator, e, f->token, f->type); Entity *prev = scope_insert_entity(c->context.scope, uvar); diff --git a/src/checker/expr.cpp b/src/checker/expr.cpp index 55011467b..787df12e4 100644 --- a/src/checker/expr.cpp +++ b/src/checker/expr.cpp @@ -258,15 +258,15 @@ void check_fields(Checker *c, AstNode *node, AstNodeArray decls, Entity *using_index_expr = NULL; - struct Delay { + typedef struct { Entity *e; AstNode *t; - }; - Array delayed_const; array_init(&delayed_const, c->tmp_allocator, other_field_count); - Array delayed_type; array_init(&delayed_type, c->tmp_allocator, other_field_count); + } Delay; + Array(Delay) delayed_const; array_init_reserve(&delayed_const, c->tmp_allocator, other_field_count); + Array(Delay) delayed_type; array_init_reserve(&delayed_type, c->tmp_allocator, other_field_count); for_array(decl_index, decls) { - AstNode *decl = decls[decl_index]; + AstNode *decl = decls.e[decl_index]; if (decl->kind == AstNode_ConstDecl) { ast_node(cd, ConstDecl, decl); @@ -275,8 +275,8 @@ void check_fields(Checker *c, AstNode *node, AstNodeArray decls, Entity **entities = gb_alloc_array(c->allocator, Entity *, entity_count); for_array(i, cd->values) { - AstNode *name = cd->names[i]; - AstNode *value = cd->values[i]; + AstNode *name = cd->names.e[i]; + AstNode *value = cd->values.e[i]; GB_ASSERT(name->kind == AstNode_Ident); ExactValue v = {ExactValue_Invalid}; @@ -299,7 +299,7 @@ void check_fields(Checker *c, AstNode *node, AstNodeArray decls, } for_array(i, cd->names) { - AstNode *name = cd->names[i]; + AstNode *name = cd->names.e[i]; Entity *e = entities[i]; Token name_token = name->Ident; if (str_eq(name_token.string, str_lit("_"))) { @@ -342,17 +342,17 @@ void check_fields(Checker *c, AstNode *node, AstNodeArray decls, } for_array(i, delayed_type) { - check_const_decl(c, delayed_type[i].e, delayed_type[i].t, NULL); + check_const_decl(c, delayed_type.e[i].e, delayed_type.e[i].t, NULL); } for_array(i, delayed_const) { - check_type_decl(c, delayed_const[i].e, delayed_const[i].t, NULL, NULL); + check_type_decl(c, delayed_const.e[i].e, delayed_const.e[i].t, NULL, NULL); } if (node->kind == AstNode_UnionType) { isize field_index = 0; fields[field_index++] = make_entity_type_name(c->allocator, c->context.scope, empty_token, NULL); for_array(decl_index, decls) { - AstNode *decl = decls[decl_index]; + AstNode *decl = decls.e[decl_index]; if (decl->kind != AstNode_VarDecl) { continue; } @@ -361,7 +361,7 @@ void check_fields(Checker *c, AstNode *node, AstNodeArray decls, Type *base_type = check_type(c, vd->type, NULL, cycle_checker); for_array(name_index, vd->names) { - AstNode *name = vd->names[name_index]; + AstNode *name = vd->names.e[name_index]; Token name_token = name->Ident; Type *type = make_type_named(c->allocator, name_token.string, base_type, NULL); @@ -388,7 +388,7 @@ void check_fields(Checker *c, AstNode *node, AstNodeArray decls, } else { isize field_index = 0; for_array(decl_index, decls) { - AstNode *decl = decls[decl_index]; + AstNode *decl = decls.e[decl_index]; if (decl->kind != AstNode_VarDecl) { continue; } @@ -398,13 +398,13 @@ void check_fields(Checker *c, AstNode *node, AstNodeArray decls, if (vd->is_using) { if (vd->names.count > 1) { - error(ast_node_token(vd->names[0]), + error(ast_node_token(vd->names.e[0]), "Cannot apply `using` to more than one of the same type"); } } for_array(name_index, vd->names) { - AstNode *name = vd->names[name_index]; + AstNode *name = vd->names.e[name_index]; Token name_token = name->Ident; Entity *e = make_entity_field(c->allocator, c->context.scope, name_token, type, vd->is_using, cast(i32)field_index); @@ -429,14 +429,14 @@ void check_fields(Checker *c, AstNode *node, AstNodeArray decls, if (vd->is_using) { Type *t = base_type(type_deref(type)); if (!is_type_struct(t) && !is_type_raw_union(t)) { - Token name_token = vd->names[0]->Ident; + Token name_token = vd->names.e[0]->Ident; if (is_type_indexable(t)) { b32 ok = true; for_array(emi, entity_map.entries) { - Entity *e = entity_map.entries[emi].value; + Entity *e = entity_map.entries.e[emi].value; if (e->kind == Entity_Variable && e->flags & EntityFlag_Anonymous) { if (is_type_indexable(e->type)) { - if (e->identifier != vd->names[0]) { + if (e->identifier != vd->names.e[0]) { ok = false; using_index_expr = e; break; @@ -505,7 +505,7 @@ void check_struct_type(Checker *c, Type *struct_type, AstNode *node, CycleChecke isize field_count = 0; isize other_field_count = 0; for_array(decl_index, st->decls) { - AstNode *decl = st->decls[decl_index]; + AstNode *decl = st->decls.e[decl_index]; switch (decl->kind) { case_ast_node(vd, VarDecl, decl); field_count += vd->names.count; @@ -571,7 +571,7 @@ void check_union_type(Checker *c, Type *union_type, AstNode *node, CycleChecker isize field_count = 1; isize other_field_count = 0; for_array(decl_index, ut->decls) { - AstNode *decl = ut->decls[decl_index]; + AstNode *decl = ut->decls.e[decl_index]; switch (decl->kind) { case_ast_node(vd, VarDecl, decl); field_count += vd->names.count; @@ -608,7 +608,7 @@ void check_raw_union_type(Checker *c, Type *union_type, AstNode *node, CycleChec isize field_count = 0; isize other_field_count = 0; for_array(decl_index, ut->decls) { - AstNode *decl = ut->decls[decl_index]; + AstNode *decl = ut->decls.e[decl_index]; switch (decl->kind) { case_ast_node(vd, VarDecl, decl); field_count += vd->names.count; @@ -699,7 +699,7 @@ void check_enum_type(Checker *c, Type *enum_type, Type *named_type, AstNode *nod Entity *blank_entity = make_entity_constant(c->allocator, c->context.scope, blank_token, constant_type, make_exact_value_integer(0));; for_array(i, et->fields) { - AstNode *field = et->fields[i]; + AstNode *field = et->fields.e[i]; ast_node(f, FieldValue, field); Token name_token = f->field->Ident; @@ -790,7 +790,7 @@ Type *check_get_params(Checker *c, Scope *scope, AstNodeArray params, b32 *is_va isize variable_count = 0; for_array(i, params) { - AstNode *field = params[i]; + AstNode *field = params.e[i]; ast_node(p, Parameter, field); variable_count += p->names.count; } @@ -798,7 +798,7 @@ Type *check_get_params(Checker *c, Scope *scope, AstNodeArray params, b32 *is_va Entity **variables = gb_alloc_array(c->allocator, Entity *, variable_count); isize variable_index = 0; for_array(i, params) { - ast_node(p, Parameter, params[i]); + ast_node(p, Parameter, params.e[i]); AstNode *type_expr = p->type; if (type_expr) { if (type_expr->kind == AstNode_Ellipsis) { @@ -806,13 +806,13 @@ Type *check_get_params(Checker *c, Scope *scope, AstNodeArray params, b32 *is_va if (i+1 == params.count) { is_variadic = true; } else { - error(ast_node_token(params[i]), "Invalid AST: Invalid variadic parameter"); + error(ast_node_token(params.e[i]), "Invalid AST: Invalid variadic parameter"); } } Type *type = check_type(c, type_expr); for_array(j, p->names) { - AstNode *name = p->names[j]; + AstNode *name = p->names.e[j]; if (name->kind == AstNode_Ident) { Entity *param = make_entity_param(c->allocator, scope, name->Ident, type, p->is_using); add_entity(c, scope, name, param); @@ -853,7 +853,7 @@ Type *check_get_results(Checker *c, Scope *scope, AstNodeArray results) { Entity **variables = gb_alloc_array(c->allocator, Entity *, results.count); isize variable_index = 0; for_array(i, results) { - AstNode *item = results[i]; + AstNode *item = results.e[i]; Type *type = check_type(c, item); Token token = ast_node_token(item); token.string = str_lit(""); // NOTE(bill): results are not named @@ -2610,17 +2610,17 @@ b32 check_builtin_procedure(Checker *c, Operand *operand, AstNode *call, i32 id) // NOTE(bill): The first arg may be a Type, this will be checked case by case break; default: - check_multi_expr(c, operand, ce->args[0]); + check_multi_expr(c, operand, ce->args.e[0]); } switch (id) { case BuiltinProc_new: { // new :: proc(Type) -> ^Type Operand op = {}; - check_expr_or_type(c, &op, ce->args[0]); + check_expr_or_type(c, &op, ce->args.e[0]); Type *type = op.type; if ((op.mode != Addressing_Type && type == NULL) || type == t_invalid) { - error(ast_node_token(ce->args[0]), "Expected a type for `new`"); + error(ast_node_token(ce->args.e[0]), "Expected a type for `new`"); return false; } operand->mode = Addressing_Value; @@ -2629,17 +2629,17 @@ b32 check_builtin_procedure(Checker *c, Operand *operand, AstNode *call, i32 id) case BuiltinProc_new_slice: { // new_slice :: proc(Type, len: int[, cap: int]) -> []Type Operand op = {}; - check_expr_or_type(c, &op, ce->args[0]); + check_expr_or_type(c, &op, ce->args.e[0]); Type *type = op.type; if ((op.mode != Addressing_Type && type == NULL) || type == t_invalid) { - error(ast_node_token(ce->args[0]), "Expected a type for `new_slice`"); + error(ast_node_token(ce->args.e[0]), "Expected a type for `new_slice`"); return false; } - AstNode *len = ce->args[1]; + AstNode *len = ce->args.e[1]; AstNode *cap = NULL; if (ce->args.count > 2) { - cap = ce->args[2]; + cap = ce->args.e[2]; } check_expr(c, &op, len); @@ -2681,9 +2681,9 @@ b32 check_builtin_procedure(Checker *c, Operand *operand, AstNode *call, i32 id) case BuiltinProc_size_of: { // size_of :: proc(Type) -> untyped int - Type *type = check_type(c, ce->args[0]); + Type *type = check_type(c, ce->args.e[0]); if (type == NULL || type == t_invalid) { - error(ast_node_token(ce->args[0]), "Expected a type for `size_of`"); + error(ast_node_token(ce->args.e[0]), "Expected a type for `size_of`"); return false; } @@ -2707,9 +2707,9 @@ b32 check_builtin_procedure(Checker *c, Operand *operand, AstNode *call, i32 id) case BuiltinProc_align_of: { // align_of :: proc(Type) -> untyped int - Type *type = check_type(c, ce->args[0]); + Type *type = check_type(c, ce->args.e[0]); if (type == NULL || type == t_invalid) { - error(ast_node_token(ce->args[0]), "Expected a type for `align_of`"); + error(ast_node_token(ce->args.e[0]), "Expected a type for `align_of`"); return false; } operand->mode = Addressing_Constant; @@ -2732,14 +2732,14 @@ b32 check_builtin_procedure(Checker *c, Operand *operand, AstNode *call, i32 id) case BuiltinProc_offset_of: { // offset_of :: proc(Type, field) -> untyped int Operand op = {}; - Type *bt = check_type(c, ce->args[0]); + Type *bt = check_type(c, ce->args.e[0]); Type *type = base_type(bt); if (type == NULL || type == t_invalid) { - error(ast_node_token(ce->args[0]), "Expected a type for `offset_of`"); + error(ast_node_token(ce->args.e[0]), "Expected a type for `offset_of`"); return false; } - AstNode *field_arg = unparen_expr(ce->args[1]); + AstNode *field_arg = unparen_expr(ce->args.e[1]); if (field_arg == NULL || field_arg->kind != AstNode_Ident) { error(ast_node_token(field_arg), "Expected an identifier for field argument"); @@ -2755,14 +2755,14 @@ b32 check_builtin_procedure(Checker *c, Operand *operand, AstNode *call, i32 id) Selection sel = lookup_field(c->allocator, type, arg->string, operand->mode == Addressing_Type); if (sel.entity == NULL) { gbString type_str = type_to_string(bt); - error(ast_node_token(ce->args[0]), + error(ast_node_token(ce->args.e[0]), "`%s` has no field named `%.*s`", type_str, LIT(arg->string)); gb_string_free(type_str); return false; } if (sel.indirect) { gbString type_str = type_to_string(bt); - error(ast_node_token(ce->args[0]), + error(ast_node_token(ce->args.e[0]), "Field `%.*s` is embedded via a pointer in `%s`", LIT(arg->string), type_str); gb_string_free(type_str); return false; @@ -2775,7 +2775,7 @@ b32 check_builtin_procedure(Checker *c, Operand *operand, AstNode *call, i32 id) case BuiltinProc_offset_of_val: { // offset_of_val :: proc(val: expression) -> untyped int - AstNode *arg = unparen_expr(ce->args[0]); + AstNode *arg = unparen_expr(ce->args.e[0]); if (arg->kind != AstNode_SelectorExpr) { gbString str = expr_to_string(arg); error(ast_node_token(arg), "`%s` is not a selector expression", str); @@ -2810,7 +2810,7 @@ b32 check_builtin_procedure(Checker *c, Operand *operand, AstNode *call, i32 id) } if (sel.indirect) { gbString type_str = type_to_string(type); - error(ast_node_token(ce->args[0]), + error(ast_node_token(ce->args.e[0]), "Field `%.*s` is embedded via a pointer in `%s`", LIT(i->string), type_str); gb_string_free(type_str); return false; @@ -2835,7 +2835,7 @@ b32 check_builtin_procedure(Checker *c, Operand *operand, AstNode *call, i32 id) case BuiltinProc_type_info: { // type_info :: proc(Type) -> ^Type_Info - AstNode *expr = ce->args[0]; + AstNode *expr = ce->args.e[0]; Type *type = check_type(c, expr); if (type == NULL || type == t_invalid) { error(ast_node_token(expr), "Invalid argument to `type_info`"); @@ -2850,7 +2850,7 @@ b32 check_builtin_procedure(Checker *c, Operand *operand, AstNode *call, i32 id) case BuiltinProc_type_info_of_val: { // type_info_of_val :: proc(val: Type) -> ^Type_Info - AstNode *expr = ce->args[0]; + AstNode *expr = ce->args.e[0]; check_assignment(c, operand, NULL, str_lit("argument of `type_info_of_val`")); if (operand->mode == Addressing_Invalid || operand->mode == Addressing_Builtin) @@ -2867,13 +2867,13 @@ b32 check_builtin_procedure(Checker *c, Operand *operand, AstNode *call, i32 id) // compile_assert :: proc(cond: bool) if (!is_type_boolean(operand->type) && operand->mode != Addressing_Constant) { - gbString str = expr_to_string(ce->args[0]); + gbString str = expr_to_string(ce->args.e[0]); error(ast_node_token(call), "`%s` is not a constant boolean", str); gb_string_free(str); return false; } if (!operand->value.value_bool) { - gbString str = expr_to_string(ce->args[0]); + gbString str = expr_to_string(ce->args.e[0]); error(ast_node_token(call), "Compile time assertion: `%s`", str); gb_string_free(str); } @@ -2883,7 +2883,7 @@ b32 check_builtin_procedure(Checker *c, Operand *operand, AstNode *call, i32 id) // assert :: proc(cond: bool) if (!is_type_boolean(operand->type)) { - gbString str = expr_to_string(ce->args[0]); + gbString str = expr_to_string(ce->args.e[0]); error(ast_node_token(call), "`%s` is not a boolean", str); gb_string_free(str); return false; @@ -2896,7 +2896,7 @@ b32 check_builtin_procedure(Checker *c, Operand *operand, AstNode *call, i32 id) // panic :: proc(msg: string) if (!is_type_string(operand->type)) { - gbString str = expr_to_string(ce->args[0]); + gbString str = expr_to_string(ce->args.e[0]); error(ast_node_token(call), "`%s` is not a string", str); gb_string_free(str); return false; @@ -2914,7 +2914,7 @@ b32 check_builtin_procedure(Checker *c, Operand *operand, AstNode *call, i32 id) dest_type = d->Slice.elem; } Operand op = {}; - check_expr(c, &op, ce->args[1]); + check_expr(c, &op, ce->args.e[1]); if (op.mode == Addressing_Invalid) { return false; } @@ -2929,8 +2929,8 @@ b32 check_builtin_procedure(Checker *c, Operand *operand, AstNode *call, i32 id) } if (!are_types_identical(dest_type, src_type)) { - gbString d_arg = expr_to_string(ce->args[0]); - gbString s_arg = expr_to_string(ce->args[1]); + gbString d_arg = expr_to_string(ce->args.e[0]); + gbString s_arg = expr_to_string(ce->args.e[1]); gbString d_str = type_to_string(dest_type); gbString s_str = type_to_string(src_type); error(ast_node_token(call), @@ -2953,7 +2953,7 @@ b32 check_builtin_procedure(Checker *c, Operand *operand, AstNode *call, i32 id) x_type = base_type(operand->type); Operand op = {}; - check_expr(c, &op, ce->args[1]); + check_expr(c, &op, ce->args.e[1]); if (op.mode == Addressing_Invalid) { return false; } @@ -2966,8 +2966,8 @@ b32 check_builtin_procedure(Checker *c, Operand *operand, AstNode *call, i32 id) Type *elem_type = x_type->Pointer.elem->Slice.elem; if (!check_is_assignable_to(c, &op, elem_type)) { - gbString d_arg = expr_to_string(ce->args[0]); - gbString s_arg = expr_to_string(ce->args[1]); + gbString d_arg = expr_to_string(ce->args.e[0]); + gbString s_arg = expr_to_string(ce->args.e[1]); gbString d_str = type_to_string(elem_type); gbString s_str = type_to_string(y_type); error(ast_node_token(call), @@ -3002,7 +3002,7 @@ b32 check_builtin_procedure(Checker *c, Operand *operand, AstNode *call, i32 id) if (i == 0) { continue; } - AstNode *arg = ce->args[i]; + AstNode *arg = ce->args.e[i]; Operand op = {}; check_expr(c, &op, arg); if (op.mode == Addressing_Invalid) { @@ -3057,7 +3057,7 @@ b32 check_builtin_procedure(Checker *c, Operand *operand, AstNode *call, i32 id) return false; } - AstNode *offset = ce->args[1]; + AstNode *offset = ce->args.e[1]; Operand op = {}; check_expr(c, &op, offset); if (op.mode == Addressing_Invalid) @@ -3161,10 +3161,10 @@ b32 check_builtin_procedure(Checker *c, Operand *operand, AstNode *call, i32 id) return false; } - AstNode *len = ce->args[1]; + AstNode *len = ce->args.e[1]; AstNode *cap = NULL; if (ce->args.count > 2) { - cap = ce->args[2]; + cap = ce->args.e[2]; } Operand op = {}; @@ -3215,7 +3215,7 @@ b32 check_builtin_procedure(Checker *c, Operand *operand, AstNode *call, i32 id) return false; } - AstNode *other_arg = ce->args[1]; + AstNode *other_arg = ce->args.e[1]; Operand a = *operand; Operand b = {}; check_expr(c, &b, other_arg); @@ -3284,7 +3284,7 @@ b32 check_builtin_procedure(Checker *c, Operand *operand, AstNode *call, i32 id) return false; } - AstNode *other_arg = ce->args[1]; + AstNode *other_arg = ce->args.e[1]; Operand a = *operand; Operand b = {}; check_expr(c, &b, other_arg); @@ -3446,18 +3446,18 @@ void check_call_arguments(Checker *c, Operand *operand, Type *proc_type, AstNode gbTempArenaMemory tmp = gb_temp_arena_memory_begin(&c->tmp_arena); - Array operands; - array_init(&operands, c->tmp_allocator, 2*param_count); + Array(Operand) operands; + array_init_reserve(&operands, c->tmp_allocator, 2*param_count); for_array(i, ce->args) { Operand o = {}; - check_multi_expr(c, &o, ce->args[i]); + check_multi_expr(c, &o, ce->args.e[i]); if (o.type->kind != Type_Tuple) { array_add(&operands, o); } else { auto *tuple = &o.type->Tuple; if (variadic && i >= param_count) { - error(ast_node_token(ce->args[i]), + error(ast_node_token(ce->args.e[i]), "`..` in a variadic procedure cannot be applied to a %td-valued expression", tuple->variable_count); operand->mode = Addressing_Invalid; goto end; @@ -3493,9 +3493,9 @@ void check_call_arguments(Checker *c, Operand *operand, Type *proc_type, AstNode isize operand_index = 0; for (; operand_index < param_count; operand_index++) { Type *arg_type = sig_params[operand_index]->type; - Operand o = operands[operand_index]; + Operand o = operands.e[operand_index]; if (variadic) { - o = operands[operand_index]; + o = operands.e[operand_index]; } check_assignment(c, &o, arg_type, str_lit("argument"), true); } @@ -3507,7 +3507,7 @@ void check_call_arguments(Checker *c, Operand *operand, Type *proc_type, AstNode Type *elem = base_type(slice)->Slice.elem; Type *t = elem; for (; operand_index < operands.count; operand_index++) { - Operand o = operands[operand_index]; + Operand o = operands.e[operand_index]; if (vari_expand) { variadic_expand = true; t = slice; @@ -3556,7 +3556,7 @@ ExprKind check_call_expr(Checker *c, Operand *operand, AstNode *call) { if (operand->mode == Addressing_Invalid) { for_array(i, ce->args) { - check_expr_base(c, operand, ce->args[i]); + check_expr_base(c, operand, ce->args.e[i]); } operand->mode = Addressing_Invalid; operand->expr = call; @@ -3721,11 +3721,11 @@ ExprKind check__expr_base(Checker *c, Operand *o, AstNode *node, Type *type_hint } { // Checker values isize field_count = t->Record.field_count; - if (cl->elems[0]->kind == AstNode_FieldValue) { + if (cl->elems.e[0]->kind == AstNode_FieldValue) { b32 *fields_visited = gb_alloc_array(c->allocator, b32, field_count); for_array(i, cl->elems) { - AstNode *elem = cl->elems[i]; + AstNode *elem = cl->elems.e[i]; if (elem->kind != AstNode_FieldValue) { error(ast_node_token(elem), "Mixture of `field = value` and value elements in a structure literal is not allowed"); @@ -3754,16 +3754,16 @@ ExprKind check__expr_base(Checker *c, Operand *o, AstNode *node, Type *type_hint continue; } - Entity *field = t->Record.fields[sel.index[0]]; + Entity *field = t->Record.fields[sel.index.e[0]]; add_entity_use(c, fv->field, field); - if (fields_visited[sel.index[0]]) { + if (fields_visited[sel.index.e[0]]) { error(ast_node_token(elem), "Duplicate field `%.*s` in structure literal", LIT(name)); continue; } - fields_visited[sel.index[0]] = true; + fields_visited[sel.index.e[0]] = true; check_expr(c, o, fv->value); if (base_type(field->type) == t_any) { @@ -3778,7 +3778,7 @@ ExprKind check__expr_base(Checker *c, Operand *o, AstNode *node, Type *type_hint } } else { for_array(index, cl->elems) { - AstNode *elem = cl->elems[index]; + AstNode *elem = cl->elems.e[index]; if (elem->kind == AstNode_FieldValue) { error(ast_node_token(elem), "Mixture of `field = value` and value elements in a structure literal is not allowed"); @@ -3836,7 +3836,7 @@ ExprKind check__expr_base(Checker *c, Operand *o, AstNode *node, Type *type_hint } for (; index < elem_count; index++) { - AstNode *e = cl->elems[index]; + AstNode *e = cl->elems.e[index]; if (e->kind == AstNode_FieldValue) { error(ast_node_token(e), "`field = value` is only allowed in struct literals"); @@ -3868,7 +3868,7 @@ ExprKind check__expr_base(Checker *c, Operand *o, AstNode *node, Type *type_hint if (t->kind == Type_Vector) { if (t->Vector.count > 1 && gb_is_between(index, 2, t->Vector.count-1)) { - error(ast_node_token(cl->elems[0]), + error(ast_node_token(cl->elems.e[0]), "Expected either 1 (broadcast) or %td elements in vector literal, got %td", t->Vector.count, index); } } @@ -4274,12 +4274,12 @@ gbString write_expr_to_string(gbString str, AstNode *node); gbString write_params_to_string(gbString str, AstNodeArray params, char *sep) { for_array(i, params) { - ast_node(p, Parameter, params[i]); + ast_node(p, Parameter, params.e[i]); if (i > 0) { str = gb_string_appendc(str, sep); } - str = write_expr_to_string(str, params[i]); + str = write_expr_to_string(str, params.e[i]); } return str; } @@ -4324,7 +4324,7 @@ gbString write_expr_to_string(gbString str, AstNode *node) { if (i > 0) { str = gb_string_appendc(str, ", "); } - str = write_expr_to_string(str, cl->elems[i]); + str = write_expr_to_string(str, cl->elems.e[i]); } str = gb_string_appendc(str, "}"); case_end; @@ -4429,7 +4429,7 @@ gbString write_expr_to_string(gbString str, AstNode *node) { str = gb_string_appendc(str, "using "); } for_array(i, p->names) { - AstNode *name = p->names[i]; + AstNode *name = p->names.e[i]; if (i > 0) str = gb_string_appendc(str, ", "); str = write_expr_to_string(str, name); @@ -4444,7 +4444,7 @@ gbString write_expr_to_string(gbString str, AstNode *node) { str = gb_string_appendc(str, "("); for_array(i, ce->args) { - AstNode *arg = ce->args[i]; + AstNode *arg = ce->args.e[i]; if (i > 0) { str = gb_string_appendc(str, ", "); } @@ -4467,7 +4467,7 @@ gbString write_expr_to_string(gbString str, AstNode *node) { if (i > 0) { str = gb_string_appendc(str, "; "); } - str = write_expr_to_string(str, st->decls[i]); + str = write_expr_to_string(str, st->decls.e[i]); } // str = write_params_to_string(str, st->decl_list, ", "); str = gb_string_appendc(str, "}"); @@ -4479,7 +4479,7 @@ gbString write_expr_to_string(gbString str, AstNode *node) { if (i > 0) { str = gb_string_appendc(str, "; "); } - str = write_expr_to_string(str, st->decls[i]); + str = write_expr_to_string(str, st->decls.e[i]); } // str = write_params_to_string(str, st->decl_list, ", "); str = gb_string_appendc(str, "}"); @@ -4491,7 +4491,7 @@ gbString write_expr_to_string(gbString str, AstNode *node) { if (i > 0) { str = gb_string_appendc(str, "; "); } - str = write_expr_to_string(str, st->decls[i]); + str = write_expr_to_string(str, st->decls.e[i]); } // str = write_params_to_string(str, st->decl_list, ", "); str = gb_string_appendc(str, "}"); diff --git a/src/checker/stmt.cpp b/src/checker/stmt.cpp index b5db09efc..ad7778f9f 100644 --- a/src/checker/stmt.cpp +++ b/src/checker/stmt.cpp @@ -23,16 +23,16 @@ void check_stmt_list(Checker *c, AstNodeArray stmts, u32 flags) { Entity *e; DeclInfo *d; } Delay; - Array delayed_const; array_init(&delayed_const, c->tmp_allocator, stmts.count); - Array delayed_type; array_init(&delayed_type, c->tmp_allocator, stmts.count); + Array(Delay) delayed_const; array_init_reserve(&delayed_const, c->tmp_allocator, stmts.count); + Array(Delay) delayed_type; array_init_reserve(&delayed_type, c->tmp_allocator, stmts.count); for_array(i, stmts) { - AstNode *node = stmts[i]; + AstNode *node = stmts.e[i]; switch (node->kind) { case_ast_node(cd, ConstDecl, node); for_array(i, cd->values) { - AstNode *name = cd->names[i]; - AstNode *value = cd->values[i]; + AstNode *name = cd->names.e[i]; + AstNode *value = cd->values.e[i]; ExactValue v = {ExactValue_Invalid}; Entity *e = make_entity_constant(c->allocator, c->context.scope, name->Ident, NULL, v); @@ -74,17 +74,17 @@ void check_stmt_list(Checker *c, AstNodeArray stmts, u32 flags) { } for_array(i, delayed_type) { - check_entity_decl(c, delayed_type[i].e, delayed_type[i].d, NULL); + check_entity_decl(c, delayed_type.e[i].e, delayed_type.e[i].d, NULL); } for_array(i, delayed_const) { - check_entity_decl(c, delayed_const[i].e, delayed_const[i].d, NULL); + check_entity_decl(c, delayed_const.e[i].e, delayed_const.e[i].d, NULL); } b32 ft_ok = (flags & Stmt_FallthroughAllowed) != 0; u32 f = flags & (~Stmt_FallthroughAllowed); for_array(i, stmts) { - AstNode *n = stmts[i]; + AstNode *n = stmts.e[i]; if (n->kind == AstNode_EmptyStmt) { continue; } @@ -102,7 +102,7 @@ b32 check_is_terminating_list(AstNodeArray stmts) { // Iterate backwards for (isize n = stmts.count-1; n >= 0; n--) { - AstNode *stmt = stmts[n]; + AstNode *stmt = stmts.e[n]; if (stmt->kind != AstNode_EmptyStmt) { return check_is_terminating(stmt); } @@ -113,7 +113,7 @@ b32 check_is_terminating_list(AstNodeArray stmts) { b32 check_has_break_list(AstNodeArray stmts, b32 implicit) { for_array(i, stmts) { - AstNode *stmt = stmts[i]; + AstNode *stmt = stmts.e[i]; if (check_has_break(stmt, implicit)) { return true; } @@ -187,7 +187,7 @@ b32 check_is_terminating(AstNode *node) { case_ast_node(ms, MatchStmt, node); b32 has_default = false; for_array(i, ms->body->BlockStmt.stmts) { - AstNode *clause = ms->body->BlockStmt.stmts[i]; + AstNode *clause = ms->body->BlockStmt.stmts.e[i]; ast_node(cc, CaseClause, clause); if (cc->list.count == 0) { has_default = true; @@ -203,7 +203,7 @@ b32 check_is_terminating(AstNode *node) { case_ast_node(ms, TypeMatchStmt, node); b32 has_default = false; for_array(i, ms->body->BlockStmt.stmts) { - AstNode *clause = ms->body->BlockStmt.stmts[i]; + AstNode *clause = ms->body->BlockStmt.stmts.e[i]; ast_node(cc, CaseClause, clause); if (cc->list.count == 0) { has_default = true; @@ -433,11 +433,11 @@ void check_stmt_internal(Checker *c, AstNode *node, u32 flags) { // NOTE(bill): If there is a bad syntax error, rhs > lhs which would mean there would need to be // an extra allocation - Array operands; - array_init(&operands, c->tmp_allocator, 2 * as->lhs.count); + Array(Operand) operands; + array_init_reserve(&operands, c->tmp_allocator, 2 * as->lhs.count); for_array(i, as->rhs) { - AstNode *rhs = as->rhs[i]; + AstNode *rhs = as->rhs.e[i]; Operand o = {}; check_multi_expr(c, &o, rhs); if (o.type->kind != Type_Tuple) { @@ -456,11 +456,11 @@ void check_stmt_internal(Checker *c, AstNode *node, u32 flags) { isize operand_count = gb_min(as->lhs.count, operands.count); for (isize i = 0; i < operand_count; i++) { - AstNode *lhs = as->lhs[i]; - check_assignment_variable(c, &operands[i], lhs); + AstNode *lhs = as->lhs.e[i]; + check_assignment_variable(c, &operands.e[i], lhs); } if (lhs_count != rhs_count) { - error(ast_node_token(as->lhs[0]), "Assignment count mismatch `%td` = `%td`", lhs_count, rhs_count); + error(ast_node_token(as->lhs.e[0]), "Assignment count mismatch `%td` = `%td`", lhs_count, rhs_count); } gb_temp_arena_memory_end(tmp); @@ -484,15 +484,15 @@ void check_stmt_internal(Checker *c, AstNode *node, u32 flags) { be->op = op; be->op.kind = cast(TokenKind)(cast(i32)be->op.kind - (Token_AddEq - Token_Add)); // NOTE(bill): Only use the first one will be used - be->left = as->lhs[0]; - be->right = as->rhs[0]; + be->left = as->lhs.e[0]; + be->right = as->rhs.e[0]; check_binary_expr(c, &operand, &binary_expr); if (operand.mode == Addressing_Invalid) { return; } // NOTE(bill): Only use the first one will be used - check_assignment_variable(c, &operand, as->lhs[0]); + check_assignment_variable(c, &operand, as->lhs.e[0]); } break; } case_end; @@ -550,7 +550,7 @@ void check_stmt_internal(Checker *c, AstNode *node, u32 flags) { } - Type *proc_type = c->proc_stack[c->proc_stack.count-1]; + Type *proc_type = c->proc_stack.e[c->proc_stack.count-1]; isize result_count = 0; if (proc_type->Proc.results) { result_count = proc_type->Proc.results->Tuple.variable_count; @@ -569,7 +569,7 @@ void check_stmt_internal(Checker *c, AstNode *node, u32 flags) { rs->results, str_lit("return statement")); } } else if (rs->results.count > 0) { - error(ast_node_token(rs->results[0]), "No return values expected"); + error(ast_node_token(rs->results.e[0]), "No return values expected"); } case_end; @@ -628,7 +628,7 @@ void check_stmt_internal(Checker *c, AstNode *node, u32 flags) { AstNode *first_default = NULL; ast_node(bs, BlockStmt, ms->body); for_array(i, bs->stmts) { - AstNode *stmt = bs->stmts[i]; + AstNode *stmt = bs->stmts.e[i]; AstNode *default_stmt = NULL; if (stmt->kind == AstNode_CaseClause) { ast_node(cc, CaseClause, stmt); @@ -661,7 +661,7 @@ void check_stmt_internal(Checker *c, AstNode *node, u32 flags) { map_init(&seen, heap_allocator()); for_array(i, bs->stmts) { - AstNode *stmt = bs->stmts[i]; + AstNode *stmt = bs->stmts.e[i]; if (stmt->kind != AstNode_CaseClause) { // NOTE(bill): error handled by above multiple default checker continue; @@ -670,7 +670,7 @@ void check_stmt_internal(Checker *c, AstNode *node, u32 flags) { for_array(j, cc->list) { - AstNode *expr = cc->list[j]; + AstNode *expr = cc->list.e[j]; Operand y = {}; Operand z = {}; Token eq = {Token_CmpEq}; @@ -772,7 +772,7 @@ void check_stmt_internal(Checker *c, AstNode *node, u32 flags) { AstNode *first_default = NULL; ast_node(bs, BlockStmt, ms->body); for_array(i, bs->stmts) { - AstNode *stmt = bs->stmts[i]; + AstNode *stmt = bs->stmts.e[i]; AstNode *default_stmt = NULL; if (stmt->kind == AstNode_CaseClause) { ast_node(cc, CaseClause, stmt); @@ -804,7 +804,7 @@ void check_stmt_internal(Checker *c, AstNode *node, u32 flags) { map_init(&seen, heap_allocator()); for_array(i, bs->stmts) { - AstNode *stmt = bs->stmts[i]; + AstNode *stmt = bs->stmts.e[i]; if (stmt->kind != AstNode_CaseClause) { // NOTE(bill): error handled by above multiple default checker continue; @@ -815,7 +815,7 @@ void check_stmt_internal(Checker *c, AstNode *node, u32 flags) { Type *bt = base_type(type_deref(x.type)); - AstNode *type_expr = cc->list.count > 0 ? cc->list[0] : NULL; + AstNode *type_expr = cc->list.count > 0 ? cc->list.e[0] : NULL; Type *case_type = NULL; if (type_expr != NULL) { // Otherwise it's a default expression Operand y = {}; @@ -988,7 +988,7 @@ void check_stmt_internal(Checker *c, AstNode *node, u32 flags) { case Entity_ImportName: { Scope *scope = e->ImportName.scope; for_array(i, scope->elements.entries) { - Entity *decl = scope->elements.entries[i].value; + Entity *decl = scope->elements.entries.e[i].value; Entity *found = scope_insert_entity(c->context.scope, decl); if (found != NULL) { gbString expr_str = expr_to_string(expr); @@ -1012,7 +1012,7 @@ void check_stmt_internal(Checker *c, AstNode *node, u32 flags) { Scope **found = map_get(&c->info.scopes, hash_pointer(t->Record.node)); GB_ASSERT(found != NULL); for_array(i, (*found)->elements.entries) { - Entity *f = (*found)->elements.entries[i].value; + Entity *f = (*found)->elements.entries.e[i].value; if (f->kind == Entity_Variable) { Entity *uvar = make_entity_using_variable(c->allocator, e, f->token, f->type); if (is_selector) { @@ -1068,7 +1068,7 @@ void check_stmt_internal(Checker *c, AstNode *node, u32 flags) { check_var_decl_node(c, us->node); for_array(name_index, vd->names) { - AstNode *item = vd->names[name_index]; + AstNode *item = vd->names.e[name_index]; ast_node(i, Ident, item); String name = i->string; Entity *e = scope_lookup_entity(c->context.scope, name); @@ -1077,7 +1077,7 @@ void check_stmt_internal(Checker *c, AstNode *node, u32 flags) { Scope **found = map_get(&c->info.scopes, hash_pointer(t->Record.node)); GB_ASSERT(found != NULL); for_array(i, (*found)->elements.entries) { - Entity *f = (*found)->elements.entries[i].value; + Entity *f = (*found)->elements.entries.e[i].value; if (f->kind == Entity_Variable) { Entity *uvar = make_entity_using_variable(c->allocator, e, f->token, f->type); Entity *prev = scope_insert_entity(c->context.scope, uvar); diff --git a/src/checker/types.cpp b/src/checker/types.cpp index c10b8e6f1..8e814b9b6 100644 --- a/src/checker/types.cpp +++ b/src/checker/types.cpp @@ -805,14 +805,16 @@ struct BaseTypeSizes { i64 max_align; }; +typedef Array(isize) Array_isize; + struct Selection { - Entity *entity; - Array index; - b32 indirect; // Set if there was a pointer deref anywhere down the line + Entity * entity; + Array_isize index; + b32 indirect; // Set if there was a pointer deref anywhere down the line }; Selection empty_selection = {}; -Selection make_selection(Entity *entity, Array index, b32 indirect) { +Selection make_selection(Entity *entity, Array_isize index, b32 indirect) { Selection s = {entity, index, indirect}; return s; } @@ -820,7 +822,7 @@ Selection make_selection(Entity *entity, Array index, b32 indirect) { void selection_add_index(Selection *s, isize index) { // IMPORTANT NOTE(bill): this requires a stretchy buffer/dynamic array so it requires some form // of heap allocation - if (s->index.data == NULL) { + if (s->index.e == NULL) { array_init(&s->index, heap_allocator()); } array_add(&s->index, index); @@ -1334,7 +1336,7 @@ i64 type_offset_of_from_selection(BaseTypeSizes s, gbAllocator allocator, Type * Type *t = type; i64 offset = 0; for_array(i, sel.index) { - isize index = sel.index[i]; + isize index = sel.index.e[i]; t = base_type(t); offset += type_offset_of(s, allocator, t, index); if (t->kind == Type_Record && t->Record.kind == TypeRecord_Struct) { diff --git a/src/common.cpp b/src/common.cpp index ee4ca9817..e61ebaa98 100644 --- a/src/common.cpp +++ b/src/common.cpp @@ -18,13 +18,12 @@ String get_module_dir() { return global_module_path; } - Array path_buf; - array_init(&path_buf, heap_allocator(), 300); - array_resize(&path_buf, 300); + Array(wchar_t) path_buf; + array_init_count(&path_buf, heap_allocator(), 300); isize len = 0; for (;;) { - len = GetModuleFileNameW(NULL, &path_buf[0], path_buf.count); + len = GetModuleFileNameW(NULL, &path_buf.e[0], path_buf.count); if (len == 0) { return make_string(NULL, 0); } @@ -250,8 +249,8 @@ struct MapEntry { template struct Map { - Array hashes; - Array > entries; + Array(isize) hashes; + Array(MapEntry) entries; }; template void map_init (Map *h, gbAllocator a); @@ -284,8 +283,8 @@ gb_inline void map_init(Map *h, gbAllocator a) { template gb_inline void map_init_with_reserve(Map *h, gbAllocator a, isize capacity) { - array_init(&h->hashes, a, capacity); - array_init(&h->entries, a, capacity); + array_init_reserve(&h->hashes, a, capacity); + array_init_reserve(&h->entries, a, capacity); } template @@ -308,13 +307,13 @@ gb_internal MapFindResult map__find(Map *h, HashKey key) { MapFindResult fr = {-1, -1, -1}; if (h->hashes.count > 0) { fr.hash_index = key.key % h->hashes.count; - fr.entry_index = h->hashes[fr.hash_index]; + fr.entry_index = h->hashes.e[fr.hash_index]; while (fr.entry_index >= 0) { - if (hash_key_equal(h->entries[fr.entry_index].key, key)) { + if (hash_key_equal(h->entries.e[fr.entry_index].key, key)) { return fr; } fr.entry_prev = fr.entry_index; - fr.entry_index = h->entries[fr.entry_index].next; + fr.entry_index = h->entries.e[fr.entry_index].next; } } return fr; @@ -325,13 +324,13 @@ gb_internal MapFindResult map__find(Map *h, MapEntry *e) { MapFindResult fr = {-1, -1, -1}; if (h->hashes.count > 0) { fr.hash_index = e->key.key % h->hashes.count; - fr.entry_index = h->hashes[fr.hash_index]; + fr.entry_index = h->hashes.e[fr.hash_index]; while (fr.entry_index >= 0) { - if (&h->entries[fr.entry_index] == e) { + if (&h->entries.e[fr.entry_index] == e) { return fr; } fr.entry_prev = fr.entry_index; - fr.entry_index = h->entries[fr.entry_index].next; + fr.entry_index = h->entries.e[fr.entry_index].next; } } return fr; @@ -357,10 +356,10 @@ void map_rehash(Map *h, isize new_count) { array_resize(&nh.hashes, new_count); array_reserve(&nh.entries, h->entries.count); for (i = 0; i < new_count; i++) { - nh.hashes[i] = -1; + nh.hashes.e[i] = -1; } for (i = 0; i < h->entries.count; i++) { - MapEntry *e = &h->entries[i]; + MapEntry *e = &h->entries.e[i]; MapFindResult fr; if (nh.hashes.count == 0) { map_grow(&nh); @@ -368,12 +367,12 @@ void map_rehash(Map *h, isize new_count) { fr = map__find(&nh, e->key); j = map__add_entry(&nh, e->key); if (fr.entry_prev < 0) { - nh.hashes[fr.hash_index] = j; + nh.hashes.e[fr.hash_index] = j; } else { - nh.entries[fr.entry_prev].next = j; + nh.entries.e[fr.entry_prev].next = j; } - nh.entries[j].next = fr.entry_index; - nh.entries[j].value = e->value; + nh.entries.e[j].next = fr.entry_index; + nh.entries.e[j].value = e->value; if (map__full(&nh)) { map_grow(&nh); } @@ -386,7 +385,7 @@ template gb_inline T *map_get(Map *h, HashKey key) { isize index = map__find(h, key).entry_index; if (index >= 0) - return &h->entries[index].value; + return &h->entries.e[index].value; return NULL; } @@ -402,12 +401,12 @@ void map_set(Map *h, HashKey key, T value) { } else { index = map__add_entry(h, key); if (fr.entry_prev >= 0) { - h->entries[fr.entry_prev].next = index; + h->entries.e[fr.entry_prev].next = index; } else { - h->hashes[fr.hash_index] = index; + h->hashes.e[fr.hash_index] = index; } } - h->entries[index].value = value; + h->entries.e[index].value = value; if (map__full(h)) map_grow(h); @@ -418,20 +417,20 @@ void map_set(Map *h, HashKey key, T value) { template void map__erase(Map *h, MapFindResult fr) { if (fr.entry_prev < 0) { - h->hashes[fr.hash_index] = h->entries[fr.entry_index].next; + h->hashes.e[fr.hash_index] = h->entries.e[fr.entry_index].next; } else { - h->entries[fr.entry_prev].next = h->entries[fr.entry_index].next; + h->entries.e[fr.entry_prev].next = h->entries.e[fr.entry_index].next; } if (fr.entry_index == h->entries.count-1) { array_pop(&h->entries); return; } - h->entries[fr.entry_index] = h->entries[h->entries.count-1]; - MapFindResult last = map__find(h, h->entries[fr.entry_index].key); + h->entries.e[fr.entry_index] = h->entries.e[h->entries.count-1]; + MapFindResult last = map__find(h, h->entries.e[fr.entry_index].key); if (last.entry_prev >= 0) { - h->entries[last.entry_prev].next = fr.entry_index; + h->entries.e[last.entry_prev].next = fr.entry_index; } else { - h->hashes[last.hash_index] = fr.entry_index; + h->hashes.e[last.hash_index] = fr.entry_index; } } @@ -457,17 +456,17 @@ MapEntry *multi_map_find_first(Map *h, HashKey key) { if (i < 0) { return NULL; } - return &h->entries[i]; + return &h->entries.e[i]; } template MapEntry *multi_map_find_next(Map *h, MapEntry *e) { isize i = e->next; while (i >= 0) { - if (hash_key_equal(h->entries[i].key, e->key)) { - return &h->entries[i]; + if (hash_key_equal(h->entries.e[i].key, e->key)) { + return &h->entries.e[i]; } - i = h->entries[i].next; + i = h->entries.e[i].next; } return NULL; } @@ -501,12 +500,12 @@ void multi_map_insert(Map *h, HashKey key, T value) { MapFindResult fr = map__find(h, key); isize i = map__add_entry(h, key); if (fr.entry_prev < 0) { - h->hashes[fr.hash_index] = i; + h->hashes.e[fr.hash_index] = i; } else { - h->entries[fr.entry_prev].next = i; + h->entries.e[fr.entry_prev].next = i; } - h->entries[i].next = fr.entry_index; - h->entries[i].value = value; + h->entries.e[i].next = fr.entry_index; + h->entries.e[i].value = value; if (map__full(h)) { map_grow(h); } diff --git a/src/main.cpp b/src/main.cpp index a7a95a555..bb5232c81 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -233,7 +233,7 @@ int main(int argc, char **argv) { // defer (gb_string_free(lib_str)); char lib_str_buf[1024] = {0}; for_array(i, parser.foreign_libraries) { - String lib = parser.foreign_libraries[i]; + String lib = parser.foreign_libraries.e[i]; isize len = gb_snprintf(lib_str_buf, gb_size_of(lib_str_buf), " %.*s.lib", LIT(lib)); lib_str = gb_string_appendc(lib_str, lib_str_buf); diff --git a/src/parser.cpp b/src/parser.cpp index ae6043204..9956f5e3c 100644 --- a/src/parser.cpp +++ b/src/parser.cpp @@ -15,13 +15,13 @@ enum ParseFileError { ParseFile_Count, }; -typedef Array AstNodeArray; +typedef Array(AstNode *) AstNodeArray; struct AstFile { i32 id; gbArena arena; Tokenizer tokenizer; - Array tokens; + Array(Token) tokens; isize curr_token_index; Token curr_token; Token prev_token; // previous non-comment @@ -53,10 +53,10 @@ struct ImportedFile { struct Parser { String init_fullpath; - Array files; - Array imports; + Array(AstFile) files; + Array(ImportedFile) imports; gbAtomic32 import_index; - Array foreign_libraries; + Array(String) foreign_libraries; isize total_token_count; gbMutex mutex; }; @@ -452,9 +452,9 @@ Token ast_node_token(AstNode *node) { case AstNode_BadDecl: return node->BadDecl.begin; case AstNode_VarDecl: - return ast_node_token(node->VarDecl.names[0]); + return ast_node_token(node->VarDecl.names.e[0]); case AstNode_ConstDecl: - return ast_node_token(node->ConstDecl.names[0]); + return ast_node_token(node->ConstDecl.names.e[0]); case AstNode_ProcDecl: return node->ProcDecl.name->Ident; case AstNode_TypeDecl: @@ -465,7 +465,7 @@ Token ast_node_token(AstNode *node) { return node->ForeignLibrary.token; case AstNode_Parameter: { if (node->Parameter.names.count > 0) { - return ast_node_token(node->Parameter.names[0]); + return ast_node_token(node->Parameter.names.e[0]); } else { return ast_node_token(node->Parameter.type); } @@ -981,7 +981,7 @@ b32 next_token(AstFile *f) { } f->curr_token_index++; - f->curr_token = f->tokens[f->curr_token_index]; + f->curr_token = f->tokens.e[f->curr_token_index]; if (f->curr_token.kind == Token_Comment) { return next_token(f); } @@ -1518,8 +1518,8 @@ AstNode *parse_atom_expr(AstFile *f, b32 lhs) { // TODO(bill): Handle this } AstNode *proc = parse_identifier(f); - Array args; - array_init(&args, gb_arena_allocator(&f->arena), 1); + AstNodeArray args; + array_init_reserve(&args, gb_arena_allocator(&f->arena), 1); array_add(&args, operand); operand = make_call_expr(f, proc, args, ast_node_token(operand), op, empty_token); } break; @@ -1719,8 +1719,8 @@ AstNode *parse_binary_expr(AstFile *f, b32 lhs, i32 prec_in) { expression = call; } else */{ right = parse_binary_expr(f, false, prec+1); - Array args = {}; - array_init(&args, gb_arena_allocator(&f->arena), 2); + AstNodeArray args = {}; + array_init_reserve(&args, gb_arena_allocator(&f->arena), 2); array_add(&args, expression); array_add(&args, right); expression = make_call_expr(f, proc, args, op, ast_node_token(right), empty_token); @@ -1831,12 +1831,12 @@ AstNode *parse_simple_stmt(AstFile *f) { syntax_error(f->curr_token, "You cannot use a simple statement in the file scope"); return make_bad_stmt(f, f->curr_token, f->curr_token); } - statement = make_inc_dec_stmt(f, token, lhs[0]); + statement = make_inc_dec_stmt(f, token, lhs.e[0]); next_token(f); return statement; } - return make_expr_stmt(f, lhs[0]); + return make_expr_stmt(f, lhs.e[0]); } @@ -1858,7 +1858,7 @@ AstNode *convert_stmt_to_expr(AstFile *f, AstNode *statement, String kind) { return statement->ExprStmt.expr; syntax_error(f->curr_token, "Expected `%.*s`, found a simple statement.", LIT(kind)); - return make_bad_expr(f, f->curr_token, f->tokens[f->curr_token_index+1]); + return make_bad_expr(f, f->curr_token, f->tokens.e[f->curr_token_index+1]); } AstNodeArray parse_identfier_list(AstFile *f) { @@ -1998,11 +1998,11 @@ AstNodeArray parse_struct_params(AstFile *f, isize *decl_count_, b32 using_allow if (decl->kind == AstNode_ProcDecl) { syntax_error(f->curr_token, "Procedure declarations are not allowed within a structure"); - decl = make_bad_decl(f, ast_node_token(names[0]), f->curr_token); + decl = make_bad_decl(f, ast_node_token(names.e[0]), f->curr_token); } } else { syntax_error(f->curr_token, "Illegal structure field"); - decl = make_bad_decl(f, ast_node_token(names[0]), f->curr_token); + decl = make_bad_decl(f, ast_node_token(names.e[0]), f->curr_token); } expect_semicolon_after_stmt(f, decl); @@ -2280,7 +2280,7 @@ AstNode *parse_decl(AstFile *f, AstNodeArray names) { AstNode *type = NULL; for_array(i, names) { - AstNode *name = names[i]; + AstNode *name = names.e[i]; if (name->kind == AstNode_Ident) { String n = name->Ident.string; // NOTE(bill): Check for reserved identifiers @@ -2318,8 +2318,8 @@ AstNode *parse_decl(AstFile *f, AstNodeArray names) { next_token(f); } if (names.count != 1) { - syntax_error(ast_node_token(names[0]), "You can only declare one type at a time"); - return make_bad_decl(f, names[0]->Ident, token); + syntax_error(ast_node_token(names.e[0]), "You can only declare one type at a time"); + return make_bad_decl(f, names.e[0]->Ident, token); } if (type != NULL) { @@ -2327,12 +2327,12 @@ AstNode *parse_decl(AstFile *f, AstNodeArray names) { // NOTE(bill): Do not fail though } - return make_type_decl(f, token, names[0], parse_type(f)); + return make_type_decl(f, token, names.e[0], parse_type(f)); } else if (f->curr_token.kind == Token_proc && is_mutable == false) { // NOTE(bill): Procedure declarations Token proc_token = f->curr_token; - AstNode *name = names[0]; + AstNode *name = names.e[0]; if (names.count != 1) { syntax_error(proc_token, "You can only declare one procedure at a time"); return make_bad_decl(f, name->Ident, proc_token); @@ -2364,7 +2364,7 @@ AstNode *parse_decl(AstFile *f, AstNodeArray names) { } } - if (values.data == NULL) { + if (values.e == NULL) { values = make_ast_node_array(f); } @@ -2421,7 +2421,7 @@ AstNode *parse_if_stmt(AstFile *f) { break; default: syntax_error(f->curr_token, "Expected if statement block statement"); - else_stmt = make_bad_stmt(f, f->curr_token, f->tokens[f->curr_token_index+1]); + else_stmt = make_bad_stmt(f, f->curr_token, f->tokens.e[f->curr_token_index+1]); break; } } @@ -2443,7 +2443,7 @@ AstNode *parse_return_stmt(AstFile *f) { results = parse_rhs_expr_list(f); } if (f->curr_token.kind != Token_CloseBrace) { - expect_semicolon_after_stmt(f, results[0]); + expect_semicolon_after_stmt(f, results.e[0]); } return make_return_stmt(f, token, results); @@ -2891,8 +2891,8 @@ ParseFileError init_ast_file(AstFile *f, String fullpath) { } f->curr_token_index = 0; - f->prev_token = f->tokens[f->curr_token_index]; - f->curr_token = f->tokens[f->curr_token_index]; + f->prev_token = f->tokens.e[f->curr_token_index]; + f->curr_token = f->tokens.e[f->curr_token_index]; // NOTE(bill): Is this big enough or too small? isize arena_size = gb_size_of(AstNode); @@ -2934,7 +2934,7 @@ b32 init_parser(Parser *p) { void destroy_parser(Parser *p) { // TODO(bill): Fix memory leak for_array(i, p->files) { - destroy_ast_file(&p->files[i]); + destroy_ast_file(&p->files.e[i]); } #if 1 for_array(i, p->imports) { @@ -2952,7 +2952,7 @@ b32 try_add_import_path(Parser *p, String path, String rel_path, TokenPos pos) { gb_mutex_lock(&p->mutex); for_array(i, p->imports) { - String import = p->imports[i].path; + String import = p->imports.e[i].path; if (str_eq(import, path)) { return false; } @@ -3009,7 +3009,7 @@ b32 try_add_foreign_library_path(Parser *p, String import_file) { gb_mutex_lock(&p->mutex); for_array(i, p->foreign_libraries) { - String import = p->foreign_libraries[i]; + String import = p->foreign_libraries.e[i]; if (str_eq(import, import_file)) { return false; } @@ -3096,7 +3096,7 @@ void parse_file(Parser *p, AstFile *f) { f->decls = parse_stmt_list(f); for_array(i, f->decls) { - AstNode *node = f->decls[i]; + AstNode *node = f->decls.e[i]; if (!is_ast_node_decl(node) && node->kind != AstNode_BadStmt && node->kind != AstNode_EmptyStmt) { @@ -3114,7 +3114,7 @@ void parse_file(Parser *p, AstFile *f) { syntax_error(ast_node_token(node), "Invalid #import path: `%.*s`", LIT(file_str)); } // NOTE(bill): It's a naughty name - f->decls[i] = make_bad_decl(f, id->token, id->token); + f->decls.e[i] = make_bad_decl(f, id->token, id->token); continue; } @@ -3143,7 +3143,7 @@ void parse_file(Parser *p, AstFile *f) { syntax_error(ast_node_token(node), "Invalid `foreign_library` path"); } // NOTE(bill): It's a naughty name - f->decls[i] = make_bad_decl(f, id->token, id->token); + f->decls.e[i] = make_bad_decl(f, id->token, id->token); continue; } @@ -3189,7 +3189,7 @@ ParseFileError parse_files(Parser *p, char *init_filename) { } for_array(i, p->imports) { - ImportedFile imported_file = p->imports[i]; + ImportedFile imported_file = p->imports.e[i]; String import_path = imported_file.path; String import_rel_path = imported_file.rel_path; TokenPos pos = imported_file.pos; @@ -3235,7 +3235,7 @@ ParseFileError parse_files(Parser *p, char *init_filename) { } for_array(i, p->files) { - p->total_token_count += p->files[i].tokens.count; + p->total_token_count += p->files.e[i].tokens.count; } diff --git a/src/ssa.cpp b/src/ssa.cpp index 76ec843a8..244b33de1 100644 --- a/src/ssa.cpp +++ b/src/ssa.cpp @@ -1,7 +1,9 @@ -struct ssaProcedure; -struct ssaBlock; -struct ssaValue; -struct ssaDebugInfo; +typedef struct ssaProcedure ssaProcedure; +typedef struct ssaBlock ssaBlock; +typedef struct ssaValue ssaValue; +typedef struct ssaDebugInfo ssaDebugInfo; + +typedef Array(ssaValue *) ssaValueArray; struct ssaModule { CheckerInfo * info; @@ -27,14 +29,14 @@ struct ssaModule { i32 global_string_index; i32 global_array_index; // For ConstantSlice - Array procs; // NOTE(bill): All procedures with bodies - Array procs_to_generate; // NOTE(bill): Procedures to generate + Array(ssaProcedure *) procs; // NOTE(bill): All procedures with bodies + ssaValueArray procs_to_generate; // NOTE(bill): Procedures to generate }; // NOTE(bill): For more info, see https://en.wikipedia.org/wiki/Dominator_(graph_theory) struct ssaDomNode { ssaBlock * idom; // Parent (Immediate Dominator) - Array children; + Array(ssaBlock *) children; i32 pre, post; // Ordering in tree }; @@ -49,11 +51,11 @@ struct ssaBlock { ssaDomNode dom; i32 gaps; - Array instrs; - Array locals; + ssaValueArray instrs; + ssaValueArray locals; - Array preds; - Array succs; + Array(ssaBlock *) preds; + Array(ssaBlock *) succs; }; struct ssaTargetList { @@ -86,7 +88,7 @@ struct ssaDefer { struct ssaProcedure { ssaProcedure * parent; - Array children; + Array(ssaProcedure *) children; Entity * entity; ssaModule * module; @@ -96,15 +98,15 @@ struct ssaProcedure { AstNode * body; u64 tags; - Array params; - Array defer_stmts; - Array blocks; + ssaValueArray params; + Array(ssaDefer) defer_stmts; + Array(ssaBlock *) blocks; i32 scope_index; ssaBlock * decl_block; ssaBlock * entry_block; ssaBlock * curr_block; ssaTargetList * target_list; - Array referrers; + ssaValueArray referrers; i32 local_count; i32 instr_count; @@ -198,7 +200,7 @@ struct ssaInstr { Entity * entity; Type * type; b32 zero_initialized; - Array referrers; + ssaValueArray referrers; } Local; struct { ssaValue *address; @@ -271,7 +273,7 @@ struct ssaInstr { ssaValue *false_value; } Select; struct { - Array edges; + ssaValueArray edges; Type *type; } Phi; struct { @@ -359,7 +361,7 @@ struct ssaValue { Entity * entity; Type * type; ssaValue * value; - Array referrers; + ssaValueArray referrers; b8 is_constant; b8 is_private; b8 is_thread_local; @@ -369,7 +371,7 @@ struct ssaValue { ssaProcedure * parent; Entity * entity; Type * type; - Array referrers; + ssaValueArray referrers; } Param; ssaProcedure Proc; ssaBlock Block; @@ -483,7 +485,7 @@ struct ssaDebugInfo { TokenPos pos; } Proc; struct { - Array procs; + Array(ssaDebugInfo *) procs; } AllProcs; @@ -495,7 +497,7 @@ struct ssaDebugInfo { } BasicType; struct { ssaDebugInfo * return_type; - Array param_types; + Array(ssaDebugInfo *) param_types; } ProcType; struct { ssaDebugInfo * base_type; @@ -509,7 +511,7 @@ struct ssaDebugInfo { TokenPos pos; i32 size; i32 align; - Array elements; + Array(ssaDebugInfo *) elements; } CompositeType; struct { String name; @@ -649,7 +651,7 @@ ssaInstr *ssa_get_last_instr(ssaBlock *block) { if (block != NULL) { isize len = block->instrs.count; if (len > 0) { - ssaValue *v = block->instrs[len-1]; + ssaValue *v = block->instrs.e[len-1]; GB_ASSERT(v->kind == ssaValue_Instr); return &v->Instr; } @@ -682,7 +684,7 @@ void ssa_set_instr_parent(ssaValue *instr, ssaBlock *parent) { } } -Array *ssa_value_referrers(ssaValue *v) { +ssaValueArray *ssa_value_referrers(ssaValue *v) { switch (v->kind) { case ssaValue_Global: return &v->Global.referrers; @@ -927,7 +929,7 @@ ssaValue *ssa_make_instr_if(ssaProcedure *p, ssaValue *cond, ssaBlock *true_bloc } -ssaValue *ssa_make_instr_phi(ssaProcedure *p, Array edges, Type *type) { +ssaValue *ssa_make_instr_phi(ssaProcedure *p, ssaValueArray edges, Type *type) { ssaValue *v = ssa_alloc_instr(p, ssaInstr_Phi); ssaInstr *i = &v->Instr; i->Phi.edges = edges; @@ -1064,11 +1066,11 @@ ssaValue *ssa_make_value_procedure(gbAllocator a, ssaModule *m, Entity *entity, v->Proc.type_expr = type_expr; v->Proc.body = body; v->Proc.name = name; - array_init(&v->Proc.referrers, heap_allocator(), 0); // TODO(bill): replace heap allocator + array_init(&v->Proc.referrers, heap_allocator()); // TODO(bill): replace heap allocator Type *t = base_type(type); GB_ASSERT(is_type_proc(t)); - array_init(&v->Proc.params, heap_allocator(), t->Proc.param_count); + array_init_reserve(&v->Proc.params, heap_allocator(), t->Proc.param_count); return v; } @@ -1359,7 +1361,7 @@ void ssa_emit_defer_stmts(ssaProcedure *proc, ssaDeferExitKind kind, ssaBlock *b isize count = proc->defer_stmts.count; isize i = count; while (i --> 0) { - ssaDefer d = proc->defer_stmts[i]; + ssaDefer d = proc->defer_stmts.e[i]; if (kind == ssaDeferExit_Default) { if (proc->scope_index == d.scope_index && d.scope_index > 1) { @@ -1686,7 +1688,7 @@ ssaValue *ssa_emit_deep_field_gep(ssaProcedure *proc, Type *type, ssaValue *e, S GB_ASSERT(sel.index.count > 0); for_array(i, sel.index) { - i32 index = cast(i32)sel.index[i]; + i32 index = cast(i32)sel.index.e[i]; if (is_type_pointer(type)) { type = type_deref(type); e = ssa_emit_load(proc, e); @@ -1739,7 +1741,7 @@ ssaValue *ssa_emit_deep_field_ev(ssaProcedure *proc, Type *type, ssaValue *e, Se GB_ASSERT(sel.index.count > 0); for_array(i, sel.index) { - isize index = sel.index[i]; + i32 index = cast(i32)sel.index.e[i]; if (is_type_pointer(type)) { type = type_deref(type); e = ssa_emit_load(proc, e); @@ -2336,7 +2338,7 @@ isize ssa_type_info_index(CheckerInfo *info, Type *type) { // NOTE(bill): Do manual search // TODO(bill): This is O(n) and can be very slow for_array(i, info->type_info_map.entries){ - auto *e = &info->type_info_map.entries[i]; + auto *e = &info->type_info_map.entries.e[i]; Type *prev_type = cast(Type *)e->key.ptr; if (are_types_identical(prev_type, type)) { entry_index = e->value; @@ -2417,8 +2419,8 @@ ssaValue *ssa_emit_logical_binary_expr(ssaProcedure *proc, AstNode *expr) { return ssa_build_expr(proc, be->right); } - Array edges = {}; - array_init(&edges, proc->module->allocator, done->preds.count+1); + ssaValueArray edges = {}; + array_init_reserve(&edges, proc->module->allocator, done->preds.count+1); for_array(i, done->preds) { array_add(&edges, short_circuit); } @@ -2754,11 +2756,11 @@ ssaValue *ssa_build_single_expr(ssaProcedure *proc, AstNode *expr, TypeAndValue Entity *e = *found; switch (e->Builtin.id) { case BuiltinProc_type_info: { - Type *t = default_type(type_of_expr(proc->module->info, ce->args[0])); + Type *t = default_type(type_of_expr(proc->module->info, ce->args.e[0])); return ssa_type_info(proc, t); } break; case BuiltinProc_type_info_of_val: { - Type *t = default_type(type_of_expr(proc->module->info, ce->args[0])); + Type *t = default_type(type_of_expr(proc->module->info, ce->args.e[0])); return ssa_type_info(proc, t); } break; @@ -2767,7 +2769,7 @@ ssaValue *ssa_build_single_expr(ssaProcedure *proc, AstNode *expr, TypeAndValue // new :: proc(Type) -> ^Type gbAllocator allocator = proc->module->allocator; - Type *type = type_of_expr(proc->module->info, ce->args[0]); + Type *type = type_of_expr(proc->module->info, ce->args.e[0]); Type *ptr_type = make_type_pointer(allocator, type); i64 s = type_size_of(proc->module->sizes, allocator, type); @@ -2786,7 +2788,7 @@ ssaValue *ssa_build_single_expr(ssaProcedure *proc, AstNode *expr, TypeAndValue // new_slice :: proc(Type, len: int[, cap: int]) -> ^Type gbAllocator allocator = proc->module->allocator; - Type *type = type_of_expr(proc->module->info, ce->args[0]); + Type *type = type_of_expr(proc->module->info, ce->args.e[0]); Type *ptr_type = make_type_pointer(allocator, type); Type *slice_type = make_type_slice(allocator, type); @@ -2796,13 +2798,13 @@ ssaValue *ssa_build_single_expr(ssaProcedure *proc, AstNode *expr, TypeAndValue ssaValue *elem_size = ssa_make_const_int(allocator, s); ssaValue *elem_align = ssa_make_const_int(allocator, a); - ssaValue *len = ssa_emit_conv(proc, ssa_build_expr(proc, ce->args[1]), t_int); + ssaValue *len = ssa_emit_conv(proc, ssa_build_expr(proc, ce->args.e[1]), t_int); ssaValue *cap = len; if (ce->args.count == 3) { - cap = ssa_emit_conv(proc, ssa_build_expr(proc, ce->args[2]), t_int); + cap = ssa_emit_conv(proc, ssa_build_expr(proc, ce->args.e[2]), t_int); } - ssa_emit_slice_bounds_check(proc, ast_node_token(ce->args[1]), v_zero, len, cap, false); + ssa_emit_slice_bounds_check(proc, ast_node_token(ce->args.e[1]), v_zero, len, cap, false); ssaValue *slice_size = ssa_emit_arith(proc, Token_Mul, elem_size, cap, t_int); @@ -2825,7 +2827,7 @@ ssaValue *ssa_build_single_expr(ssaProcedure *proc, AstNode *expr, TypeAndValue case BuiltinProc_assert: { ssa_emit_comment(proc, str_lit("assert")); - ssaValue *cond = ssa_build_expr(proc, ce->args[0]); + ssaValue *cond = ssa_build_expr(proc, ce->args.e[0]); GB_ASSERT(is_type_boolean(ssa_type(cond))); cond = ssa_emit_comp(proc, Token_CmpEq, cond, v_false); @@ -2836,9 +2838,9 @@ ssaValue *ssa_build_single_expr(ssaProcedure *proc, AstNode *expr, TypeAndValue proc->curr_block = err; // TODO(bill): Cleanup allocations here - Token token = ast_node_token(ce->args[0]); + Token token = ast_node_token(ce->args.e[0]); TokenPos pos = token.pos; - gbString expr = expr_to_string(ce->args[0]); + gbString expr = expr_to_string(ce->args.e[0]); isize expr_len = gb_string_length(expr); String expr_str = {}; expr_str.text = cast(u8 *)gb_alloc_copy_align(proc->module->allocator, expr, expr_len, 1); @@ -2861,10 +2863,10 @@ ssaValue *ssa_build_single_expr(ssaProcedure *proc, AstNode *expr, TypeAndValue case BuiltinProc_panic: { ssa_emit_comment(proc, str_lit("panic")); - ssaValue *msg = ssa_build_expr(proc, ce->args[0]); + ssaValue *msg = ssa_build_expr(proc, ce->args.e[0]); GB_ASSERT(is_type_string(ssa_type(msg))); - Token token = ast_node_token(ce->args[0]); + Token token = ast_node_token(ce->args.e[0]); TokenPos pos = token.pos; ssaValue **args = gb_alloc_array(proc->module->allocator, ssaValue *, 4); @@ -2881,8 +2883,8 @@ ssaValue *ssa_build_single_expr(ssaProcedure *proc, AstNode *expr, TypeAndValue case BuiltinProc_copy: { ssa_emit_comment(proc, str_lit("copy")); // copy :: proc(dst, src: []Type) -> int - AstNode *dst_node = ce->args[0]; - AstNode *src_node = ce->args[1]; + AstNode *dst_node = ce->args.e[0]; + AstNode *src_node = ce->args.e[1]; ssaValue *dst_slice = ssa_build_expr(proc, dst_node); ssaValue *src_slice = ssa_build_expr(proc, src_node); Type *slice_type = base_type(ssa_type(dst_slice)); @@ -2915,8 +2917,8 @@ ssaValue *ssa_build_single_expr(ssaProcedure *proc, AstNode *expr, TypeAndValue case BuiltinProc_append: { ssa_emit_comment(proc, str_lit("append")); // append :: proc(s: ^[]Type, item: Type) -> bool - AstNode *sptr_node = ce->args[0]; - AstNode *item_node = ce->args[1]; + AstNode *sptr_node = ce->args.e[0]; + AstNode *item_node = ce->args.e[1]; ssaValue *slice_ptr = ssa_build_expr(proc, sptr_node); ssaValue *slice = ssa_emit_load(proc, slice_ptr); @@ -2971,7 +2973,7 @@ ssaValue *ssa_build_single_expr(ssaProcedure *proc, AstNode *expr, TypeAndValue case BuiltinProc_swizzle: { ssa_emit_comment(proc, str_lit("swizzle")); - ssaValue *vector = ssa_build_expr(proc, ce->args[0]); + ssaValue *vector = ssa_build_expr(proc, ce->args.e[0]); isize index_count = ce->args.count-1; if (index_count == 0) { return vector; @@ -2981,7 +2983,7 @@ ssaValue *ssa_build_single_expr(ssaProcedure *proc, AstNode *expr, TypeAndValue isize index = 0; for_array(i, ce->args) { if (i == 0) continue; - TypeAndValue *tv = type_and_value_of_expression(proc->module->info, ce->args[i]); + TypeAndValue *tv = type_and_value_of_expression(proc->module->info, ce->args.e[i]); GB_ASSERT(is_type_integer(tv->type)); GB_ASSERT(tv->value.kind == ExactValue_Integer); indices[index++] = cast(i32)tv->value.value_integer; @@ -2994,15 +2996,15 @@ ssaValue *ssa_build_single_expr(ssaProcedure *proc, AstNode *expr, TypeAndValue #if 0 case BuiltinProc_ptr_offset: { ssa_emit_comment(proc, str_lit("ptr_offset")); - ssaValue *ptr = ssa_build_expr(proc, ce->args[0]); - ssaValue *offset = ssa_build_expr(proc, ce->args[1]); + ssaValue *ptr = ssa_build_expr(proc, ce->args.e[0]); + ssaValue *offset = ssa_build_expr(proc, ce->args.e[1]); return ssa_emit_ptr_offset(proc, ptr, offset); } break; case BuiltinProc_ptr_sub: { ssa_emit_comment(proc, str_lit("ptr_sub")); - ssaValue *ptr_a = ssa_build_expr(proc, ce->args[0]); - ssaValue *ptr_b = ssa_build_expr(proc, ce->args[1]); + ssaValue *ptr_a = ssa_build_expr(proc, ce->args.e[0]); + ssaValue *ptr_b = ssa_build_expr(proc, ce->args.e[1]); Type *ptr_type = base_type(ssa_type(ptr_a)); GB_ASSERT(ptr_type->kind == Type_Pointer); isize elem_size = type_size_of(proc->module->sizes, proc->module->allocator, ptr_type->Pointer.elem); @@ -3019,14 +3021,14 @@ ssaValue *ssa_build_single_expr(ssaProcedure *proc, AstNode *expr, TypeAndValue case BuiltinProc_slice_ptr: { ssa_emit_comment(proc, str_lit("slice_ptr")); - ssaValue *ptr = ssa_build_expr(proc, ce->args[0]); - ssaValue *len = ssa_build_expr(proc, ce->args[1]); + ssaValue *ptr = ssa_build_expr(proc, ce->args.e[0]); + ssaValue *len = ssa_build_expr(proc, ce->args.e[1]); ssaValue *cap = len; len = ssa_emit_conv(proc, len, t_int); if (ce->args.count == 3) { - cap = ssa_build_expr(proc, ce->args[2]); + cap = ssa_build_expr(proc, ce->args.e[2]); cap = ssa_emit_conv(proc, cap, t_int); } @@ -3041,8 +3043,8 @@ ssaValue *ssa_build_single_expr(ssaProcedure *proc, AstNode *expr, TypeAndValue case BuiltinProc_min: { ssa_emit_comment(proc, str_lit("min")); - ssaValue *x = ssa_build_expr(proc, ce->args[0]); - ssaValue *y = ssa_build_expr(proc, ce->args[1]); + ssaValue *x = ssa_build_expr(proc, ce->args.e[0]); + ssaValue *y = ssa_build_expr(proc, ce->args.e[1]); Type *t = base_type(ssa_type(x)); ssaValue *cond = ssa_emit_comp(proc, Token_Lt, x, y); return ssa_emit_select(proc, cond, x, y); @@ -3050,8 +3052,8 @@ ssaValue *ssa_build_single_expr(ssaProcedure *proc, AstNode *expr, TypeAndValue case BuiltinProc_max: { ssa_emit_comment(proc, str_lit("max")); - ssaValue *x = ssa_build_expr(proc, ce->args[0]); - ssaValue *y = ssa_build_expr(proc, ce->args[1]); + ssaValue *x = ssa_build_expr(proc, ce->args.e[0]); + ssaValue *y = ssa_build_expr(proc, ce->args.e[1]); Type *t = base_type(ssa_type(x)); ssaValue *cond = ssa_emit_comp(proc, Token_Gt, x, y); return ssa_emit_select(proc, cond, x, y); @@ -3061,7 +3063,7 @@ ssaValue *ssa_build_single_expr(ssaProcedure *proc, AstNode *expr, TypeAndValue ssa_emit_comment(proc, str_lit("abs")); gbAllocator a = proc->module->allocator; - ssaValue *x = ssa_build_expr(proc, ce->args[0]); + ssaValue *x = ssa_build_expr(proc, ce->args.e[0]); Type *original_type = ssa_type(x); Type *t = original_type; i64 sz = type_size_of(proc->module->sizes, a, t); @@ -3100,7 +3102,7 @@ ssaValue *ssa_build_single_expr(ssaProcedure *proc, AstNode *expr, TypeAndValue case BuiltinProc_enum_to_string: { ssa_emit_comment(proc, str_lit("enum_to_string")); - ssaValue *x = ssa_build_expr(proc, ce->args[0]); + ssaValue *x = ssa_build_expr(proc, ce->args.e[0]); Type *t = ssa_type(x); ssaValue *ti = ssa_type_info(proc, t); @@ -3125,7 +3127,7 @@ ssaValue *ssa_build_single_expr(ssaProcedure *proc, AstNode *expr, TypeAndValue isize arg_count = 0; for_array(i, ce->args) { - AstNode *a = ce->args[i]; + AstNode *a = ce->args.e[i]; Type *at = base_type(type_of_expr(proc->module->info, a)); if (at->kind == Type_Tuple) { arg_count += at->Tuple.variable_count; @@ -3138,7 +3140,7 @@ ssaValue *ssa_build_single_expr(ssaProcedure *proc, AstNode *expr, TypeAndValue b32 vari_expand = ce->ellipsis.pos.line != 0; for_array(i, ce->args) { - ssaValue *a = ssa_build_expr(proc, ce->args[i]); + ssaValue *a = ssa_build_expr(proc, ce->args.e[i]); Type *at = ssa_type(a); if (at->kind == Type_Tuple) { for (isize i = 0; i < at->Tuple.variable_count; i++) { @@ -3614,7 +3616,7 @@ ssaAddr ssa_build_addr(ssaProcedure *proc, AstNode *expr) { case Type_Vector: { ssaValue *result = ssa_add_module_constant(proc->module, type, make_exact_value_compound(expr)); for_array(index, cl->elems) { - AstNode *elem = cl->elems[index]; + AstNode *elem = cl->elems.e[index]; if (is_elem_const(proc->module, elem, et)) { continue; } @@ -3645,7 +3647,7 @@ ssaAddr ssa_build_addr(ssaProcedure *proc, AstNode *expr) { if (cl->elems.count > 0) { ssa_emit_store(proc, v, ssa_add_module_constant(proc->module, type, make_exact_value_compound(expr))); for_array(field_index, cl->elems) { - AstNode *elem = cl->elems[field_index]; + AstNode *elem = cl->elems.e[field_index]; ssaValue *field_expr = NULL; Entity *field = NULL; @@ -3654,12 +3656,12 @@ ssaAddr ssa_build_addr(ssaProcedure *proc, AstNode *expr) { if (elem->kind == AstNode_FieldValue) { ast_node(fv, FieldValue, elem); Selection sel = lookup_field(proc->module->allocator, bt, fv->field->Ident.string, false); - index = sel.index[0]; + index = sel.index.e[0]; elem = fv->value; } else { TypeAndValue *tav = type_and_value_of_expression(proc->module->info, elem); Selection sel = lookup_field(proc->module->allocator, bt, st->fields_in_src_order[field_index]->token.string, false); - index = sel.index[0]; + index = sel.index.e[0]; } field = st->fields[index]; @@ -3682,7 +3684,7 @@ ssaAddr ssa_build_addr(ssaProcedure *proc, AstNode *expr) { if (cl->elems.count > 0) { ssa_emit_store(proc, v, ssa_add_module_constant(proc->module, type, make_exact_value_compound(expr))); for_array(i, cl->elems) { - AstNode *elem = cl->elems[i]; + AstNode *elem = cl->elems.e[i]; if (is_elem_const(proc->module, elem, et)) { continue; } @@ -3706,7 +3708,7 @@ ssaAddr ssa_build_addr(ssaProcedure *proc, AstNode *expr) { ssaValue *data = ssa_emit_array_ep(proc, slice->ConstantSlice.backing_array, v_zero32); for_array(i, cl->elems) { - AstNode *elem = cl->elems[i]; + AstNode *elem = cl->elems.e[i]; if (is_elem_const(proc->module, elem, et)) { continue; } @@ -3802,7 +3804,7 @@ void ssa_build_cond(ssaProcedure *proc, AstNode *cond, ssaBlock *true_block, ssa void ssa_build_stmt_list(ssaProcedure *proc, AstNodeArray stmts) { for_array(i, stmts) { - ssa_build_stmt(proc, stmts[i]); + ssa_build_stmt(proc, stmts.e[i]); } } @@ -3848,19 +3850,19 @@ void ssa_build_stmt_internal(ssaProcedure *proc, AstNode *node) { if (vd->values.count == 0) { // declared and zero-initialized for_array(i, vd->names) { - AstNode *name = vd->names[i]; + AstNode *name = vd->names.e[i]; if (!ssa_is_blank_ident(name)) { ssa_add_local_for_identifier(proc, name, true); } } } else { // Tuple(s) - Array lvals; - Array inits; - array_init(&lvals, m->tmp_allocator, vd->names.count); - array_init(&inits, m->tmp_allocator, vd->names.count); + Array(ssaAddr) lvals; + ssaValueArray inits; + array_init_reserve(&lvals, m->tmp_allocator, vd->names.count); + array_init_reserve(&inits, m->tmp_allocator, vd->names.count); for_array(i, vd->names) { - AstNode *name = vd->names[i]; + AstNode *name = vd->names.e[i]; ssaAddr lval = ssa_make_addr(NULL, NULL); if (!ssa_is_blank_ident(name)) { ssa_add_local_for_identifier(proc, name, false); @@ -3871,7 +3873,7 @@ void ssa_build_stmt_internal(ssaProcedure *proc, AstNode *node) { } for_array(i, vd->values) { - ssaValue *init = ssa_build_expr(proc, vd->values[i]); + ssaValue *init = ssa_build_expr(proc, vd->values.e[i]); Type *t = ssa_type(init); if (t->kind == Type_Tuple) { for (isize i = 0; i < t->Tuple.variable_count; i++) { @@ -3886,11 +3888,11 @@ void ssa_build_stmt_internal(ssaProcedure *proc, AstNode *node) { for_array(i, inits) { - if (lvals[i].addr == NULL) { + if (lvals.e[i].addr == NULL) { continue; } - ssaValue *v = ssa_emit_conv(proc, inits[i], ssa_addr_type(lvals[i])); - ssa_addr_store(proc, lvals[i], v); + ssaValue *v = ssa_emit_conv(proc, inits.e[i], ssa_addr_type(lvals.e[i])); + ssa_addr_store(proc, lvals.e[i], v); } } @@ -4012,11 +4014,11 @@ void ssa_build_stmt_internal(ssaProcedure *proc, AstNode *node) { switch (as->op.kind) { case Token_Eq: { - Array lvals; + Array(ssaAddr) lvals; array_init(&lvals, m->tmp_allocator); for_array(i, as->lhs) { - AstNode *lhs = as->lhs[i]; + AstNode *lhs = as->lhs.e[i]; ssaAddr lval = {}; if (!ssa_is_blank_ident(lhs)) { lval = ssa_build_addr(proc, lhs); @@ -4026,28 +4028,28 @@ void ssa_build_stmt_internal(ssaProcedure *proc, AstNode *node) { if (as->lhs.count == as->rhs.count) { if (as->lhs.count == 1) { - AstNode *rhs = as->rhs[0]; + AstNode *rhs = as->rhs.e[0]; ssaValue *init = ssa_build_expr(proc, rhs); - ssa_addr_store(proc, lvals[0], init); + ssa_addr_store(proc, lvals.e[0], init); } else { - Array inits; - array_init(&inits, m->tmp_allocator, lvals.count); + ssaValueArray inits; + array_init_reserve(&inits, m->tmp_allocator, lvals.count); for_array(i, as->rhs) { - ssaValue *init = ssa_build_expr(proc, as->rhs[i]); + ssaValue *init = ssa_build_expr(proc, as->rhs.e[i]); array_add(&inits, init); } for_array(i, inits) { - ssa_addr_store(proc, lvals[i], inits[i]); + ssa_addr_store(proc, lvals.e[i], inits.e[i]); } } } else { - Array inits; - array_init(&inits, m->tmp_allocator, lvals.count); + ssaValueArray inits; + array_init_reserve(&inits, m->tmp_allocator, lvals.count); for_array(i, as->rhs) { - ssaValue *init = ssa_build_expr(proc, as->rhs[i]); + ssaValue *init = ssa_build_expr(proc, as->rhs.e[i]); Type *t = ssa_type(init); // TODO(bill): refactor for code reuse as this is repeated a bit if (t->kind == Type_Tuple) { @@ -4062,7 +4064,7 @@ void ssa_build_stmt_internal(ssaProcedure *proc, AstNode *node) { } for_array(i, inits) { - ssa_addr_store(proc, lvals[i], inits[i]); + ssa_addr_store(proc, lvals.e[i], inits.e[i]); } } @@ -4073,8 +4075,8 @@ void ssa_build_stmt_internal(ssaProcedure *proc, AstNode *node) { // +=, -=, etc i32 op = cast(i32)as->op.kind; op += Token_Add - Token_AddEq; // Convert += to + - ssaAddr lhs = ssa_build_addr(proc, as->lhs[0]); - ssaValue *value = ssa_build_expr(proc, as->rhs[0]); + ssaAddr lhs = ssa_build_addr(proc, as->lhs.e[0]); + ssaValue *value = ssa_build_expr(proc, as->rhs.e[0]); ssa_build_assign_op(proc, lhs, value, cast(TokenKind)op); } break; } @@ -4111,15 +4113,15 @@ void ssa_build_stmt_internal(ssaProcedure *proc, AstNode *node) { // No return values } else if (return_count == 1) { Entity *e = return_type_tuple->variables[0]; - v = ssa_emit_conv(proc, ssa_build_expr(proc, rs->results[0]), e->type); + v = ssa_emit_conv(proc, ssa_build_expr(proc, rs->results.e[0]), e->type); } else { gbTempArenaMemory tmp = gb_temp_arena_memory_begin(&proc->module->tmp_arena); - Array results; - array_init(&results, proc->module->tmp_allocator, return_count); + ssaValueArray results; + array_init_reserve(&results, proc->module->tmp_allocator, return_count); for_array(res_index, rs->results) { - ssaValue *res = ssa_build_expr(proc, rs->results[res_index]); + ssaValue *res = ssa_build_expr(proc, rs->results.e[res_index]); Type *t = ssa_type(res); if (t->kind == Type_Tuple) { for (isize i = 0; i < t->Tuple.variable_count; i++) { @@ -4136,7 +4138,7 @@ void ssa_build_stmt_internal(ssaProcedure *proc, AstNode *node) { v = ssa_add_local_generated(proc, ret_type); for_array(i, results) { Entity *e = return_type_tuple->variables[i]; - ssaValue *res = ssa_emit_conv(proc, results[i], e->type); + ssaValue *res = ssa_emit_conv(proc, results.e[i], e->type); ssaValue *field = ssa_emit_struct_ep(proc, v, i); ssa_emit_store(proc, field, res); } @@ -4255,7 +4257,7 @@ void ssa_build_stmt_internal(ssaProcedure *proc, AstNode *node) { isize case_count = body->stmts.count; for_array(i, body->stmts) { - AstNode *clause = body->stmts[i]; + AstNode *clause = body->stmts.e[i]; ssaBlock *body = fall; ast_node(cc, CaseClause, clause); @@ -4287,7 +4289,7 @@ void ssa_build_stmt_internal(ssaProcedure *proc, AstNode *node) { ssaBlock *next_cond = NULL; for_array(j, cc->list) { - AstNode *expr = cc->list[j]; + AstNode *expr = cc->list.e[j]; next_cond = ssa_add_block(proc, clause, "match.case.next"); ssaValue *cond = ssa_emit_comp(proc, Token_CmpEq, tag, ssa_build_expr(proc, expr)); @@ -4355,7 +4357,7 @@ void ssa_build_stmt_internal(ssaProcedure *proc, AstNode *node) { isize case_count = body->stmts.count; for_array(i, body->stmts) { - AstNode *clause = body->stmts[i]; + AstNode *clause = body->stmts.e[i]; ast_node(cc, CaseClause, clause); if (cc->list.count == 0) { @@ -4526,10 +4528,10 @@ void ssa_build_stmt_internal(ssaProcedure *proc, AstNode *node) { void ssa_number_proc_registers(ssaProcedure *proc) { i32 reg_index = 0; for_array(i, proc->blocks) { - ssaBlock *b = proc->blocks[i]; + ssaBlock *b = proc->blocks.e[i]; b->index = i; for_array(j, b->instrs) { - ssaValue *value = b->instrs[j]; + ssaValue *value = b->instrs.e[j]; GB_ASSERT(value->kind == ssaValue_Instr); ssaInstr *instr = &value->Instr; if (ssa_instr_type(instr) == NULL) { // NOTE(bill): Ignore non-returning instructions @@ -4697,7 +4699,7 @@ void ssa_init_module(ssaModule *m, Checker *c) { isize count = 0; for_array(entry_index, m->info->type_info_map.entries) { - auto *entry = &m->info->type_info_map.entries[entry_index]; + auto *entry = &m->info->type_info_map.entries.e[entry_index]; Type *t = cast(Type *)cast(uintptr)entry->key.key; switch (t->kind) { @@ -4725,7 +4727,7 @@ void ssa_init_module(ssaModule *m, Checker *c) { { ssaDebugInfo *di = ssa_alloc_debug_info(m->allocator, ssaDebugInfo_CompileUnit); - di->CompileUnit.file = m->info->files.entries[0].value; // Zeroth is the init file + di->CompileUnit.file = m->info->files.entries.e[0].value; // Zeroth is the init file di->CompileUnit.producer = str_lit("odin"); map_set(&m->debug_info, hash_pointer(m), di); @@ -4832,7 +4834,7 @@ void ssa_gen_tree(ssaGen *s) { Entity *entry_point = NULL; for_array(i, info->entities.entries) { - auto *entry = &info->entities.entries[i]; + auto *entry = &info->entities.entries.e[i]; Entity *e = cast(Entity *)cast(uintptr)entry->key.key; String name = e->token.string; if (e->kind == Entity_Variable) { @@ -4844,17 +4846,17 @@ void ssa_gen_tree(ssaGen *s) { } } - struct ssaGlobalVariable { + typedef struct ssaGlobalVariable { ssaValue *var, *init; DeclInfo *decl; - }; - Array global_variables; - array_init(&global_variables, m->tmp_allocator, global_variable_max_count); + } ssaGlobalVariable; + Array(ssaGlobalVariable) global_variables; + array_init_reserve(&global_variables, m->tmp_allocator, global_variable_max_count); m->min_dep_map = generate_minimum_dependency_map(info, entry_point); for_array(i, info->entities.entries) { - auto *entry = &info->entities.entries[i]; + auto *entry = &info->entities.entries.e[i]; Entity *e = cast(Entity *)entry->key.ptr; String name = e->token.string; DeclInfo *decl = entry->value; @@ -4936,19 +4938,19 @@ void ssa_gen_tree(ssaGen *s) { } for_array(i, m->members.entries) { - auto *entry = &m->members.entries[i]; + auto *entry = &m->members.entries.e[i]; ssaValue *v = entry->value; if (v->kind == ssaValue_Proc) ssa_build_proc(v, NULL); } - ssaDebugInfo *compile_unit = m->debug_info.entries[0].value; + ssaDebugInfo *compile_unit = m->debug_info.entries.e[0].value; GB_ASSERT(compile_unit->kind == ssaDebugInfo_CompileUnit); ssaDebugInfo *all_procs = ssa_alloc_debug_info(m->allocator, ssaDebugInfo_AllProcs); isize all_proc_max_count = 0; for_array(i, m->debug_info.entries) { - auto *entry = &m->debug_info.entries[i]; + auto *entry = &m->debug_info.entries.e[i]; ssaDebugInfo *di = entry->value; di->id = i; if (di->kind == ssaDebugInfo_Proc) { @@ -4956,13 +4958,13 @@ void ssa_gen_tree(ssaGen *s) { } } - array_init(&all_procs->AllProcs.procs, m->allocator, all_proc_max_count); + array_init_reserve(&all_procs->AllProcs.procs, m->allocator, all_proc_max_count); map_set(&m->debug_info, hash_pointer(all_procs), all_procs); // NOTE(bill): This doesn't need to be mapped compile_unit->CompileUnit.all_procs = all_procs; for_array(i, m->debug_info.entries) { - auto *entry = &m->debug_info.entries[i]; + auto *entry = &m->debug_info.entries.e[i]; ssaDebugInfo *di = entry->value; di->id = i; if (di->kind == ssaDebugInfo_Proc) { @@ -4993,7 +4995,7 @@ void ssa_gen_tree(ssaGen *s) { // TODO(bill): Should do a dependency graph do check which order to initialize them in? for_array(i, global_variables) { - ssaGlobalVariable *var = &global_variables[i]; + ssaGlobalVariable *var = &global_variables.e[i]; if (var->decl->init_expr != NULL) { var->init = ssa_build_expr(proc, var->decl->init_expr); } @@ -5001,7 +5003,7 @@ void ssa_gen_tree(ssaGen *s) { // NOTE(bill): Initialize constants first for_array(i, global_variables) { - ssaGlobalVariable *var = &global_variables[i]; + ssaGlobalVariable *var = &global_variables.e[i]; if (var->init != NULL) { if (var->init->kind == ssaValue_Constant) { ssa_emit_store(proc, var->var, var->init); @@ -5010,7 +5012,7 @@ void ssa_gen_tree(ssaGen *s) { } for_array(i, global_variables) { - ssaGlobalVariable *var = &global_variables[i]; + ssaGlobalVariable *var = &global_variables.e[i]; if (var->init != NULL) { if (var->init->kind != ssaValue_Constant) { ssa_emit_store(proc, var->var, var->init); @@ -5055,7 +5057,7 @@ void ssa_gen_tree(ssaGen *s) { for_array(type_info_map_index, info->type_info_map.entries) { - auto *entry = &info->type_info_map.entries[type_info_map_index]; + auto *entry = &info->type_info_map.entries.e[type_info_map_index]; Type *t = cast(Type *)cast(uintptr)entry->key.key; t = default_type(t); isize entry_index = entry->value; @@ -5418,7 +5420,7 @@ void ssa_gen_tree(ssaGen *s) { } for_array(i, m->procs_to_generate) { - ssa_build_proc(m->procs_to_generate[i], m->procs_to_generate[i]->Proc.parent); + ssa_build_proc(m->procs_to_generate.e[i], m->procs_to_generate.e[i]->Proc.parent); } // { diff --git a/src/ssa_opt.cpp b/src/ssa_opt.cpp index 2b572be84..63cdb7733 100644 --- a/src/ssa_opt.cpp +++ b/src/ssa_opt.cpp @@ -1,6 +1,6 @@ // Optimizations for the SSA code -void ssa_opt_add_operands(Array *ops, ssaInstr *i) { +void ssa_opt_add_operands(ssaValueArray *ops, ssaInstr *i) { switch (i->kind) { case ssaInstr_Comment: break; @@ -51,7 +51,7 @@ void ssa_opt_add_operands(Array *ops, ssaInstr *i) { break; case ssaInstr_Phi: for_array(j, i->Phi.edges) { - array_add(ops, i->Phi.edges[j]); + array_add(ops, i->Phi.edges.e[j]); } break; case ssaInstr_Unreachable: break; @@ -99,24 +99,24 @@ void ssa_opt_add_operands(Array *ops, ssaInstr *i) { void ssa_opt_block_replace_pred(ssaBlock *b, ssaBlock *from, ssaBlock *to) { for_array(i, b->preds) { - ssaBlock *pred = b->preds[i]; + ssaBlock *pred = b->preds.e[i]; if (pred == from) { - b->preds[i] = to; + b->preds.e[i] = to; } } } void ssa_opt_block_replace_succ(ssaBlock *b, ssaBlock *from, ssaBlock *to) { for_array(i, b->succs) { - ssaBlock *succ = b->succs[i]; + ssaBlock *succ = b->succs.e[i]; if (succ == from) { - b->succs[i] = to; + b->succs.e[i] = to; } } } b32 ssa_opt_block_has_phi(ssaBlock *b) { - return b->instrs[0]->Instr.kind == ssaInstr_Phi; + return b->instrs.e[0]->Instr.kind == ssaInstr_Phi; } @@ -128,10 +128,10 @@ b32 ssa_opt_block_has_phi(ssaBlock *b) { -Array ssa_get_block_phi_nodes(ssaBlock *b) { - Array phis = {}; +ssaValueArray ssa_get_block_phi_nodes(ssaBlock *b) { + ssaValueArray phis = {}; for_array(i, b->instrs) { - ssaInstr *instr = &b->instrs[i]->Instr; + ssaInstr *instr = &b->instrs.e[i]->Instr; if (instr->kind != ssaInstr_Phi) { phis = b->instrs; phis.count = i; @@ -145,19 +145,19 @@ void ssa_remove_pred(ssaBlock *b, ssaBlock *p) { auto phis = ssa_get_block_phi_nodes(b); isize i = 0; for_array(j, b->preds) { - ssaBlock *pred = b->preds[j]; + ssaBlock *pred = b->preds.e[j]; if (pred != p) { - b->preds[i] = b->preds[j]; + b->preds.e[i] = b->preds.e[j]; for_array(k, phis) { - auto *phi = &phis[k]->Instr.Phi; - phi->edges[i] = phi->edges[j]; + auto *phi = &phis.e[k]->Instr.Phi; + phi->edges.e[i] = phi->edges.e[j]; } i++; } } b->preds.count = i; for_array(k, phis) { - auto *phi = &phis[k]->Instr.Phi; + auto *phi = &phis.e[k]->Instr.Phi; phi->edges.count = i; } @@ -166,13 +166,13 @@ void ssa_remove_pred(ssaBlock *b, ssaBlock *p) { void ssa_remove_dead_blocks(ssaProcedure *proc) { isize j = 0; for_array(i, proc->blocks) { - ssaBlock *b = proc->blocks[i]; + ssaBlock *b = proc->blocks.e[i]; if (b == NULL) { continue; } // NOTE(bill): Swap order b->index = j; - proc->blocks[j++] = b; + proc->blocks.e[j++] = b; } proc->blocks.count = j; } @@ -182,7 +182,7 @@ void ssa_mark_reachable(ssaBlock *b) { isize const BLACK = -1; b->index = BLACK; for_array(i, b->succs) { - ssaBlock *succ = b->succs[i]; + ssaBlock *succ = b->succs.e[i]; if (succ->index == WHITE) { ssa_mark_reachable(succ); } @@ -193,23 +193,23 @@ void ssa_remove_unreachable_blocks(ssaProcedure *proc) { isize const WHITE = 0; isize const BLACK = -1; for_array(i, proc->blocks) { - proc->blocks[i]->index = WHITE; + proc->blocks.e[i]->index = WHITE; } - ssa_mark_reachable(proc->blocks[0]); + ssa_mark_reachable(proc->blocks.e[0]); for_array(i, proc->blocks) { - ssaBlock *b = proc->blocks[i]; + ssaBlock *b = proc->blocks.e[i]; if (b->index == WHITE) { for_array(j, b->succs) { - ssaBlock *c = b->succs[j]; + ssaBlock *c = b->succs.e[j]; if (c->index == BLACK) { ssa_remove_pred(c, b); } } // NOTE(bill): Mark as empty but don't actually free it // As it's been allocated with an arena - proc->blocks[i] = NULL; + proc->blocks.e[i] = NULL; } } ssa_remove_dead_blocks(proc); @@ -219,7 +219,7 @@ b32 ssa_opt_block_fusion(ssaProcedure *proc, ssaBlock *a) { if (a->succs.count != 1) { return false; } - ssaBlock *b = a->succs[0]; + ssaBlock *b = a->succs.e[0]; if (b->preds.count != 1) { return false; } @@ -230,21 +230,21 @@ b32 ssa_opt_block_fusion(ssaProcedure *proc, ssaBlock *a) { array_pop(&a->instrs); // Remove branch at end for_array(i, b->instrs) { - array_add(&a->instrs, b->instrs[i]); - ssa_set_instr_parent(b->instrs[i], a); + array_add(&a->instrs, b->instrs.e[i]); + ssa_set_instr_parent(b->instrs.e[i], a); } array_clear(&a->succs); for_array(i, b->succs) { - array_add(&a->succs, b->succs[i]); + array_add(&a->succs, b->succs.e[i]); } // Fix preds links for_array(i, b->succs) { - ssa_opt_block_replace_pred(b->succs[i], b, a); + ssa_opt_block_replace_pred(b->succs.e[i], b, a); } - proc->blocks[b->index] = NULL; + proc->blocks.e[b->index] = NULL; return true; } @@ -256,7 +256,7 @@ void ssa_opt_blocks(ssaProcedure *proc) { while (changed) { changed = false; for_array(i, proc->blocks) { - ssaBlock *b = proc->blocks[i]; + ssaBlock *b = proc->blocks.e[i]; if (b == NULL) { continue; } @@ -275,16 +275,16 @@ void ssa_opt_blocks(ssaProcedure *proc) { void ssa_opt_build_referrers(ssaProcedure *proc) { gbTempArenaMemory tmp = gb_temp_arena_memory_begin(&proc->module->tmp_arena); - Array ops = {}; // NOTE(bill): Act as a buffer - array_init(&ops, proc->module->tmp_allocator, 64); // HACK(bill): This _could_ overflow the temp arena + ssaValueArray ops = {}; // NOTE(bill): Act as a buffer + array_init_reserve(&ops, proc->module->tmp_allocator, 64); // HACK(bill): This _could_ overflow the temp arena for_array(i, proc->blocks) { - ssaBlock *b = proc->blocks[i]; + ssaBlock *b = proc->blocks.e[i]; for_array(j, b->instrs) { - ssaValue *instr = b->instrs[j]; + ssaValue *instr = b->instrs.e[j]; array_clear(&ops); ssa_opt_add_operands(&ops, &instr->Instr); for_array(k, ops) { - ssaValue *op = ops[k]; + ssaValue *op = ops.e[k]; if (op == NULL) { continue; } @@ -326,7 +326,7 @@ i32 ssa_lt_depth_first_search(ssaLTState *lt, ssaBlock *p, i32 i, ssaBlock **pre lt->sdom[p->index] = p; ssa_lt_link(lt, NULL, p); for_array(index, p->succs) { - ssaBlock *q = p->succs[index]; + ssaBlock *q = p->succs.e[index]; if (lt->sdom[q->index] == NULL) { lt->parent[q->index] = p; i = ssa_lt_depth_first_search(lt, q, i, preorder); @@ -356,7 +356,7 @@ ssaDomPrePost ssa_opt_number_dom_tree(ssaBlock *v, i32 pre, i32 post) { v->dom.pre = pre++; for_array(i, v->dom.children) { - result = ssa_opt_number_dom_tree(v->dom.children[i], result.pre, result.post); + result = ssa_opt_number_dom_tree(v->dom.children.e[i], result.pre, result.post); } v->dom.post = post++; @@ -383,7 +383,7 @@ void ssa_opt_build_dom_tree(ssaProcedure *proc) { ssaBlock **preorder = &buf[3*n]; ssaBlock **buckets = &buf[4*n]; - ssaBlock *root = proc->blocks[0]; + ssaBlock *root = proc->blocks.e[0]; // Step 1 - number vertices i32 pre_num = ssa_lt_depth_first_search(<, root, 0, preorder); @@ -405,7 +405,7 @@ void ssa_opt_build_dom_tree(ssaProcedure *proc) { // Step 2 - Compute all sdoms lt.sdom[w->index] = lt.parent[w->index]; for_array(pred_index, w->preds) { - ssaBlock *v = w->preds[pred_index]; + ssaBlock *v = w->preds.e[pred_index]; ssaBlock *u = ssa_lt_eval(<, v); if (lt.sdom[u->index]->dom.pre < lt.sdom[w->index]->dom.pre) { lt.sdom[w->index] = lt.sdom[u->index]; @@ -441,7 +441,7 @@ void ssa_opt_build_dom_tree(ssaProcedure *proc) { // Calculate children relation as inverse of idom auto *children = &w->dom.idom->dom.children; - if (children->data == NULL) { + if (children->e == NULL) { // TODO(bill): Is this good enough for memory allocations? array_init(children, heap_allocator()); } @@ -464,7 +464,7 @@ void ssa_opt_tree(ssaGen *s) { s->opt_called = true; for_array(member_index, s->module.procs) { - ssaProcedure *proc = s->module.procs[member_index]; + ssaProcedure *proc = s->module.procs.e[member_index]; if (proc->blocks.count == 0) { // Prototype/external procedure continue; } diff --git a/src/ssa_print.cpp b/src/ssa_print.cpp index 28df7e42c..f4ed5544c 100644 --- a/src/ssa_print.cpp +++ b/src/ssa_print.cpp @@ -435,7 +435,7 @@ void ssa_print_exact_value(ssaFileBuffer *f, ssaModule *m, ExactValue value, Typ if (i > 0) { ssa_fprintf(f, ", "); } - TypeAndValue *tav = type_and_value_of_expression(m->info, cl->elems[i]); + TypeAndValue *tav = type_and_value_of_expression(m->info, cl->elems.e[i]); GB_ASSERT(tav != NULL); ssa_print_compound_element(f, m, tav->value, elem_type); } @@ -460,7 +460,7 @@ void ssa_print_exact_value(ssaFileBuffer *f, ssaModule *m, ExactValue value, Typ Type *elem_type = type->Vector.elem; if (elem_count == 1 && type->Vector.count > 1) { - TypeAndValue *tav = type_and_value_of_expression(m->info, cl->elems[0]); + TypeAndValue *tav = type_and_value_of_expression(m->info, cl->elems.e[0]); GB_ASSERT(tav != NULL); for (isize i = 0; i < type->Vector.count; i++) { @@ -474,7 +474,7 @@ void ssa_print_exact_value(ssaFileBuffer *f, ssaModule *m, ExactValue value, Typ if (i > 0) { ssa_fprintf(f, ", "); } - TypeAndValue *tav = type_and_value_of_expression(m->info, cl->elems[i]); + TypeAndValue *tav = type_and_value_of_expression(m->info, cl->elems.e[i]); GB_ASSERT(tav != NULL); ssa_print_compound_element(f, m, tav->value, elem_type); } @@ -496,23 +496,23 @@ void ssa_print_exact_value(ssaFileBuffer *f, ssaModule *m, ExactValue value, Typ ExactValue *values = gb_alloc_array(m->tmp_allocator, ExactValue, value_count); - if (cl->elems[0]->kind == AstNode_FieldValue) { + if (cl->elems.e[0]->kind == AstNode_FieldValue) { isize elem_count = cl->elems.count; for (isize i = 0; i < elem_count; i++) { - ast_node(fv, FieldValue, cl->elems[i]); + ast_node(fv, FieldValue, cl->elems.e[i]); String name = fv->field->Ident.string; TypeAndValue *tav = type_and_value_of_expression(m->info, fv->value); GB_ASSERT(tav != NULL); Selection sel = lookup_field(m->allocator, type, name, false); - Entity *f = type->Record.fields[sel.index[0]]; + Entity *f = type->Record.fields[sel.index.e[0]]; values[f->Variable.field_index] = tav->value; } } else { for (isize i = 0; i < value_count; i++) { - TypeAndValue *tav = type_and_value_of_expression(m->info, cl->elems[i]); + TypeAndValue *tav = type_and_value_of_expression(m->info, cl->elems.e[i]); GB_ASSERT(tav != NULL); Entity *f = type->Record.fields_in_src_order[i]; @@ -754,11 +754,11 @@ void ssa_print_instr(ssaFileBuffer *f, ssaModule *m, ssaValue *value) { ssa_fprintf(f, ", "); } - ssaValue *edge = instr->Phi.edges[i]; + ssaValue *edge = instr->Phi.edges.e[i]; ssaBlock *block = NULL; if (instr->parent != NULL && i < instr->parent->preds.count) { - block = instr->parent->preds[i]; + block = instr->parent->preds.e[i]; } ssa_fprintf(f, "[ "); @@ -1238,14 +1238,14 @@ void ssa_print_proc(ssaFileBuffer *f, ssaModule *m, ssaProcedure *proc) { ssa_fprintf(f, "{\n"); for_array(i, proc->blocks) { - ssaBlock *block = proc->blocks[i]; + ssaBlock *block = proc->blocks.e[i]; if (i > 0) ssa_fprintf(f, "\n"); ssa_print_block_name(f, block); ssa_fprintf(f, ":\n"); for_array(j, block->instrs) { - ssaValue *value = block->instrs[j]; + ssaValue *value = block->instrs.e[j]; ssa_print_instr(f, m, value); } } @@ -1255,7 +1255,7 @@ void ssa_print_proc(ssaFileBuffer *f, ssaModule *m, ssaProcedure *proc) { } for_array(i, proc->children) { - ssa_print_proc(f, m, proc->children[i]); + ssa_print_proc(f, m, proc->children.e[i]); } } @@ -1296,7 +1296,7 @@ void ssa_print_llvm_ir(ssaGen *ssa) { for_array(member_index, m->members.entries) { - auto *entry = &m->members.entries[member_index]; + auto *entry = &m->members.entries.e[member_index]; ssaValue *v = entry->value; if (v->kind != ssaValue_TypeName) { continue; @@ -1307,7 +1307,7 @@ void ssa_print_llvm_ir(ssaGen *ssa) { ssa_fprintf(f, "\n"); for_array(member_index, m->members.entries) { - auto *entry = &m->members.entries[member_index]; + auto *entry = &m->members.entries.e[member_index]; ssaValue *v = entry->value; if (v->kind != ssaValue_Proc) { continue; @@ -1318,7 +1318,7 @@ void ssa_print_llvm_ir(ssaGen *ssa) { } for_array(member_index, m->members.entries) { - auto *entry = &m->members.entries[member_index]; + auto *entry = &m->members.entries.e[member_index]; ssaValue *v = entry->value; if (v->kind != ssaValue_Proc) { continue; @@ -1330,7 +1330,7 @@ void ssa_print_llvm_ir(ssaGen *ssa) { for_array(member_index, m->members.entries) { - auto *entry = &m->members.entries[member_index]; + auto *entry = &m->members.entries.e[member_index]; ssaValue *v = entry->value; if (v->kind != ssaValue_Global) { continue; @@ -1376,7 +1376,7 @@ void ssa_print_llvm_ir(ssaGen *ssa) { ssa_fprintf(f, "!llvm.dbg.cu = !{!0}\n"); for_array(di_index, m->debug_info.entries) { - auto *entry = &m->debug_info.entries[di_index]; + auto *entry = &m->debug_info.entries.e[di_index]; ssaDebugInfo *di = entry->value; ssa_fprintf(f, "!%d = ", di->id); @@ -1422,7 +1422,7 @@ void ssa_print_llvm_ir(ssaGen *ssa) { case ssaDebugInfo_AllProcs: ssa_fprintf(f, "!{"); for_array(proc_index, di->AllProcs.procs) { - ssaDebugInfo *p = di->AllProcs.procs[proc_index]; + ssaDebugInfo *p = di->AllProcs.procs.e[proc_index]; if (proc_index > 0) {ssa_fprintf(f, ",");} ssa_fprintf(f, "!%d", p->id); } diff --git a/src/timings.cpp b/src/timings.cpp index 8de2164fe..c2deedb44 100644 --- a/src/timings.cpp +++ b/src/timings.cpp @@ -6,7 +6,7 @@ struct TimeStamp { struct Timings { TimeStamp total; - Array sections; + Array(TimeStamp) sections; u64 freq; }; @@ -51,7 +51,7 @@ TimeStamp make_time_stamp(String label) { } void timings_init(Timings *t, String label, isize buffer_size) { - array_init(&t->sections, heap_allocator(), buffer_size); + array_init_reserve(&t->sections, heap_allocator(), buffer_size); t->total = make_time_stamp(label); t->freq = time_stamp__freq(); } @@ -62,7 +62,7 @@ void timings_destroy(Timings *t) { void timings__stop_current_section(Timings *t) { if (t->sections.count > 0) { - t->sections[t->sections.count-1].finish = time_stamp_time_now(); + t->sections.e[t->sections.count-1].finish = time_stamp_time_now(); } } @@ -84,7 +84,7 @@ void timings_print_all(Timings *t) { isize max_len = t->total.label.len; for_array(i, t->sections) { - TimeStamp ts = t->sections[i]; + TimeStamp ts = t->sections.e[i]; max_len = gb_max(max_len, ts.label.len); } @@ -96,7 +96,7 @@ void timings_print_all(Timings *t) { time_stamp_as_ms(t->total, t->freq)); for_array(i, t->sections) { - TimeStamp ts = t->sections[i]; + TimeStamp ts = t->sections.e[i]; gb_printf("%.*s%.*s - %.3f ms\n", LIT(ts.label), cast(int)(max_len-ts.label.len), SPACES, diff --git a/src/tokenizer.cpp b/src/tokenizer.cpp index 42c2b7b69..331d5a1a9 100644 --- a/src/tokenizer.cpp +++ b/src/tokenizer.cpp @@ -296,7 +296,7 @@ struct Tokenizer { isize line_count; isize error_count; - Array allocated_strings; + Array(String) allocated_strings; }; @@ -400,7 +400,7 @@ gb_inline void destroy_tokenizer(Tokenizer *t) { gb_free(heap_allocator(), t->start); } for_array(i, t->allocated_strings) { - gb_free(heap_allocator(), t->allocated_strings[i].text); + gb_free(heap_allocator(), t->allocated_strings.e[i].text); } array_free(&t->allocated_strings); }