Browse Source

Compiler internal change: TypeRecord_Enum -> Type_Enum

Ginger Bill 8 years ago
parent
commit
d936ca1ea0
6 changed files with 137 additions and 160 deletions
  1. 9 11
      src/check_expr.cpp
  2. 5 35
      src/check_stmt.cpp
  3. 4 3
      src/checker.cpp
  4. 49 49
      src/ir.cpp
  5. 5 3
      src/ir_print.cpp
  6. 65 59
      src/types.cpp

+ 9 - 11
src/check_expr.cpp

@@ -119,7 +119,7 @@ bool check_is_assignable_to_using_subtype(Type *src, Type *dst) {
 	src_is_ptr = src != prev_src;
 	src_is_ptr = src != prev_src;
 	src = base_type(src);
 	src = base_type(src);
 
 
-	if (!is_type_struct(src) && !is_type_union(src)) {
+	if (!is_type_struct(src)) {
 		return false;
 		return false;
 	}
 	}
 
 
@@ -1070,7 +1070,7 @@ void check_enum_type(Checker *c, Type *enum_type, Type *named_type, AstNode *nod
 	}
 	}
 
 
 	// NOTE(bill): Must be up here for the `check_init_constant` system
 	// NOTE(bill): Must be up here for the `check_init_constant` system
-	enum_type->Record.enum_base_type = base_type;
+	enum_type->Enum.base_type = base_type;
 
 
 	Map<Entity *> entity_map = {}; // Key: String
 	Map<Entity *> entity_map = {}; // Key: String
 	map_init_with_reserve(&entity_map, c->tmp_allocator, 2*(et->fields.count));
 	map_init_with_reserve(&entity_map, c->tmp_allocator, 2*(et->fields.count));
@@ -1171,17 +1171,17 @@ void check_enum_type(Checker *c, Type *enum_type, Type *named_type, AstNode *nod
 	GB_ASSERT(fields.count <= et->fields.count);
 	GB_ASSERT(fields.count <= et->fields.count);
 
 
 
 
-	enum_type->Record.fields      = fields.data;
-	enum_type->Record.field_count = fields.count;
+	enum_type->Enum.fields      = fields.data;
+	enum_type->Enum.field_count = fields.count;
 
 
-	enum_type->Record.enum_count = make_entity_constant(c->allocator, c->context.scope,
+	enum_type->Enum.count = make_entity_constant(c->allocator, c->context.scope,
 		make_token_ident(str_lit("count")), t_int, exact_value_i64(fields.count));
 		make_token_ident(str_lit("count")), t_int, exact_value_i64(fields.count));
-	enum_type->Record.enum_min_value = make_entity_constant(c->allocator, c->context.scope,
+	enum_type->Enum.min_value = make_entity_constant(c->allocator, c->context.scope,
 		make_token_ident(str_lit("min_value")), constant_type, min_value);
 		make_token_ident(str_lit("min_value")), constant_type, min_value);
-	enum_type->Record.enum_max_value = make_entity_constant(c->allocator, c->context.scope,
+	enum_type->Enum.max_value = make_entity_constant(c->allocator, c->context.scope,
 		make_token_ident(str_lit("max_value")), constant_type, max_value);
 		make_token_ident(str_lit("max_value")), constant_type, max_value);
 
 
-	enum_type->Record.names = make_names_field_for_record(c, c->context.scope);
+	enum_type->Enum.names = make_names_field_for_record(c, c->context.scope);
 }
 }
 
 
 
 
@@ -2569,7 +2569,7 @@ bool check_type_internal(Checker *c, AstNode *e, Type **type, Type *named_type)
 		check_open_scope(c, e);
 		check_open_scope(c, e);
 		check_enum_type(c, *type, named_type, e);
 		check_enum_type(c, *type, named_type, e);
 		check_close_scope(c);
 		check_close_scope(c);
-		(*type)->Record.node = e;
+		(*type)->Enum.node = e;
 		return true;
 		return true;
 	case_end;
 	case_end;
 
 
@@ -3069,8 +3069,6 @@ void check_comparison(Checker *c, Operand *x, Operand *y, TokenKind op) {
 			if (x->type == err_type && is_operand_nil(*x)) {
 			if (x->type == err_type && is_operand_nil(*x)) {
 				err_type = y->type;
 				err_type = y->type;
 			}
 			}
-			gb_printf_err("%d %d\n", is_operand_nil(*x), type_has_nil(y->type));
-			gb_printf_err("%d %d\n", is_operand_nil(*y), type_has_nil(x->type));
 			gbString type_string = type_to_string(err_type);
 			gbString type_string = type_to_string(err_type);
 			err_str = gb_string_make(c->tmp_allocator,
 			err_str = gb_string_make(c->tmp_allocator,
 			                         gb_bprintf("operator `%.*s` not defined for type `%s`", LIT(token_strings[op]), type_string));
 			                         gb_bprintf("operator `%.*s` not defined for type `%s`", LIT(token_strings[op]), type_string));

+ 5 - 35
src/check_stmt.cpp

@@ -489,39 +489,10 @@ bool check_using_stmt_entity(Checker *c, AstNodeUsingStmt *us, AstNode *expr, bo
 						f->using_parent = e;
 						f->using_parent = e;
 					}
 					}
 				}
 				}
-			} else if (is_type_enum(t)) {
-				for (isize i = 0; i < t->Record.field_count; i++) {
-					Entity *f = t->Record.fields[i];
-					Entity *found = scope_insert_entity(c->context.scope, f);
-					if (found != nullptr) {
-						gbString expr_str = expr_to_string(expr);
-						error(us->token, "Namespace collision while `using` `%s` of: %.*s", expr_str, LIT(found->token.string));
-						gb_string_free(expr_str);
-						return false;
-					}
-					f->using_parent = e;
-				}
-			}
-		} else {
-			error(us->token, "`using` can be only applied to record type entities");
-		}
-		/* if (is_type_union(t)) {
-			TokenPos pos = ast_node_token(expr).pos;
-			for (isize i = 1; i < t->Record.variant_count; i++) {
-				Entity *f = t->Record.variants[i];
-				// gb_printf_err("%s\n", type_to_string(f->type));
-				Entity *found = scope_insert_entity(c->context.scope, f);
-				if (found != nullptr) {
-					gbString expr_str = expr_to_string(expr);
-					error(us->token, "Namespace collision while `using` `%s` of: %.*s", expr_str, LIT(found->token.string));
-					gb_string_free(expr_str);
-					return false;
-				}
-				f->using_parent = e;
 			}
 			}
-		} else if (is_type_enum(t)) {
-			for (isize i = 0; i < t->Record.field_count; i++) {
-				Entity *f = t->Record.fields[i];
+		} else if (t->kind == Type_Enum) {
+			for (isize i = 0; i < t->Enum.field_count; i++) {
+				Entity *f = t->Enum.fields[i];
 				Entity *found = scope_insert_entity(c->context.scope, f);
 				Entity *found = scope_insert_entity(c->context.scope, f);
 				if (found != nullptr) {
 				if (found != nullptr) {
 					gbString expr_str = expr_to_string(expr);
 					gbString expr_str = expr_to_string(expr);
@@ -531,10 +502,9 @@ bool check_using_stmt_entity(Checker *c, AstNodeUsingStmt *us, AstNode *expr, bo
 				}
 				}
 				f->using_parent = e;
 				f->using_parent = e;
 			}
 			}
-
 		} else {
 		} else {
-			error(us->token, "`using` can be only applied to `union` or `enum` type entities");
-		} */
+			error(us->token, "`using` can be only applied to record type entities");
+		}
 	} break;
 	} break;
 
 
 	case Entity_ImportName: {
 	case Entity_ImportName: {

+ 4 - 3
src/checker.cpp

@@ -1148,11 +1148,12 @@ void add_type_info_type(Checker *c, Type *t) {
 		add_type_info_type(c, t_int);
 		add_type_info_type(c, t_int);
 		break;
 		break;
 
 
+	case Type_Enum:
+		add_type_info_type(c, bt->Enum.base_type);
+		break;
+
 	case Type_Record: {
 	case Type_Record: {
 		switch (bt->Record.kind) {
 		switch (bt->Record.kind) {
-		case TypeRecord_Enum:
-			add_type_info_type(c, bt->Record.enum_base_type);
-			break;
 		case TypeRecord_Union:
 		case TypeRecord_Union:
 			add_type_info_type(c, t_int);
 			add_type_info_type(c, t_int);
 			for (isize i = 0; i < bt->Record.variant_count; i++) {
 			for (isize i = 0; i < bt->Record.variant_count; i++) {

+ 49 - 49
src/ir.cpp

@@ -7995,6 +7995,55 @@ void ir_gen_tree(irGen *s) {
 					ir_fill_slice(proc, ir_emit_struct_ep(proc, tag, 0), memory_types, count, count);
 					ir_fill_slice(proc, ir_emit_struct_ep(proc, tag, 0), memory_types, count, count);
 					ir_fill_slice(proc, ir_emit_struct_ep(proc, tag, 1), memory_names, count, count);
 					ir_fill_slice(proc, ir_emit_struct_ep(proc, tag, 1), memory_names, count, count);
 				} break;
 				} break;
+				case Type_Enum:
+					ir_emit_comment(proc, str_lit("TypeInfoEnum"));
+					tag = ir_emit_conv(proc, variant_ptr, t_type_info_enum_ptr);
+					{
+						GB_ASSERT(t->Enum.base_type != nullptr);
+						irValue *base = ir_type_info(proc, t->Enum.base_type);
+						ir_emit_store(proc, ir_emit_struct_ep(proc, tag, 0), base);
+
+						if (t->Enum.field_count > 0) {
+							Entity **fields = t->Enum.fields;
+							isize count = t->Enum.field_count;
+							irValue *name_array  = ir_generate_array(m, t_string, count,
+							                                         str_lit("__$enum_names"), cast(i64)entry_index);
+							irValue *value_array = ir_generate_array(m, t_type_info_enum_value, count,
+							                                         str_lit("__$enum_values"), cast(i64)entry_index);
+
+							bool is_value_int = is_type_integer(t->Enum.base_type);
+
+							for (isize i = 0; i < count; i++) {
+								irValue *name_ep  = ir_emit_array_epi(proc, name_array, i);
+								irValue *value_ep = ir_emit_array_epi(proc, value_array, i);
+
+								ExactValue value = fields[i]->Constant.value;
+
+								if (is_value_int) {
+									value_ep = ir_emit_conv(proc, value_ep, t_i128_ptr);
+									ir_emit_store(proc, value_ep, ir_value_constant(a, t_i128, value));
+								} else {
+									GB_ASSERT(is_type_float(t->Enum.base_type));
+									f64 f = value.value_float;
+									value_ep = ir_emit_conv(proc, value_ep, t_f64_ptr);
+									ir_emit_store(proc, value_ep, ir_const_f64(a, f));
+								}
+
+								ir_emit_store(proc, name_ep, ir_const_string(a, fields[i]->token.string));
+							}
+
+							irValue *v_count = ir_const_int(a, count);
+
+							irValue *names = ir_emit_struct_ep(proc, tag, 1);
+							irValue *name_array_elem = ir_array_elem(proc, name_array);
+							ir_fill_slice(proc, names, name_array_elem, v_count, v_count);
+
+							irValue *values = ir_emit_struct_ep(proc, tag, 2);
+							irValue *value_array_elem = ir_array_elem(proc, value_array);
+							ir_fill_slice(proc, values, value_array_elem, v_count, v_count);
+						}
+					}
+					break;
 				case Type_Record: {
 				case Type_Record: {
 					switch (t->Record.kind) {
 					switch (t->Record.kind) {
 					case TypeRecord_Struct: {
 					case TypeRecord_Struct: {
@@ -8132,55 +8181,6 @@ void ir_gen_tree(irGen *s) {
 						ir_fill_slice(proc, ir_emit_struct_ep(proc, tag, 1), memory_names,   count, count);
 						ir_fill_slice(proc, ir_emit_struct_ep(proc, tag, 1), memory_names,   count, count);
 						ir_fill_slice(proc, ir_emit_struct_ep(proc, tag, 2), memory_offsets, count, count);
 						ir_fill_slice(proc, ir_emit_struct_ep(proc, tag, 2), memory_offsets, count, count);
 					} break;
 					} break;
-					case TypeRecord_Enum:
-						ir_emit_comment(proc, str_lit("TypeInfoEnum"));
-						tag = ir_emit_conv(proc, variant_ptr, t_type_info_enum_ptr);
-						{
-							GB_ASSERT(t->Record.enum_base_type != nullptr);
-							irValue *base = ir_type_info(proc, t->Record.enum_base_type);
-							ir_emit_store(proc, ir_emit_struct_ep(proc, tag, 0), base);
-
-							if (t->Record.field_count > 0) {
-								Entity **fields = t->Record.fields;
-								isize count = t->Record.field_count;
-								irValue *name_array  = ir_generate_array(m, t_string, count,
-								                                         str_lit("__$enum_names"), cast(i64)entry_index);
-								irValue *value_array = ir_generate_array(m, t_type_info_enum_value, count,
-								                                         str_lit("__$enum_values"), cast(i64)entry_index);
-
-								bool is_value_int = is_type_integer(t->Record.enum_base_type);
-
-								for (isize i = 0; i < count; i++) {
-									irValue *name_ep  = ir_emit_array_epi(proc, name_array, i);
-									irValue *value_ep = ir_emit_array_epi(proc, value_array, i);
-
-									ExactValue value = fields[i]->Constant.value;
-
-									if (is_value_int) {
-										value_ep = ir_emit_conv(proc, value_ep, t_i128_ptr);
-										ir_emit_store(proc, value_ep, ir_value_constant(a, t_i128, value));
-									} else {
-										GB_ASSERT(is_type_float(t->Record.enum_base_type));
-										f64 f = value.value_float;
-										value_ep = ir_emit_conv(proc, value_ep, t_f64_ptr);
-										ir_emit_store(proc, value_ep, ir_const_f64(a, f));
-									}
-
-									ir_emit_store(proc, name_ep, ir_const_string(a, fields[i]->token.string));
-								}
-
-								irValue *v_count = ir_const_int(a, count);
-
-								irValue *names = ir_emit_struct_ep(proc, tag, 1);
-								irValue *name_array_elem = ir_array_elem(proc, name_array);
-								ir_fill_slice(proc, names, name_array_elem, v_count, v_count);
-
-								irValue *values = ir_emit_struct_ep(proc, tag, 2);
-								irValue *value_array_elem = ir_array_elem(proc, value_array);
-								ir_fill_slice(proc, values, value_array_elem, v_count, v_count);
-							}
-						}
-						break;
 					}
 					}
 				} break;
 				} break;
 				case Type_Map: {
 				case Type_Map: {

+ 5 - 3
src/ir_print.cpp

@@ -280,6 +280,11 @@ void ir_print_type(irFileBuffer *f, irModule *m, Type *t) {
 		ir_print_type(f, m, t_allocator);
 		ir_print_type(f, m, t_allocator);
 		ir_fprintf(f, "}");
 		ir_fprintf(f, "}");
 		return;
 		return;
+
+	case Type_Enum:
+		ir_print_type(f, m, base_enum_type(t));
+		return;
+
 	case Type_Record: {
 	case Type_Record: {
 		switch (t->Record.kind) {
 		switch (t->Record.kind) {
 		case TypeRecord_Struct:
 		case TypeRecord_Struct:
@@ -331,9 +336,6 @@ void ir_print_type(irFileBuffer *f, irModule *m, Type *t) {
 			i64 align_of_union = type_align_of(heap_allocator(), t);
 			i64 align_of_union = type_align_of(heap_allocator(), t);
 			ir_fprintf(f, "{[0 x <%lld x i8>], [%lld x i8]}", align_of_union, size_of_union);
 			ir_fprintf(f, "{[0 x <%lld x i8>], [%lld x i8]}", align_of_union, size_of_union);
 		} return;
 		} return;
-		case TypeRecord_Enum:
-			ir_print_type(f, m, base_enum_type(t));
-			return;
 		}
 		}
 	} break;
 	} break;
 
 

+ 65 - 59
src/types.cpp

@@ -74,7 +74,7 @@ enum TypeRecordKind {
 	TypeRecord_Struct,
 	TypeRecord_Struct,
 	TypeRecord_RawUnion,
 	TypeRecord_RawUnion,
 	TypeRecord_Union, // Tagged
 	TypeRecord_Union, // Tagged
-	TypeRecord_Enum,
+	// TypeRecord_Enum,
 
 
 	TypeRecord_Count,
 	TypeRecord_Count,
 };
 };
@@ -110,10 +110,10 @@ struct TypeRecord {
 	i64      custom_align; // NOTE(bill): Only used in structs at the moment
 	i64      custom_align; // NOTE(bill): Only used in structs at the moment
 	Entity * names;
 	Entity * names;
 
 
-	Type *   enum_base_type;
-	Entity * enum_count;
-	Entity * enum_min_value;
-	Entity * enum_max_value;
+	// Type *   enum_base_type;
+	// Entity * enum_count;
+	// Entity * enum_min_value;
+	// Entity * enum_max_value;
 };
 };
 
 
 #define TYPE_KINDS                                        \
 #define TYPE_KINDS                                        \
@@ -126,6 +126,17 @@ struct TypeRecord {
 	TYPE_KIND(Vector,  struct { Type *elem; i64 count; }) \
 	TYPE_KIND(Vector,  struct { Type *elem; i64 count; }) \
 	TYPE_KIND(Slice,   struct { Type *elem; })            \
 	TYPE_KIND(Slice,   struct { Type *elem; })            \
 	TYPE_KIND(Record,  TypeRecord)                        \
 	TYPE_KIND(Record,  TypeRecord)                        \
+	TYPE_KIND(Enum, struct {                              \
+		Entity **fields;                                  \
+		i32      field_count;                             \
+		AstNode *node;                                    \
+		Scope *  scope;                                   \
+		Entity * names;                                   \
+		Type *   base_type;                               \
+		Entity * count;                                   \
+		Entity * min_value;                               \
+		Entity * max_value;                               \
+	})                                                    \
 	TYPE_KIND(Named, struct {                             \
 	TYPE_KIND(Named, struct {                             \
 		String  name;                                     \
 		String  name;                                     \
 		Type *  base;                                     \
 		Type *  base;                                     \
@@ -423,9 +434,8 @@ Type *base_type(Type *t) {
 Type *base_enum_type(Type *t) {
 Type *base_enum_type(Type *t) {
 	Type *bt = base_type(t);
 	Type *bt = base_type(t);
 	if (bt != nullptr &&
 	if (bt != nullptr &&
-	    bt->kind == Type_Record &&
-	    bt->Record.kind == TypeRecord_Enum) {
-		return bt->Record.enum_base_type;
+	    bt->kind == Type_Enum) {
+		return bt->Enum.base_type;
 	}
 	}
 	return t;
 	return t;
 }
 }
@@ -443,12 +453,9 @@ Type *core_type(Type *t) {
 			}
 			}
 			t = t->Named.base;
 			t = t->Named.base;
 			continue;
 			continue;
-		case Type_Record:
-			if (t->Record.kind == TypeRecord_Enum) {
-				t = t->Record.enum_base_type;
-				continue;
-			}
-			break;
+		case Type_Enum:
+			t = t->Enum.base_type;
+			continue;
 		case Type_Atomic:
 		case Type_Atomic:
 			t = t->Atomic.elem;
 			t = t->Atomic.elem;
 			continue;
 			continue;
@@ -544,8 +551,7 @@ Type *make_type_raw_union(gbAllocator a) {
 }
 }
 
 
 Type *make_type_enum(gbAllocator a) {
 Type *make_type_enum(gbAllocator a) {
-	Type *t = alloc_type(a, Type_Record);
-	t->Record.kind = TypeRecord_Enum;
+	Type *t = alloc_type(a, Type_Enum);
 	return t;
 	return t;
 }
 }
 
 
@@ -877,7 +883,7 @@ bool is_type_raw_union(Type *t) {
 }
 }
 bool is_type_enum(Type *t) {
 bool is_type_enum(Type *t) {
 	t = base_type(t);
 	t = base_type(t);
-	return (t->kind == Type_Record && t->Record.kind == TypeRecord_Enum);
+	return (t->kind == Type_Enum);
 }
 }
 bool is_type_bit_field(Type *t) {
 bool is_type_bit_field(Type *t) {
 	t = base_type(t);
 	t = base_type(t);
@@ -989,13 +995,14 @@ bool is_type_polymorphic(Type *t) {
 		#endif
 		#endif
 		break;
 		break;
 
 
-	case Type_Record:
-		if (t->Record.kind == TypeRecord_Enum) {
-			if (t->Record.enum_base_type != nullptr) {
-				return is_type_polymorphic(t->Record.enum_base_type);
+	case Type_Enum:
+		if (t->kind == Type_Enum) {
+			if (t->Enum.base_type != nullptr) {
+				return is_type_polymorphic(t->Enum.base_type);
 			}
 			}
 			return false;
 			return false;
 		}
 		}
+	case Type_Record:
 		for (isize i = 0; i < t->Record.field_count; i++) {
 		for (isize i = 0; i < t->Record.field_count; i++) {
 		    if (is_type_polymorphic(t->Record.fields[i]->type)) {
 		    if (is_type_polymorphic(t->Record.fields[i]->type)) {
 		    	return true;
 		    	return true;
@@ -1070,12 +1077,8 @@ bool is_type_comparable(Type *t) {
 		return true;
 		return true;
 	case Type_Pointer:
 	case Type_Pointer:
 		return true;
 		return true;
-	case Type_Record: {
-		if (is_type_enum(t)) {
-			return is_type_comparable(core_type(t));
-		}
-		return false;
-	} break;
+	case Type_Enum:
+		return is_type_comparable(core_type(t));
 	case Type_Array:
 	case Type_Array:
 		return false;
 		return false;
 	case Type_Vector:
 	case Type_Vector:
@@ -1133,6 +1136,10 @@ bool are_types_identical(Type *x, Type *y) {
 		}
 		}
 		break;
 		break;
 
 
+
+	case Type_Enum:
+		return x == y; // NOTE(bill): All enums are unique
+
 	case Type_Record:
 	case Type_Record:
 		if (y->kind == Type_Record) {
 		if (y->kind == Type_Record) {
 			if (x->Record.kind == y->Record.kind) {
 			if (x->Record.kind == y->Record.kind) {
@@ -1170,9 +1177,6 @@ bool are_types_identical(Type *x, Type *y) {
 						return true;
 						return true;
 					}
 					}
 					break;
 					break;
-
-				case TypeRecord_Enum:
-					return x == y; // NOTE(bill): All enums are unique
 				}
 				}
 			}
 			}
 		}
 		}
@@ -1554,23 +1558,23 @@ Selection lookup_field_with_selection(gbAllocator a, Type *type_, String field_n
 
 
 		if (is_type_enum(type)) {
 		if (is_type_enum(type)) {
 			// NOTE(bill): These may not have been added yet, so check in case
 			// NOTE(bill): These may not have been added yet, so check in case
-			if (type->Record.enum_count != nullptr) {
+			if (type->Enum.count != nullptr) {
 				if (field_name == "count") {
 				if (field_name == "count") {
-					sel.entity = type->Record.enum_count;
+					sel.entity = type->Enum.count;
 					return sel;
 					return sel;
 				}
 				}
 				if (field_name == "min_value") {
 				if (field_name == "min_value") {
-					sel.entity = type->Record.enum_min_value;
+					sel.entity = type->Enum.min_value;
 					return sel;
 					return sel;
 				}
 				}
 				if (field_name == "max_value") {
 				if (field_name == "max_value") {
-					sel.entity = type->Record.enum_max_value;
+					sel.entity = type->Enum.max_value;
 					return sel;
 					return sel;
 				}
 				}
 			}
 			}
 
 
-			for (isize i = 0; i < type->Record.field_count; i++) {
-				Entity *f = type->Record.fields[i];
+			for (isize i = 0; i < type->Enum.field_count; i++) {
+				Entity *f = type->Enum.fields[i];
 				GB_ASSERT(f->kind == Entity_Constant);
 				GB_ASSERT(f->kind == Entity_Constant);
 				String str = f->token.string;
 				String str = f->token.string;
 
 
@@ -1821,10 +1825,11 @@ i64 type_align_of_internal(gbAllocator allocator, Type *t, TypePath *path) {
 		GB_PANIC("TODO(bill): Fixed map alignment");
 		GB_PANIC("TODO(bill): Fixed map alignment");
 	} break;
 	} break;
 
 
+	case Type_Enum:
+		return type_align_of_internal(allocator, t->Enum.base_type, path);
+
 	case Type_Record: {
 	case Type_Record: {
 		switch (t->Record.kind) {
 		switch (t->Record.kind) {
-		case TypeRecord_Enum:
-			return type_align_of_internal(allocator, t->Record.enum_base_type, path);
 		case TypeRecord_Struct:
 		case TypeRecord_Struct:
 			if (t->Record.custom_align > 0) {
 			if (t->Record.custom_align > 0) {
 				return gb_clamp(t->Record.custom_align, 1, build_context.max_align);
 				return gb_clamp(t->Record.custom_align, 1, build_context.max_align);
@@ -2072,10 +2077,11 @@ i64 type_size_of_internal(gbAllocator allocator, Type *t, TypePath *path) {
 		return align_formula(size, align);
 		return align_formula(size, align);
 	} break;
 	} break;
 
 
+	case Type_Enum:
+		return type_size_of_internal(allocator, t->Enum.base_type, path);
+
 	case Type_Record: {
 	case Type_Record: {
 		switch (t->Record.kind) {
 		switch (t->Record.kind) {
-		case TypeRecord_Enum:
-			return type_size_of_internal(allocator, t->Record.enum_base_type, path);
 
 
 		case TypeRecord_Struct: {
 		case TypeRecord_Struct: {
 			i64 count = t->Record.field_count;
 			i64 count = t->Record.field_count;
@@ -2317,6 +2323,25 @@ gbString write_type_to_string(gbString str, Type *type) {
 		str = write_type_to_string(str, type->DynamicArray.elem);
 		str = write_type_to_string(str, type->DynamicArray.elem);
 		break;
 		break;
 
 
+	case Type_Enum:
+		str = gb_string_appendc(str, "enum");
+		if (type->Enum.base_type != nullptr) {
+		str = gb_string_appendc(str, " ");
+			str = write_type_to_string(str, type->Enum.base_type);
+		}
+		str = gb_string_appendc(str, " {");
+		for (isize i = 0; i < type->Enum.field_count; i++) {
+			Entity *f = type->Enum.fields[i];
+			GB_ASSERT(f->kind == Entity_Constant);
+			if (i > 0) {
+				str = gb_string_appendc(str, ", ");
+			}
+			str = gb_string_append_length(str, f->token.string.text, f->token.string.len);
+			// str = gb_string_appendc(str, " = ");
+		}
+		str = gb_string_appendc(str, "}");
+		break;
+
 	case Type_Record: {
 	case Type_Record: {
 		switch (type->Record.kind) {
 		switch (type->Record.kind) {
 		case TypeRecord_Struct:
 		case TypeRecord_Struct:
@@ -2377,25 +2402,6 @@ gbString write_type_to_string(gbString str, Type *type) {
 			}
 			}
 			str = gb_string_appendc(str, "}");
 			str = gb_string_appendc(str, "}");
 			break;
 			break;
-
-		case TypeRecord_Enum:
-			str = gb_string_appendc(str, "enum");
-			if (type->Record.enum_base_type != nullptr) {
-			str = gb_string_appendc(str, " ");
-				str = write_type_to_string(str, type->Record.enum_base_type);
-			}
-			str = gb_string_appendc(str, " {");
-			for (isize i = 0; i < type->Record.field_count; i++) {
-				Entity *f = type->Record.fields[i];
-				GB_ASSERT(f->kind == Entity_Constant);
-				if (i > 0) {
-					str = gb_string_appendc(str, ", ");
-				}
-				str = gb_string_append_length(str, f->token.string.text, f->token.string.len);
-				// str = gb_string_appendc(str, " = ");
-			}
-			str = gb_string_appendc(str, "}");
-			break;
 		}
 		}
 	} break;
 	} break;