aboutsummaryrefslogtreecommitdiff
path: root/src/analyze.cpp
diff options
context:
space:
mode:
authorAndrew Kelley <superjoe30@gmail.com>2017-12-03 20:43:56 -0500
committerAndrew Kelley <superjoe30@gmail.com>2017-12-03 20:43:56 -0500
commit0ad1239522c70418990dc7b9da4e128da7cdd1d5 (patch)
tree3a434788633db0a3d6e30f779fc1239a7513205a /src/analyze.cpp
parent137c8f5e8a6023db24f90555e968b592a4b843e4 (diff)
downloadzig-0ad1239522c70418990dc7b9da4e128da7cdd1d5.tar.gz
zig-0ad1239522c70418990dc7b9da4e128da7cdd1d5.zip
rework enums and unions and their relationship to each other
* @enumTagName renamed to @tagName and it works on enums and union-enums * Remove the EnumTag type. Now there is only enum and union, and the tag type of a union is always an enum. * unions support specifying the tag enum type, and they support inferring an enum tag type. * Enums no longer support field types but they do support setting the tag values. Likewise union-enums when inferring an enum tag type support setting the tag values. * It is now an error for enums and unions to have 0 fields. * switch statements support union-enums closes #618
Diffstat (limited to 'src/analyze.cpp')
-rw-r--r--src/analyze.cpp607
1 files changed, 301 insertions, 306 deletions
diff --git a/src/analyze.cpp b/src/analyze.cpp
index b7d12443a0..9d2d4f1a8f 100644
--- a/src/analyze.cpp
+++ b/src/analyze.cpp
@@ -223,7 +223,6 @@ bool type_is_complete(TypeTableEntry *type_entry) {
case TypeTableEntryIdNamespace:
case TypeTableEntryIdBlock:
case TypeTableEntryIdBoundFn:
- case TypeTableEntryIdEnumTag:
case TypeTableEntryIdArgTuple:
return true;
}
@@ -260,7 +259,6 @@ bool type_has_zero_bits_known(TypeTableEntry *type_entry) {
case TypeTableEntryIdNamespace:
case TypeTableEntryIdBlock:
case TypeTableEntryIdBoundFn:
- case TypeTableEntryIdEnumTag:
case TypeTableEntryIdArgTuple:
case TypeTableEntryIdOpaque:
return true;
@@ -1175,7 +1173,6 @@ static TypeTableEntry *analyze_fn_type(CodeGen *g, AstNode *proto_node, Scope *c
case TypeTableEntryIdEnum:
case TypeTableEntryIdUnion:
case TypeTableEntryIdFn:
- case TypeTableEntryIdEnumTag:
ensure_complete_type(g, type_entry);
if (fn_type_id.cc == CallingConventionUnspecified && !type_is_copyable(g, type_entry)) {
add_node_error(g, param_node->data.param_decl.type,
@@ -1239,7 +1236,6 @@ static TypeTableEntry *analyze_fn_type(CodeGen *g, AstNode *proto_node, Scope *c
case TypeTableEntryIdEnum:
case TypeTableEntryIdUnion:
case TypeTableEntryIdFn:
- case TypeTableEntryIdEnumTag:
break;
}
@@ -1263,22 +1259,6 @@ bool type_is_invalid(TypeTableEntry *type_entry) {
}
-TypeTableEntry *create_enum_tag_type(CodeGen *g, TypeTableEntry *enum_type, TypeTableEntry *int_type) {
- TypeTableEntry *entry = new_type_table_entry(TypeTableEntryIdEnumTag);
-
- buf_resize(&entry->name, 0);
- buf_appendf(&entry->name, "@EnumTagType(%s)", buf_ptr(&enum_type->name));
-
- entry->is_copyable = true;
- entry->data.enum_tag.enum_type = enum_type;
- entry->data.enum_tag.int_type = int_type;
- entry->type_ref = int_type->type_ref;
- entry->di_type = int_type->di_type;
- entry->zero_bits = int_type->zero_bits;
-
- return entry;
-}
-
static void resolve_enum_type(CodeGen *g, TypeTableEntry *enum_type) {
assert(enum_type->id == TypeTableEntryIdEnum);
@@ -1308,14 +1288,6 @@ static void resolve_enum_type(CodeGen *g, TypeTableEntry *enum_type) {
assert(enum_type->data.enumeration.fields);
ZigLLVMDIEnumerator **di_enumerators = allocate<ZigLLVMDIEnumerator*>(field_count);
- uint32_t gen_field_count = enum_type->data.enumeration.gen_field_count;
- ZigLLVMDIType **union_inner_di_types = allocate<ZigLLVMDIType*>(gen_field_count);
-
- TypeTableEntry *most_aligned_union_member = nullptr;
- uint64_t size_of_most_aligned_member_in_bits = 0;
- uint64_t biggest_align_in_bits = 0;
- uint64_t biggest_size_in_bits = 0;
-
Scope *scope = &enum_type->data.enumeration.decls_scope->base;
ImportTableEntry *import = get_scope_import(scope);
@@ -1323,49 +1295,17 @@ static void resolve_enum_type(CodeGen *g, TypeTableEntry *enum_type) {
enum_type->data.enumeration.embedded_in_current = true;
for (uint32_t i = 0; i < field_count; i += 1) {
- AstNode *field_node = decl_node->data.container_decl.fields.at(i);
- TypeEnumField *type_enum_field = &enum_type->data.enumeration.fields[i];
- TypeTableEntry *field_type = type_enum_field->type_entry;
-
- di_enumerators[i] = ZigLLVMCreateDebugEnumerator(g->dbuilder, buf_ptr(type_enum_field->name), i);
-
- ensure_complete_type(g, field_type);
- if (type_is_invalid(field_type)) {
- enum_type->data.enumeration.is_invalid = true;
- continue;
- }
-
- if (!type_has_bits(field_type))
- continue;
-
- 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);
+ TypeEnumField *enum_field = &enum_type->data.enumeration.fields[i];
- assert(store_size_in_bits > 0);
- assert(abi_align_in_bits > 0);
-
- union_inner_di_types[type_enum_field->gen_index] = ZigLLVMCreateDebugMemberType(g->dbuilder,
- ZigLLVMTypeToScope(enum_type->di_type), buf_ptr(type_enum_field->name),
- import->di_file, (unsigned)(field_node->line + 1),
- store_size_in_bits,
- abi_align_in_bits,
- 0,
- 0, field_type->di_type);
-
- biggest_size_in_bits = max(biggest_size_in_bits, store_size_in_bits);
-
- if (!most_aligned_union_member || abi_align_in_bits > biggest_align_in_bits) {
- most_aligned_union_member = field_type;
- biggest_align_in_bits = abi_align_in_bits;
- size_of_most_aligned_member_in_bits = store_size_in_bits;
- }
+ // TODO send patch to LLVM to support APInt in createEnumerator instead of int64_t
+ // http://lists.llvm.org/pipermail/llvm-dev/2017-December/119456.html
+ di_enumerators[i] = ZigLLVMCreateDebugEnumerator(g->dbuilder, buf_ptr(enum_field->name),
+ bigint_as_signed(&enum_field->value));
}
// unset temporary flag
enum_type->data.enumeration.embedded_in_current = false;
enum_type->data.enumeration.complete = true;
- enum_type->data.enumeration.union_size_bytes = biggest_size_in_bits / 8;
- enum_type->data.enumeration.most_aligned_union_member = most_aligned_union_member;
if (enum_type->data.enumeration.is_invalid)
return;
@@ -1391,117 +1331,20 @@ static void resolve_enum_type(CodeGen *g, TypeTableEntry *enum_type) {
}
TypeTableEntry *tag_int_type = enum_type->data.enumeration.tag_int_type;
- TypeTableEntry *tag_type_entry = create_enum_tag_type(g, enum_type, tag_int_type);
- enum_type->data.enumeration.tag_type = tag_type_entry;
-
- uint64_t align_of_tag_in_bits = 8*LLVMABIAlignmentOfType(g->target_data_ref, tag_int_type->type_ref);
-
- if (most_aligned_union_member) {
- // create llvm type for union
- uint64_t padding_in_bits = biggest_size_in_bits - size_of_most_aligned_member_in_bits;
- LLVMTypeRef union_type_ref;
- if (padding_in_bits > 0) {
- TypeTableEntry *u8_type = get_int_type(g, false, 8);
- TypeTableEntry *padding_array = get_array_type(g, u8_type, padding_in_bits / 8);
- LLVMTypeRef union_element_types[] = {
- most_aligned_union_member->type_ref,
- padding_array->type_ref,
- };
- union_type_ref = LLVMStructType(union_element_types, 2, false);
- } else {
- union_type_ref = most_aligned_union_member->type_ref;
- }
- enum_type->data.enumeration.union_type_ref = union_type_ref;
-
- assert(8*LLVMABIAlignmentOfType(g->target_data_ref, union_type_ref) >= biggest_align_in_bits);
- assert(8*LLVMStoreSizeOfType(g->target_data_ref, union_type_ref) >= biggest_size_in_bits);
-
- if (align_of_tag_in_bits >= biggest_align_in_bits) {
- enum_type->data.enumeration.gen_tag_index = 0;
- enum_type->data.enumeration.gen_union_index = 1;
- } else {
- enum_type->data.enumeration.gen_union_index = 0;
- enum_type->data.enumeration.gen_tag_index = 1;
- }
-
- // create llvm type for root struct
- LLVMTypeRef root_struct_element_types[2];
- root_struct_element_types[enum_type->data.enumeration.gen_tag_index] = tag_type_entry->type_ref;
- root_struct_element_types[enum_type->data.enumeration.gen_union_index] = union_type_ref;
- LLVMStructSetBody(enum_type->type_ref, root_struct_element_types, 2, false);
-
- // create debug type for tag
- uint64_t tag_debug_size_in_bits = 8*LLVMStoreSizeOfType(g->target_data_ref, tag_type_entry->type_ref);
- uint64_t tag_debug_align_in_bits = 8*LLVMABIAlignmentOfType(g->target_data_ref, tag_type_entry->type_ref);
- ZigLLVMDIType *tag_di_type = ZigLLVMCreateDebugEnumerationType(g->dbuilder,
- ZigLLVMTypeToScope(enum_type->di_type), "AnonEnum",
- import->di_file, (unsigned)(decl_node->line + 1),
- tag_debug_size_in_bits, tag_debug_align_in_bits, di_enumerators, field_count,
- tag_type_entry->di_type, "");
-
- // create debug type for union
- ZigLLVMDIType *union_di_type = ZigLLVMCreateDebugUnionType(g->dbuilder,
- ZigLLVMTypeToScope(enum_type->di_type), "AnonUnion",
- import->di_file, (unsigned)(decl_node->line + 1),
- biggest_size_in_bits, biggest_align_in_bits, 0, union_inner_di_types,
- gen_field_count, 0, "");
-
- // create debug types for members of root struct
- uint64_t tag_offset_in_bits = 8*LLVMOffsetOfElement(g->target_data_ref, enum_type->type_ref,
- enum_type->data.enumeration.gen_tag_index);
- ZigLLVMDIType *tag_member_di_type = ZigLLVMCreateDebugMemberType(g->dbuilder,
- ZigLLVMTypeToScope(enum_type->di_type), "tag_field",
- import->di_file, (unsigned)(decl_node->line + 1),
- tag_debug_size_in_bits,
- tag_debug_align_in_bits,
- tag_offset_in_bits,
- 0, tag_di_type);
-
- uint64_t union_offset_in_bits = 8*LLVMOffsetOfElement(g->target_data_ref, enum_type->type_ref,
- enum_type->data.enumeration.gen_union_index);
- ZigLLVMDIType *union_member_di_type = ZigLLVMCreateDebugMemberType(g->dbuilder,
- ZigLLVMTypeToScope(enum_type->di_type), "union_field",
- import->di_file, (unsigned)(decl_node->line + 1),
- biggest_size_in_bits,
- biggest_align_in_bits,
- union_offset_in_bits,
- 0, union_di_type);
-
- // create debug type for root struct
- ZigLLVMDIType *di_root_members[2];
- di_root_members[enum_type->data.enumeration.gen_tag_index] = tag_member_di_type;
- di_root_members[enum_type->data.enumeration.gen_union_index] = union_member_di_type;
-
- uint64_t debug_size_in_bits = 8*LLVMStoreSizeOfType(g->target_data_ref, enum_type->type_ref);
- uint64_t debug_align_in_bits = 8*LLVMABISizeOfType(g->target_data_ref, enum_type->type_ref);
- ZigLLVMDIType *replacement_di_type = ZigLLVMCreateDebugStructType(g->dbuilder,
- ZigLLVMFileToScope(import->di_file),
- buf_ptr(&enum_type->name),
- import->di_file, (unsigned)(decl_node->line + 1),
- debug_size_in_bits,
- debug_align_in_bits,
- 0, nullptr, di_root_members, 2, 0, nullptr, "");
-
- ZigLLVMReplaceTemporary(g->dbuilder, enum_type->di_type, replacement_di_type);
- enum_type->di_type = replacement_di_type;
- } else {
- // create llvm type for root struct
- enum_type->type_ref = tag_type_entry->type_ref;
- // create debug type for tag
- uint64_t tag_debug_size_in_bits = 8*LLVMStoreSizeOfType(g->target_data_ref, tag_type_entry->type_ref);
- uint64_t tag_debug_align_in_bits = 8*LLVMABIAlignmentOfType(g->target_data_ref, tag_type_entry->type_ref);
- ZigLLVMDIType *tag_di_type = ZigLLVMCreateDebugEnumerationType(g->dbuilder,
- ZigLLVMFileToScope(import->di_file), buf_ptr(&enum_type->name),
- import->di_file, (unsigned)(decl_node->line + 1),
- tag_debug_size_in_bits,
- tag_debug_align_in_bits,
- di_enumerators, field_count,
- tag_type_entry->di_type, "");
+ // create debug type for tag
+ uint64_t tag_debug_size_in_bits = 8*LLVMStoreSizeOfType(g->target_data_ref, tag_int_type->type_ref);
+ uint64_t tag_debug_align_in_bits = 8*LLVMABIAlignmentOfType(g->target_data_ref, tag_int_type->type_ref);
+ ZigLLVMDIType *tag_di_type = ZigLLVMCreateDebugEnumerationType(g->dbuilder,
+ ZigLLVMFileToScope(import->di_file), buf_ptr(&enum_type->name),
+ import->di_file, (unsigned)(decl_node->line + 1),
+ tag_debug_size_in_bits,
+ tag_debug_align_in_bits,
+ di_enumerators, field_count,
+ tag_int_type->di_type, "");
- ZigLLVMReplaceTemporary(g->dbuilder, enum_type->di_type, tag_di_type);
- enum_type->di_type = tag_di_type;
- }
+ ZigLLVMReplaceTemporary(g->dbuilder, enum_type->di_type, tag_di_type);
+ enum_type->di_type = tag_di_type;
}
static bool type_allowed_in_packed_struct(TypeTableEntry *type_entry) {
@@ -1517,7 +1360,6 @@ static bool type_allowed_in_packed_struct(TypeTableEntry *type_entry) {
case TypeTableEntryIdNullLit:
case TypeTableEntryIdErrorUnion:
case TypeTableEntryIdPureError:
- case TypeTableEntryIdEnumTag:
case TypeTableEntryIdNamespace:
case TypeTableEntryIdBlock:
case TypeTableEntryIdBoundFn:
@@ -1541,8 +1383,7 @@ static bool type_allowed_in_packed_struct(TypeTableEntry *type_entry) {
return child_type->id == TypeTableEntryIdPointer || child_type->id == TypeTableEntryIdFn;
}
case TypeTableEntryIdEnum:
- return type_entry->data.enumeration.gen_field_count == 0 &&
- type_entry->data.enumeration.decl_node->data.container_decl.init_arg_expr != nullptr;
+ return type_entry->data.enumeration.decl_node->data.container_decl.init_arg_expr != nullptr;
}
zig_unreachable();
}
@@ -1850,6 +1691,7 @@ static void resolve_union_type(CodeGen *g, TypeTableEntry *union_type) {
if (union_type->data.unionation.embedded_in_current) {
if (!union_type->data.unionation.reported_infinite_err) {
union_type->data.unionation.reported_infinite_err = true;
+ union_type->data.unionation.is_invalid = true;
add_node_error(g, decl_node, buf_sprintf("union '%s' contains itself", buf_ptr(&union_type->name)));
}
return;
@@ -1871,8 +1713,7 @@ static void resolve_union_type(CodeGen *g, TypeTableEntry *union_type) {
uint64_t biggest_align_in_bits = 0;
uint64_t biggest_size_in_bits = 0;
- bool auto_layout = (union_type->data.unionation.layout == ContainerLayoutAuto);
- ZigLLVMDIEnumerator **di_enumerators = allocate<ZigLLVMDIEnumerator*>(field_count);
+ ZigLLVMDIEnumerator **di_enumerators;
Scope *scope = &union_type->data.unionation.decls_scope->base;
ImportTableEntry *import = get_scope_import(scope);
@@ -1880,10 +1721,77 @@ static void resolve_union_type(CodeGen *g, TypeTableEntry *union_type) {
// set temporary flag
union_type->data.unionation.embedded_in_current = true;
+ HashMap<BigInt, AstNode *, bigint_hash, bigint_eql> occupied_tag_values = {};
+
+ AstNode *enum_type_node = decl_node->data.container_decl.init_arg_expr;
+ bool auto_layout = (union_type->data.unionation.layout == ContainerLayoutAuto);
+ bool want_safety = (field_count >= 2) && (auto_layout || enum_type_node != nullptr);
+ TypeTableEntry *tag_type;
+ bool create_enum_type = decl_node->data.container_decl.auto_enum || (enum_type_node == nullptr && want_safety);
+ bool *covered_enum_fields;
+ if (create_enum_type) {
+ occupied_tag_values.init(field_count);
+
+ di_enumerators = allocate<ZigLLVMDIEnumerator*>(field_count);
+
+ TypeTableEntry *tag_int_type;
+ if (enum_type_node != nullptr) {
+ tag_int_type = analyze_type_expr(g, scope, enum_type_node);
+ if (type_is_invalid(tag_int_type)) {
+ union_type->data.unionation.is_invalid = true;
+ return;
+ }
+ if (tag_int_type->id != TypeTableEntryIdInt) {
+ add_node_error(g, enum_type_node,
+ buf_sprintf("expected integer tag type, found '%s'", buf_ptr(&tag_int_type->name)));
+ union_type->data.unionation.is_invalid = true;
+ return;
+ }
+ } else {
+ tag_int_type = get_smallest_unsigned_int_type(g, field_count - 1);
+ }
+
+ tag_type = new_type_table_entry(TypeTableEntryIdEnum);
+ buf_resize(&tag_type->name, 0);
+ buf_appendf(&tag_type->name, "@EnumTagType(%s)", buf_ptr(&union_type->name));
+ tag_type->is_copyable = true;
+ tag_type->type_ref = tag_int_type->type_ref;
+ tag_type->zero_bits = tag_int_type->zero_bits;
+
+ tag_type->data.enumeration.tag_int_type = tag_int_type;
+ tag_type->data.enumeration.zero_bits_known = true;
+ tag_type->data.enumeration.decl_node = decl_node;
+ tag_type->data.enumeration.layout = ContainerLayoutAuto;
+ tag_type->data.enumeration.src_field_count = field_count;
+ tag_type->data.enumeration.fields = allocate<TypeEnumField>(field_count);
+ tag_type->data.enumeration.decls_scope = union_type->data.unionation.decls_scope;
+ tag_type->data.enumeration.complete = true;
+ } else if (enum_type_node != nullptr) {
+ TypeTableEntry *enum_type = analyze_type_expr(g, scope, enum_type_node);
+ if (type_is_invalid(enum_type)) {
+ union_type->data.unionation.is_invalid = true;
+ union_type->data.unionation.embedded_in_current = false;
+ return;
+ }
+ if (enum_type->id != TypeTableEntryIdEnum) {
+ union_type->data.unionation.is_invalid = true;
+ union_type->data.unionation.embedded_in_current = false;
+ add_node_error(g, enum_type_node,
+ buf_sprintf("expected enum tag type, found '%s'", buf_ptr(&enum_type->name)));
+ return;
+ }
+ tag_type = enum_type;
+ covered_enum_fields = allocate<bool>(enum_type->data.enumeration.src_field_count);
+ } else {
+ tag_type = nullptr;
+ }
+ union_type->data.unionation.tag_type = tag_type;
+
for (uint32_t i = 0; i < field_count; i += 1) {
AstNode *field_node = decl_node->data.container_decl.fields.at(i);
- TypeUnionField *type_union_field = &union_type->data.unionation.fields[i];
- TypeTableEntry *field_type = type_union_field->type_entry;
+ TypeUnionField *union_field = &union_type->data.unionation.fields[i];
+ Buf *field_name = field_node->data.struct_field.name;
+ TypeTableEntry *field_type = union_field->type_entry;
ensure_complete_type(g, field_type);
if (type_is_invalid(field_type)) {
@@ -1891,19 +1799,68 @@ static void resolve_union_type(CodeGen *g, TypeTableEntry *union_type) {
continue;
}
+ if (create_enum_type) {
+ di_enumerators[i] = ZigLLVMCreateDebugEnumerator(g->dbuilder, buf_ptr(field_name), i);
+ union_field->enum_field = &tag_type->data.enumeration.fields[i];
+ union_field->enum_field->name = field_name;
+ union_field->enum_field->decl_index = i;
+
+ AstNode *tag_value = field_node->data.struct_field.value;
+ // In this first pass we resolve explicit tag values.
+ // In a second pass we will fill in the unspecified ones.
+ if (tag_value != nullptr) {
+ TypeTableEntry *tag_int_type = tag_type->data.enumeration.tag_int_type;
+ IrInstruction *result_inst = analyze_const_value(g, scope, tag_value, tag_int_type, nullptr);
+ if (result_inst->value.type->id == TypeTableEntryIdInvalid) {
+ union_type->data.unionation.is_invalid = true;
+ continue;
+ }
+ assert(result_inst->value.special != ConstValSpecialRuntime);
+ assert(result_inst->value.type->id == TypeTableEntryIdInt);
+ auto entry = occupied_tag_values.put_unique(result_inst->value.data.x_bigint, tag_value);
+ if (entry == nullptr) {
+ bigint_init_bigint(&union_field->enum_field->value, &result_inst->value.data.x_bigint);
+ } else {
+ Buf *val_buf = buf_alloc();
+ bigint_append_buf(val_buf, &result_inst->value.data.x_bigint, 10);
+
+ ErrorMsg *msg = add_node_error(g, tag_value,
+ buf_sprintf("enum tag value %s already taken", buf_ptr(val_buf)));
+ add_error_note(g, msg, entry->value,
+ buf_sprintf("other occurrence here"));
+ union_type->data.unionation.is_invalid = true;
+ continue;
+ }
+ }
+ } else if (enum_type_node != nullptr) {
+ union_field->enum_field = find_enum_type_field(tag_type, field_name);
+ if (union_field->enum_field == nullptr) {
+ ErrorMsg *msg = add_node_error(g, field_node,
+ buf_sprintf("enum field not found: '%s'", buf_ptr(field_name)));
+ add_error_note(g, msg, tag_type->data.enumeration.decl_node,
+ buf_sprintf("enum declared here"));
+ union_type->data.unionation.is_invalid = true;
+ continue;
+ }
+ covered_enum_fields[union_field->enum_field->decl_index] = true;
+ } else {
+ union_field->enum_field = allocate<TypeEnumField>(1);
+ union_field->enum_field->name = field_name;
+ union_field->enum_field->decl_index = i;
+ bigint_init_unsigned(&union_field->enum_field->value, i);
+ }
+
if (!type_has_bits(field_type))
continue;
- 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);
assert(store_size_in_bits > 0);
assert(abi_align_in_bits > 0);
- union_inner_di_types[type_union_field->gen_index] = ZigLLVMCreateDebugMemberType(g->dbuilder,
- ZigLLVMTypeToScope(union_type->di_type), buf_ptr(type_union_field->name),
+ union_inner_di_types[union_field->gen_index] = ZigLLVMCreateDebugMemberType(g->dbuilder,
+ ZigLLVMTypeToScope(union_type->di_type), buf_ptr(union_field->enum_field->name),
import->di_file, (unsigned)(field_node->line + 1),
store_size_in_bits,
abi_align_in_bits,
@@ -1919,6 +1876,49 @@ static void resolve_union_type(CodeGen *g, TypeTableEntry *union_type) {
}
}
+ if (create_enum_type) {
+ // Now iterate again and populate the unspecified tag values
+ uint32_t next_maybe_unoccupied_index = 0;
+
+ for (uint32_t field_i = 0; field_i < field_count; field_i += 1) {
+ AstNode *field_node = decl_node->data.container_decl.fields.at(field_i);
+ TypeUnionField *union_field = &union_type->data.unionation.fields[field_i];
+ AstNode *tag_value = field_node->data.struct_field.value;
+
+ if (tag_value == nullptr) {
+ if (occupied_tag_values.size() == 0) {
+ bigint_init_unsigned(&union_field->enum_field->value, next_maybe_unoccupied_index);
+ next_maybe_unoccupied_index += 1;
+ } else {
+ BigInt proposed_value;
+ for (;;) {
+ bigint_init_unsigned(&proposed_value, next_maybe_unoccupied_index);
+ next_maybe_unoccupied_index += 1;
+ auto entry = occupied_tag_values.put_unique(proposed_value, field_node);
+ if (entry != nullptr) {
+ continue;
+ }
+ break;
+ }
+ bigint_init_bigint(&union_field->enum_field->value, &proposed_value);
+ }
+ }
+ }
+ } else if (enum_type_node != nullptr) {
+ for (uint32_t i = 0; i < tag_type->data.enumeration.src_field_count; i += 1) {
+ TypeEnumField *enum_field = &tag_type->data.enumeration.fields[i];
+ if (!covered_enum_fields[i]) {
+ AstNode *enum_decl_node = tag_type->data.enumeration.decl_node;
+ AstNode *field_node = enum_decl_node->data.container_decl.fields.at(i);
+ ErrorMsg *msg = add_node_error(g, decl_node,
+ buf_sprintf("enum field missing: '%s'", buf_ptr(enum_field->name)));
+ add_error_note(g, msg, field_node,
+ buf_sprintf("declared here"));
+ union_type->data.unionation.is_invalid = true;
+ }
+ }
+ }
+
// unset temporary flag
union_type->data.unionation.embedded_in_current = false;
union_type->data.unionation.complete = true;
@@ -1950,11 +1950,9 @@ static void resolve_union_type(CodeGen *g, TypeTableEntry *union_type) {
assert(most_aligned_union_member != nullptr);
- bool want_safety = auto_layout && (field_count >= 2);
uint64_t padding_in_bits = biggest_size_in_bits - size_of_most_aligned_member_in_bits;
-
- if (!want_safety) {
+ if (tag_type == nullptr) {
if (padding_in_bits > 0) {
TypeTableEntry *u8_type = get_int_type(g, false, 8);
TypeTableEntry *padding_array = get_array_type(g, u8_type, padding_in_bits / 8);
@@ -1994,6 +1992,8 @@ static void resolve_union_type(CodeGen *g, TypeTableEntry *union_type) {
padding_array->type_ref,
};
union_type_ref = LLVMStructType(union_element_types, 2, false);
+ } else if (most_aligned_union_member == nullptr) {
+ zig_panic("TODO zero bit payload");
} else {
union_type_ref = most_aligned_union_member->type_ref;
}
@@ -2003,9 +2003,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, field_count - 1);
- TypeTableEntry *tag_type_entry = tag_int_type;
- union_type->data.unionation.tag_type = tag_type_entry;
+ TypeTableEntry *tag_int_type = tag_type->data.enumeration.tag_int_type;
uint64_t align_of_tag_in_bits = 8*LLVMABIAlignmentOfType(g->target_data_ref, tag_int_type->type_ref);
if (align_of_tag_in_bits >= biggest_align_in_bits) {
@@ -2017,21 +2015,24 @@ static void resolve_union_type(CodeGen *g, TypeTableEntry *union_type) {
}
LLVMTypeRef root_struct_element_types[2];
- root_struct_element_types[union_type->data.unionation.gen_tag_index] = tag_type_entry->type_ref;
+ root_struct_element_types[union_type->data.unionation.gen_tag_index] = tag_type->type_ref;
root_struct_element_types[union_type->data.unionation.gen_union_index] = union_type_ref;
LLVMStructSetBody(union_type->type_ref, root_struct_element_types, 2, false);
// create debug type for root struct
- // create debug type for tag
- uint64_t tag_debug_size_in_bits = 8*LLVMStoreSizeOfType(g->target_data_ref, tag_type_entry->type_ref);
- uint64_t tag_debug_align_in_bits = 8*LLVMABIAlignmentOfType(g->target_data_ref, tag_type_entry->type_ref);
- 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, field_count,
- tag_type_entry->di_type, "");
+ uint64_t tag_debug_size_in_bits = 8*LLVMStoreSizeOfType(g->target_data_ref, tag_type->type_ref);
+ uint64_t tag_debug_align_in_bits = 8*LLVMABIAlignmentOfType(g->target_data_ref, tag_type->type_ref);
+ if (create_enum_type) {
+ // create debug type for tag
+ 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, field_count,
+ tag_type->di_type, "");
+ tag_type->di_type = tag_di_type;
+ }
// create debug type for union
ZigLLVMDIType *union_di_type = ZigLLVMCreateDebugUnionType(g->dbuilder,
@@ -2046,19 +2047,19 @@ static void resolve_union_type(CodeGen *g, TypeTableEntry *union_type) {
union_type->data.unionation.gen_tag_index);
ZigLLVMDIType *union_member_di_type = ZigLLVMCreateDebugMemberType(g->dbuilder,
- ZigLLVMTypeToScope(union_type->di_type), "union_field",
+ ZigLLVMTypeToScope(union_type->di_type), "payload",
import->di_file, (unsigned)(decl_node->line + 1),
biggest_size_in_bits,
biggest_align_in_bits,
union_offset_in_bits,
0, union_di_type);
ZigLLVMDIType *tag_member_di_type = ZigLLVMCreateDebugMemberType(g->dbuilder,
- ZigLLVMTypeToScope(union_type->di_type), "tag_field",
+ ZigLLVMTypeToScope(union_type->di_type), "tag",
import->di_file, (unsigned)(decl_node->line + 1),
tag_debug_size_in_bits,
tag_debug_align_in_bits,
tag_offset_in_bits,
- 0, tag_di_type);
+ 0, tag_type->di_type);
ZigLLVMDIType *di_root_members[2];
di_root_members[union_type->data.unionation.gen_tag_index] = tag_member_di_type;
@@ -2104,7 +2105,6 @@ static void resolve_enum_zero_bits(CodeGen *g, TypeTableEntry *enum_type) {
enum_type->data.enumeration.fields = nullptr;
enum_type->data.enumeration.is_invalid = true;
enum_type->data.enumeration.zero_bits_loop_flag = false;
- enum_type->data.enumeration.gen_field_count = 0;
enum_type->data.enumeration.zero_bits_known = true;
return;
}
@@ -2112,8 +2112,6 @@ static void resolve_enum_zero_bits(CodeGen *g, TypeTableEntry *enum_type) {
enum_type->data.enumeration.src_field_count = field_count;
enum_type->data.enumeration.fields = allocate<TypeEnumField>(field_count);
- uint32_t biggest_align_bytes = 0;
-
Scope *scope = &enum_type->data.enumeration.decls_scope->base;
HashMap<BigInt, AstNode *, bigint_hash, bigint_eql> occupied_tag_values = {};
@@ -2143,14 +2141,20 @@ static void resolve_enum_zero_bits(CodeGen *g, TypeTableEntry *enum_type) {
}
}
enum_type->data.enumeration.tag_int_type = tag_int_type;
+ enum_type->type_ref = tag_int_type->type_ref;
- uint32_t gen_field_index = 0;
for (uint32_t field_i = 0; field_i < field_count; field_i += 1) {
AstNode *field_node = decl_node->data.container_decl.fields.at(field_i);
TypeEnumField *type_enum_field = &enum_type->data.enumeration.fields[field_i];
type_enum_field->name = field_node->data.struct_field.name;
- TypeTableEntry *field_type = analyze_type_expr(g, scope, field_node->data.struct_field.type);
- type_enum_field->type_entry = field_type;
+ type_enum_field->decl_index = field_i;
+
+ if (field_node->data.struct_field.type != nullptr) {
+ ErrorMsg *msg = add_node_error(g, field_node->data.struct_field.type,
+ buf_sprintf("structs and unions, not enums, support field types"));
+ add_error_note(g, msg, decl_node,
+ buf_sprintf("consider 'union(enum)' here"));
+ }
AstNode *tag_value = field_node->data.struct_field.value;
@@ -2179,23 +2183,6 @@ static void resolve_enum_zero_bits(CodeGen *g, TypeTableEntry *enum_type) {
continue;
}
}
-
- type_ensure_zero_bits_known(g, field_type);
- if (type_is_invalid(field_type)) {
- enum_type->data.enumeration.is_invalid = true;
- continue;
- }
-
- if (!type_has_bits(field_type))
- continue;
-
- type_enum_field->gen_index = gen_field_index;
- gen_field_index += 1;
-
- uint32_t field_align_bytes = get_abi_alignment(g, field_type);
- if (field_align_bytes > biggest_align_bytes) {
- biggest_align_bytes = field_align_bytes;
- }
}
// Now iterate again and populate the unspecified tag values
@@ -2227,15 +2214,8 @@ static void resolve_enum_zero_bits(CodeGen *g, TypeTableEntry *enum_type) {
}
enum_type->data.enumeration.zero_bits_loop_flag = false;
- enum_type->data.enumeration.gen_field_count = gen_field_index;
- enum_type->zero_bits = (gen_field_index == 0 && field_count < 2);
+ enum_type->zero_bits = (field_count < 2);
enum_type->data.enumeration.zero_bits_known = true;
-
- // also compute abi_alignment
- if (!enum_type->zero_bits) {
- uint32_t align_of_tag_in_bytes = LLVMABIAlignmentOfType(g->target_data_ref, tag_int_type->type_ref);
- enum_type->data.enumeration.abi_alignment = max(align_of_tag_in_bytes, biggest_align_bytes);
- }
}
static void resolve_struct_zero_bits(CodeGen *g, TypeTableEntry *struct_type) {
@@ -2279,6 +2259,13 @@ static void resolve_struct_zero_bits(CodeGen *g, TypeTableEntry *struct_type) {
AstNode *field_node = decl_node->data.container_decl.fields.at(i);
TypeStructField *type_struct_field = &struct_type->data.structure.fields[i];
type_struct_field->name = field_node->data.struct_field.name;
+
+ if (field_node->data.struct_field.type == nullptr) {
+ add_node_error(g, field_node, buf_sprintf("struct field missing type"));
+ struct_type->data.structure.is_invalid = true;
+ continue;
+ }
+
TypeTableEntry *field_type = analyze_type_expr(g, scope, field_node->data.struct_field.type);
type_struct_field->type_entry = field_type;
type_struct_field->src_index = i;
@@ -2338,6 +2325,16 @@ static void resolve_union_zero_bits(CodeGen *g, TypeTableEntry *union_type) {
assert(!union_type->data.unionation.fields);
uint32_t field_count = (uint32_t)decl_node->data.container_decl.fields.length;
+ if (field_count == 0) {
+ add_node_error(g, decl_node, buf_sprintf("unions must have 1 or more fields"));
+
+ union_type->data.unionation.src_field_count = field_count;
+ union_type->data.unionation.fields = nullptr;
+ union_type->data.unionation.is_invalid = true;
+ union_type->data.unionation.zero_bits_loop_flag = false;
+ union_type->data.unionation.zero_bits_known = true;
+ return;
+ }
union_type->data.unionation.src_field_count = field_count;
union_type->data.unionation.fields = allocate<TypeUnionField>(field_count);
@@ -2348,17 +2345,23 @@ static void resolve_union_zero_bits(CodeGen *g, TypeTableEntry *union_type) {
uint32_t gen_field_index = 0;
for (uint32_t i = 0; i < field_count; i += 1) {
AstNode *field_node = decl_node->data.container_decl.fields.at(i);
- TypeUnionField *type_union_field = &union_type->data.unionation.fields[i];
- 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;
+ TypeUnionField *union_field = &union_type->data.unionation.fields[i];
+ union_field->name = field_node->data.struct_field.name;
- // TODO look for enum arg to union
- bigint_init_unsigned(&type_union_field->value, i);
+ if (field_node->data.struct_field.type == nullptr) {
+ add_node_error(g, field_node, buf_sprintf("union field missing type"));
+ union_type->data.unionation.is_invalid = true;
+ continue;
+ }
- if (field_node->data.struct_field.value != nullptr) {
- add_node_error(g, field_node->data.struct_field.value,
- buf_sprintf("enums, not unions, support field assignment"));
+ TypeTableEntry *field_type = analyze_type_expr(g, scope, field_node->data.struct_field.type);
+ union_field->type_entry = field_type;
+
+ if (field_node->data.struct_field.value != nullptr && !decl_node->data.container_decl.auto_enum) {
+ ErrorMsg *msg = add_node_error(g, field_node->data.struct_field.value,
+ buf_sprintf("non-enum union field assignment"));
+ add_error_note(g, msg, decl_node,
+ buf_sprintf("consider 'union(enum)' here"));
}
type_ensure_zero_bits_known(g, field_type);
@@ -2370,7 +2373,7 @@ static void resolve_union_zero_bits(CodeGen *g, TypeTableEntry *union_type) {
if (!type_has_bits(field_type))
continue;
- type_union_field->gen_index = gen_field_index;
+ union_field->gen_index = gen_field_index;
gen_field_index += 1;
uint32_t field_align_bytes = get_abi_alignment(g, field_type);
@@ -2379,11 +2382,32 @@ static void resolve_union_zero_bits(CodeGen *g, TypeTableEntry *union_type) {
}
}
- bool auto_layout = (union_type->data.unionation.layout == ContainerLayoutAuto);
+ bool src_have_tag = decl_node->data.container_decl.auto_enum ||
+ decl_node->data.container_decl.init_arg_expr != nullptr;
+
+ if (src_have_tag && union_type->data.unionation.layout != ContainerLayoutAuto) {
+ const char *qual_str;
+ switch (union_type->data.unionation.layout) {
+ case ContainerLayoutAuto:
+ zig_unreachable();
+ case ContainerLayoutPacked:
+ qual_str = "packed";
+ break;
+ case ContainerLayoutExtern:
+ qual_str = "extern";
+ break;
+ }
+ AstNode *source_node = (decl_node->data.container_decl.init_arg_expr != nullptr) ?
+ decl_node->data.container_decl.init_arg_expr : decl_node;
+ add_node_error(g, source_node,
+ buf_sprintf("%s union does not support enum tag type", qual_str));
+ union_type->data.unionation.is_invalid = true;
+ return;
+ }
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 && (field_count < 2 || !auto_layout));
+ union_type->zero_bits = (gen_field_index == 0 && (field_count < 2 || !src_have_tag));
union_type->data.unionation.zero_bits_known = true;
// also compute abi_alignment
@@ -2848,7 +2872,6 @@ TypeTableEntry *validate_var_type(CodeGen *g, AstNode *source_node, TypeTableEnt
case TypeTableEntryIdUnion:
case TypeTableEntryIdFn:
case TypeTableEntryIdBoundFn:
- case TypeTableEntryIdEnumTag:
return type_entry;
}
zig_unreachable();
@@ -3265,19 +3288,20 @@ TypeUnionField *find_union_type_field(TypeTableEntry *type_entry, Buf *name) {
assert(type_entry->data.unionation.complete);
for (uint32_t i = 0; i < type_entry->data.unionation.src_field_count; i += 1) {
TypeUnionField *field = &type_entry->data.unionation.fields[i];
- if (buf_eql_buf(field->name, name)) {
+ if (buf_eql_buf(field->enum_field->name, name)) {
return field;
}
}
return nullptr;
}
-static TypeUnionField *find_union_field_by_tag(TypeTableEntry *type_entry, const BigInt *tag) {
+TypeUnionField *find_union_field_by_tag(TypeTableEntry *type_entry, const BigInt *tag) {
assert(type_entry->id == TypeTableEntryIdUnion);
assert(type_entry->data.unionation.complete);
+ assert(type_entry->data.unionation.gen_tag_index != SIZE_MAX);
for (uint32_t i = 0; i < type_entry->data.unionation.src_field_count; i += 1) {
TypeUnionField *field = &type_entry->data.unionation.fields[i];
- if (bigint_cmp(&field->value, tag) == CmpEQ) {
+ if (bigint_cmp(&field->enum_field->value, tag) == CmpEQ) {
return field;
}
}
@@ -3323,7 +3347,6 @@ static bool is_container(TypeTableEntry *type_entry) {
case TypeTableEntryIdNamespace:
case TypeTableEntryIdBlock:
case TypeTableEntryIdBoundFn:
- case TypeTableEntryIdEnumTag:
case TypeTableEntryIdArgTuple:
case TypeTableEntryIdOpaque:
return false;
@@ -3374,7 +3397,6 @@ void resolve_container_type(CodeGen *g, TypeTableEntry *type_entry) {
case TypeTableEntryIdBoundFn:
case TypeTableEntryIdInvalid:
case TypeTableEntryIdVar:
- case TypeTableEntryIdEnumTag:
case TypeTableEntryIdArgTuple:
case TypeTableEntryIdOpaque:
zig_unreachable();
@@ -3828,7 +3850,7 @@ bool handle_is_ptr(TypeTableEntry *type_entry) {
case TypeTableEntryIdPointer:
case TypeTableEntryIdPureError:
case TypeTableEntryIdFn:
- case TypeTableEntryIdEnumTag:
+ case TypeTableEntryIdEnum:
return false;
case TypeTableEntryIdArray:
case TypeTableEntryIdStruct:
@@ -3836,9 +3858,6 @@ bool handle_is_ptr(TypeTableEntry *type_entry) {
return type_has_bits(type_entry);
case TypeTableEntryIdErrorUnion:
return type_has_bits(type_entry->data.error.child_type);
- case TypeTableEntryIdEnum:
- assert(type_entry->data.enumeration.complete);
- return type_entry->data.enumeration.gen_field_count != 0;
case TypeTableEntryIdMaybe:
return type_has_bits(type_entry->data.maybe.child_type) &&
type_entry->data.maybe.child_type->id != TypeTableEntryIdPointer &&
@@ -3980,7 +3999,6 @@ static uint32_t hash_const_val(ConstExprValue *const_val) {
return (uint32_t)4149439618;
case TypeTableEntryIdInt:
case TypeTableEntryIdNumLitInt:
- case TypeTableEntryIdEnumTag:
{
uint32_t result = 1331471175;
for (size_t i = 0; i < const_val->data.x_bigint.digit_count; i += 1) {
@@ -3989,6 +4007,15 @@ static uint32_t hash_const_val(ConstExprValue *const_val) {
}
return result;
}
+ case TypeTableEntryIdEnum:
+ {
+ uint32_t result = 31643936;
+ for (size_t i = 0; i < const_val->data.x_enum_tag.digit_count; i += 1) {
+ uint64_t digit = bigint_ptr(&const_val->data.x_enum_tag)[i];
+ result ^= ((uint32_t)(digit >> 32)) ^ (uint32_t)(result);
+ }
+ return result;
+ }
case TypeTableEntryIdFloat:
switch (const_val->type->data.floating.bit_count) {
case 32:
@@ -4089,9 +4116,6 @@ static uint32_t hash_const_val(ConstExprValue *const_val) {
case TypeTableEntryIdPureError:
// TODO better hashing algorithm
return 2630160122;
- case TypeTableEntryIdEnum:
- // TODO better hashing algorithm
- return 31643936;
case TypeTableEntryIdFn:
return 4133894920 ^ hash_ptr(const_val->data.x_fn.fn_entry);
case TypeTableEntryIdNamespace:
@@ -4224,7 +4248,6 @@ bool type_requires_comptime(TypeTableEntry *type_entry) {
case TypeTableEntryIdInt:
case TypeTableEntryIdFloat:
case TypeTableEntryIdPointer:
- case TypeTableEntryIdEnumTag:
case TypeTableEntryIdVoid:
case TypeTableEntryIdUnreachable:
return false;
@@ -4295,6 +4318,7 @@ ConstExprValue *create_const_bigint(TypeTableEntry *type, const BigInt *bigint)
return const_val;
}
+
void init_const_unsigned_negative(ConstExprValue *const_val, TypeTableEntry *type, uint64_t x, bool negative) {
const_val->special = ConstValSpecialStatic;
const_val->type = type;
@@ -4358,18 +4382,19 @@ ConstExprValue *create_const_float(TypeTableEntry *type, double value) {
return const_val;
}
-void init_const_enum_tag(ConstExprValue *const_val, TypeTableEntry *type, const BigInt *tag) {
+void init_const_enum(ConstExprValue *const_val, TypeTableEntry *type, const BigInt *tag) {
const_val->special = ConstValSpecialStatic;
const_val->type = type;
- bigint_init_bigint(&const_val->data.x_enum.tag, tag);
+ bigint_init_bigint(&const_val->data.x_enum_tag, tag);
}
-ConstExprValue *create_const_enum_tag(TypeTableEntry *type, const BigInt *tag) {
+ConstExprValue *create_const_enum(TypeTableEntry *type, const BigInt *tag) {
ConstExprValue *const_val = create_const_vals(1);
- init_const_enum_tag(const_val, type, tag);
+ init_const_enum(const_val, type, tag);
return const_val;
}
+
void init_const_bool(CodeGen *g, ConstExprValue *const_val, bool value) {
const_val->special = ConstValSpecialStatic;
const_val->type = g->builtin_types.entry_bool;
@@ -4567,20 +4592,8 @@ bool const_values_equal(ConstExprValue *a, ConstExprValue *b) {
switch (a->type->id) {
case TypeTableEntryIdOpaque:
zig_unreachable();
- case TypeTableEntryIdEnum: {
- ConstEnumValue *enum1 = &a->data.x_enum;
- ConstEnumValue *enum2 = &b->data.x_enum;
- if (bigint_cmp(&enum1->tag, &enum2->tag) == CmpEQ) {
- TypeEnumField *field = find_enum_field_by_tag(a->type, &enum1->tag);
- assert(field != nullptr);
- if (type_has_bits(field->type_entry)) {
- zig_panic("TODO const expr analyze enum field value for equality");
- } else {
- return true;
- }
- }
- return false;
- }
+ case TypeTableEntryIdEnum:
+ return bigint_cmp(&a->data.x_enum_tag, &b->data.x_enum_tag) == CmpEQ;
case TypeTableEntryIdUnion: {
ConstUnionValue *union1 = &a->data.x_union;
ConstUnionValue *union2 = &b->data.x_union;
@@ -4622,7 +4635,6 @@ bool const_values_equal(ConstExprValue *a, ConstExprValue *b) {
return bigfloat_cmp(&a->data.x_bigfloat, &b->data.x_bigfloat) == CmpEQ;
case TypeTableEntryIdInt:
case TypeTableEntryIdNumLitInt:
- case TypeTableEntryIdEnumTag:
return bigint_cmp(&a->data.x_bigint, &b->data.x_bigint) == CmpEQ;
case TypeTableEntryIdPointer:
if (a->data.x_ptr.special != b->data.x_ptr.special)
@@ -4949,7 +4961,8 @@ void render_const_value(CodeGen *g, Buf *buf, ConstExprValue *const_val) {
}
case TypeTableEntryIdEnum:
{
- buf_appendf(buf, "(enum %s constant)", buf_ptr(&type_entry->name));
+ TypeEnumField *field = find_enum_field_by_tag(type_entry, &const_val->data.x_enum_tag);
+ buf_appendf(buf, "%s.%s", buf_ptr(&type_entry->name), buf_ptr(field->name));
return;
}
case TypeTableEntryIdErrorUnion:
@@ -4967,14 +4980,6 @@ void render_const_value(CodeGen *g, Buf *buf, ConstExprValue *const_val) {
buf_appendf(buf, "(pure error constant)");
return;
}
- case TypeTableEntryIdEnumTag:
- {
- TypeTableEntry *enum_type = type_entry->data.enum_tag.enum_type;
- size_t field_index = bigint_as_unsigned(&const_val->data.x_bigint);
- TypeEnumField *field = &enum_type->data.enumeration.fields[field_index];
- buf_appendf(buf, "%s.%s", buf_ptr(&enum_type->name), buf_ptr(field->name));
- return;
- }
case TypeTableEntryIdArgTuple:
{
buf_appendf(buf, "(args value)");
@@ -5036,7 +5041,6 @@ uint32_t type_id_hash(TypeId x) {
case TypeTableEntryIdErrorUnion:
case TypeTableEntryIdPureError:
case TypeTableEntryIdEnum:
- case TypeTableEntryIdEnumTag:
case TypeTableEntryIdUnion:
case TypeTableEntryIdFn:
case TypeTableEntryIdNamespace:
@@ -5081,7 +5085,6 @@ bool type_id_eql(TypeId a, TypeId b) {
case TypeTableEntryIdErrorUnion:
case TypeTableEntryIdPureError:
case TypeTableEntryIdEnum:
- case TypeTableEntryIdEnumTag:
case TypeTableEntryIdUnion:
case TypeTableEntryIdFn:
case TypeTableEntryIdNamespace:
@@ -5196,7 +5199,6 @@ static const TypeTableEntryId all_type_ids[] = {
TypeTableEntryIdErrorUnion,
TypeTableEntryIdPureError,
TypeTableEntryIdEnum,
- TypeTableEntryIdEnumTag,
TypeTableEntryIdUnion,
TypeTableEntryIdFn,
TypeTableEntryIdNamespace,
@@ -5254,22 +5256,20 @@ size_t type_id_index(TypeTableEntryId id) {
return 15;
case TypeTableEntryIdEnum:
return 16;
- case TypeTableEntryIdEnumTag:
- return 17;
case TypeTableEntryIdUnion:
- return 18;
+ return 17;
case TypeTableEntryIdFn:
- return 19;
+ return 18;
case TypeTableEntryIdNamespace:
- return 20;
+ return 19;
case TypeTableEntryIdBlock:
- return 21;
+ return 20;
case TypeTableEntryIdBoundFn:
- return 22;
+ return 21;
case TypeTableEntryIdArgTuple:
- return 23;
+ return 22;
case TypeTableEntryIdOpaque:
- return 24;
+ return 23;
}
zig_unreachable();
}
@@ -5313,8 +5313,6 @@ const char *type_id_name(TypeTableEntryId id) {
return "Error";
case TypeTableEntryIdEnum:
return "Enum";
- case TypeTableEntryIdEnumTag:
- return "EnumTag";
case TypeTableEntryIdUnion:
return "Union";
case TypeTableEntryIdFn:
@@ -5381,9 +5379,6 @@ uint32_t get_abi_alignment(CodeGen *g, TypeTableEntry *type_entry) {
if (type_entry->id == TypeTableEntryIdStruct) {
assert(type_entry->data.structure.abi_alignment != 0);
return type_entry->data.structure.abi_alignment;
- } else if (type_entry->id == TypeTableEntryIdEnum) {
- assert(type_entry->data.enumeration.abi_alignment != 0);
- return type_entry->data.enumeration.abi_alignment;
} else if (type_entry->id == TypeTableEntryIdUnion) {
assert(type_entry->data.unionation.abi_alignment != 0);
return type_entry->data.unionation.abi_alignment;