aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorgingerBill <bill@gingerbill.org>2021-09-13 00:58:39 +0100
committergingerBill <bill@gingerbill.org>2021-09-13 00:58:39 +0100
commitfb8fa5217d4a5081dacc0a74a786cd2efc964fdb (patch)
tree49724edef53493c6630aa8b2ae91ea3ad57621a4 /src
parent6585601765c24523e43ca3a158abc61d373168db (diff)
Begin minimize `Type` size by replacing `Array` with `Slice` etc
Diffstat (limited to 'src')
-rw-r--r--src/array.cpp13
-rw-r--r--src/check_builtin.cpp32
-rw-r--r--src/check_expr.cpp36
-rw-r--r--src/check_type.cpp55
-rw-r--r--src/checker.cpp39
-rw-r--r--src/llvm_backend.cpp6
-rw-r--r--src/llvm_backend_const.cpp4
-rw-r--r--src/llvm_backend_expr.cpp8
-rw-r--r--src/llvm_backend_general.cpp2
-rw-r--r--src/llvm_backend_proc.cpp4
-rw-r--r--src/llvm_backend_stmt.cpp6
-rw-r--r--src/llvm_backend_type.cpp4
-rw-r--r--src/types.cpp48
13 files changed, 147 insertions, 110 deletions
diff --git a/src/array.cpp b/src/array.cpp
index 90d85563c..521fa91e2 100644
--- a/src/array.cpp
+++ b/src/array.cpp
@@ -151,6 +151,19 @@ void slice_copy(Slice<T> *slice, Slice<T> const &data, isize offset, isize count
template <typename T>
+gb_inline Slice<T> slice(Slice<T> const &array, isize lo, isize hi) {
+ GB_ASSERT(0 <= lo && lo <= hi && hi <= array.count);
+ Slice<T> out = {};
+ isize len = hi-lo;
+ if (len > 0) {
+ out.data = array.data+lo;
+ out.count = len;
+ }
+ return out;
+}
+
+
+template <typename T>
void slice_ordered_remove(Slice<T> *array, isize index) {
GB_ASSERT(0 <= index && index < array->count);
diff --git a/src/check_builtin.cpp b/src/check_builtin.cpp
index 1f3928bd8..1f9eea45d 100644
--- a/src/check_builtin.cpp
+++ b/src/check_builtin.cpp
@@ -64,13 +64,13 @@ void check_or_else_split_types(CheckerContext *c, Operand *x, String const &name
Type *right_type = nullptr;
if (x->type->kind == Type_Tuple) {
auto const &vars = x->type->Tuple.variables;
- auto lhs = array_slice(vars, 0, vars.count-1);
+ auto lhs = slice(vars, 0, vars.count-1);
auto rhs = vars[vars.count-1];
if (lhs.count == 1) {
left_type = lhs[0]->type;
} else if (lhs.count != 0) {
left_type = alloc_type_tuple();
- left_type->Tuple.variables = array_make_from_ptr(lhs.data, lhs.count, lhs.count);
+ left_type->Tuple.variables = lhs;
}
right_type = rhs->type;
@@ -120,13 +120,13 @@ void check_or_return_split_types(CheckerContext *c, Operand *x, String const &na
Type *right_type = nullptr;
if (x->type->kind == Type_Tuple) {
auto const &vars = x->type->Tuple.variables;
- auto lhs = array_slice(vars, 0, vars.count-1);
+ auto lhs = slice(vars, 0, vars.count-1);
auto rhs = vars[vars.count-1];
if (lhs.count == 1) {
left_type = lhs[0]->type;
} else if (lhs.count != 0) {
left_type = alloc_type_tuple();
- left_type->Tuple.variables = array_make_from_ptr(lhs.data, lhs.count, lhs.count);
+ left_type->Tuple.variables = lhs;
}
right_type = rhs->type;
@@ -1156,12 +1156,12 @@ bool check_builtin_procedure(CheckerContext *c, Operand *operand, Ast *call, i32
if (is_type_struct(type)) {
isize variable_count = type->Struct.fields.count;
- array_init(&tuple->Tuple.variables, a, variable_count);
+ slice_init(&tuple->Tuple.variables, a, variable_count);
// TODO(bill): Should I copy each of the entities or is this good enough?
gb_memmove_array(tuple->Tuple.variables.data, type->Struct.fields.data, variable_count);
} else if (is_type_array(type)) {
isize variable_count = cast(isize)type->Array.count;
- array_init(&tuple->Tuple.variables, a, variable_count);
+ slice_init(&tuple->Tuple.variables, a, variable_count);
for (isize i = 0; i < variable_count; i++) {
tuple->Tuple.variables[i] = alloc_entity_array_elem(nullptr, blank_token, type->Array.elem, cast(i32)i);
}
@@ -1240,14 +1240,14 @@ bool check_builtin_procedure(CheckerContext *c, Operand *operand, Ast *call, i32
} else if (is_type_enum(type)) {
operand->mode = Addressing_Constant;
operand->type = original_type;
- operand->value = type->Enum.min_value;
+ operand->value = *type->Enum.min_value;
return true;
} else if (is_type_enumerated_array(type)) {
Type *bt = base_type(type);
GB_ASSERT(bt->kind == Type_EnumeratedArray);
operand->mode = Addressing_Constant;
operand->type = bt->EnumeratedArray.index;
- operand->value = bt->EnumeratedArray.min_value;
+ operand->value = *bt->EnumeratedArray.min_value;
return true;
}
gbString type_str = type_to_string(original_type);
@@ -1414,14 +1414,14 @@ bool check_builtin_procedure(CheckerContext *c, Operand *operand, Ast *call, i32
} else if (is_type_enum(type)) {
operand->mode = Addressing_Constant;
operand->type = original_type;
- operand->value = type->Enum.max_value;
+ operand->value = *type->Enum.max_value;
return true;
} else if (is_type_enumerated_array(type)) {
Type *bt = base_type(type);
GB_ASSERT(bt->kind == Type_EnumeratedArray);
operand->mode = Addressing_Constant;
operand->type = bt->EnumeratedArray.index;
- operand->value = bt->EnumeratedArray.max_value;
+ operand->value = *bt->EnumeratedArray.max_value;
return true;
}
gbString type_str = type_to_string(original_type);
@@ -1788,8 +1788,8 @@ bool check_builtin_procedure(CheckerContext *c, Operand *operand, Ast *call, i32
if (elem == nullptr) {
elem = alloc_type_struct();
elem->Struct.scope = s;
- elem->Struct.fields = fields;
- elem->Struct.tags = array_make<String>(permanent_allocator(), fields.count);
+ elem->Struct.fields = slice_from_array(fields);
+ elem->Struct.tags = slice_make<String>(permanent_allocator(), fields.count);
elem->Struct.node = dummy_node_struct;
type_set_offsets(elem);
}
@@ -1938,8 +1938,8 @@ bool check_builtin_procedure(CheckerContext *c, Operand *operand, Ast *call, i32
if (is_type_array(elem)) {
Type *old_array = base_type(elem);
soa_struct = alloc_type_struct();
- soa_struct->Struct.fields = array_make<Entity *>(heap_allocator(), cast(isize)old_array->Array.count);
- soa_struct->Struct.tags = array_make<String>(heap_allocator(), cast(isize)old_array->Array.count);
+ soa_struct->Struct.fields = slice_make<Entity *>(heap_allocator(), cast(isize)old_array->Array.count);
+ soa_struct->Struct.tags = slice_make<String>(heap_allocator(), cast(isize)old_array->Array.count);
soa_struct->Struct.node = operand->expr;
soa_struct->Struct.soa_kind = StructSoa_Fixed;
soa_struct->Struct.soa_elem = elem;
@@ -1971,8 +1971,8 @@ bool check_builtin_procedure(CheckerContext *c, Operand *operand, Ast *call, i32
Type *old_struct = base_type(elem);
soa_struct = alloc_type_struct();
- soa_struct->Struct.fields = array_make<Entity *>(heap_allocator(), old_struct->Struct.fields.count);
- soa_struct->Struct.tags = array_make<String>(heap_allocator(), old_struct->Struct.tags.count);
+ soa_struct->Struct.fields = slice_make<Entity *>(heap_allocator(), old_struct->Struct.fields.count);
+ soa_struct->Struct.tags = slice_make<String>(heap_allocator(), old_struct->Struct.tags.count);
soa_struct->Struct.node = operand->expr;
soa_struct->Struct.soa_kind = StructSoa_Fixed;
soa_struct->Struct.soa_elem = elem;
diff --git a/src/check_expr.cpp b/src/check_expr.cpp
index 8607ee3cb..69d60d651 100644
--- a/src/check_expr.cpp
+++ b/src/check_expr.cpp
@@ -1023,10 +1023,10 @@ bool is_polymorphic_type_assignable(CheckerContext *c, Type *poly, Type *source,
if (poly->EnumeratedArray.count != source->EnumeratedArray.count) {
return false;
}
- if (compare_exact_values(Token_NotEq, poly->EnumeratedArray.min_value, source->EnumeratedArray.min_value)) {
+ if (compare_exact_values(Token_NotEq, *poly->EnumeratedArray.min_value, *source->EnumeratedArray.min_value)) {
return false;
}
- if (compare_exact_values(Token_NotEq, poly->EnumeratedArray.max_value, source->EnumeratedArray.max_value)) {
+ if (compare_exact_values(Token_NotEq, *poly->EnumeratedArray.max_value, *source->EnumeratedArray.max_value)) {
return false;
}
return is_polymorphic_type_assignable(c, poly->EnumeratedArray.index, source->EnumeratedArray.index, true, modify_type);
@@ -3425,8 +3425,8 @@ bool check_index_value(CheckerContext *c, Type *main_type, bool open_range, Ast
if (is_type_enum(index_type)) {
Type *bt = base_type(index_type);
GB_ASSERT(bt->kind == Type_Enum);
- ExactValue lo = bt->Enum.min_value;
- ExactValue hi = bt->Enum.max_value;
+ ExactValue const &lo = *bt->Enum.min_value;
+ ExactValue const &hi = *bt->Enum.max_value;
String lo_str = {};
String hi_str = {};
if (bt->Enum.fields.count > 0) {
@@ -3556,7 +3556,7 @@ ExactValue get_constant_field_single(CheckerContext *c, ExactValue value, i32 in
if (is_type_enumerated_array(node->tav.type)) {
Type *bt = base_type(node->tav.type);
GB_ASSERT(bt->kind == Type_EnumeratedArray);
- corrected_index = index + exact_value_to_i64(bt->EnumeratedArray.min_value);
+ corrected_index = index + exact_value_to_i64(*bt->EnumeratedArray.min_value);
}
if (op != Token_RangeHalf) {
if (lo <= corrected_index && corrected_index <= hi) {
@@ -3580,7 +3580,7 @@ ExactValue get_constant_field_single(CheckerContext *c, ExactValue value, i32 in
if (is_type_enumerated_array(node->tav.type)) {
Type *bt = base_type(node->tav.type);
GB_ASSERT(bt->kind == Type_EnumeratedArray);
- index_value = exact_value_sub(index_value, bt->EnumeratedArray.min_value);
+ index_value = exact_value_sub(index_value, *bt->EnumeratedArray.min_value);
}
i64 field_index = exact_value_to_i64(index_value);
@@ -3738,6 +3738,18 @@ void check_did_you_mean_type(String const &name, Array<Entity *> const &fields)
check_did_you_mean_print(&d);
}
+void check_did_you_mean_type(String const &name, Slice<Entity *> const &fields) {
+ ERROR_BLOCK();
+
+ DidYouMeanAnswers d = did_you_mean_make(heap_allocator(), fields.count, name);
+ defer (did_you_mean_destroy(&d));
+
+ for_array(i, fields) {
+ did_you_mean_append(&d, fields[i]->token.string);
+ }
+ check_did_you_mean_print(&d);
+}
+
void check_did_you_mean_scope(String const &name, Scope *scope) {
ERROR_BLOCK();
@@ -7305,8 +7317,8 @@ ExprKind check_expr_base_internal(CheckerContext *c, Operand *o, Ast *node, Type
gbString index_type_str = type_to_string(index_type);
defer (gb_string_free(index_type_str));
- i64 total_lo = exact_value_to_i64(t->EnumeratedArray.min_value);
- i64 total_hi = exact_value_to_i64(t->EnumeratedArray.max_value);
+ i64 total_lo = exact_value_to_i64(*t->EnumeratedArray.min_value);
+ i64 total_hi = exact_value_to_i64(*t->EnumeratedArray.max_value);
String total_lo_string = {};
String total_hi_string = {};
@@ -7319,10 +7331,10 @@ ExprKind check_expr_base_internal(CheckerContext *c, Operand *o, Ast *node, Type
if (f->kind != Entity_Constant) {
continue;
}
- if (total_lo_string.len == 0 && compare_exact_values(Token_CmpEq, f->Constant.value, t->EnumeratedArray.min_value)) {
+ if (total_lo_string.len == 0 && compare_exact_values(Token_CmpEq, f->Constant.value, *t->EnumeratedArray.min_value)) {
total_lo_string = f->token.string;
}
- if (total_hi_string.len == 0 && compare_exact_values(Token_CmpEq, f->Constant.value, t->EnumeratedArray.max_value)) {
+ if (total_hi_string.len == 0 && compare_exact_values(Token_CmpEq, f->Constant.value, *t->EnumeratedArray.max_value)) {
total_hi_string = f->token.string;
}
if (total_lo_string.len != 0 && total_hi_string.len != 0) {
@@ -8472,13 +8484,13 @@ ExprKind check_expr_base_internal(CheckerContext *c, Operand *o, Ast *node, Type
Type *params = alloc_type_tuple();
Type *results = alloc_type_tuple();
if (param_types.count != 0) {
- array_init(&params->Tuple.variables, heap_allocator(), param_types.count);
+ slice_init(&params->Tuple.variables, heap_allocator(), param_types.count);
for_array(i, param_types) {
params->Tuple.variables[i] = alloc_entity_param(scope, blank_token, param_types[i], false, true);
}
}
if (return_type != nullptr) {
- array_init(&results->Tuple.variables, heap_allocator(), 1);
+ slice_init(&results->Tuple.variables, heap_allocator(), 1);
results->Tuple.variables[0] = alloc_entity_param(scope, blank_token, return_type, false, true);
}
diff --git a/src/check_type.cpp b/src/check_type.cpp
index 3541eef61..2c9f589c7 100644
--- a/src/check_type.cpp
+++ b/src/check_type.cpp
@@ -92,10 +92,10 @@ bool does_field_type_allow_using(Type *t) {
return false;
}
-void check_struct_fields(CheckerContext *ctx, Ast *node, Array<Entity *> *fields, Array<String> *tags, Slice<Ast *> const &params,
+void check_struct_fields(CheckerContext *ctx, Ast *node, Slice<Entity *> *fields, Slice<String> *tags, Slice<Ast *> const &params,
isize init_field_capacity, Type *struct_type, String context) {
- *fields = array_make<Entity *>(heap_allocator(), 0, init_field_capacity);
- *tags = array_make<String>(heap_allocator(), 0, init_field_capacity);
+ auto fields_array = array_make<Entity *>(heap_allocator(), 0, init_field_capacity);
+ auto tags_array = array_make<String>(heap_allocator(), 0, init_field_capacity);
GB_ASSERT(node->kind == Ast_StructType);
GB_ASSERT(struct_type->kind == Type_Struct);
@@ -153,20 +153,20 @@ void check_struct_fields(CheckerContext *ctx, Ast *node, Array<Entity *> *fields
Entity *field = alloc_entity_field(ctx->scope, name_token, type, is_using, field_src_index);
add_entity(ctx, ctx->scope, name, field);
- array_add(fields, field);
+ array_add(&fields_array, field);
String tag = p->tag.string;
if (tag.len != 0 && !unquote_string(permanent_allocator(), &tag, 0, tag.text[0] == '`')) {
error(p->tag, "Invalid string literal");
tag = {};
}
- array_add(tags, tag);
+ array_add(&tags_array, tag);
field_src_index += 1;
}
if (is_using && p->names.count > 0) {
- Type *first_type = (*fields)[fields->count-1]->type;
+ Type *first_type = fields_array[fields_array.count-1]->type;
Type *t = base_type(type_deref(first_type));
if (!does_field_type_allow_using(t) &&
@@ -182,6 +182,9 @@ void check_struct_fields(CheckerContext *ctx, Ast *node, Array<Entity *> *fields
populate_using_entity_scope(ctx, node, p, type);
}
}
+
+ *fields = slice_from_array(fields_array);
+ *tags = slice_from_array(tags_array);
}
@@ -498,7 +501,7 @@ Type *check_record_polymorphic_params(CheckerContext *ctx, Ast *polymorphic_para
if (entities.count > 0) {
Type *tuple = alloc_type_tuple();
- tuple->Tuple.variables = entities;
+ tuple->Tuple.variables = slice_from_array(entities);
polymorphic_params_type = tuple;
}
}
@@ -816,8 +819,8 @@ void check_enum_type(CheckerContext *ctx, Type *enum_type, Type *named_type, Ast
enum_type->Enum.fields = fields;
enum_type->Enum.names = make_names_field_for_struct(ctx, ctx->scope);
- enum_type->Enum.min_value = min_value;
- enum_type->Enum.max_value = max_value;
+ *enum_type->Enum.min_value = min_value;
+ *enum_type->Enum.max_value = max_value;
enum_type->Enum.min_value_index = min_value_index;
enum_type->Enum.max_value_index = max_value_index;
@@ -1705,7 +1708,7 @@ Type *check_get_params(CheckerContext *ctx, Scope *scope, Ast *_params, bool *is
}
Type *tuple = alloc_type_tuple();
- tuple->Tuple.variables = variables;
+ tuple->Tuple.variables = slice_from_array(variables);
if (success_) *success_ = success;
if (specialization_count_) *specialization_count_ = specialization_count;
@@ -1815,7 +1818,7 @@ Type *check_get_results(CheckerContext *ctx, Scope *scope, Ast *_results) {
}
}
- tuple->Tuple.variables = variables;
+ tuple->Tuple.variables = slice_from_array(variables);
return tuple;
}
@@ -2059,7 +2062,7 @@ i64 check_array_count(CheckerContext *ctx, Operand *o, Ast *e) {
Type *make_optional_ok_type(Type *value, bool typed) {
gbAllocator a = permanent_allocator();
Type *t = alloc_type_tuple();
- array_init(&t->Tuple.variables, a, 2);
+ slice_init(&t->Tuple.variables, a, 2);
t->Tuple.variables[0] = alloc_entity_field(nullptr, blank_token, value, false, 0);
t->Tuple.variables[1] = alloc_entity_field(nullptr, blank_token, typed ? t_bool : t_untyped_bool, false, 1);
return t;
@@ -2083,11 +2086,11 @@ void init_map_entry_type(Type *type) {
*/
Scope *s = create_scope(nullptr, builtin_pkg->scope);
- auto fields = array_make<Entity *>(permanent_allocator(), 0, 4);
- array_add(&fields, alloc_entity_field(s, make_token_ident(str_lit("hash")), t_uintptr, false, cast(i32)fields.count, EntityState_Resolved));
- array_add(&fields, alloc_entity_field(s, make_token_ident(str_lit("next")), t_int, false, cast(i32)fields.count, EntityState_Resolved));
- array_add(&fields, alloc_entity_field(s, make_token_ident(str_lit("key")), type->Map.key, false, cast(i32)fields.count, EntityState_Resolved));
- array_add(&fields, alloc_entity_field(s, make_token_ident(str_lit("value")), type->Map.value, false, cast(i32)fields.count, EntityState_Resolved));
+ auto fields = slice_make<Entity *>(permanent_allocator(), 4);
+ fields[0] = alloc_entity_field(s, make_token_ident(str_lit("hash")), t_uintptr, false, cast(i32)fields.count, EntityState_Resolved);
+ fields[1] = alloc_entity_field(s, make_token_ident(str_lit("next")), t_int, false, cast(i32)fields.count, EntityState_Resolved);
+ fields[2] = alloc_entity_field(s, make_token_ident(str_lit("key")), type->Map.key, false, cast(i32)fields.count, EntityState_Resolved);
+ fields[3] = alloc_entity_field(s, make_token_ident(str_lit("value")), type->Map.value, false, cast(i32)fields.count, EntityState_Resolved);
entry_type->Struct.fields = fields;
@@ -2120,9 +2123,9 @@ void init_map_internal_types(Type *type) {
Type *entries_type = alloc_type_dynamic_array(type->Map.entry_type);
- auto fields = array_make<Entity *>(permanent_allocator(), 0, 2);
- array_add(&fields, alloc_entity_field(s, make_token_ident(str_lit("hashes")), hashes_type, false, 0, EntityState_Resolved));
- array_add(&fields, alloc_entity_field(s, make_token_ident(str_lit("entries")), entries_type, false, 1, EntityState_Resolved));
+ auto fields = slice_make<Entity *>(permanent_allocator(), 2);
+ fields[0] = alloc_entity_field(s, make_token_ident(str_lit("hashes")), hashes_type, false, 0, EntityState_Resolved);
+ fields[1] = alloc_entity_field(s, make_token_ident(str_lit("entries")), entries_type, false, 1, EntityState_Resolved);
generated_struct_type->Struct.fields = fields;
@@ -2239,8 +2242,8 @@ Type *make_soa_struct_internal(CheckerContext *ctx, Ast *array_typ_expr, Ast *el
field_count = 0;
soa_struct = alloc_type_struct();
- soa_struct->Struct.fields = array_make<Entity *>(heap_allocator(), field_count+extra_field_count);
- soa_struct->Struct.tags = array_make<String>(heap_allocator(), field_count+extra_field_count);
+ soa_struct->Struct.fields = slice_make<Entity *>(heap_allocator(), field_count+extra_field_count);
+ soa_struct->Struct.tags = slice_make<String>(heap_allocator(), field_count+extra_field_count);
soa_struct->Struct.node = array_typ_expr;
soa_struct->Struct.soa_kind = soa_kind;
soa_struct->Struct.soa_elem = elem;
@@ -2254,8 +2257,8 @@ Type *make_soa_struct_internal(CheckerContext *ctx, Ast *array_typ_expr, Ast *el
field_count = cast(isize)old_array->Array.count;
soa_struct = alloc_type_struct();
- soa_struct->Struct.fields = array_make<Entity *>(heap_allocator(), field_count+extra_field_count);
- soa_struct->Struct.tags = array_make<String>(heap_allocator(), field_count+extra_field_count);
+ soa_struct->Struct.fields = slice_make<Entity *>(heap_allocator(), field_count+extra_field_count);
+ soa_struct->Struct.tags = slice_make<String>(heap_allocator(), field_count+extra_field_count);
soa_struct->Struct.node = array_typ_expr;
soa_struct->Struct.soa_kind = soa_kind;
soa_struct->Struct.soa_elem = elem;
@@ -2296,8 +2299,8 @@ Type *make_soa_struct_internal(CheckerContext *ctx, Ast *array_typ_expr, Ast *el
GB_ASSERT(old_struct->Struct.tags.count == field_count);
soa_struct = alloc_type_struct();
- soa_struct->Struct.fields = array_make<Entity *>(heap_allocator(), field_count+extra_field_count);
- soa_struct->Struct.tags = array_make<String>(heap_allocator(), field_count+extra_field_count);
+ soa_struct->Struct.fields = slice_make<Entity *>(heap_allocator(), field_count+extra_field_count);
+ soa_struct->Struct.tags = slice_make<String>(heap_allocator(), field_count+extra_field_count);
soa_struct->Struct.node = array_typ_expr;
soa_struct->Struct.soa_kind = soa_kind;
soa_struct->Struct.soa_elem = elem;
diff --git a/src/checker.cpp b/src/checker.cpp
index 5544ef58e..8d85784fa 100644
--- a/src/checker.cpp
+++ b/src/checker.cpp
@@ -4865,22 +4865,25 @@ void check_deferred_procedures(Checker *c) {
Entity *dst = src->Procedure.deferred_procedure.entity;
GB_ASSERT(dst != nullptr);
GB_ASSERT(dst->kind == Entity_Procedure);
+
+ char const *attribute = "deferred_none";
+ switch (dst_kind) {
+ case DeferredProcedure_none:
+ attribute = "deferred_none";
+ break;
+ case DeferredProcedure_in:
+ attribute = "deferred_in";
+ break;
+ case DeferredProcedure_out:
+ attribute = "deferred_out";
+ break;
+ case DeferredProcedure_in_out:
+ attribute = "deferred_in_out";
+ break;
+ }
if (is_type_polymorphic(src->type) || is_type_polymorphic(dst->type)) {
- switch (dst_kind) {
- case DeferredProcedure_none:
- error(src->token, "'deferred_none' cannot be used with a polymorphic procedure");
- break;
- case DeferredProcedure_in:
- error(src->token, "'deferred_in' cannot be used with a polymorphic procedure");
- break;
- case DeferredProcedure_out:
- error(src->token, "'deferred_out' cannot be used with a polymorphic procedure");
- break;
- case DeferredProcedure_in_out:
- error(src->token, "'deferred_in_out' cannot be used with a polymorphic procedure");
- break;
- }
+ error(src->token, "'%s' cannot be used with a polymorphic procedure", attribute);
continue;
}
@@ -4974,17 +4977,19 @@ void check_deferred_procedures(Checker *c) {
GB_ASSERT(src_results->kind == Type_Tuple);
len += src_results->Tuple.variables.count;
}
- array_init(&sv, heap_allocator(), 0, len);
+ slice_init(&sv, heap_allocator(), len);
+ isize offset = 0;
if (src_params != nullptr) {
for_array(i, src_params->Tuple.variables) {
- array_add(&sv, src_params->Tuple.variables[i]);
+ sv[offset++] = src_params->Tuple.variables[i];
}
}
if (src_results != nullptr) {
for_array(i, src_results->Tuple.variables) {
- array_add(&sv, src_results->Tuple.variables[i]);
+ sv[offset++] = src_results->Tuple.variables[i];
}
}
+ GB_ASSERT(offset == len);
if (are_types_identical(tsrc, dst_params)) {
diff --git a/src/llvm_backend.cpp b/src/llvm_backend.cpp
index 5fff3c486..3e8498776 100644
--- a/src/llvm_backend.cpp
+++ b/src/llvm_backend.cpp
@@ -761,7 +761,7 @@ lbProcedure *lb_create_main_procedure(lbModule *m, lbProcedure *startup_runtime)
if (build_context.metrics.os == TargetOs_windows && build_context.build_mode == BuildMode_DynamicLibrary) {
is_dll_main = true;
name = str_lit("DllMain");
- array_init(&params->Tuple.variables, permanent_allocator(), 3);
+ slice_init(&params->Tuple.variables, permanent_allocator(), 3);
params->Tuple.variables[0] = alloc_entity_param(nullptr, make_token_ident("hinstDLL"), t_rawptr, false, true);
params->Tuple.variables[1] = alloc_entity_param(nullptr, make_token_ident("fdwReason"), t_u32, false, true);
params->Tuple.variables[2] = alloc_entity_param(nullptr, make_token_ident("lpReserved"), t_rawptr, false, true);
@@ -769,12 +769,12 @@ lbProcedure *lb_create_main_procedure(lbModule *m, lbProcedure *startup_runtime)
name = str_lit("mainCRTStartup");
} else {
has_args = true;
- array_init(&params->Tuple.variables, permanent_allocator(), 2);
+ slice_init(&params->Tuple.variables, permanent_allocator(), 2);
params->Tuple.variables[0] = alloc_entity_param(nullptr, make_token_ident("argc"), t_i32, false, true);
params->Tuple.variables[1] = alloc_entity_param(nullptr, make_token_ident("argv"), t_ptr_cstring, false, true);
}
- array_init(&results->Tuple.variables, permanent_allocator(), 1);
+ slice_init(&results->Tuple.variables, permanent_allocator(), 1);
results->Tuple.variables[0] = alloc_entity_param(nullptr, blank_token, t_i32, false, true);
Type *proc_type = alloc_type_proc(nullptr,
diff --git a/src/llvm_backend_const.cpp b/src/llvm_backend_const.cpp
index 5ad2b09b6..d46992976 100644
--- a/src/llvm_backend_const.cpp
+++ b/src/llvm_backend_const.cpp
@@ -690,8 +690,8 @@ lbValue lb_const_value(lbModule *m, Type *type, ExactValue value, bool allow_loc
isize value_index = 0;
- i64 total_lo = exact_value_to_i64(type->EnumeratedArray.min_value);
- i64 total_hi = exact_value_to_i64(type->EnumeratedArray.max_value);
+ i64 total_lo = exact_value_to_i64(*type->EnumeratedArray.min_value);
+ i64 total_hi = exact_value_to_i64(*type->EnumeratedArray.max_value);
for (i64 i = total_lo; i <= total_hi; i++) {
bool found = false;
diff --git a/src/llvm_backend_expr.cpp b/src/llvm_backend_expr.cpp
index a4b4564c0..efd0eaf40 100644
--- a/src/llvm_backend_expr.cpp
+++ b/src/llvm_backend_expr.cpp
@@ -2872,13 +2872,13 @@ lbAddr lb_build_addr(lbProcedure *p, Ast *expr) {
auto index_tv = type_and_value_of_expr(ie->index);
lbValue index = {};
- if (compare_exact_values(Token_NotEq, t->EnumeratedArray.min_value, exact_value_i64(0))) {
+ if (compare_exact_values(Token_NotEq, *t->EnumeratedArray.min_value, exact_value_i64(0))) {
if (index_tv.mode == Addressing_Constant) {
- ExactValue idx = exact_value_sub(index_tv.value, t->EnumeratedArray.min_value);
+ ExactValue idx = exact_value_sub(index_tv.value, *t->EnumeratedArray.min_value);
index = lb_const_value(p->module, index_type, idx);
} else {
index = lb_emit_conv(p, lb_build_expr(p, ie->index), t_int);
- index = lb_emit_arith(p, Token_Sub, index, lb_const_value(p->module, index_type, t->EnumeratedArray.min_value), index_type);
+ index = lb_emit_arith(p, Token_Sub, index, lb_const_value(p->module, index_type, *t->EnumeratedArray.min_value), index_type);
}
} else {
index = lb_emit_conv(p, lb_build_expr(p, ie->index), t_int);
@@ -3472,7 +3472,7 @@ lbAddr lb_build_addr(lbProcedure *p, Ast *expr) {
}
- i32 index_offset = cast(i32)exact_value_to_i64(bt->EnumeratedArray.min_value);
+ i32 index_offset = cast(i32)exact_value_to_i64(*bt->EnumeratedArray.min_value);
for_array(i, temp_data) {
i32 index = temp_data[i].elem_index - index_offset;
diff --git a/src/llvm_backend_general.cpp b/src/llvm_backend_general.cpp
index 113c9ba62..f481c122e 100644
--- a/src/llvm_backend_general.cpp
+++ b/src/llvm_backend_general.cpp
@@ -1670,7 +1670,7 @@ LLVMTypeRef lb_type_internal(lbModule *m, Type *type) {
LLVMTypeRef *fields = gb_alloc_array(permanent_allocator(), LLVMTypeRef, field_count);
i64 alignment = type_align_of(type);
unsigned size_of_union = cast(unsigned)type_size_of(type);
- fields[0] = lb_alignment_prefix_type_hack(m, alignment);
+ fields[0] = lb_alignment_prefix_type_hack(m, gb_min(alignment, 16));
fields[1] = LLVMArrayType(lb_type(m, t_u8), size_of_union);
return LLVMStructTypeInContext(ctx, fields, field_count, false);
}
diff --git a/src/llvm_backend_proc.cpp b/src/llvm_backend_proc.cpp
index ffbb532f0..ce6807571 100644
--- a/src/llvm_backend_proc.cpp
+++ b/src/llvm_backend_proc.cpp
@@ -1393,7 +1393,7 @@ lbValue lb_build_builtin_proc(lbProcedure *p, Ast *expr, TypeAndValue const &tv,
Type *res_type = nullptr;
gbAllocator a = permanent_allocator();
res_type = alloc_type_tuple();
- array_init(&res_type->Tuple.variables, a, 2);
+ slice_init(&res_type->Tuple.variables, a, 2);
res_type->Tuple.variables[0] = alloc_entity_field(nullptr, blank_token, type, false, 0);
res_type->Tuple.variables[1] = alloc_entity_field(nullptr, blank_token, t_llvm_bool, false, 1);
@@ -1738,7 +1738,7 @@ lbValue lb_build_builtin_proc(lbProcedure *p, Ast *expr, TypeAndValue const &tv,
if (tv.type->kind == Type_Tuple) {
Type *fix_typed = alloc_type_tuple();
- array_init(&fix_typed->Tuple.variables, permanent_allocator(), 2);
+ slice_init(&fix_typed->Tuple.variables, permanent_allocator(), 2);
fix_typed->Tuple.variables[0] = tv.type->Tuple.variables[0];
fix_typed->Tuple.variables[1] = alloc_entity_field(nullptr, blank_token, t_llvm_bool, false, 1);
diff --git a/src/llvm_backend_stmt.cpp b/src/llvm_backend_stmt.cpp
index 148790ac6..ac922b642 100644
--- a/src/llvm_backend_stmt.cpp
+++ b/src/llvm_backend_stmt.cpp
@@ -332,8 +332,8 @@ void lb_build_range_indexed(lbProcedure *p, lbValue expr, Type *val_type, lbValu
val = lb_emit_load(p, lb_emit_array_ep(p, expr, idx));
// NOTE(bill): Override the idx value for the enumeration
Type *index_type = expr_type->EnumeratedArray.index;
- if (compare_exact_values(Token_NotEq, expr_type->EnumeratedArray.min_value, exact_value_u64(0))) {
- idx = lb_emit_arith(p, Token_Add, idx, lb_const_value(m, index_type, expr_type->EnumeratedArray.min_value), index_type);
+ if (compare_exact_values(Token_NotEq, *expr_type->EnumeratedArray.min_value, exact_value_u64(0))) {
+ idx = lb_emit_arith(p, Token_Add, idx, lb_const_value(m, index_type, *expr_type->EnumeratedArray.min_value), index_type);
}
}
break;
@@ -984,7 +984,7 @@ void lb_build_unroll_range_stmt(lbProcedure *p, AstUnrollRangeStmt *rs, Scope *s
lb_addr_store(p, val0_addr, lb_emit_load(p, elem));
}
if (val1_type) {
- ExactValue idx = exact_value_add(exact_value_i64(i), t->EnumeratedArray.min_value);
+ ExactValue idx = exact_value_add(exact_value_i64(i), *t->EnumeratedArray.min_value);
lb_addr_store(p, val1_addr, lb_const_value(m, val1_type, idx));
}
diff --git a/src/llvm_backend_type.cpp b/src/llvm_backend_type.cpp
index af3fadc3c..f5665c718 100644
--- a/src/llvm_backend_type.cpp
+++ b/src/llvm_backend_type.cpp
@@ -450,8 +450,8 @@ void lb_setup_type_info_data(lbProcedure *p) { // NOTE(bill): Setup type_info da
lbValue min_value = lb_emit_struct_ep(p, tag, 4);
lbValue max_value = lb_emit_struct_ep(p, tag, 5);
- lbValue min_v = lb_const_value(m, t_i64, t->EnumeratedArray.min_value);
- lbValue max_v = lb_const_value(m, t_i64, t->EnumeratedArray.max_value);
+ lbValue min_v = lb_const_value(m, t_i64, *t->EnumeratedArray.min_value);
+ lbValue max_v = lb_const_value(m, t_i64, *t->EnumeratedArray.max_value);
lb_emit_store(p, min_value, min_v);
lb_emit_store(p, max_value, max_v);
diff --git a/src/types.cpp b/src/types.cpp
index 37a05d5a6..4362ae45b 100644
--- a/src/types.cpp
+++ b/src/types.cpp
@@ -129,9 +129,9 @@ enum StructSoaKind {
};
struct TypeStruct {
- Array<Entity *> fields;
- Array<String> tags;
- Array<i64> offsets;
+ Slice<Entity *> fields;
+ Slice<String> tags;
+ Slice<i64> offsets;
Ast * node;
Scope * scope;
@@ -145,12 +145,12 @@ struct TypeStruct {
i64 soa_count;
StructSoaKind soa_kind;
- bool are_offsets_set;
- bool are_offsets_being_processed;
- bool is_packed;
- bool is_raw_union;
bool is_polymorphic;
- bool is_poly_specialized;
+ bool are_offsets_set : 1;
+ bool are_offsets_being_processed : 1;
+ bool is_packed : 1;
+ bool is_raw_union : 1;
+ bool is_poly_specialized : 1;
};
struct TypeUnion {
@@ -216,8 +216,8 @@ struct TypeProc {
TYPE_KIND(EnumeratedArray, struct { \
Type *elem; \
Type *index; \
- ExactValue min_value; \
- ExactValue max_value; \
+ ExactValue *min_value; \
+ ExactValue *max_value; \
i64 count; \
TokenKind op; \
}) \
@@ -239,14 +239,14 @@ struct TypeProc {
Scope * scope; \
Entity * names; \
Type * base_type; \
- ExactValue min_value; \
- ExactValue max_value; \
+ ExactValue *min_value; \
+ ExactValue *max_value; \
isize min_value_index; \
isize max_value_index; \
}) \
TYPE_KIND(Tuple, struct { \
- Array<Entity *> variables; /* Entity_Variable */ \
- Array<i64> offsets; \
+ Slice<Entity *> variables; /* Entity_Variable */ \
+ Slice<i64> offsets; \
bool are_offsets_being_processed; \
bool are_offsets_set; \
bool is_packed; \
@@ -803,15 +803,17 @@ Type *alloc_type_array(Type *elem, i64 count, Type *generic_count = nullptr) {
return t;
}
-Type *alloc_type_enumerated_array(Type *elem, Type *index, ExactValue min_value, ExactValue max_value, TokenKind op) {
+Type *alloc_type_enumerated_array(Type *elem, Type *index, ExactValue const *min_value, ExactValue const *max_value, TokenKind op) {
Type *t = alloc_type(Type_EnumeratedArray);
t->EnumeratedArray.elem = elem;
t->EnumeratedArray.index = index;
- t->EnumeratedArray.min_value = min_value;
- t->EnumeratedArray.max_value = max_value;
+ t->EnumeratedArray.min_value = gb_alloc_item(permanent_allocator(), ExactValue);
+ t->EnumeratedArray.max_value = gb_alloc_item(permanent_allocator(), ExactValue);
+ gb_memmove(t->EnumeratedArray.min_value, min_value, gb_size_of(ExactValue));
+ gb_memmove(t->EnumeratedArray.max_value, max_value, gb_size_of(ExactValue));
t->EnumeratedArray.op = op;
- t->EnumeratedArray.count = 1 + exact_value_to_i64(exact_value_sub(max_value, min_value));
+ t->EnumeratedArray.count = 1 + exact_value_to_i64(exact_value_sub(*max_value, *min_value));
return t;
}
@@ -841,6 +843,8 @@ Type *alloc_type_union() {
Type *alloc_type_enum() {
Type *t = alloc_type(Type_Enum);
+ t->Enum.min_value = gb_alloc_item(permanent_allocator(), ExactValue);
+ t->Enum.max_value = gb_alloc_item(permanent_allocator(), ExactValue);
return t;
}
@@ -3080,9 +3084,9 @@ i64 type_align_of_internal(Type *t, TypePath *path) {
return gb_clamp(next_pow2(type_size_of_internal(t, path)), 1, build_context.word_size);
}
-Array<i64> type_set_offsets_of(Array<Entity *> const &fields, bool is_packed, bool is_raw_union) {
+Slice<i64> type_set_offsets_of(Slice<Entity *> const &fields, bool is_packed, bool is_raw_union) {
gbAllocator a = permanent_allocator();
- auto offsets = array_make<i64>(a, fields.count);
+ auto offsets = slice_make<i64>(a, fields.count);
i64 curr_offset = 0;
if (is_raw_union) {
for_array(i, fields) {
@@ -3463,7 +3467,7 @@ Type *reduce_tuple_to_single_type(Type *original_type) {
Type *alloc_type_struct_from_field_types(Type **field_types, isize field_count, bool is_packed) {
Type *t = alloc_type_struct();
- t->Struct.fields = array_make<Entity *>(heap_allocator(), field_count);
+ t->Struct.fields = slice_make<Entity *>(heap_allocator(), field_count);
Scope *scope = nullptr;
for_array(i, t->Struct.fields) {
@@ -3483,7 +3487,7 @@ Type *alloc_type_tuple_from_field_types(Type **field_types, isize field_count, b
}
Type *t = alloc_type_tuple();
- t->Tuple.variables = array_make<Entity *>(heap_allocator(), field_count);
+ t->Tuple.variables = slice_make<Entity *>(heap_allocator(), field_count);
Scope *scope = nullptr;
for_array(i, t->Tuple.variables) {