| ... | ... | @@ -13473,6 +13473,41 @@ static IrInstruction *ir_analyze_container_field_ptr(IrAnalyze *ira, Buf *field_ |
| 13473 | 13473 | } else if (bare_type->id == TypeTableEntryIdUnion) { |
| 13474 | 13474 | TypeUnionField *field = find_union_type_field(bare_type, field_name); |
| 13475 | 13475 | if (field) { |
| 13476 | if (instr_is_comptime(container_ptr)) { |
| 13477 | ConstExprValue *ptr_val = ir_resolve_const(ira, container_ptr, UndefBad); |
| 13478 | if (!ptr_val) |
| 13479 | return ira->codegen->invalid_instruction; |
| 13480 | |
| 13481 | if (ptr_val->data.x_ptr.special != ConstPtrSpecialHardCodedAddr) { |
| 13482 | ConstExprValue *union_val = const_ptr_pointee(ira->codegen, ptr_val); |
| 13483 | if (type_is_invalid(union_val->type)) |
| 13484 | return ira->codegen->invalid_instruction; |
| 13485 | |
| 13486 | TypeUnionField *actual_field = find_union_field_by_tag(bare_type, &union_val->data.x_union.tag); |
| 13487 | if (actual_field == nullptr) |
| 13488 | zig_unreachable(); |
| 13489 | |
| 13490 | if (field != actual_field) { |
| 13491 | ir_add_error_node(ira, source_instr->source_node, |
| 13492 | buf_sprintf("accessing union field '%s' while field '%s' is set", buf_ptr(field_name), |
| 13493 | buf_ptr(actual_field->name))); |
| 13494 | return ira->codegen->invalid_instruction; |
| 13495 | } |
| 13496 | |
| 13497 | ConstExprValue *payload_val = union_val->data.x_union.payload; |
| 13498 | TypeTableEntry *ptr_type = get_pointer_to_type_extra(ira->codegen, payload_val->type, is_const, is_volatile, |
| 13499 | get_abi_alignment(ira->codegen, payload_val->type), 0, 0); |
| 13500 | |
| 13501 | IrInstruction *result = ir_get_const(ira, source_instr); |
| 13502 | ConstExprValue *const_val = &result->value; |
| 13503 | const_val->data.x_ptr.special = ConstPtrSpecialRef; |
| 13504 | const_val->data.x_ptr.mut = container_ptr->value.data.x_ptr.mut; |
| 13505 | const_val->data.x_ptr.data.ref.pointee = payload_val; |
| 13506 | const_val->type = ptr_type; |
| 13507 | return result; |
| 13508 | } |
| 13509 | } |
| 13510 | |
| 13476 | 13511 | IrInstruction *result = ir_build_union_field_ptr(&ira->new_irb, source_instr->scope, source_instr->source_node, container_ptr, field); |
| 13477 | 13512 | result->value.type = get_pointer_to_type_extra(ira->codegen, field->type_entry, is_const, is_volatile, |
| 13478 | 13513 | get_abi_alignment(ira->codegen, field->type_entry), 0, 0); |
| ... | ... | @@ -15706,8 +15741,12 @@ static TypeTableEntry *ir_analyze_instruction_type_info(IrAnalyze *ira, |
| 15706 | 15741 | TypeTableEntry *result_type = var_value->data.x_type; |
| 15707 | 15742 | |
| 15708 | 15743 | ConstExprValue *out_val = ir_build_const_from(ira, &instruction->base); |
| 15744 | // TODO: Do I need those? probably set in ir_build_const_from |
| 15745 | //out_val->special = ConstValSpecialStatic; |
| 15746 | //out_val->type = result_type; |
| 15747 | |
| 15709 | 15748 | bigint_init_unsigned(&out_val->data.x_union.tag, type_id_index(type_entry->id)); |
| 15710 | | out_val->data.x_union.parent.id = ConstParentIdNone; |
| 15749 | //out_val->data.x_union.parent.id = ConstParentIdNone; |
| 15711 | 15750 | |
| 15712 | 15751 | switch (type_entry->id) { |
| 15713 | 15752 | case TypeTableEntryIdInvalid: |
| ... | ... | @@ -15724,9 +15763,34 @@ static TypeTableEntry *ir_analyze_instruction_type_info(IrAnalyze *ira, |
| 15724 | 15763 | case TypeTableEntryIdBlock: |
| 15725 | 15764 | case TypeTableEntryIdArgTuple: |
| 15726 | 15765 | case TypeTableEntryIdOpaque: |
| 15727 | | // TODO: Check out this is the way to handle voids; |
| 15728 | 15766 | out_val->data.x_union.payload = nullptr; |
| 15729 | 15767 | break; |
| 15768 | case TypeTableEntryIdInt: |
| 15769 | { |
| 15770 | // Error from 'ir_resolve_const': "unable to evaluate constant expression" |
| 15771 | ConstExprValue *payload = create_const_vals(1); |
| 15772 | out_val->data.x_union.payload = payload; |
| 15773 | |
| 15774 | payload->special = ConstValSpecialStatic; |
| 15775 | payload->type = get_builtin_value(ira->codegen, "IntInfo")->type; |
| 15776 | |
| 15777 | ConstExprValue *fields = create_const_vals(2); |
| 15778 | payload->data.x_struct.fields = fields; |
| 15779 | |
| 15780 | payload->data.x_struct.parent.id = ConstParentIdUnion; |
| 15781 | payload->data.x_struct.parent.data.p_union.union_val = out_val; |
| 15782 | |
| 15783 | // TODO: See what happens if we don't set the field type (set it to nullptr) |
| 15784 | fields[0].special = ConstValSpecialStatic; |
| 15785 | fields[0].type = ira->codegen->builtin_types.entry_bool; |
| 15786 | fields[0].data.x_bool = type_entry->data.integral.is_signed; |
| 15787 | |
| 15788 | fields[1].special = ConstValSpecialStatic; |
| 15789 | fields[1].type = ira->codegen->builtin_types.entry_u8; |
| 15790 | bigint_init_unsigned(&fields[1].data.x_bigint, type_entry->data.integral.bit_count); |
| 15791 | |
| 15792 | break; |
| 15793 | } |
| 15730 | 15794 | default: |
| 15731 | 15795 | zig_panic("@typeInfo unsupported for %s", buf_ptr(&type_entry->name)); |
| 15732 | 15796 | } |