diff options
| author | Andrew Kelley <andrew@ziglang.org> | 2020-01-22 12:12:36 -0500 |
|---|---|---|
| committer | Andrew Kelley <andrew@ziglang.org> | 2020-01-22 12:12:36 -0500 |
| commit | 97b2ac598b91194c09a96c9ed86e4f9b266d019c (patch) | |
| tree | f8ddd18aaf3a52981f3a97faeac8ef7bd20e6908 /src/analyze.cpp | |
| parent | 7e674d6761c057985003694f98861f589b6cf313 (diff) | |
| parent | c522699f28c1df806865c527a7a68a875e606527 (diff) | |
| download | zig-97b2ac598b91194c09a96c9ed86e4f9b266d019c.tar.gz zig-97b2ac598b91194c09a96c9ed86e4f9b266d019c.zip | |
Merge remote-tracking branch 'origin/master' into llvm10
Diffstat (limited to 'src/analyze.cpp')
| -rw-r--r-- | src/analyze.cpp | 42 |
1 files changed, 33 insertions, 9 deletions
diff --git a/src/analyze.cpp b/src/analyze.cpp index b7838003c8..638b0b03b0 100644 --- a/src/analyze.cpp +++ b/src/analyze.cpp @@ -2569,15 +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); - 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); @@ -2612,13 +2605,14 @@ static Error resolve_enum_zero_bits(CodeGen *g, ZigType *enum_type) { buf_ptr(&wanted_tag_int_type->name))); add_error_note(g, msg, decl_node->data.container_decl.init_arg_expr, buf_sprintf("any integral type of size 8, 16, 32, 64 or 128 bit is valid")); - return ErrorNone; + return ErrorSemanticAnalyzeFail; } } tag_int_type = wanted_tag_int_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; @@ -2627,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) { @@ -2648,6 +2667,11 @@ static Error resolve_enum_zero_bits(CodeGen *g, ZigType *enum_type) { buf_sprintf("consider 'union(enum)' here")); } + if (buf_eql_str(type_enum_field->name, "_")) { + 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); if (field_entry != nullptr) { ErrorMsg *msg = add_node_error(g, field_node, @@ -8288,7 +8312,7 @@ static void resolve_llvm_types_enum(CodeGen *g, ZigType *enum_type, ResolveStatu uint32_t field_count = enum_type->data.enumeration.src_field_count; - assert(enum_type->data.enumeration.fields); + assert(field_count == 0 || enum_type->data.enumeration.fields != nullptr); ZigLLVMDIEnumerator **di_enumerators = allocate<ZigLLVMDIEnumerator*>(field_count); for (uint32_t i = 0; i < field_count; i += 1) { |
