mirror of
https://github.com/ziglang/zig.git
synced 2024-12-03 10:28:48 +00:00
implement constant values for enums with payload
This commit is contained in:
parent
3a9009b08e
commit
fdadab40c6
@ -859,6 +859,7 @@ struct TypeTableEntryEnum {
|
||||
TypeEnumField *fields;
|
||||
bool is_invalid; // true if any fields are invalid
|
||||
TypeTableEntry *tag_type;
|
||||
TypeTableEntry *union_type;
|
||||
|
||||
// reminder: hash tables must be initialized before use
|
||||
HashMap<Buf *, FnTableEntry *, buf_hash, buf_eql_buf> fn_table;
|
||||
|
@ -973,6 +973,7 @@ static void resolve_enum_type(CodeGen *g, ImportTableEntry *import, TypeTableEnt
|
||||
|
||||
if (!enum_type->data.enumeration.is_invalid) {
|
||||
enum_type->data.enumeration.gen_field_count = gen_field_index;
|
||||
enum_type->data.enumeration.union_type = biggest_union_member;
|
||||
|
||||
TypeTableEntry *tag_type_entry = get_smallest_unsigned_int_type(g, field_count);
|
||||
enum_type->data.enumeration.tag_type = tag_type_entry;
|
||||
@ -2034,6 +2035,9 @@ static TypeTableEntry *analyze_enum_value_expr(CodeGen *g, ImportTableEntry *imp
|
||||
codegen->type_entry = enum_type;
|
||||
codegen->source_node = field_access_node;
|
||||
context->struct_val_expr_alloca_list.append(codegen);
|
||||
|
||||
Expr *expr = get_resolved_expr(field_access_node);
|
||||
expr->const_val.ok = false;
|
||||
} else if (type_enum_field->type_entry->id != TypeTableEntryIdVoid) {
|
||||
add_node_error(g, field_access_node,
|
||||
buf_sprintf("enum value '%s.%s' requires parameter of type '%s'",
|
||||
|
@ -2567,7 +2567,20 @@ static LLVMValueRef gen_const_val(CodeGen *g, TypeTableEntry *type_entry, ConstE
|
||||
if (type_entry->data.enumeration.gen_field_count == 0) {
|
||||
return tag_value;
|
||||
} else {
|
||||
zig_panic("TODO");
|
||||
TypeTableEntry *union_type = type_entry->data.enumeration.union_type;
|
||||
TypeEnumField *enum_field = &type_entry->data.enumeration.fields[const_val->data.x_enum.tag];
|
||||
assert(enum_field->value == const_val->data.x_enum.tag);
|
||||
LLVMValueRef union_value;
|
||||
if (type_has_bits(enum_field->type_entry)) {
|
||||
union_value = gen_const_val(g, union_type, const_val->data.x_enum.payload);
|
||||
} else {
|
||||
union_value = LLVMGetUndef(union_type->type_ref);
|
||||
}
|
||||
LLVMValueRef fields[] = {
|
||||
tag_value,
|
||||
union_value,
|
||||
};
|
||||
return LLVMConstNamedStruct(type_entry->type_ref, fields, 2);
|
||||
}
|
||||
}
|
||||
case TypeTableEntryIdFn:
|
||||
|
@ -38,11 +38,31 @@ fn call_struct_field(foo: Foo) -> i32 {
|
||||
|
||||
|
||||
|
||||
error AnError;
|
||||
error AnError;
|
||||
error SecondError;
|
||||
|
||||
#attribute("test")
|
||||
fn redefinition_of_error_values_allowed() {
|
||||
if (error.AnError == error.SecondError) unreachable{}
|
||||
}
|
||||
error AnError;
|
||||
error AnError;
|
||||
error SecondError;
|
||||
|
||||
|
||||
|
||||
|
||||
#attribute("test")
|
||||
fn constant_enum_with_payload() {
|
||||
should_be_empty(AnEnumWithPayload.Empty);
|
||||
should_be_13(AnEnumWithPayload.Full(13));
|
||||
}
|
||||
|
||||
fn should_be_empty(x: AnEnumWithPayload) {
|
||||
if (x != AnEnumWithPayload.Empty) unreachable{}
|
||||
}
|
||||
|
||||
fn should_be_13(x: AnEnumWithPayload) {
|
||||
}
|
||||
|
||||
enum AnEnumWithPayload {
|
||||
Empty,
|
||||
Full: i32,
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user