| ... | @@ -2005,15 +2005,6 @@ static Error resolve_enum_zero_bits(CodeGen *g, ZigType *enum_type) { | ... | @@ -2005,15 +2005,6 @@ static Error resolve_enum_zero_bits(CodeGen *g, ZigType *enum_type) { |
| 2005 | buf_ptr(&wanted_tag_int_type->name))); | 2005 | buf_ptr(&wanted_tag_int_type->name))); |
| 2006 | add_error_note(g, msg, decl_node->data.container_decl.init_arg_expr, | 2006 | add_error_note(g, msg, decl_node->data.container_decl.init_arg_expr, |
| 2007 | buf_sprintf("valid types are 'i8', 'c_int' and 'c_uint' or compatible types")); | 2007 | buf_sprintf("valid types are 'i8', 'c_int' and 'c_uint' or compatible types")); |
| 2008 | } else if (wanted_tag_int_type->data.integral.is_signed) { | | |
| 2009 | enum_type->data.enumeration.is_invalid = true; | | |
| 2010 | add_node_error(g, decl_node->data.container_decl.init_arg_expr, | | |
| 2011 | buf_sprintf("expected unsigned integer, found '%s'", buf_ptr(&wanted_tag_int_type->name))); | | |
| 2012 | } else if (wanted_tag_int_type->data.integral.bit_count < tag_int_type->data.integral.bit_count) { | | |
| 2013 | enum_type->data.enumeration.is_invalid = true; | | |
| 2014 | add_node_error(g, decl_node->data.container_decl.init_arg_expr, | | |
| 2015 | buf_sprintf("'%s' too small to hold all bits; must be at least '%s'", | | |
| 2016 | buf_ptr(&wanted_tag_int_type->name), buf_ptr(&tag_int_type->name))); | | |
| 2017 | } else { | 2008 | } else { |
| 2018 | tag_int_type = wanted_tag_int_type; | 2009 | tag_int_type = wanted_tag_int_type; |
| 2019 | } | 2010 | } |
| ... | @@ -2078,30 +2069,46 @@ static Error resolve_enum_zero_bits(CodeGen *g, ZigType *enum_type) { | ... | @@ -2078,30 +2069,46 @@ static Error resolve_enum_zero_bits(CodeGen *g, ZigType *enum_type) { |
| 2078 | } | 2069 | } |
| 2079 | | 2070 | |
| 2080 | // Now iterate again and populate the unspecified tag values | 2071 | // Now iterate again and populate the unspecified tag values |
| 2081 | uint32_t next_maybe_unoccupied_index = 0; | 2072 | BigInt next_maybe_unoccupied_index; |
| | 2073 | bigint_init_unsigned(&next_maybe_unoccupied_index, 0); |
| | 2074 | |
| | 2075 | // Since we're allocating positive values only we have one less bit |
| | 2076 | // available if the tag type is signed (eg. for a i8 we can only use (0,127)) |
| | 2077 | unsigned tag_bit_width = tag_int_type->size_in_bits; |
| | 2078 | if (tag_int_type->data.integral.is_signed) |
| | 2079 | tag_bit_width--; |
| 2082 | | 2080 | |
| 2083 | for (uint32_t field_i = 0; field_i < field_count; field_i += 1) { | 2081 | for (uint32_t field_i = 0; field_i < field_count; field_i += 1) { |
| 2084 | AstNode *field_node = decl_node->data.container_decl.fields.at(field_i); | 2082 | AstNode *field_node = decl_node->data.container_decl.fields.at(field_i); |
| 2085 | TypeEnumField *type_enum_field = &enum_type->data.enumeration.fields[field_i]; | 2083 | TypeEnumField *type_enum_field = &enum_type->data.enumeration.fields[field_i]; |
| 2086 | AstNode *tag_value = field_node->data.struct_field.value; | 2084 | AstNode *tag_value = field_node->data.struct_field.value; |
| 2087 | | 2085 | |
| 2088 | if (tag_value == nullptr) { | 2086 | // Already handled in the loop above |
| 2089 | if (occupied_tag_values.size() == 0) { | 2087 | if (tag_value != nullptr) |
| 2090 | bigint_init_unsigned(&type_enum_field->value, next_maybe_unoccupied_index); | 2088 | continue; |
| 2091 | next_maybe_unoccupied_index += 1; | 2089 | |
| 2092 | } else { | 2090 | // Make sure we can represent this number with tag_int_type |
| 2093 | BigInt proposed_value; | 2091 | const unsigned repr_bits = bigint_bits_needed(&next_maybe_unoccupied_index); |
| 2094 | for (;;) { | 2092 | if (repr_bits > tag_bit_width) { |
| 2095 | bigint_init_unsigned(&proposed_value, next_maybe_unoccupied_index); | 2093 | enum_type->data.enumeration.is_invalid = true; |
| 2096 | next_maybe_unoccupied_index += 1; | 2094 | add_node_error(g, field_node, |
| 2097 | auto entry = occupied_tag_values.put_unique(proposed_value, field_node); | 2095 | buf_sprintf("enumeration value %" ZIG_PRI_u64 " too large for type '%s'", |
| 2098 | if (entry != nullptr) { | 2096 | bigint_as_unsigned(&next_maybe_unoccupied_index), |
| 2099 | continue; | 2097 | buf_ptr(&tag_int_type->name))); |
| 2100 | } | 2098 | break; |
| | 2099 | } |
| | 2100 | |
| | 2101 | if (occupied_tag_values.size() == 0) { |
| | 2102 | type_enum_field->value = next_maybe_unoccupied_index; |
| | 2103 | bigint_incr(&next_maybe_unoccupied_index); |
| | 2104 | } else { |
| | 2105 | for (;;) { |
| | 2106 | auto entry = occupied_tag_values.put_unique(next_maybe_unoccupied_index, field_node); |
| | 2107 | if (entry == nullptr) |
| 2101 | break; | 2108 | break; |
| 2102 | } | 2109 | bigint_incr(&next_maybe_unoccupied_index); |
| 2103 | bigint_init_bigint(&type_enum_field->value, &proposed_value); | | |
| 2104 | } | 2110 | } |
| | 2111 | type_enum_field->value = next_maybe_unoccupied_index; |
| 2105 | } | 2112 | } |
| 2106 | } | 2113 | } |
| 2107 | | 2114 | |