diff options
| author | Vexu <git@vexu.eu> | 2020-01-16 22:48:01 +0200 |
|---|---|---|
| committer | Vexu <git@vexu.eu> | 2020-01-16 22:52:10 +0200 |
| commit | 6c8f01dcde03380806338758d489c3f2a78e5b5b (patch) | |
| tree | 138593beebb1e6712b56d3e35e7d299ce54ef962 /src/analyze.cpp | |
| parent | 6450736c5f9039565802e1f898a8fd402ba12c63 (diff) | |
| download | zig-6c8f01dcde03380806338758d489c3f2a78e5b5b.tar.gz zig-6c8f01dcde03380806338758d489c3f2a78e5b5b.zip | |
correct field count
Diffstat (limited to 'src/analyze.cpp')
| -rw-r--r-- | src/analyze.cpp | 60 |
1 files changed, 31 insertions, 29 deletions
diff --git a/src/analyze.cpp b/src/analyze.cpp index 18dc7e032c..e064677a09 100644 --- a/src/analyze.cpp +++ b/src/analyze.cpp @@ -2569,16 +2569,8 @@ static Error resolve_enum_zero_bits(CodeGen *g, ZigType *enum_type) { return ErrorSemanticAnalyzeFail; } - enum_type->data.enumeration.src_field_count = field_count; - enum_type->data.enumeration.fields = allocate<TypeEnumField>(field_count); - enum_type->data.enumeration.fields_by_name.init(field_count); - enum_type->data.enumeration.non_exhaustive = false; - Scope *scope = &enum_type->data.enumeration.decls_scope->base; - HashMap<BigInt, AstNode *, bigint_hash, bigint_eql> occupied_tag_values = {}; - occupied_tag_values.init(field_count); - ZigType *tag_int_type; if (enum_type->data.enumeration.layout == ContainerLayoutExtern) { tag_int_type = get_c_int_type(g, CIntTypeInt); @@ -2620,6 +2612,7 @@ static Error resolve_enum_zero_bits(CodeGen *g, ZigType *enum_type) { } } + enum_type->data.enumeration.non_exhaustive = false; enum_type->data.enumeration.tag_int_type = tag_int_type; enum_type->size_in_bits = tag_int_type->size_in_bits; enum_type->abi_size = tag_int_type->abi_size; @@ -2628,6 +2621,31 @@ static Error resolve_enum_zero_bits(CodeGen *g, ZigType *enum_type) { BigInt bi_one; bigint_init_unsigned(&bi_one, 1); + AstNode *last_field_node = decl_node->data.container_decl.fields.at(field_count - 1); + if (buf_eql_str(last_field_node->data.struct_field.name, "_")) { + field_count -= 1; + if (field_count > 1 && log2_u64(field_count) == enum_type->size_in_bits) { + add_node_error(g, last_field_node, buf_sprintf("non-exhaustive enum specifies every value")); + enum_type->data.enumeration.resolve_status = ResolveStatusInvalid; + } + if (decl_node->data.container_decl.init_arg_expr == nullptr) { + add_node_error(g, last_field_node, buf_sprintf("non-exhaustive enum must specify size")); + enum_type->data.enumeration.resolve_status = ResolveStatusInvalid; + } + if (last_field_node->data.struct_field.value != nullptr) { + add_node_error(g, last_field_node, buf_sprintf("value assigned to '_' field of non-exhaustive enum")); + enum_type->data.enumeration.resolve_status = ResolveStatusInvalid; + } + enum_type->data.enumeration.non_exhaustive = true; + } + + enum_type->data.enumeration.src_field_count = field_count; + enum_type->data.enumeration.fields = allocate<TypeEnumField>(field_count); + enum_type->data.enumeration.fields_by_name.init(field_count); + + HashMap<BigInt, AstNode *, bigint_hash, bigint_eql> occupied_tag_values = {}; + occupied_tag_values.init(field_count); + TypeEnumField *last_enum_field = nullptr; for (uint32_t field_i = 0; field_i < field_count; field_i += 1) { @@ -2649,27 +2667,9 @@ static Error resolve_enum_zero_bits(CodeGen *g, ZigType *enum_type) { buf_sprintf("consider 'union(enum)' here")); } - AstNode *tag_value = field_node->data.struct_field.value; - if (buf_eql_str(type_enum_field->name, "_")) { - if (decl_node->data.container_decl.init_arg_expr == nullptr) { - add_node_error(g, field_node, buf_sprintf("non-exhaustive enum must specify size")); - enum_type->data.enumeration.resolve_status = ResolveStatusInvalid; - } - if (field_count > 1 && log2_u64(field_count - 1) == enum_type->size_in_bits) { - add_node_error(g, field_node, buf_sprintf("non-exhaustive enum specifies every value")); - enum_type->data.enumeration.resolve_status = ResolveStatusInvalid; - } - if (field_i != field_count - 1) { - add_node_error(g, field_node, buf_sprintf("'_' field of non-exhaustive enum must be last")); - enum_type->data.enumeration.resolve_status = ResolveStatusInvalid; - } - if (tag_value != nullptr) { - add_node_error(g, field_node, buf_sprintf("value assigned to '_' field of non-exhaustive enum")); - enum_type->data.enumeration.resolve_status = ResolveStatusInvalid; - } - enum_type->data.enumeration.non_exhaustive = true; - continue; + add_node_error(g, field_node, buf_sprintf("'_' field of non-exhaustive enum must be last")); + enum_type->data.enumeration.resolve_status = ResolveStatusInvalid; } auto field_entry = enum_type->data.enumeration.fields_by_name.put_unique(type_enum_field->name, type_enum_field); @@ -2681,6 +2681,8 @@ static Error resolve_enum_zero_bits(CodeGen *g, ZigType *enum_type) { continue; } + AstNode *tag_value = field_node->data.struct_field.value; + if (tag_value != nullptr) { // A user-specified value is available ZigValue *result = analyze_const_value(g, scope, tag_value, tag_int_type, @@ -3293,7 +3295,7 @@ static Error resolve_union_zero_bits(CodeGen *g, ZigType *union_type) { } 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] && !buf_eql_str(enum_field->name, "_")) { + 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, |
