mirror of
https://github.com/Ed94/Odin.git
synced 2026-08-06 07:38:48 +00:00
Remove empty union check on array types; Fix overflowing error printing
This commit is contained in:
+35
-46
@@ -2790,6 +2790,38 @@ Type *make_optional_ok_type(gbAllocator a, Type *value) {
|
|||||||
return t;
|
return t;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void generate_map_struct_type(gbAllocator a, Type *type) {
|
||||||
|
GB_ASSERT(type->kind == Type_Map);
|
||||||
|
if (type->Map.generated_struct_type != NULL) return;
|
||||||
|
|
||||||
|
Type *generated_struct_type = make_type_struct(a);
|
||||||
|
|
||||||
|
/*
|
||||||
|
struct {
|
||||||
|
hashes: [dynamic]int;
|
||||||
|
entries; [dynamic]EntryType;
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
AstNode *dummy_node = gb_alloc_item(a, AstNode);
|
||||||
|
dummy_node->kind = AstNode_Invalid;
|
||||||
|
Scope *s = make_scope(universal_scope, a);
|
||||||
|
|
||||||
|
Type *hashes_type = make_type_dynamic_array(a, t_int);
|
||||||
|
Type *entries_type = make_type_dynamic_array(a, type->Map.entry_type);
|
||||||
|
|
||||||
|
Array<Entity *> fields = {};
|
||||||
|
array_init(&fields, a, 2);
|
||||||
|
array_add(&fields, make_entity_field(a, s, make_token_ident(str_lit("hashes")), hashes_type, false, 0));
|
||||||
|
array_add(&fields, make_entity_field(a, s, make_token_ident(str_lit("entries")), entries_type, false, 1));
|
||||||
|
|
||||||
|
|
||||||
|
generated_struct_type->Struct.fields = fields;
|
||||||
|
generated_struct_type->Struct.fields_in_src_order = fields;
|
||||||
|
|
||||||
|
type_set_offsets(a, generated_struct_type);
|
||||||
|
type->Map.generated_struct_type = generated_struct_type;
|
||||||
|
}
|
||||||
|
|
||||||
void check_map_type(Checker *c, Type *type, AstNode *node) {
|
void check_map_type(Checker *c, Type *type, AstNode *node) {
|
||||||
GB_ASSERT(type->kind == Type_Map);
|
GB_ASSERT(type->kind == Type_Map);
|
||||||
ast_node(mt, MapType, node);
|
ast_node(mt, MapType, node);
|
||||||
@@ -2854,35 +2886,7 @@ void check_map_type(Checker *c, Type *type, AstNode *node) {
|
|||||||
type->Map.entry_type = entry_type;
|
type->Map.entry_type = entry_type;
|
||||||
}
|
}
|
||||||
|
|
||||||
{
|
generate_map_struct_type(a, type);
|
||||||
Type *generated_struct_type = make_type_struct(a);
|
|
||||||
|
|
||||||
/*
|
|
||||||
struct {
|
|
||||||
hashes: [dynamic]int,
|
|
||||||
entries; [dynamic]Entry_Type,
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
AstNode *dummy_node = gb_alloc_item(a, AstNode);
|
|
||||||
dummy_node->kind = AstNode_Invalid;
|
|
||||||
check_open_scope(c, dummy_node);
|
|
||||||
|
|
||||||
Type *hashes_type = make_type_dynamic_array(a, t_int);
|
|
||||||
Type *entries_type = make_type_dynamic_array(a, type->Map.entry_type);
|
|
||||||
|
|
||||||
Array<Entity *> fields = {};
|
|
||||||
array_init(&fields, a, 2);
|
|
||||||
array_add(&fields, make_entity_field(a, c->context.scope, make_token_ident(str_lit("hashes")), hashes_type, false, 0));
|
|
||||||
array_add(&fields, make_entity_field(a, c->context.scope, make_token_ident(str_lit("entries")), entries_type, false, 1));
|
|
||||||
|
|
||||||
check_close_scope(c);
|
|
||||||
|
|
||||||
generated_struct_type->Struct.fields = fields;
|
|
||||||
generated_struct_type->Struct.fields_in_src_order = fields;
|
|
||||||
|
|
||||||
type_set_offsets(a, generated_struct_type);
|
|
||||||
type->Map.generated_struct_type = generated_struct_type;
|
|
||||||
}
|
|
||||||
|
|
||||||
type->Map.lookup_result_type = make_optional_ok_type(a, value);
|
type->Map.lookup_result_type = make_optional_ok_type(a, value);
|
||||||
|
|
||||||
@@ -3021,19 +3025,9 @@ bool check_type_internal(Checker *c, AstNode *e, Type **type, Type *named_type)
|
|||||||
error(at->count, "... can only be used in conjuction with compound literals");
|
error(at->count, "... can only be used in conjuction with compound literals");
|
||||||
count = 0;
|
count = 0;
|
||||||
}
|
}
|
||||||
if (is_type_empty_union(elem)) {
|
|
||||||
gbString str = type_to_string(elem);
|
|
||||||
error(at->elem, "An empty union `%s` is not allowed as an array element type", str);
|
|
||||||
gb_string_free(str);
|
|
||||||
}
|
|
||||||
*type = make_type_array(c->allocator, elem, count);
|
*type = make_type_array(c->allocator, elem, count);
|
||||||
} else {
|
} else {
|
||||||
Type *elem = check_type(c, at->elem);
|
Type *elem = check_type(c, at->elem);
|
||||||
if (is_type_empty_union(elem)) {
|
|
||||||
gbString str = type_to_string(elem);
|
|
||||||
error(at->elem, "An empty union `%s` is not allowed as an slice element type", str);
|
|
||||||
gb_string_free(str);
|
|
||||||
}
|
|
||||||
*type = make_type_slice(c->allocator, elem);
|
*type = make_type_slice(c->allocator, elem);
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
@@ -3041,11 +3035,6 @@ bool check_type_internal(Checker *c, AstNode *e, Type **type, Type *named_type)
|
|||||||
|
|
||||||
case_ast_node(dat, DynamicArrayType, e);
|
case_ast_node(dat, DynamicArrayType, e);
|
||||||
Type *elem = check_type(c, dat->elem);
|
Type *elem = check_type(c, dat->elem);
|
||||||
if (is_type_empty_union(elem)) {
|
|
||||||
gbString str = type_to_string(elem);
|
|
||||||
error(dat->elem, "An empty union `%s` is not allowed as an dynamic array element type", str);
|
|
||||||
gb_string_free(str);
|
|
||||||
}
|
|
||||||
*type = make_type_dynamic_array(c->allocator, elem);
|
*type = make_type_dynamic_array(c->allocator, elem);
|
||||||
return true;
|
return true;
|
||||||
case_end;
|
case_end;
|
||||||
@@ -3408,7 +3397,7 @@ bool check_representable_as_constant(Checker *c, ExactValue in_value, Type *type
|
|||||||
}
|
}
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}else if (is_type_pointer(type)) {
|
} else if (is_type_pointer(type)) {
|
||||||
if (in_value.kind == ExactValue_Pointer) {
|
if (in_value.kind == ExactValue_Pointer) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@@ -3441,7 +3430,7 @@ void check_is_expressible(Checker *c, Operand *o, Type *type) {
|
|||||||
} else {
|
} else {
|
||||||
str = i128_to_string(i, buf, gb_size_of(buf));
|
str = i128_to_string(i, buf, gb_size_of(buf));
|
||||||
}
|
}
|
||||||
error(o->expr, "`%s = %.*s` overflows `%s`", a, str, b);
|
error(o->expr, "`%s = %.*s` overflows `%s`", a, LIT(str), b);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
error(o->expr, "Cannot convert `%s` to `%s`", a, b);
|
error(o->expr, "Cannot convert `%s` to `%s`", a, b);
|
||||||
|
|||||||
@@ -1182,6 +1182,7 @@ void add_type_info_type(Checker *c, Type *t) {
|
|||||||
} break;
|
} break;
|
||||||
|
|
||||||
case Type_Map: {
|
case Type_Map: {
|
||||||
|
generate_map_struct_type(c->allocator, bt);
|
||||||
add_type_info_type(c, bt->Map.key);
|
add_type_info_type(c, bt->Map.key);
|
||||||
add_type_info_type(c, bt->Map.value);
|
add_type_info_type(c, bt->Map.value);
|
||||||
add_type_info_type(c, bt->Map.generated_struct_type);
|
add_type_info_type(c, bt->Map.generated_struct_type);
|
||||||
|
|||||||
+1
-1
@@ -1733,7 +1733,7 @@ void print_llvm_ir(irGen *ir) {
|
|||||||
ir_file_buffer_init(f, &ir->output_file);
|
ir_file_buffer_init(f, &ir->output_file);
|
||||||
|
|
||||||
ir_print_encoded_local(f, str_lit("..opaque"));
|
ir_print_encoded_local(f, str_lit("..opaque"));
|
||||||
ir_fprintf(f, " = type opaque;\n");
|
ir_fprintf(f, " = type {};\n");
|
||||||
ir_print_encoded_local(f, str_lit("..string"));
|
ir_print_encoded_local(f, str_lit("..string"));
|
||||||
ir_fprintf(f, " = type {i8*, ");
|
ir_fprintf(f, " = type {i8*, ");
|
||||||
ir_print_type(f, m, t_int);
|
ir_print_type(f, m, t_int);
|
||||||
|
|||||||
+22
-14
@@ -150,12 +150,12 @@ struct TypeStruct {
|
|||||||
ProcCallingConvention calling_convention; \
|
ProcCallingConvention calling_convention; \
|
||||||
}) \
|
}) \
|
||||||
TYPE_KIND(Map, struct { \
|
TYPE_KIND(Map, struct { \
|
||||||
i64 count; /* 0 if dynamic */ \
|
i64 count; /* 0 if dynamic */ \
|
||||||
Type *key; \
|
Type * key; \
|
||||||
Type *value; \
|
Type * value; \
|
||||||
Type *entry_type; \
|
Type * entry_type; \
|
||||||
Type *generated_struct_type; \
|
Type * generated_struct_type; \
|
||||||
Type *lookup_result_type; \
|
Type * lookup_result_type; \
|
||||||
}) \
|
}) \
|
||||||
TYPE_KIND(BitFieldValue, struct { u32 bits; }) \
|
TYPE_KIND(BitFieldValue, struct { u32 bits; }) \
|
||||||
TYPE_KIND(BitField, struct { \
|
TYPE_KIND(BitField, struct { \
|
||||||
@@ -386,10 +386,11 @@ gb_global Type *t_map_header = nullptr;
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
i64 type_size_of (gbAllocator allocator, Type *t);
|
i64 type_size_of (gbAllocator allocator, Type *t);
|
||||||
i64 type_align_of (gbAllocator allocator, Type *t);
|
i64 type_align_of (gbAllocator allocator, Type *t);
|
||||||
i64 type_offset_of (gbAllocator allocator, Type *t, i32 index);
|
i64 type_offset_of (gbAllocator allocator, Type *t, i32 index);
|
||||||
gbString type_to_string(Type *type);
|
gbString type_to_string (Type *type);
|
||||||
|
void generate_map_struct_type(gbAllocator a, Type *type);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@@ -585,6 +586,8 @@ Type *make_type_bit_field(gbAllocator a) {
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
|
||||||
@@ -1819,6 +1822,8 @@ i64 type_align_of_internal(gbAllocator allocator, Type *t, TypePath *path) {
|
|||||||
|
|
||||||
case Type_Map: {
|
case Type_Map: {
|
||||||
if (t->Map.count == 0) { // Dynamic
|
if (t->Map.count == 0) { // Dynamic
|
||||||
|
// return build_context.word_size;
|
||||||
|
generate_map_struct_type(allocator, t);
|
||||||
return type_align_of_internal(allocator, t->Map.generated_struct_type, path);
|
return type_align_of_internal(allocator, t->Map.generated_struct_type, path);
|
||||||
}
|
}
|
||||||
GB_PANIC("TODO(bill): Fixed map alignment");
|
GB_PANIC("TODO(bill): Fixed map alignment");
|
||||||
@@ -2000,10 +2005,6 @@ i64 type_size_of_internal(gbAllocator allocator, Type *t, TypePath *path) {
|
|||||||
return alignment*(count-1) + size;
|
return alignment*(count-1) + size;
|
||||||
} break;
|
} break;
|
||||||
|
|
||||||
case Type_DynamicArray:
|
|
||||||
// data + len + cap + allocator(procedure+data)
|
|
||||||
return 3*build_context.word_size + 2*build_context.word_size;
|
|
||||||
|
|
||||||
case Type_Vector: {
|
case Type_Vector: {
|
||||||
#if 0
|
#if 0
|
||||||
i64 count, bit_size, total_size_in_bits, total_size;
|
i64 count, bit_size, total_size_in_bits, total_size;
|
||||||
@@ -2044,8 +2045,15 @@ i64 type_size_of_internal(gbAllocator allocator, Type *t, TypePath *path) {
|
|||||||
case Type_Slice: // ptr + count
|
case Type_Slice: // ptr + count
|
||||||
return 3 * build_context.word_size;
|
return 3 * build_context.word_size;
|
||||||
|
|
||||||
|
case Type_DynamicArray:
|
||||||
|
// data + len + cap + allocator(procedure+data)
|
||||||
|
return 3*build_context.word_size + 2*build_context.word_size;
|
||||||
|
|
||||||
case Type_Map: {
|
case Type_Map: {
|
||||||
if (t->Map.count == 0) { // Dynamic
|
if (t->Map.count == 0) { // Dynamic
|
||||||
|
// i64 da = 3*build_context.word_size + 2*build_context.word_size;
|
||||||
|
// return 2 * da;
|
||||||
|
generate_map_struct_type(allocator, t);
|
||||||
return type_size_of_internal(allocator, t->Map.generated_struct_type, path);
|
return type_size_of_internal(allocator, t->Map.generated_struct_type, path);
|
||||||
}
|
}
|
||||||
GB_PANIC("TODO(bill): Fixed map size");
|
GB_PANIC("TODO(bill): Fixed map size");
|
||||||
|
|||||||
Reference in New Issue
Block a user