aboutsummaryrefslogtreecommitdiff
path: root/src/analyze.cpp
diff options
context:
space:
mode:
authorAndrew Kelley <andrew@ziglang.org>2020-01-22 12:12:36 -0500
committerAndrew Kelley <andrew@ziglang.org>2020-01-22 12:12:36 -0500
commit97b2ac598b91194c09a96c9ed86e4f9b266d019c (patch)
treef8ddd18aaf3a52981f3a97faeac8ef7bd20e6908 /src/analyze.cpp
parent7e674d6761c057985003694f98861f589b6cf313 (diff)
parentc522699f28c1df806865c527a7a68a875e606527 (diff)
downloadzig-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.cpp42
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) {