diff --git a/src/check_expr.cpp b/src/check_expr.cpp index fcaf943a7..e25a687b1 100644 --- a/src/check_expr.cpp +++ b/src/check_expr.cpp @@ -2790,6 +2790,38 @@ Type *make_optional_ok_type(gbAllocator a, Type *value) { 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 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) { GB_ASSERT(type->kind == Type_Map); 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 *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 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; - } + generate_map_struct_type(a, type); 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"); 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); } else { 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); } 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); 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); return true; case_end; @@ -3408,7 +3397,7 @@ bool check_representable_as_constant(Checker *c, ExactValue in_value, Type *type } return false; - }else if (is_type_pointer(type)) { + } else if (is_type_pointer(type)) { if (in_value.kind == ExactValue_Pointer) { return true; } @@ -3441,7 +3430,7 @@ void check_is_expressible(Checker *c, Operand *o, Type *type) { } else { 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 { error(o->expr, "Cannot convert `%s` to `%s`", a, b); diff --git a/src/checker.cpp b/src/checker.cpp index 4c77f25ee..47b720736 100644 --- a/src/checker.cpp +++ b/src/checker.cpp @@ -1182,6 +1182,7 @@ void add_type_info_type(Checker *c, Type *t) { } break; 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.value); add_type_info_type(c, bt->Map.generated_struct_type); diff --git a/src/ir_print.cpp b/src/ir_print.cpp index 23c385140..f54671519 100644 --- a/src/ir_print.cpp +++ b/src/ir_print.cpp @@ -1733,7 +1733,7 @@ void print_llvm_ir(irGen *ir) { ir_file_buffer_init(f, &ir->output_file); 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_fprintf(f, " = type {i8*, "); ir_print_type(f, m, t_int); diff --git a/src/types.cpp b/src/types.cpp index 13480eb3f..becb4cf06 100644 --- a/src/types.cpp +++ b/src/types.cpp @@ -150,12 +150,12 @@ struct TypeStruct { ProcCallingConvention calling_convention; \ }) \ TYPE_KIND(Map, struct { \ - i64 count; /* 0 if dynamic */ \ - Type *key; \ - Type *value; \ - Type *entry_type; \ - Type *generated_struct_type; \ - Type *lookup_result_type; \ + i64 count; /* 0 if dynamic */ \ + Type * key; \ + Type * value; \ + Type * entry_type; \ + Type * generated_struct_type; \ + Type * lookup_result_type; \ }) \ TYPE_KIND(BitFieldValue, struct { u32 bits; }) \ 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_align_of (gbAllocator allocator, Type *t); -i64 type_offset_of (gbAllocator allocator, Type *t, i32 index); -gbString type_to_string(Type *type); +i64 type_size_of (gbAllocator allocator, Type *t); +i64 type_align_of (gbAllocator allocator, Type *t); +i64 type_offset_of (gbAllocator allocator, Type *t, i32 index); +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: { 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); } 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; } break; - case Type_DynamicArray: - // data + len + cap + allocator(procedure+data) - return 3*build_context.word_size + 2*build_context.word_size; - case Type_Vector: { #if 0 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 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: { 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); } GB_PANIC("TODO(bill): Fixed map size");