authorgravatar for alex_naskos@hotmail.comAlexandros Naskos <alex_naskos@hotmail.com> 2018-04-24 15:03:46+03:00
committergravatar for alex_naskos@hotmail.comAlexandros Naskos <alex_naskos@hotmail.com> 2018-04-24 15:03:46+03:00
logec2a3ed500d4ba269c87b3ad0efe7bcc89eb2057
treed7e124dc1700117c65a8e77f1705e1d8976464d8
parentfb88f5a0d21f68632a8c712e14a9640f9c4f6cb3

Attempt at adding comptime union field access


2 files changed, 67 insertions(+), 2 deletions(-)

src/codegen.cpp+1
...@@ -6347,6 +6347,7 @@ static void define_builtin_compile_vars(CodeGen *g) {...@@ -6347,6 +6347,7 @@ static void define_builtin_compile_vars(CodeGen *g) {
6347 buf_appendf(contents, "};\n\n");6347 buf_appendf(contents, "};\n\n");
6348 }6348 }
6349 {6349 {
6350 // TODO: Add method info where methods are supported.
6350 buf_appendf(contents,6351 buf_appendf(contents,
6351 "pub const IntInfo = struct {\n"6352 "pub const IntInfo = struct {\n"
6352 " is_signed: bool,\n"6353 " is_signed: bool,\n"
src/ir.cpp+66-2
...@@ -13473,6 +13473,41 @@ static IrInstruction *ir_analyze_container_field_ptr(IrAnalyze *ira, Buf *field_...@@ -13473,6 +13473,41 @@ static IrInstruction *ir_analyze_container_field_ptr(IrAnalyze *ira, Buf *field_
13473 } else if (bare_type->id == TypeTableEntryIdUnion) {13473 } else if (bare_type->id == TypeTableEntryIdUnion) {
13474 TypeUnionField *field = find_union_type_field(bare_type, field_name);13474 TypeUnionField *field = find_union_type_field(bare_type, field_name);
13475 if (field) {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 IrInstruction *result = ir_build_union_field_ptr(&ira->new_irb, source_instr->scope, source_instr->source_node, container_ptr, field);13511 IrInstruction *result = ir_build_union_field_ptr(&ira->new_irb, source_instr->scope, source_instr->source_node, container_ptr, field);
13477 result->value.type = get_pointer_to_type_extra(ira->codegen, field->type_entry, is_const, is_volatile,13512 result->value.type = get_pointer_to_type_extra(ira->codegen, field->type_entry, is_const, is_volatile,
13478 get_abi_alignment(ira->codegen, field->type_entry), 0, 0);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,8 +15741,12 @@ static TypeTableEntry *ir_analyze_instruction_type_info(IrAnalyze *ira,
15706 TypeTableEntry *result_type = var_value->data.x_type;15741 TypeTableEntry *result_type = var_value->data.x_type;
1570715742
15708 ConstExprValue *out_val = ir_build_const_from(ira, &instruction->base);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 bigint_init_unsigned(&out_val->data.x_union.tag, type_id_index(type_entry->id));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;
1571115750
15712 switch (type_entry->id) {15751 switch (type_entry->id) {
15713 case TypeTableEntryIdInvalid:15752 case TypeTableEntryIdInvalid:
...@@ -15724,9 +15763,34 @@ static TypeTableEntry *ir_analyze_instruction_type_info(IrAnalyze *ira,...@@ -15724,9 +15763,34 @@ static TypeTableEntry *ir_analyze_instruction_type_info(IrAnalyze *ira,
15724 case TypeTableEntryIdBlock:15763 case TypeTableEntryIdBlock:
15725 case TypeTableEntryIdArgTuple:15764 case TypeTableEntryIdArgTuple:
15726 case TypeTableEntryIdOpaque:15765 case TypeTableEntryIdOpaque:
15727 // TODO: Check out this is the way to handle voids;
15728 out_val->data.x_union.payload = nullptr;15766 out_val->data.x_union.payload = nullptr;
15729 break;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 default:15794 default:
15731 zig_panic("@typeInfo unsupported for %s", buf_ptr(&type_entry->name));15795 zig_panic("@typeInfo unsupported for %s", buf_ptr(&type_entry->name));
15732 }15796 }