aboutsummaryrefslogtreecommitdiff
path: root/src/ir.cpp
diff options
context:
space:
mode:
authorVeikka Tuominen <git@vexu.eu>2020-09-14 16:43:49 +0300
committerGitHub <noreply@github.com>2020-09-14 16:43:49 +0300
commitd073836894df8b9fb56f24f577a51dd09a85a932 (patch)
tree920723ea7cbe577934f0fb9670332f40dc7fd94a /src/ir.cpp
parentc49435f76b07cbf3fdd6a10303a1a0ee4290e59a (diff)
parentacdf1f0bde9a07cae2fbe33739f5f4aee7989f7b (diff)
downloadzig-d073836894df8b9fb56f24f577a51dd09a85a932.tar.gz
zig-d073836894df8b9fb56f24f577a51dd09a85a932.zip
Merge pull request #6172 from tadeokondrak/@Type(.Union)
Implement @Type for Union
Diffstat (limited to 'src/ir.cpp')
-rw-r--r--src/ir.cpp105
1 files changed, 85 insertions, 20 deletions
diff --git a/src/ir.cpp b/src/ir.cpp
index 803b97891f..6cb5d8bc2d 100644
--- a/src/ir.cpp
+++ b/src/ir.cpp
@@ -25424,8 +25424,6 @@ static Error ir_make_type_info_value(IrAnalyze *ira, IrInst* source_instr, ZigTy
init_const_slice(ira->codegen, fields[2], union_field_array, 0, union_field_count, false);
- ZigType *type_info_enum_field_type = ir_type_info_get_type(ira, "EnumField", nullptr);
-
for (uint32_t union_field_index = 0; union_field_index < union_field_count; union_field_index++) {
TypeUnionField *union_field = &type_entry->data.unionation.fields[union_field_index];
ZigValue *union_field_val = &union_field_array->data.x_array.data.s_none.elements[union_field_index];
@@ -25433,20 +25431,10 @@ static Error ir_make_type_info_value(IrAnalyze *ira, IrInst* source_instr, ZigTy
union_field_val->special = ConstValSpecialStatic;
union_field_val->type = type_info_union_field_type;
- ZigValue **inner_fields = alloc_const_vals_ptrs(ira->codegen, 3);
+ ZigValue **inner_fields = alloc_const_vals_ptrs(ira->codegen, 2);
inner_fields[1]->special = ConstValSpecialStatic;
- inner_fields[1]->type = get_optional_type(ira->codegen, type_info_enum_field_type);
-
- if (fields[1]->data.x_optional == nullptr) {
- inner_fields[1]->data.x_optional = nullptr;
- } else {
- inner_fields[1]->data.x_optional = ira->codegen->pass1_arena->create<ZigValue>();
- make_enum_field_val(ira, inner_fields[1]->data.x_optional, union_field->enum_field, type_info_enum_field_type);
- }
-
- inner_fields[2]->special = ConstValSpecialStatic;
- inner_fields[2]->type = ira->codegen->builtin_types.entry_type;
- inner_fields[2]->data.x_type = union_field->type_entry;
+ inner_fields[1]->type = ira->codegen->builtin_types.entry_type;
+ inner_fields[1]->data.x_type = union_field->type_entry;
ZigValue *name = create_const_str_lit(ira->codegen, union_field->name)->data.x_ptr.data.ref.pointee;
init_const_slice(ira->codegen, inner_fields[0], name, 0, buf_len(union_field->name), true);
@@ -26102,7 +26090,8 @@ static ZigType *type_info_to_type(IrAnalyze *ira, IrInst *source_instr, ZigTypeI
entry->data.structure.layout = layout;
entry->data.structure.special = is_tuple ? StructSpecialInferredTuple : StructSpecialNone;
entry->data.structure.created_by_at_type = true;
- entry->data.structure.decls_scope = create_decls_scope(ira->codegen, nullptr, nullptr, entry, entry, &entry->name);
+ entry->data.structure.decls_scope = create_decls_scope(
+ ira->codegen, source_instr->source_node, source_instr->scope, entry, get_scope_import(source_instr->scope), &entry->name);
assert(fields_ptr->data.x_ptr.special == ConstPtrSpecialBaseArray);
assert(fields_ptr->data.x_ptr.data.base_array.elem_index == 0);
@@ -26226,13 +26215,89 @@ static ZigType *type_info_to_type(IrAnalyze *ira, IrInst *source_instr, ZigTypeI
return ira->codegen->invalid_inst_gen->value->type;
field->value = *field_int_value;
}
+ return entry;
+ }
+ case ZigTypeIdUnion: {
+ assert(payload->special == ConstValSpecialStatic);
+ assert(payload->type == ir_type_info_get_type(ira, "Union", nullptr));
+ ZigValue *layout_value = get_const_field(ira, source_instr->source_node, payload, "layout", 0);
+ if (layout_value == nullptr)
+ return ira->codegen->invalid_inst_gen->value->type;
+ assert(layout_value->special == ConstValSpecialStatic);
+ assert(layout_value->type == ir_type_info_get_type(ira, "ContainerLayout", nullptr));
+ ContainerLayout layout = (ContainerLayout)bigint_as_u32(&layout_value->data.x_enum_tag);
+
+ ZigType *tag_type = get_const_field_meta_type_optional(ira, source_instr->source_node, payload, "tag_type", 1);
+ if (tag_type != nullptr && type_is_invalid(tag_type)) {
+ return ira->codegen->invalid_inst_gen->value->type;
+ }
+ if (tag_type != nullptr && tag_type->id != ZigTypeIdEnum) {
+ ir_add_error(ira, source_instr, buf_sprintf(
+ "expected enum type, found '%s'", type_id_name(tag_type->id)));
+ return ira->codegen->invalid_inst_gen->value->type;
+ }
+
+ ZigValue *fields_value = get_const_field(ira, source_instr->source_node, payload, "fields", 2);
+ if (fields_value == nullptr)
+ return ira->codegen->invalid_inst_gen->value->type;
+
+ assert(fields_value->special == ConstValSpecialStatic);
+ assert(is_slice(fields_value->type));
+ ZigValue *fields_ptr = fields_value->data.x_struct.fields[slice_ptr_index];
+ ZigValue *fields_len_value = fields_value->data.x_struct.fields[slice_len_index];
+ size_t fields_len = bigint_as_usize(&fields_len_value->data.x_bigint);
+
+ ZigValue *decls_value = get_const_field(ira, source_instr->source_node, payload, "decls", 3);
+ if (decls_value == nullptr)
+ return ira->codegen->invalid_inst_gen->value->type;
+
+ assert(decls_value->special == ConstValSpecialStatic);
+ assert(is_slice(decls_value->type));
+ ZigValue *decls_len_value = decls_value->data.x_struct.fields[slice_len_index];
+ size_t decls_len = bigint_as_usize(&decls_len_value->data.x_bigint);
+ if (decls_len != 0) {
+ ir_add_error(ira, source_instr, buf_create_from_str("TypeInfo.Union.decls must be empty for @Type"));
+ return ira->codegen->invalid_inst_gen->value->type;
+ }
+
+ ZigType *entry = new_type_table_entry(ZigTypeIdUnion);
+ buf_init_from_buf(&entry->name,
+ get_anon_type_name(ira->codegen, ira->old_irb.exec, "union", source_instr->scope, source_instr->source_node, &entry->name));
+ entry->data.unionation.decl_node = source_instr->source_node;
+ entry->data.unionation.fields = heap::c_allocator.allocate<TypeUnionField>(fields_len);
+ entry->data.unionation.fields_by_name.init(fields_len);
+ entry->data.unionation.decls_scope = create_decls_scope(
+ ira->codegen, source_instr->source_node, source_instr->scope, entry, get_scope_import(source_instr->scope), &entry->name);
+ entry->data.unionation.tag_type = tag_type;
+ entry->data.unionation.src_field_count = fields_len;
+ entry->data.unionation.layout = layout;
+
+ assert(fields_ptr->data.x_ptr.special == ConstPtrSpecialBaseArray);
+ assert(fields_ptr->data.x_ptr.data.base_array.elem_index == 0);
+ ZigValue *fields_arr = fields_ptr->data.x_ptr.data.base_array.array_val;
+ assert(fields_arr->special == ConstValSpecialStatic);
+ assert(fields_arr->data.x_array.special == ConstArraySpecialNone);
+ for (size_t i = 0; i < fields_len; i++) {
+ ZigValue *field_value = &fields_arr->data.x_array.data.s_none.elements[i];
+ assert(field_value->type == ir_type_info_get_type(ira, "UnionField", nullptr));
+ TypeUnionField *field = &entry->data.unionation.fields[i];
+ field->name = buf_alloc();
+ if ((err = get_const_field_buf(ira, source_instr->source_node, field_value, "name", 0, field->name)))
+ return ira->codegen->invalid_inst_gen->value->type;
+ if (entry->data.unionation.fields_by_name.put_unique(field->name, field) != nullptr) {
+ ir_add_error(ira, source_instr, buf_sprintf("duplicate union field '%s'", buf_ptr(field->name)));
+ return ira->codegen->invalid_inst_gen->value->type;
+ }
+ field->decl_node = source_instr->source_node;
+ ZigValue *type_value = get_const_field(ira, source_instr->source_node, field_value, "field_type", 1);
+ if (type_value == nullptr)
+ return ira->codegen->invalid_inst_gen->value->type;
+ field->type_val = type_value;
+ field->type_entry = type_value->data.x_type;
+ }
return entry;
}
- case ZigTypeIdUnion:
- ir_add_error(ira, source_instr, buf_sprintf(
- "TODO implement @Type for 'TypeInfo.%s': see https://github.com/ziglang/zig/issues/2907", type_id_name(tagTypeId)));
- return ira->codegen->invalid_inst_gen->value->type;
case ZigTypeIdFn:
case ZigTypeIdBoundFn:
ir_add_error(ira, source_instr, buf_sprintf(