Browse Source

Fix minimal dependency generation for polymorphic structs (related to issue #121)

gingerBill 7 years ago
parent
commit
e05fe1837d
4 changed files with 454 additions and 438 deletions
  1. 4 2
      src/check_expr.cpp
  2. 11 3
      src/checker.cpp
  3. 436 432
      src/ir.cpp
  4. 3 1
      src/ir_print.cpp

+ 4 - 2
src/check_expr.cpp

@@ -4867,8 +4867,10 @@ ExprKind check_call_expr(Checker *c, Operand *operand, AstNode *call) {
 					AstNode *s = ident->SelectorExpr.selector;
 					AstNode *s = ident->SelectorExpr.selector;
 					ident = s;
 					ident = s;
 				}
 				}
-				add_entity_use(c, ident, entity_of_ident(&c->info, ident));
-				add_type_and_value(&c->info, call, Addressing_Type, operand->type, empty_exact_value);
+				Type *ot = operand->type; GB_ASSERT(ot->kind == Type_Named);
+				Entity *e = ot->Named.type_name;
+				add_entity_use(c, ident, e);
+				add_type_and_value(&c->info, call, Addressing_Type, ot, empty_exact_value);
 			} else {
 			} else {
 				operand->mode = Addressing_Invalid;
 				operand->mode = Addressing_Invalid;
 				operand->type = t_invalid;
 				operand->type = t_invalid;

+ 11 - 3
src/checker.cpp

@@ -818,8 +818,8 @@ void add_declaration_dependency(Checker *c, Entity *e) {
 		return;
 		return;
 	}
 	}
 	if (c->context.decl != nullptr) {
 	if (c->context.decl != nullptr) {
-		DeclInfo *decl = decl_info_of_entity(&c->info, e);
-		if (decl) add_dependency(c->context.decl, e);
+		// DeclInfo *decl = decl_info_of_entity(&c->info, e);
+		add_dependency(c->context.decl, e);
 	}
 	}
 }
 }
 
 
@@ -1213,6 +1213,9 @@ void add_entity_use(Checker *c, AstNode *identifier, Entity *entity) {
 	if (identifier->kind != AstNode_Ident) {
 	if (identifier->kind != AstNode_Ident) {
 		return;
 		return;
 	}
 	}
+	if (entity->identifier == nullptr) {
+		entity->identifier = identifier;
+	}
 	HashKey key = hash_node(identifier);
 	HashKey key = hash_node(identifier);
 	map_set(&c->info.uses, key, entity);
 	map_set(&c->info.uses, key, entity);
 	add_declaration_dependency(c, entity); // TODO(bill): Should this be here?
 	add_declaration_dependency(c, entity); // TODO(bill): Should this be here?
@@ -1435,10 +1438,14 @@ void add_dependency_to_map(PtrSet<Entity *> *map, CheckerInfo *info, Entity *ent
 	if (entity == nullptr) {
 	if (entity == nullptr) {
 		return;
 		return;
 	}
 	}
+
+	String name = entity->token.string;
+
 	if (entity->type != nullptr &&
 	if (entity->type != nullptr &&
 	    is_type_polymorphic(entity->type)) {
 	    is_type_polymorphic(entity->type)) {
+
 		DeclInfo *decl = decl_info_of_entity(info, entity);
 		DeclInfo *decl = decl_info_of_entity(info, entity);
-		if (decl->gen_proc_type == nullptr) {
+		if (decl != nullptr && decl->gen_proc_type == nullptr) {
 			return;
 			return;
 		}
 		}
 	}
 	}
@@ -1447,6 +1454,7 @@ void add_dependency_to_map(PtrSet<Entity *> *map, CheckerInfo *info, Entity *ent
 		return;
 		return;
 	}
 	}
 
 
+
 	ptr_set_add(map, entity);
 	ptr_set_add(map, entity);
 	DeclInfo *decl = decl_info_of_entity(info, entity);
 	DeclInfo *decl = decl_info_of_entity(info, entity);
 	if (decl != nullptr) {
 	if (decl != nullptr) {

+ 436 - 432
src/ir.cpp

@@ -3752,13 +3752,18 @@ void ir_gen_global_type_name(irModule *m, Entity *e, String name) {
 		auto found = map_get(&m->info->gen_types, hash_pointer(e->type));
 		auto found = map_get(&m->info->gen_types, hash_pointer(e->type));
 		if (found != nullptr) {
 		if (found != nullptr) {
 			for_array(i, *found) {
 			for_array(i, *found) {
-				Entity *e = (*found)[i];
-				ir_mangle_add_sub_type_name(m, e, name);
+				Entity *sub = (*found)[i];
+				// gb_printf_err("--> %.*s\n", LIT(sub->token.string));
+				if (ptr_set_exists(&m->min_dep_set, sub)) {
+					ir_mangle_add_sub_type_name(m, sub, name);
+				}
 			}
 			}
 		}
 		}
 		return;
 		return;
 	}
 	}
 
 
+	if (!ptr_set_exists(&m->min_dep_set, e)) return;
+
 	irValue *t = ir_value_type_name(m->allocator, name, e->type);
 	irValue *t = ir_value_type_name(m->allocator, name, e->type);
 	ir_module_add_value(m, e, t);
 	ir_module_add_value(m, e, t);
 	map_set(&m->members, hash_string(name), t);
 	map_set(&m->members, hash_string(name), t);
@@ -5890,7 +5895,6 @@ void ir_build_poly_proc(irProcedure *proc, AstNodeProcLit *pd, Entity *e) {
 }
 }
 
 
 
 
-
 void ir_build_constant_value_decl(irProcedure *proc, AstNodeValueDecl *vd) {
 void ir_build_constant_value_decl(irProcedure *proc, AstNodeValueDecl *vd) {
 	if (vd == nullptr || vd->is_mutable) {
 	if (vd == nullptr || vd->is_mutable) {
 		return;
 		return;
@@ -5909,8 +5913,6 @@ void ir_build_constant_value_decl(irProcedure *proc, AstNodeValueDecl *vd) {
 			continue;
 			continue;
 		}
 		}
 
 
-		String entity_name = e->token.string;
-
 		if (e->kind == Entity_TypeName) {
 		if (e->kind == Entity_TypeName) {
 			bool polymorphic_struct = false;
 			bool polymorphic_struct = false;
 			if (e->type != nullptr && e->kind == Entity_TypeName) {
 			if (e->type != nullptr && e->kind == Entity_TypeName) {
@@ -5926,19 +5928,18 @@ void ir_build_constant_value_decl(irProcedure *proc, AstNodeValueDecl *vd) {
 
 
 			// NOTE(bill): Generate a new name
 			// NOTE(bill): Generate a new name
 			// parent_proc.name-guid
 			// parent_proc.name-guid
-			String ts_name = entity_name;
+			String ts_name = e->token.string;
 
 
+			irModule *m = proc->module;
 			isize name_len = proc->name.len + 1 + ts_name.len + 1 + 10 + 1;
 			isize name_len = proc->name.len + 1 + ts_name.len + 1 + 10 + 1;
-			u8 *name_text = gb_alloc_array(proc->module->allocator, u8, name_len);
-			i32 guid = cast(i32)proc->module->members.entries.count;
+			u8 *name_text = gb_alloc_array(m->allocator, u8, name_len);
+			i32 guid = cast(i32)m->members.entries.count;
 			name_len = gb_snprintf(cast(char *)name_text, name_len, "%.*s.%.*s-%d", LIT(proc->name), LIT(ts_name), guid);
 			name_len = gb_snprintf(cast(char *)name_text, name_len, "%.*s.%.*s-%d", LIT(proc->name), LIT(ts_name), guid);
 			String name = make_string(name_text, name_len-1);
 			String name = make_string(name_text, name_len-1);
 
 
-			irValue *value = ir_value_type_name(proc->module->allocator,
-			                                           name, e->type);
-			map_set(&proc->module->entity_names, hash_entity(e), name);
-			ir_gen_global_type_name(proc->module, e, name);
-
+			irValue *value = ir_value_type_name(m->allocator, name, e->type);
+			map_set(&m->entity_names, hash_entity(e), name);
+			ir_gen_global_type_name(m, e, name);
 		} else if (e->kind == Entity_Procedure) {
 		} else if (e->kind == Entity_Procedure) {
 			CheckerInfo *info = proc->module->info;
 			CheckerInfo *info = proc->module->info;
 			DeclInfo *decl = decl_info_of_entity(info, e);
 			DeclInfo *decl = decl_info_of_entity(info, e);
@@ -7655,6 +7656,426 @@ void ir_add_foreign_library_path(irModule *m, Entity *e) {
 	array_add(&m->foreign_library_paths, library_path);
 	array_add(&m->foreign_library_paths, library_path);
 }
 }
 
 
+void ir_setup_type_info_data(irProcedure *proc) { // NOTE(bill): Setup type_info data
+	irModule *m = proc->module;
+	gbAllocator a = m->allocator;
+	CheckerInfo *info = m->info;
+
+	if (true) {
+		irValue *global_type_table = ir_find_global_variable(proc, str_lit("__type_table"));
+		Type *type = base_type(type_deref(ir_type(ir_global_type_info_data)));
+		GB_ASSERT(is_type_array(type));
+		irValue *len = ir_const_int(proc->module->allocator, type->Array.count);
+		ir_fill_slice(proc, global_type_table,
+		              ir_emit_array_epi(proc, ir_global_type_info_data, 0),
+		              len, len);
+	}
+
+
+	// Useful types
+	Type *t_i64_slice_ptr    = make_type_pointer(a, make_type_slice(a, t_i64));
+	Type *t_string_slice_ptr = make_type_pointer(a, make_type_slice(a, t_string));
+
+	i32 type_info_member_types_index = 0;
+	i32 type_info_member_names_index = 0;
+	i32 type_info_member_offsets_index = 0;
+
+	for_array(type_info_map_index, info->type_info_map.entries) {
+		auto *entry = &info->type_info_map.entries[type_info_map_index];
+		Type *t = cast(Type *)entry->key.ptr;
+		t = default_type(t);
+		if (t == t_invalid) {
+			continue;
+		}
+
+		isize entry_index = type_info_index(info, t);
+
+		irValue *tag = nullptr;
+		irValue *ti_ptr = ir_emit_array_epi(proc, ir_global_type_info_data, cast(i32)entry_index);
+		irValue *variant_ptr = ir_emit_struct_ep(proc, ti_ptr, 2);
+
+		ir_emit_store(proc, ir_emit_struct_ep(proc, ti_ptr, 0), ir_const_int(a, type_size_of(a, t)));
+		ir_emit_store(proc, ir_emit_struct_ep(proc, ti_ptr, 1), ir_const_int(a, type_align_of(a, t)));
+
+
+		switch (t->kind) {
+		case Type_Named: {
+			ir_emit_comment(proc, str_lit("TypeInfoNamed"));
+			tag = ir_emit_conv(proc, variant_ptr, t_type_info_named_ptr);
+
+			// TODO(bill): Which is better? The mangled name or actual name?
+			irValue *name = ir_const_string(a, t->Named.type_name->token.string);
+			irValue *gtip = ir_get_type_info_ptr(proc, t->Named.base);
+
+			ir_emit_store(proc, ir_emit_struct_ep(proc, tag, 0), name);
+			ir_emit_store(proc, ir_emit_struct_ep(proc, tag, 1), gtip);
+			break;
+		}
+
+		case Type_Basic:
+			ir_emit_comment(proc, str_lit("TypeInfoBasic"));
+			switch (t->Basic.kind) {
+			case Basic_bool:
+				tag = ir_emit_conv(proc, variant_ptr, t_type_info_boolean_ptr);
+				break;
+
+			case Basic_i8:
+			case Basic_u8:
+			case Basic_i16:
+			case Basic_u16:
+			case Basic_i32:
+			case Basic_u32:
+			case Basic_i64:
+			case Basic_u64:
+			case Basic_i128:
+			case Basic_u128:
+			case Basic_int:
+			case Basic_uint: {
+				tag = ir_emit_conv(proc, variant_ptr, t_type_info_integer_ptr);
+				irValue *is_signed = ir_const_bool(a, (t->Basic.flags & BasicFlag_Unsigned) == 0);
+				ir_emit_store(proc, ir_emit_struct_ep(proc, tag, 0), is_signed);
+				break;
+			}
+
+			case Basic_rune:
+				tag = ir_emit_conv(proc, variant_ptr, t_type_info_rune_ptr);
+				break;
+
+			// case Basic_f16:
+			case Basic_f32:
+			case Basic_f64:
+				tag = ir_emit_conv(proc, variant_ptr, t_type_info_float_ptr);
+				break;
+
+			// case Basic_complex32:
+			case Basic_complex64:
+			case Basic_complex128:
+				tag = ir_emit_conv(proc, variant_ptr, t_type_info_complex_ptr);
+				break;
+
+			case Basic_rawptr:
+				tag = ir_emit_conv(proc, variant_ptr, t_type_info_pointer_ptr);
+				break;
+
+			case Basic_string:
+				tag = ir_emit_conv(proc, variant_ptr, t_type_info_string_ptr);
+				break;
+
+			case Basic_any:
+				tag = ir_emit_conv(proc, variant_ptr, t_type_info_any_ptr);
+				break;
+			}
+			break;
+
+		case Type_Pointer: {
+			ir_emit_comment(proc, str_lit("TypeInfoPointer"));
+			tag = ir_emit_conv(proc, variant_ptr, t_type_info_pointer_ptr);
+			irValue *gep = ir_get_type_info_ptr(proc, t->Pointer.elem);
+			ir_emit_store(proc, ir_emit_struct_ep(proc, tag, 0), gep);
+			break;
+		}
+		case Type_Array: {
+			ir_emit_comment(proc, str_lit("TypeInfoArray"));
+			tag = ir_emit_conv(proc, variant_ptr, t_type_info_array_ptr);
+			irValue *gep = ir_get_type_info_ptr(proc, t->Array.elem);
+			ir_emit_store(proc, ir_emit_struct_ep(proc, tag, 0), gep);
+
+			isize ez = type_size_of(a, t->Array.elem);
+			irValue *elem_size = ir_emit_struct_ep(proc, tag, 1);
+			ir_emit_store(proc, elem_size, ir_const_int(a, ez));
+
+			irValue *count = ir_emit_struct_ep(proc, tag, 2);
+			ir_emit_store(proc, count, ir_const_int(a, t->Array.count));
+
+			break;
+		}
+		case Type_DynamicArray: {
+			ir_emit_comment(proc, str_lit("TypeInfoDynamicArray"));
+			tag = ir_emit_conv(proc, variant_ptr, t_type_info_dynamic_array_ptr);
+			irValue *gep = ir_get_type_info_ptr(proc, t->DynamicArray.elem);
+			ir_emit_store(proc, ir_emit_struct_ep(proc, tag, 0), gep);
+
+			isize ez = type_size_of(a, t->DynamicArray.elem);
+			irValue *elem_size = ir_emit_struct_ep(proc, tag, 1);
+			ir_emit_store(proc, elem_size, ir_const_int(a, ez));
+			break;
+		}
+		case Type_Slice: {
+			ir_emit_comment(proc, str_lit("TypeInfoSlice"));
+			tag = ir_emit_conv(proc, variant_ptr, t_type_info_slice_ptr);
+			irValue *gep = ir_get_type_info_ptr(proc, t->Slice.elem);
+			ir_emit_store(proc, ir_emit_struct_ep(proc, tag, 0), gep);
+
+			isize ez = type_size_of(a, t->Slice.elem);
+			irValue *elem_size = ir_emit_struct_ep(proc, tag, 1);
+			ir_emit_store(proc, elem_size, ir_const_int(a, ez));
+			break;
+		}
+		case Type_Vector: {
+			ir_emit_comment(proc, str_lit("TypeInfoVector"));
+			tag = ir_emit_conv(proc, variant_ptr, t_type_info_vector_ptr);
+			irValue *gep = ir_get_type_info_ptr(proc, t->Vector.elem);
+			ir_emit_store(proc, ir_emit_struct_ep(proc, tag, 0), gep);
+
+			isize ez = type_size_of(a, t->Vector.elem);
+			ir_emit_store(proc, ir_emit_struct_ep(proc, tag, 1), ir_const_int(a, ez));
+			ir_emit_store(proc, ir_emit_struct_ep(proc, tag, 2), ir_const_int(a, t->Vector.count));
+
+			break;
+		}
+		case Type_Proc: {
+			ir_emit_comment(proc, str_lit("TypeInfoProc"));
+			tag = ir_emit_conv(proc, variant_ptr, t_type_info_procedure_ptr);
+
+			irValue *params     = ir_emit_struct_ep(proc, tag, 0);
+			irValue *results    = ir_emit_struct_ep(proc, tag, 1);
+			irValue *variadic   = ir_emit_struct_ep(proc, tag, 2);
+			irValue *convention = ir_emit_struct_ep(proc, tag, 3);
+
+			if (t->Proc.params != nullptr) {
+				ir_emit_store(proc, params, ir_get_type_info_ptr(proc, t->Proc.params));
+			}
+			if (t->Proc.results != nullptr) {
+				ir_emit_store(proc, results, ir_get_type_info_ptr(proc, t->Proc.results));
+			}
+			ir_emit_store(proc, variadic, ir_const_bool(a, t->Proc.variadic));
+			ir_emit_store(proc, convention, ir_const_int(a, t->Proc.calling_convention));
+
+			// TODO(bill): TypeInfo for procedures
+			break;
+		}
+		case Type_Tuple: {
+			ir_emit_comment(proc, str_lit("TypeInfoTuple"));
+			tag = ir_emit_conv(proc, variant_ptr, t_type_info_tuple_ptr);
+
+			irValue *memory_types = ir_type_info_member_types_offset(proc, t->Tuple.variables.count);
+			irValue *memory_names = ir_type_info_member_names_offset(proc, t->Tuple.variables.count);
+
+			for_array(i, t->Tuple.variables) {
+				// NOTE(bill): offset is not used for tuples
+				Entity *f = t->Tuple.variables[i];
+
+				irValue *index     = ir_const_int(a, i);
+				irValue *type_info = ir_emit_ptr_offset(proc, memory_types, index);
+
+				ir_emit_store(proc, type_info, ir_type_info(proc, f->type));
+				if (f->token.string.len > 0) {
+					irValue *name = ir_emit_ptr_offset(proc, memory_names, index);
+					ir_emit_store(proc, name, ir_const_string(a, f->token.string));
+				}
+			}
+
+			irValue *count = ir_const_int(a, t->Tuple.variables.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);
+			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);
+					if (!is_value_int) {
+						GB_ASSERT(is_type_float(t->Enum.base_type));
+					}
+
+					for (isize i = 0; i < count; i++) {
+						irValue *name_ep  = ir_emit_array_epi(proc, name_array, cast(i32)i);
+						irValue *value_ep = ir_emit_array_epi(proc, value_array, cast(i32)i);
+
+						ExactValue value = fields[i]->Constant.value;
+						irValue *v = ir_value_constant(a, t->Enum.base_type, value);
+
+						ir_emit_store(proc, value_ep, ir_emit_conv(proc, v, t_type_info_enum_value));
+						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_Union: {
+			ir_emit_comment(proc, str_lit("TypeInfoUnion"));
+			tag = ir_emit_conv(proc, variant_ptr, t_type_info_union_ptr);
+
+			{
+				irValue *variant_types  = ir_emit_struct_ep(proc, tag, 0);
+				irValue *tag_offset_ptr = ir_emit_struct_ep(proc, tag, 1);
+				irValue *tag_type_ptr   = ir_emit_struct_ep(proc, tag, 2);
+
+				isize variant_count = gb_max(0, t->Union.variants.count);
+				irValue *memory_types = ir_type_info_member_types_offset(proc, variant_count);
+
+				// NOTE(bill): Zeroth is nil so ignore it
+				for (isize variant_index = 0; variant_index < variant_count; variant_index++) {
+					Type *vt = t->Union.variants[variant_index];
+					irValue *tip = ir_get_type_info_ptr(proc, vt);
+
+					irValue *index     = ir_const_int(a, variant_index);
+					irValue *type_info = ir_emit_ptr_offset(proc, memory_types, index);
+					ir_emit_store(proc, type_info, ir_type_info(proc, vt));
+				}
+
+				irValue *count = ir_const_int(a, variant_count);
+				ir_fill_slice(proc, variant_types, memory_types, count, count);
+
+				i64 tag_size  = union_tag_size(t);
+				i64 tag_offset = align_formula(t->Union.variant_block_size, tag_size);
+				ir_emit_store(proc, tag_offset_ptr, ir_const_int(a, tag_offset));
+				ir_emit_store(proc, tag_type_ptr,   ir_type_info(proc, union_tag_type(t)));
+			}
+
+			break;
+		}
+
+		case Type_Struct: {
+			ir_emit_comment(proc, str_lit("TypeInfoStruct"));
+			tag = ir_emit_conv(proc, variant_ptr, t_type_info_struct_ptr);
+
+			{
+				irValue *is_packed       = ir_const_bool(a, t->Struct.is_packed);
+				irValue *is_ordered      = ir_const_bool(a, t->Struct.is_ordered);
+				irValue *is_raw_union    = ir_const_bool(a, t->Struct.is_raw_union);
+				irValue *is_custom_align = ir_const_bool(a, t->Struct.custom_align != 0);
+				ir_emit_store(proc, ir_emit_struct_ep(proc, tag, 4), is_packed);
+				ir_emit_store(proc, ir_emit_struct_ep(proc, tag, 5), is_ordered);
+				ir_emit_store(proc, ir_emit_struct_ep(proc, tag, 6), is_raw_union);
+				ir_emit_store(proc, ir_emit_struct_ep(proc, tag, 7), is_custom_align);
+			}
+
+			isize count = t->Struct.fields.count;
+
+			irValue *memory_types   = ir_type_info_member_types_offset  (proc, count);
+			irValue *memory_names   = ir_type_info_member_names_offset  (proc, count);
+			irValue *memory_offsets = ir_type_info_member_offsets_offset(proc, count);
+			irValue *memory_usings  = ir_type_info_member_usings_offset (proc, count);
+
+			type_set_offsets(a, t); // NOTE(bill): Just incase the offsets have not been set yet
+			for (isize source_index = 0; source_index < count; source_index++) {
+				// TODO(bill): Order fields in source order not layout order
+				Entity *f = t->Struct.fields_in_src_order[source_index];
+				irValue *tip = ir_get_type_info_ptr(proc, f->type);
+				i64 foffset = 0;
+				if (!t->Struct.is_raw_union) {
+					foffset = t->Struct.offsets[f->Variable.field_index];
+				}
+				GB_ASSERT(f->kind == Entity_Variable && f->flags & EntityFlag_Field);
+
+				irValue *index     = ir_const_int(a, source_index);
+				irValue *type_info = ir_emit_ptr_offset(proc, memory_types,   index);
+				irValue *offset    = ir_emit_ptr_offset(proc, memory_offsets, index);
+				irValue *is_using  = ir_emit_ptr_offset(proc, memory_usings, index);
+
+				ir_emit_store(proc, type_info, ir_type_info(proc, f->type));
+				if (f->token.string.len > 0) {
+					irValue *name = ir_emit_ptr_offset(proc, memory_names,   index);
+					ir_emit_store(proc, name, ir_const_string(a, f->token.string));
+				}
+				ir_emit_store(proc, offset, ir_const_int(a, foffset));
+				ir_emit_store(proc, is_using, ir_const_bool(a, (f->flags&EntityFlag_Using) != 0));
+			}
+
+			irValue *cv = ir_const_int(a, count);
+			ir_fill_slice(proc, ir_emit_struct_ep(proc, tag, 0), memory_types,   cv, cv);
+			ir_fill_slice(proc, ir_emit_struct_ep(proc, tag, 1), memory_names,   cv, cv);
+			ir_fill_slice(proc, ir_emit_struct_ep(proc, tag, 2), memory_offsets, cv, cv);
+			ir_fill_slice(proc, ir_emit_struct_ep(proc, tag, 3), memory_usings,  cv, cv);
+			break;
+		}
+		case Type_Map: {
+			ir_emit_comment(proc, str_lit("TypeInfoMap"));
+			tag = ir_emit_conv(proc, variant_ptr, t_type_info_map_ptr);
+			generate_map_internal_types(a, t);
+
+			irValue *key              = ir_emit_struct_ep(proc, tag, 0);
+			irValue *value            = ir_emit_struct_ep(proc, tag, 1);
+			irValue *generated_struct = ir_emit_struct_ep(proc, tag, 2);
+
+			ir_emit_store(proc, key,              ir_get_type_info_ptr(proc, t->Map.key));
+			ir_emit_store(proc, value,            ir_get_type_info_ptr(proc, t->Map.value));
+			ir_emit_store(proc, generated_struct, ir_get_type_info_ptr(proc, t->Map.generated_struct_type));
+			break;
+		}
+
+		case Type_BitField: {
+			ir_emit_comment(proc, str_lit("TypeInfoBitField"));
+			tag = ir_emit_conv(proc, variant_ptr, t_type_info_bit_field_ptr);
+			// names:   []string;
+			// bits:    []u32;
+			// offsets: []u32;
+			isize count = t->BitField.field_count;
+			if (count > 0) {
+				Entity **fields = t->BitField.fields;
+				irValue *name_array   = ir_generate_array(m, t_string, count, str_lit("__$bit_field_names"),   cast(i64)entry_index);
+				irValue *bit_array    = ir_generate_array(m, t_i32,    count, str_lit("__$bit_field_bits"),    cast(i64)entry_index);
+				irValue *offset_array = ir_generate_array(m, t_i32,    count, str_lit("__$bit_field_offsets"), cast(i64)entry_index);
+
+				for (isize i = 0; i < count; i++) {
+					Entity *f = fields[i];
+					GB_ASSERT(f->type != nullptr);
+					GB_ASSERT(f->type->kind == Type_BitFieldValue);
+					irValue *name_ep   = ir_emit_array_epi(proc, name_array,   cast(i32)i);
+					irValue *bit_ep    = ir_emit_array_epi(proc, bit_array,    cast(i32)i);
+					irValue *offset_ep = ir_emit_array_epi(proc, offset_array, cast(i32)i);
+
+					ir_emit_store(proc, name_ep, ir_const_string(a, f->token.string));
+					ir_emit_store(proc, bit_ep, ir_const_i32(a, f->type->BitFieldValue.bits));
+					ir_emit_store(proc, offset_ep, ir_const_i32(a, t->BitField.offsets[i]));
+
+				}
+
+				irValue *v_count = ir_const_int(a, count);
+
+				irValue *names = ir_emit_struct_ep(proc, tag, 0);
+				irValue *name_array_elem = ir_array_elem(proc, name_array);
+				ir_fill_slice(proc, names, name_array_elem, v_count, v_count);
+
+				irValue *bits = ir_emit_struct_ep(proc, tag, 1);
+				irValue *bit_array_elem = ir_array_elem(proc, bit_array);
+				ir_fill_slice(proc, bits, bit_array_elem, v_count, v_count);
+
+				irValue *offsets = ir_emit_struct_ep(proc, tag, 2);
+				irValue *offset_array_elem = ir_array_elem(proc, offset_array);
+				ir_fill_slice(proc, offsets, offset_array_elem, v_count, v_count);
+			}
+			break;
+		}
+		}
+
+
+		if (tag != nullptr) {
+			Type *tag_type = type_deref(ir_type(tag));
+			GB_ASSERT(is_type_named(tag_type));
+			Type *variant_type = type_deref(ir_type(variant_ptr));
+			irValue *tag = ir_const_union_tag(a, variant_type, tag_type);
+			irValue *ptr = ir_emit_union_tag_ptr(proc, variant_ptr);
+			ir_emit_store(proc, ptr, tag);
+		} else {
+			GB_PANIC("Unhandled Type_Info variant: %s", type_to_string(t));
+		}
+	}
+}
 
 
 void ir_gen_tree(irGen *s) {
 void ir_gen_tree(irGen *s) {
 	irModule *m = &s->module;
 	irModule *m = &s->module;
@@ -7802,7 +8223,7 @@ void ir_gen_tree(irGen *s) {
 		if (e->type != nullptr && e->kind == Entity_TypeName) {
 		if (e->type != nullptr && e->kind == Entity_TypeName) {
 			Type *bt = base_type(e->type);
 			Type *bt = base_type(e->type);
 			if (bt->kind == Type_Struct) {
 			if (bt->kind == Type_Struct) {
-				polymorphic_struct = bt->Struct.is_polymorphic;
+				polymorphic_struct = is_type_polymorphic(bt);
 			}
 			}
 		}
 		}
 
 
@@ -8106,425 +8527,8 @@ void ir_gen_tree(irGen *s) {
 		}
 		}
 
 
 
 
+		ir_setup_type_info_data(proc);
 
 
-		{ // NOTE(bill): Setup type_info data
-			CheckerInfo *info = proc->module->info;
-
-			if (true) {
-				irValue *global_type_table = ir_find_global_variable(proc, str_lit("__type_table"));
-				Type *type = base_type(type_deref(ir_type(ir_global_type_info_data)));
-				GB_ASSERT(is_type_array(type));
-				irValue *len = ir_const_int(proc->module->allocator, type->Array.count);
-				ir_fill_slice(proc, global_type_table,
-				              ir_emit_array_epi(proc, ir_global_type_info_data, 0),
-				              len, len);
-			}
-
-
-			// Useful types
-			Type *t_i64_slice_ptr    = make_type_pointer(a, make_type_slice(a, t_i64));
-			Type *t_string_slice_ptr = make_type_pointer(a, make_type_slice(a, t_string));
-
-			i32 type_info_member_types_index = 0;
-			i32 type_info_member_names_index = 0;
-			i32 type_info_member_offsets_index = 0;
-
-			for_array(type_info_map_index, info->type_info_map.entries) {
-				auto *entry = &info->type_info_map.entries[type_info_map_index];
-				Type *t = cast(Type *)entry->key.ptr;
-				t = default_type(t);
-				if (t == t_invalid) {
-					continue;
-				}
-
-				isize entry_index = type_info_index(info, t);
-
-				irValue *tag = nullptr;
-				irValue *ti_ptr = ir_emit_array_epi(proc, ir_global_type_info_data, cast(i32)entry_index);
-				irValue *variant_ptr = ir_emit_struct_ep(proc, ti_ptr, 2);
-
-				ir_emit_store(proc, ir_emit_struct_ep(proc, ti_ptr, 0), ir_const_int(a, type_size_of(a, t)));
-				ir_emit_store(proc, ir_emit_struct_ep(proc, ti_ptr, 1), ir_const_int(a, type_align_of(a, t)));
-
-
-				switch (t->kind) {
-				case Type_Named: {
-					ir_emit_comment(proc, str_lit("TypeInfoNamed"));
-					tag = ir_emit_conv(proc, variant_ptr, t_type_info_named_ptr);
-
-					// TODO(bill): Which is better? The mangled name or actual name?
-					irValue *name = ir_const_string(a, t->Named.type_name->token.string);
-					irValue *gtip = ir_get_type_info_ptr(proc, t->Named.base);
-
-					ir_emit_store(proc, ir_emit_struct_ep(proc, tag, 0), name);
-					ir_emit_store(proc, ir_emit_struct_ep(proc, tag, 1), gtip);
-					break;
-				}
-
-				case Type_Basic:
-					ir_emit_comment(proc, str_lit("TypeInfoBasic"));
-					switch (t->Basic.kind) {
-					case Basic_bool:
-						tag = ir_emit_conv(proc, variant_ptr, t_type_info_boolean_ptr);
-						break;
-
-					case Basic_i8:
-					case Basic_u8:
-					case Basic_i16:
-					case Basic_u16:
-					case Basic_i32:
-					case Basic_u32:
-					case Basic_i64:
-					case Basic_u64:
-					case Basic_i128:
-					case Basic_u128:
-					case Basic_int:
-					case Basic_uint: {
-						tag = ir_emit_conv(proc, variant_ptr, t_type_info_integer_ptr);
-						irValue *is_signed = ir_const_bool(a, (t->Basic.flags & BasicFlag_Unsigned) == 0);
-						ir_emit_store(proc, ir_emit_struct_ep(proc, tag, 0), is_signed);
-						break;
-					}
-
-					case Basic_rune:
-						tag = ir_emit_conv(proc, variant_ptr, t_type_info_rune_ptr);
-						break;
-
-					// case Basic_f16:
-					case Basic_f32:
-					case Basic_f64:
-						tag = ir_emit_conv(proc, variant_ptr, t_type_info_float_ptr);
-						break;
-
-					// case Basic_complex32:
-					case Basic_complex64:
-					case Basic_complex128:
-						tag = ir_emit_conv(proc, variant_ptr, t_type_info_complex_ptr);
-						break;
-
-					case Basic_rawptr:
-						tag = ir_emit_conv(proc, variant_ptr, t_type_info_pointer_ptr);
-						break;
-
-					case Basic_string:
-						tag = ir_emit_conv(proc, variant_ptr, t_type_info_string_ptr);
-						break;
-
-					case Basic_any:
-						tag = ir_emit_conv(proc, variant_ptr, t_type_info_any_ptr);
-						break;
-					}
-					break;
-
-				case Type_Pointer: {
-					ir_emit_comment(proc, str_lit("TypeInfoPointer"));
-					tag = ir_emit_conv(proc, variant_ptr, t_type_info_pointer_ptr);
-					irValue *gep = ir_get_type_info_ptr(proc, t->Pointer.elem);
-					ir_emit_store(proc, ir_emit_struct_ep(proc, tag, 0), gep);
-					break;
-				}
-				case Type_Array: {
-					ir_emit_comment(proc, str_lit("TypeInfoArray"));
-					tag = ir_emit_conv(proc, variant_ptr, t_type_info_array_ptr);
-					irValue *gep = ir_get_type_info_ptr(proc, t->Array.elem);
-					ir_emit_store(proc, ir_emit_struct_ep(proc, tag, 0), gep);
-
-					isize ez = type_size_of(a, t->Array.elem);
-					irValue *elem_size = ir_emit_struct_ep(proc, tag, 1);
-					ir_emit_store(proc, elem_size, ir_const_int(a, ez));
-
-					irValue *count = ir_emit_struct_ep(proc, tag, 2);
-					ir_emit_store(proc, count, ir_const_int(a, t->Array.count));
-
-					break;
-				}
-				case Type_DynamicArray: {
-					ir_emit_comment(proc, str_lit("TypeInfoDynamicArray"));
-					tag = ir_emit_conv(proc, variant_ptr, t_type_info_dynamic_array_ptr);
-					irValue *gep = ir_get_type_info_ptr(proc, t->DynamicArray.elem);
-					ir_emit_store(proc, ir_emit_struct_ep(proc, tag, 0), gep);
-
-					isize ez = type_size_of(a, t->DynamicArray.elem);
-					irValue *elem_size = ir_emit_struct_ep(proc, tag, 1);
-					ir_emit_store(proc, elem_size, ir_const_int(a, ez));
-					break;
-				}
-				case Type_Slice: {
-					ir_emit_comment(proc, str_lit("TypeInfoSlice"));
-					tag = ir_emit_conv(proc, variant_ptr, t_type_info_slice_ptr);
-					irValue *gep = ir_get_type_info_ptr(proc, t->Slice.elem);
-					ir_emit_store(proc, ir_emit_struct_ep(proc, tag, 0), gep);
-
-					isize ez = type_size_of(a, t->Slice.elem);
-					irValue *elem_size = ir_emit_struct_ep(proc, tag, 1);
-					ir_emit_store(proc, elem_size, ir_const_int(a, ez));
-					break;
-				}
-				case Type_Vector: {
-					ir_emit_comment(proc, str_lit("TypeInfoVector"));
-					tag = ir_emit_conv(proc, variant_ptr, t_type_info_vector_ptr);
-					irValue *gep = ir_get_type_info_ptr(proc, t->Vector.elem);
-					ir_emit_store(proc, ir_emit_struct_ep(proc, tag, 0), gep);
-
-					isize ez = type_size_of(a, t->Vector.elem);
-					ir_emit_store(proc, ir_emit_struct_ep(proc, tag, 1), ir_const_int(a, ez));
-					ir_emit_store(proc, ir_emit_struct_ep(proc, tag, 2), ir_const_int(a, t->Vector.count));
-
-					break;
-				}
-				case Type_Proc: {
-					ir_emit_comment(proc, str_lit("TypeInfoProc"));
-					tag = ir_emit_conv(proc, variant_ptr, t_type_info_procedure_ptr);
-
-					irValue *params     = ir_emit_struct_ep(proc, tag, 0);
-					irValue *results    = ir_emit_struct_ep(proc, tag, 1);
-					irValue *variadic   = ir_emit_struct_ep(proc, tag, 2);
-					irValue *convention = ir_emit_struct_ep(proc, tag, 3);
-
-					if (t->Proc.params != nullptr) {
-						ir_emit_store(proc, params, ir_get_type_info_ptr(proc, t->Proc.params));
-					}
-					if (t->Proc.results != nullptr) {
-						ir_emit_store(proc, results, ir_get_type_info_ptr(proc, t->Proc.results));
-					}
-					ir_emit_store(proc, variadic, ir_const_bool(a, t->Proc.variadic));
-					ir_emit_store(proc, convention, ir_const_int(a, t->Proc.calling_convention));
-
-					// TODO(bill): TypeInfo for procedures
-					break;
-				}
-				case Type_Tuple: {
-					ir_emit_comment(proc, str_lit("TypeInfoTuple"));
-					tag = ir_emit_conv(proc, variant_ptr, t_type_info_tuple_ptr);
-
-					irValue *memory_types = ir_type_info_member_types_offset(proc, t->Tuple.variables.count);
-					irValue *memory_names = ir_type_info_member_names_offset(proc, t->Tuple.variables.count);
-
-					for_array(i, t->Tuple.variables) {
-						// NOTE(bill): offset is not used for tuples
-						Entity *f = t->Tuple.variables[i];
-
-						irValue *index     = ir_const_int(a, i);
-						irValue *type_info = ir_emit_ptr_offset(proc, memory_types, index);
-
-						ir_emit_store(proc, type_info, ir_type_info(proc, f->type));
-						if (f->token.string.len > 0) {
-							irValue *name = ir_emit_ptr_offset(proc, memory_names, index);
-							ir_emit_store(proc, name, ir_const_string(a, f->token.string));
-						}
-					}
-
-					irValue *count = ir_const_int(a, t->Tuple.variables.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);
-					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);
-							if (!is_value_int) {
-								GB_ASSERT(is_type_float(t->Enum.base_type));
-							}
-
-							for (isize i = 0; i < count; i++) {
-								irValue *name_ep  = ir_emit_array_epi(proc, name_array, cast(i32)i);
-								irValue *value_ep = ir_emit_array_epi(proc, value_array, cast(i32)i);
-
-								ExactValue value = fields[i]->Constant.value;
-								irValue *v = ir_value_constant(a, t->Enum.base_type, value);
-
-								ir_emit_store(proc, value_ep, ir_emit_conv(proc, v, t_type_info_enum_value));
-								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_Union: {
-					ir_emit_comment(proc, str_lit("TypeInfoUnion"));
-					tag = ir_emit_conv(proc, variant_ptr, t_type_info_union_ptr);
-
-					{
-						irValue *variant_types  = ir_emit_struct_ep(proc, tag, 0);
-						irValue *tag_offset_ptr = ir_emit_struct_ep(proc, tag, 1);
-						irValue *tag_type_ptr   = ir_emit_struct_ep(proc, tag, 2);
-
-						isize variant_count = gb_max(0, t->Union.variants.count);
-						irValue *memory_types = ir_type_info_member_types_offset(proc, variant_count);
-
-						// NOTE(bill): Zeroth is nil so ignore it
-						for (isize variant_index = 0; variant_index < variant_count; variant_index++) {
-							Type *vt = t->Union.variants[variant_index];
-							irValue *tip = ir_get_type_info_ptr(proc, vt);
-
-							irValue *index     = ir_const_int(a, variant_index);
-							irValue *type_info = ir_emit_ptr_offset(proc, memory_types, index);
-							ir_emit_store(proc, type_info, ir_type_info(proc, vt));
-						}
-
-						irValue *count = ir_const_int(a, variant_count);
-						ir_fill_slice(proc, variant_types, memory_types, count, count);
-
-						i64 tag_size  = union_tag_size(t);
-						i64 tag_offset = align_formula(t->Union.variant_block_size, tag_size);
-						ir_emit_store(proc, tag_offset_ptr, ir_const_int(a, tag_offset));
-						ir_emit_store(proc, tag_type_ptr,   ir_type_info(proc, union_tag_type(t)));
-					}
-
-					break;
-				}
-
-				case Type_Struct: {
-					ir_emit_comment(proc, str_lit("TypeInfoStruct"));
-					tag = ir_emit_conv(proc, variant_ptr, t_type_info_struct_ptr);
-
-					{
-						irValue *is_packed       = ir_const_bool(a, t->Struct.is_packed);
-						irValue *is_ordered      = ir_const_bool(a, t->Struct.is_ordered);
-						irValue *is_raw_union    = ir_const_bool(a, t->Struct.is_raw_union);
-						irValue *is_custom_align = ir_const_bool(a, t->Struct.custom_align != 0);
-						ir_emit_store(proc, ir_emit_struct_ep(proc, tag, 4), is_packed);
-						ir_emit_store(proc, ir_emit_struct_ep(proc, tag, 5), is_ordered);
-						ir_emit_store(proc, ir_emit_struct_ep(proc, tag, 6), is_raw_union);
-						ir_emit_store(proc, ir_emit_struct_ep(proc, tag, 7), is_custom_align);
-					}
-
-					isize count = t->Struct.fields.count;
-
-					irValue *memory_types   = ir_type_info_member_types_offset  (proc, count);
-					irValue *memory_names   = ir_type_info_member_names_offset  (proc, count);
-					irValue *memory_offsets = ir_type_info_member_offsets_offset(proc, count);
-					irValue *memory_usings  = ir_type_info_member_usings_offset (proc, count);
-
-					type_set_offsets(a, t); // NOTE(bill): Just incase the offsets have not been set yet
-					for (isize source_index = 0; source_index < count; source_index++) {
-						// TODO(bill): Order fields in source order not layout order
-						Entity *f = t->Struct.fields_in_src_order[source_index];
-						irValue *tip = ir_get_type_info_ptr(proc, f->type);
-						i64 foffset = 0;
-						if (!t->Struct.is_raw_union) {
-							foffset = t->Struct.offsets[f->Variable.field_index];
-						}
-						GB_ASSERT(f->kind == Entity_Variable && f->flags & EntityFlag_Field);
-
-						irValue *index     = ir_const_int(a, source_index);
-						irValue *type_info = ir_emit_ptr_offset(proc, memory_types,   index);
-						irValue *offset    = ir_emit_ptr_offset(proc, memory_offsets, index);
-						irValue *is_using  = ir_emit_ptr_offset(proc, memory_usings, index);
-
-						ir_emit_store(proc, type_info, ir_type_info(proc, f->type));
-						if (f->token.string.len > 0) {
-							irValue *name = ir_emit_ptr_offset(proc, memory_names,   index);
-							ir_emit_store(proc, name, ir_const_string(a, f->token.string));
-						}
-						ir_emit_store(proc, offset, ir_const_int(a, foffset));
-						ir_emit_store(proc, is_using, ir_const_bool(a, (f->flags&EntityFlag_Using) != 0));
-					}
-
-					irValue *cv = ir_const_int(a, count);
-					ir_fill_slice(proc, ir_emit_struct_ep(proc, tag, 0), memory_types,   cv, cv);
-					ir_fill_slice(proc, ir_emit_struct_ep(proc, tag, 1), memory_names,   cv, cv);
-					ir_fill_slice(proc, ir_emit_struct_ep(proc, tag, 2), memory_offsets, cv, cv);
-					ir_fill_slice(proc, ir_emit_struct_ep(proc, tag, 3), memory_usings,  cv, cv);
-					break;
-				}
-				case Type_Map: {
-					ir_emit_comment(proc, str_lit("TypeInfoMap"));
-					tag = ir_emit_conv(proc, variant_ptr, t_type_info_map_ptr);
-					generate_map_internal_types(a, t);
-
-					irValue *key              = ir_emit_struct_ep(proc, tag, 0);
-					irValue *value            = ir_emit_struct_ep(proc, tag, 1);
-					irValue *generated_struct = ir_emit_struct_ep(proc, tag, 2);
-
-					ir_emit_store(proc, key,              ir_get_type_info_ptr(proc, t->Map.key));
-					ir_emit_store(proc, value,            ir_get_type_info_ptr(proc, t->Map.value));
-					ir_emit_store(proc, generated_struct, ir_get_type_info_ptr(proc, t->Map.generated_struct_type));
-					break;
-				}
-
-				case Type_BitField: {
-					ir_emit_comment(proc, str_lit("TypeInfoBitField"));
-					tag = ir_emit_conv(proc, variant_ptr, t_type_info_bit_field_ptr);
-					// names:   []string;
-					// bits:    []u32;
-					// offsets: []u32;
-					isize count = t->BitField.field_count;
-					if (count > 0) {
-						Entity **fields = t->BitField.fields;
-						irValue *name_array   = ir_generate_array(m, t_string, count, str_lit("__$bit_field_names"),   cast(i64)entry_index);
-						irValue *bit_array    = ir_generate_array(m, t_i32,    count, str_lit("__$bit_field_bits"),    cast(i64)entry_index);
-						irValue *offset_array = ir_generate_array(m, t_i32,    count, str_lit("__$bit_field_offsets"), cast(i64)entry_index);
-
-						for (isize i = 0; i < count; i++) {
-							Entity *f = fields[i];
-							GB_ASSERT(f->type != nullptr);
-							GB_ASSERT(f->type->kind == Type_BitFieldValue);
-							irValue *name_ep   = ir_emit_array_epi(proc, name_array,   cast(i32)i);
-							irValue *bit_ep    = ir_emit_array_epi(proc, bit_array,    cast(i32)i);
-							irValue *offset_ep = ir_emit_array_epi(proc, offset_array, cast(i32)i);
-
-							ir_emit_store(proc, name_ep, ir_const_string(a, f->token.string));
-							ir_emit_store(proc, bit_ep, ir_const_i32(a, f->type->BitFieldValue.bits));
-							ir_emit_store(proc, offset_ep, ir_const_i32(a, t->BitField.offsets[i]));
-
-						}
-
-						irValue *v_count = ir_const_int(a, count);
-
-						irValue *names = ir_emit_struct_ep(proc, tag, 0);
-						irValue *name_array_elem = ir_array_elem(proc, name_array);
-						ir_fill_slice(proc, names, name_array_elem, v_count, v_count);
-
-						irValue *bits = ir_emit_struct_ep(proc, tag, 1);
-						irValue *bit_array_elem = ir_array_elem(proc, bit_array);
-						ir_fill_slice(proc, bits, bit_array_elem, v_count, v_count);
-
-						irValue *offsets = ir_emit_struct_ep(proc, tag, 2);
-						irValue *offset_array_elem = ir_array_elem(proc, offset_array);
-						ir_fill_slice(proc, offsets, offset_array_elem, v_count, v_count);
-					}
-					break;
-				}
-				}
-
-
-				if (tag != nullptr) {
-					Type *tag_type = type_deref(ir_type(tag));
-					GB_ASSERT(is_type_named(tag_type));
-					Type *variant_type = type_deref(ir_type(variant_ptr));
-					irValue *tag = ir_const_union_tag(a, variant_type, tag_type);
-					irValue *ptr = ir_emit_union_tag_ptr(proc, variant_ptr);
-					ir_emit_store(proc, ptr, tag);
-				} else {
-					GB_PANIC("Unhandled Type_Info variant: %s", type_to_string(t));
-				}
-			}
-		}
 
 
 		for_array(i, global_variables) {
 		for_array(i, global_variables) {
 			irGlobalVariable *var = &global_variables[i];
 			irGlobalVariable *var = &global_variables[i];

+ 3 - 1
src/ir_print.cpp

@@ -356,8 +356,9 @@ void ir_print_type(irFileBuffer *f, irModule *m, Type *t) {
 				ir_print_encoded_local(f, *found);
 				ir_print_encoded_local(f, *found);
 			} else {
 			} else {
 				// TODO(bill): Is this correct behaviour?!
 				// TODO(bill): Is this correct behaviour?!
+				GB_ASSERT_MSG(found != nullptr, "%.*s %p", LIT(t->Named.name), t->Named.type_name);
+				// gb_printf_err("%.*s %p\n", LIT(t->Named.name), t->Named.type_name);
 				ir_print_type(f, m, base_type(t));
 				ir_print_type(f, m, base_type(t));
-				// GB_ASSERT_MSG(found != nullptr, "%.*s %p", LIT(t->Named.name), t->Named.type_name);
 			}
 			}
 			break;
 			break;
 		}
 		}
@@ -1795,6 +1796,7 @@ void ir_print_proc(irFileBuffer *f, irModule *m, irProcedure *proc) {
 void ir_print_type_name(irFileBuffer *f, irModule *m, irValue *v) {
 void ir_print_type_name(irFileBuffer *f, irModule *m, irValue *v) {
 	GB_ASSERT(v->kind == irValue_TypeName);
 	GB_ASSERT(v->kind == irValue_TypeName);
 	Type *t = base_type(v->TypeName.type);
 	Type *t = base_type(v->TypeName.type);
+
 	ir_print_encoded_local(f, v->TypeName.name);
 	ir_print_encoded_local(f, v->TypeName.name);
 	ir_write_string(f, str_lit(" = type "));
 	ir_write_string(f, str_lit(" = type "));