mirror of
https://github.com/odin-lang/Odin.git
synced 2026-01-03 03:32:37 +00:00
Begin minimize Type size by replacing Array with Slice etc
This commit is contained in:
@@ -150,6 +150,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);
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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(¶ms->Tuple.variables, heap_allocator(), param_types.count);
|
||||
slice_init(¶ms->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);
|
||||
}
|
||||
|
||||
|
||||
@@ -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 ¶ms,
|
||||
void check_struct_fields(CheckerContext *ctx, Ast *node, Slice<Entity *> *fields, Slice<String> *tags, Slice<Ast *> const ¶ms,
|
||||
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;
|
||||
|
||||
@@ -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)) {
|
||||
|
||||
@@ -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(¶ms->Tuple.variables, permanent_allocator(), 3);
|
||||
slice_init(¶ms->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(¶ms->Tuple.variables, permanent_allocator(), 2);
|
||||
slice_init(¶ms->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,
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
|
||||
|
||||
@@ -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));
|
||||
}
|
||||
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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) {
|
||||
|
||||
Reference in New Issue
Block a user