| author | |
| committer | |
| log | fdadab40c61a6f70a65472cc95ccd5ba52c01772 |
| tree | f471173c1e54a3cd4e35759970adfcd36c991c0b |
| parent | 3a9009b08e278dafd7b59b7d09408c80ea67f1fe |
4 files changed, 41 insertions(+), 3 deletions(-)
src/all_types.hpp+1| ... | ... | @@ -859,6 +859,7 @@ struct TypeTableEntryEnum { |
| 859 | 859 | TypeEnumField *fields; |
| 860 | 860 | bool is_invalid; // true if any fields are invalid |
| 861 | 861 | TypeTableEntry *tag_type; |
| 862 | TypeTableEntry *union_type; | |
| 862 | 863 | |
| 863 | 864 | // reminder: hash tables must be initialized before use |
| 864 | 865 | HashMap<Buf *, FnTableEntry *, buf_hash, buf_eql_buf> fn_table; |
src/analyze.cpp+4| ... | ... | @@ -973,6 +973,7 @@ static void resolve_enum_type(CodeGen *g, ImportTableEntry *import, TypeTableEnt |
| 973 | 973 | |
| 974 | 974 | if (!enum_type->data.enumeration.is_invalid) { |
| 975 | 975 | enum_type->data.enumeration.gen_field_count = gen_field_index; |
| 976 | enum_type->data.enumeration.union_type = biggest_union_member; | |
| 976 | 977 | |
| 977 | 978 | TypeTableEntry *tag_type_entry = get_smallest_unsigned_int_type(g, field_count); |
| 978 | 979 | enum_type->data.enumeration.tag_type = tag_type_entry; |
| ... | ... | @@ -2034,6 +2035,9 @@ static TypeTableEntry *analyze_enum_value_expr(CodeGen *g, ImportTableEntry *imp |
| 2034 | 2035 | codegen->type_entry = enum_type; |
| 2035 | 2036 | codegen->source_node = field_access_node; |
| 2036 | 2037 | context->struct_val_expr_alloca_list.append(codegen); |
| 2038 | ||
| 2039 | Expr *expr = get_resolved_expr(field_access_node); | |
| 2040 | expr->const_val.ok = false; | |
| 2037 | 2041 | } else if (type_enum_field->type_entry->id != TypeTableEntryIdVoid) { |
| 2038 | 2042 | add_node_error(g, field_access_node, |
| 2039 | 2043 | buf_sprintf("enum value '%s.%s' requires parameter of type '%s'", |
src/codegen.cpp+14-1| ... | ... | @@ -2567,7 +2567,20 @@ static LLVMValueRef gen_const_val(CodeGen *g, TypeTableEntry *type_entry, ConstE |
| 2567 | 2567 | if (type_entry->data.enumeration.gen_field_count == 0) { |
| 2568 | 2568 | return tag_value; |
| 2569 | 2569 | } else { |
| 2570 | zig_panic("TODO"); | |
| 2570 | TypeTableEntry *union_type = type_entry->data.enumeration.union_type; | |
| 2571 | TypeEnumField *enum_field = &type_entry->data.enumeration.fields[const_val->data.x_enum.tag]; | |
| 2572 | assert(enum_field->value == const_val->data.x_enum.tag); | |
| 2573 | LLVMValueRef union_value; | |
| 2574 | if (type_has_bits(enum_field->type_entry)) { | |
| 2575 | union_value = gen_const_val(g, union_type, const_val->data.x_enum.payload); | |
| 2576 | } else { | |
| 2577 | union_value = LLVMGetUndef(union_type->type_ref); | |
| 2578 | } | |
| 2579 | LLVMValueRef fields[] = { | |
| 2580 | tag_value, | |
| 2581 | union_value, | |
| 2582 | }; | |
| 2583 | return LLVMConstNamedStruct(type_entry->type_ref, fields, 2); | |
| 2571 | 2584 | } |
| 2572 | 2585 | } |
| 2573 | 2586 | case TypeTableEntryIdFn: |
test/self_hosted.zig+22-2| ... | ... | @@ -38,11 +38,31 @@ fn call_struct_field(foo: Foo) -> i32 { |
| 38 | 38 | |
| 39 | 39 | |
| 40 | 40 | |
| 41 | #attribute("test") | |
| 42 | fn redefinition_of_error_values_allowed() { | |
| 43 | if (error.AnError == error.SecondError) unreachable{} | |
| 44 | } | |
| 41 | 45 | error AnError; |
| 42 | 46 | error AnError; |
| 43 | 47 | error SecondError; |
| 44 | 48 | |
| 49 | ||
| 50 | ||
| 51 | ||
| 45 | 52 | #attribute("test") |
| 46 | fn redefinition_of_error_values_allowed() { | |
| 47 | if (error.AnError == error.SecondError) unreachable{} | |
| 53 | fn constant_enum_with_payload() { | |
| 54 | should_be_empty(AnEnumWithPayload.Empty); | |
| 55 | should_be_13(AnEnumWithPayload.Full(13)); | |
| 56 | } | |
| 57 | ||
| 58 | fn should_be_empty(x: AnEnumWithPayload) { | |
| 59 | if (x != AnEnumWithPayload.Empty) unreachable{} | |
| 60 | } | |
| 61 | ||
| 62 | fn should_be_13(x: AnEnumWithPayload) { | |
| 63 | } | |
| 64 | ||
| 65 | enum AnEnumWithPayload { | |
| 66 | Empty, | |
| 67 | Full: i32, | |
| 48 | 68 | } |