diff options
| author | Andrew Kelley <superjoe30@gmail.com> | 2017-11-16 10:06:58 -0500 |
|---|---|---|
| committer | Andrew Kelley <superjoe30@gmail.com> | 2017-11-16 10:06:58 -0500 |
| commit | f12d36641f67564d2103f75ed7a5445219197db5 (patch) | |
| tree | 63f967ea88d81475466fbc00929e05d8fe1ec2a3 /src | |
| parent | 018cbff438cedc19d0ad18021619ec7ede997307 (diff) | |
| download | zig-f12d36641f67564d2103f75ed7a5445219197db5.tar.gz zig-f12d36641f67564d2103f75ed7a5445219197db5.zip | |
union secret field is the tag index instead of distinct type index
See #144
Diffstat (limited to 'src')
| -rw-r--r-- | src/all_types.hpp | 6 | ||||
| -rw-r--r-- | src/analyze.cpp | 18 | ||||
| -rw-r--r-- | src/codegen.cpp | 5 | ||||
| -rw-r--r-- | src/ir.cpp | 3 |
4 files changed, 15 insertions, 17 deletions
diff --git a/src/all_types.hpp b/src/all_types.hpp index a6a3f4e1e5..86c9720f69 100644 --- a/src/all_types.hpp +++ b/src/all_types.hpp @@ -105,7 +105,8 @@ struct ConstStructValue { }; struct ConstUnionValue { - ConstExprValue *value; + uint64_t tag; + ConstExprValue *payload; ConstParent parent; }; @@ -349,6 +350,7 @@ struct TypeEnumField { struct TypeUnionField { Buf *name; TypeTableEntry *type_entry; + uint32_t value; uint32_t gen_index; }; @@ -1067,8 +1069,6 @@ struct TypeTableEntryUnion { uint32_t union_size_bytes; TypeTableEntry *most_aligned_union_member; - - HashMap<const TypeTableEntry *, uint32_t, type_ptr_hash, type_ptr_eql> distinct_types = {}; }; struct FnGenParamInfo { diff --git a/src/analyze.cpp b/src/analyze.cpp index 0f8414aaf8..ebad9fe0cb 100644 --- a/src/analyze.cpp +++ b/src/analyze.cpp @@ -1872,8 +1872,6 @@ static void resolve_union_type(CodeGen *g, TypeTableEntry *union_type) { bool auto_layout = (union_type->data.unionation.layout == ContainerLayoutAuto); ZigLLVMDIEnumerator **di_enumerators = allocate<ZigLLVMDIEnumerator*>(field_count); - auto distinct_types = &union_type->data.unionation.distinct_types; - distinct_types->init(4); Scope *scope = &union_type->data.unionation.decls_scope->base; ImportTableEntry *import = get_scope_import(scope); @@ -1895,10 +1893,7 @@ static void resolve_union_type(CodeGen *g, TypeTableEntry *union_type) { if (!type_has_bits(field_type)) continue; - size_t distinct_type_index = distinct_types->size(); - if (distinct_types->put_unique(field_type, distinct_type_index) == nullptr) { - di_enumerators[i] = ZigLLVMCreateDebugEnumerator(g->dbuilder, buf_ptr(&field_type->name), distinct_type_index); - } + di_enumerators[i] = ZigLLVMCreateDebugEnumerator(g->dbuilder, buf_ptr(type_union_field->name), i); uint64_t store_size_in_bits = 8*LLVMStoreSizeOfType(g->target_data_ref, field_type->type_ref); uint64_t abi_align_in_bits = 8*LLVMABIAlignmentOfType(g->target_data_ref, field_type->type_ref); @@ -1954,7 +1949,7 @@ static void resolve_union_type(CodeGen *g, TypeTableEntry *union_type) { assert(most_aligned_union_member != nullptr); - bool want_safety = (distinct_types->size() > 1) && auto_layout; + bool want_safety = auto_layout && (field_count >= 2); uint64_t padding_in_bits = biggest_size_in_bits - size_of_most_aligned_member_in_bits; @@ -2007,7 +2002,7 @@ static void resolve_union_type(CodeGen *g, TypeTableEntry *union_type) { assert(8*LLVMStoreSizeOfType(g->target_data_ref, union_type_ref) >= biggest_size_in_bits); // create llvm type for root struct - TypeTableEntry *tag_int_type = get_smallest_unsigned_int_type(g, distinct_types->size() - 1); + TypeTableEntry *tag_int_type = get_smallest_unsigned_int_type(g, field_count - 1); TypeTableEntry *tag_type_entry = tag_int_type; union_type->data.unionation.tag_type = tag_type_entry; uint64_t align_of_tag_in_bits = 8*LLVMABIAlignmentOfType(g->target_data_ref, tag_int_type->type_ref); @@ -2034,7 +2029,7 @@ static void resolve_union_type(CodeGen *g, TypeTableEntry *union_type) { ZigLLVMDIType *tag_di_type = ZigLLVMCreateDebugEnumerationType(g->dbuilder, ZigLLVMTypeToScope(union_type->di_type), "AnonEnum", import->di_file, (unsigned)(decl_node->line + 1), - tag_debug_size_in_bits, tag_debug_align_in_bits, di_enumerators, distinct_types->size(), + tag_debug_size_in_bits, tag_debug_align_in_bits, di_enumerators, field_count, tag_type_entry->di_type, ""); // create debug type for union @@ -2257,6 +2252,7 @@ static void resolve_union_zero_bits(CodeGen *g, TypeTableEntry *union_type) { type_union_field->name = field_node->data.struct_field.name; TypeTableEntry *field_type = analyze_type_expr(g, scope, field_node->data.struct_field.type); type_union_field->type_entry = field_type; + type_union_field->value = i; type_ensure_zero_bits_known(g, field_type); if (type_is_invalid(field_type)) { @@ -2276,9 +2272,11 @@ static void resolve_union_zero_bits(CodeGen *g, TypeTableEntry *union_type) { } } + bool auto_layout = (union_type->data.unionation.layout == ContainerLayoutAuto); + union_type->data.unionation.zero_bits_loop_flag = false; union_type->data.unionation.gen_field_count = gen_field_index; - union_type->zero_bits = (gen_field_index == 0); + union_type->zero_bits = (gen_field_index == 0 && (field_count < 2 || !auto_layout)); union_type->data.unionation.zero_bits_known = true; // also compute abi_alignment diff --git a/src/codegen.cpp b/src/codegen.cpp index 26a2590e44..3777c3a87a 100644 --- a/src/codegen.cpp +++ b/src/codegen.cpp @@ -3962,7 +3962,7 @@ static LLVMValueRef gen_const_val(CodeGen *g, ConstExprValue *const_val) { case TypeTableEntryIdUnion: { LLVMTypeRef union_type_ref = type_entry->data.unionation.union_type_ref; - ConstExprValue *payload_value = const_val->data.x_union.value; + ConstExprValue *payload_value = const_val->data.x_union.payload; assert(payload_value != nullptr); if (!type_has_bits(payload_value->type)) { @@ -3999,8 +3999,7 @@ static LLVMValueRef gen_const_val(CodeGen *g, ConstExprValue *const_val) { return union_value_ref; } - size_t distinct_type_index = type_entry->data.unionation.distinct_types.get(const_val->data.x_union.value->type); - LLVMValueRef tag_value = LLVMConstInt(type_entry->data.unionation.tag_type->type_ref, distinct_type_index, false); + LLVMValueRef tag_value = LLVMConstInt(type_entry->data.unionation.tag_type->type_ref, const_val->data.x_union.tag, false); LLVMValueRef fields[2]; fields[type_entry->data.unionation.gen_union_index] = union_value_ref; diff --git a/src/ir.cpp b/src/ir.cpp index 6df6b4f828..fa59aa03f2 100644 --- a/src/ir.cpp +++ b/src/ir.cpp @@ -13158,7 +13158,8 @@ static TypeTableEntry *ir_analyze_container_init_fields_union(IrAnalyze *ira, Ir return ira->codegen->builtin_types.entry_invalid; ConstExprValue *out_val = ir_build_const_from(ira, instruction); - out_val->data.x_union.value = field_val; + out_val->data.x_union.payload = field_val; + out_val->data.x_union.tag = type_field->value; ConstParent *parent = get_const_val_parent(ira->codegen, field_val); if (parent != nullptr) { |
