authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2016-02-04 02:11:50-07:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2016-02-04 02:11:50-07:00
logfdadab40c61a6f70a65472cc95ccd5ba52c01772
treef471173c1e54a3cd4e35759970adfcd36c991c0b
parent3a9009b08e278dafd7b59b7d09408c80ea67f1fe

implement constant values for enums with payload


4 files changed, 41 insertions(+), 3 deletions(-)

src/all_types.hpp+1
......@@ -859,6 +859,7 @@ struct TypeTableEntryEnum {
859859 TypeEnumField *fields;
860860 bool is_invalid; // true if any fields are invalid
861861 TypeTableEntry *tag_type;
862 TypeTableEntry *union_type;
862863
863864 // reminder: hash tables must be initialized before use
864865 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
973973
974974 if (!enum_type->data.enumeration.is_invalid) {
975975 enum_type->data.enumeration.gen_field_count = gen_field_index;
976 enum_type->data.enumeration.union_type = biggest_union_member;
976977
977978 TypeTableEntry *tag_type_entry = get_smallest_unsigned_int_type(g, field_count);
978979 enum_type->data.enumeration.tag_type = tag_type_entry;
......@@ -2034,6 +2035,9 @@ static TypeTableEntry *analyze_enum_value_expr(CodeGen *g, ImportTableEntry *imp
20342035 codegen->type_entry = enum_type;
20352036 codegen->source_node = field_access_node;
20362037 context->struct_val_expr_alloca_list.append(codegen);
2038
2039 Expr *expr = get_resolved_expr(field_access_node);
2040 expr->const_val.ok = false;
20372041 } else if (type_enum_field->type_entry->id != TypeTableEntryIdVoid) {
20382042 add_node_error(g, field_access_node,
20392043 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
25672567 if (type_entry->data.enumeration.gen_field_count == 0) {
25682568 return tag_value;
25692569 } 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);
25712584 }
25722585 }
25732586 case TypeTableEntryIdFn:
test/self_hosted.zig+22-2
......@@ -38,11 +38,31 @@ fn call_struct_field(foo: Foo) -> i32 {
3838
3939
4040
41#attribute("test")
42fn redefinition_of_error_values_allowed() {
43 if (error.AnError == error.SecondError) unreachable{}
44}
4145error AnError;
4246error AnError;
4347error SecondError;
4448
49
50
51
4552#attribute("test")
46fn redefinition_of_error_values_allowed() {
47 if (error.AnError == error.SecondError) unreachable{}
53fn constant_enum_with_payload() {
54 should_be_empty(AnEnumWithPayload.Empty);
55 should_be_13(AnEnumWithPayload.Full(13));
56}
57
58fn should_be_empty(x: AnEnumWithPayload) {
59 if (x != AnEnumWithPayload.Empty) unreachable{}
60}
61
62fn should_be_13(x: AnEnumWithPayload) {
63}
64
65enum AnEnumWithPayload {
66 Empty,
67 Full: i32,
4868}