Browse Source

Remove empty union check on array types; Fix overflowing error printing

Ginger Bill 8 years ago
parent
commit
24c812115e
4 changed files with 59 additions and 61 deletions
  1. 35 46
      src/check_expr.cpp
  2. 1 0
      src/checker.cpp
  3. 1 1
      src/ir_print.cpp
  4. 22 14
      src/types.cpp

+ 35 - 46
src/check_expr.cpp

@@ -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;
 	}
 	}
 
 
-	{
-		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;
-	}
+	generate_map_struct_type(a, 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);

+ 1 - 0
src/checker.cpp

@@ -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
src/ir_print.cpp

@@ -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
src/types.cpp

@@ -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 */                   \
-		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(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_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: {
 	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");