| ... | ... | @@ -3795,7 +3795,29 @@ static IrInstruction *ir_gen_bool_and(IrBuilder *irb, Scope *scope, AstNode *nod |
| 3795 | 3795 | return ir_build_phi(irb, scope, node, 2, incoming_blocks, incoming_values); |
| 3796 | 3796 | } |
| 3797 | 3797 | |
| 3798 | | static IrInstruction *ir_gen_orelse(IrBuilder *irb, Scope *parent_scope, AstNode *node) { |
| 3798 | static ResultLocPeerParent *create_binary_result_peers(IrInstruction *cond_br_inst, |
| 3799 | IrBasicBlock *else_block, IrBasicBlock *endif_block, ResultLoc *parent) |
| 3800 | { |
| 3801 | ResultLocPeerParent *peer_parent = allocate<ResultLocPeerParent>(1); |
| 3802 | peer_parent->base.id = ResultLocIdPeerParent; |
| 3803 | peer_parent->base.source_instruction = cond_br_inst; |
| 3804 | peer_parent->parent = parent; |
| 3805 | peer_parent->peer_count = 2; |
| 3806 | peer_parent->peers = allocate<ResultLocPeer>(2); |
| 3807 | peer_parent->peers[0].base.id = ResultLocIdPeer; |
| 3808 | peer_parent->peers[0].base.source_instruction = cond_br_inst; |
| 3809 | peer_parent->peers[0].parent = peer_parent; |
| 3810 | peer_parent->peers[0].next_bb = else_block; |
| 3811 | peer_parent->peers[1].base.id = ResultLocIdPeer; |
| 3812 | peer_parent->peers[1].base.source_instruction = cond_br_inst; |
| 3813 | peer_parent->peers[1].parent = peer_parent; |
| 3814 | peer_parent->peers[1].next_bb = endif_block; |
| 3815 | return peer_parent; |
| 3816 | } |
| 3817 | |
| 3818 | static IrInstruction *ir_gen_orelse(IrBuilder *irb, Scope *parent_scope, AstNode *node, LVal lval, |
| 3819 | ResultLoc *result_loc) |
| 3820 | { |
| 3799 | 3821 | assert(node->type == NodeTypeBinOpExpr); |
| 3800 | 3822 | |
| 3801 | 3823 | AstNode *op1_node = node->data.bin_op_expr.op1; |
| ... | ... | @@ -3818,10 +3840,12 @@ static IrInstruction *ir_gen_orelse(IrBuilder *irb, Scope *parent_scope, AstNode |
| 3818 | 3840 | IrBasicBlock *ok_block = ir_create_basic_block(irb, parent_scope, "OptionalNonNull"); |
| 3819 | 3841 | IrBasicBlock *null_block = ir_create_basic_block(irb, parent_scope, "OptionalNull"); |
| 3820 | 3842 | IrBasicBlock *end_block = ir_create_basic_block(irb, parent_scope, "OptionalEnd"); |
| 3821 | | ir_build_cond_br(irb, parent_scope, node, is_non_null, ok_block, null_block, is_comptime); |
| 3843 | IrInstruction *cond_br_inst = ir_build_cond_br(irb, parent_scope, node, is_non_null, ok_block, null_block, is_comptime); |
| 3844 | |
| 3845 | ResultLocPeerParent *peer_parent = create_binary_result_peers(cond_br_inst, ok_block, end_block, result_loc); |
| 3822 | 3846 | |
| 3823 | 3847 | ir_set_cursor_at_end_and_append_block(irb, null_block); |
| 3824 | | IrInstruction *null_result = ir_gen_node(irb, op2_node, parent_scope); |
| 3848 | IrInstruction *null_result = ir_gen_node_extra(irb, op2_node, parent_scope, lval, &peer_parent->peers[0].base); |
| 3825 | 3849 | if (null_result == irb->codegen->invalid_instruction) |
| 3826 | 3850 | return irb->codegen->invalid_instruction; |
| 3827 | 3851 | IrBasicBlock *after_null_block = irb->current_basic_block; |
| ... | ... | @@ -3831,6 +3855,7 @@ static IrInstruction *ir_gen_orelse(IrBuilder *irb, Scope *parent_scope, AstNode |
| 3831 | 3855 | ir_set_cursor_at_end_and_append_block(irb, ok_block); |
| 3832 | 3856 | IrInstruction *unwrapped_ptr = ir_build_optional_unwrap_ptr(irb, parent_scope, node, maybe_ptr, false); |
| 3833 | 3857 | IrInstruction *unwrapped_payload = ir_build_load_ptr(irb, parent_scope, node, unwrapped_ptr); |
| 3858 | ir_build_end_expr(irb, parent_scope, node, unwrapped_payload, &peer_parent->peers[1].base); |
| 3834 | 3859 | IrBasicBlock *after_ok_block = irb->current_basic_block; |
| 3835 | 3860 | ir_build_br(irb, parent_scope, node, end_block, is_comptime); |
| 3836 | 3861 | |
| ... | ... | @@ -3841,7 +3866,8 @@ static IrInstruction *ir_gen_orelse(IrBuilder *irb, Scope *parent_scope, AstNode |
| 3841 | 3866 | IrBasicBlock **incoming_blocks = allocate<IrBasicBlock *>(2); |
| 3842 | 3867 | incoming_blocks[0] = after_null_block; |
| 3843 | 3868 | incoming_blocks[1] = after_ok_block; |
| 3844 | | return ir_build_phi(irb, parent_scope, node, 2, incoming_blocks, incoming_values); |
| 3869 | IrInstruction *phi = ir_build_phi(irb, parent_scope, node, 2, incoming_blocks, incoming_values); |
| 3870 | return ir_lval_wrap(irb, parent_scope, phi, lval, result_loc); |
| 3845 | 3871 | } |
| 3846 | 3872 | |
| 3847 | 3873 | static IrInstruction *ir_gen_error_union(IrBuilder *irb, Scope *parent_scope, AstNode *node) { |
| ... | ... | @@ -3861,7 +3887,7 @@ static IrInstruction *ir_gen_error_union(IrBuilder *irb, Scope *parent_scope, As |
| 3861 | 3887 | return ir_build_error_union(irb, parent_scope, node, err_set, payload); |
| 3862 | 3888 | } |
| 3863 | 3889 | |
| 3864 | | static IrInstruction *ir_gen_bin_op(IrBuilder *irb, Scope *scope, AstNode *node) { |
| 3890 | static IrInstruction *ir_gen_bin_op(IrBuilder *irb, Scope *scope, AstNode *node, LVal lval, ResultLoc *result_loc) { |
| 3865 | 3891 | assert(node->type == NodeTypeBinOpExpr); |
| 3866 | 3892 | |
| 3867 | 3893 | BinOpType bin_op_type = node->data.bin_op_expr.bin_op; |
| ... | ... | @@ -3869,87 +3895,87 @@ static IrInstruction *ir_gen_bin_op(IrBuilder *irb, Scope *scope, AstNode *node) |
| 3869 | 3895 | case BinOpTypeInvalid: |
| 3870 | 3896 | zig_unreachable(); |
| 3871 | 3897 | case BinOpTypeAssign: |
| 3872 | | return ir_gen_assign(irb, scope, node); |
| 3898 | return ir_lval_wrap(irb, scope, ir_gen_assign(irb, scope, node), lval, result_loc); |
| 3873 | 3899 | case BinOpTypeAssignTimes: |
| 3874 | | return ir_gen_assign_op(irb, scope, node, IrBinOpMult); |
| 3900 | return ir_lval_wrap(irb, scope, ir_gen_assign_op(irb, scope, node, IrBinOpMult), lval, result_loc); |
| 3875 | 3901 | case BinOpTypeAssignTimesWrap: |
| 3876 | | return ir_gen_assign_op(irb, scope, node, IrBinOpMultWrap); |
| 3902 | return ir_lval_wrap(irb, scope, ir_gen_assign_op(irb, scope, node, IrBinOpMultWrap), lval, result_loc); |
| 3877 | 3903 | case BinOpTypeAssignDiv: |
| 3878 | | return ir_gen_assign_op(irb, scope, node, IrBinOpDivUnspecified); |
| 3904 | return ir_lval_wrap(irb, scope, ir_gen_assign_op(irb, scope, node, IrBinOpDivUnspecified), lval, result_loc); |
| 3879 | 3905 | case BinOpTypeAssignMod: |
| 3880 | | return ir_gen_assign_op(irb, scope, node, IrBinOpRemUnspecified); |
| 3906 | return ir_lval_wrap(irb, scope, ir_gen_assign_op(irb, scope, node, IrBinOpRemUnspecified), lval, result_loc); |
| 3881 | 3907 | case BinOpTypeAssignPlus: |
| 3882 | | return ir_gen_assign_op(irb, scope, node, IrBinOpAdd); |
| 3908 | return ir_lval_wrap(irb, scope, ir_gen_assign_op(irb, scope, node, IrBinOpAdd), lval, result_loc); |
| 3883 | 3909 | case BinOpTypeAssignPlusWrap: |
| 3884 | | return ir_gen_assign_op(irb, scope, node, IrBinOpAddWrap); |
| 3910 | return ir_lval_wrap(irb, scope, ir_gen_assign_op(irb, scope, node, IrBinOpAddWrap), lval, result_loc); |
| 3885 | 3911 | case BinOpTypeAssignMinus: |
| 3886 | | return ir_gen_assign_op(irb, scope, node, IrBinOpSub); |
| 3912 | return ir_lval_wrap(irb, scope, ir_gen_assign_op(irb, scope, node, IrBinOpSub), lval, result_loc); |
| 3887 | 3913 | case BinOpTypeAssignMinusWrap: |
| 3888 | | return ir_gen_assign_op(irb, scope, node, IrBinOpSubWrap); |
| 3914 | return ir_lval_wrap(irb, scope, ir_gen_assign_op(irb, scope, node, IrBinOpSubWrap), lval, result_loc); |
| 3889 | 3915 | case BinOpTypeAssignBitShiftLeft: |
| 3890 | | return ir_gen_assign_op(irb, scope, node, IrBinOpBitShiftLeftLossy); |
| 3916 | return ir_lval_wrap(irb, scope, ir_gen_assign_op(irb, scope, node, IrBinOpBitShiftLeftLossy), lval, result_loc); |
| 3891 | 3917 | case BinOpTypeAssignBitShiftRight: |
| 3892 | | return ir_gen_assign_op(irb, scope, node, IrBinOpBitShiftRightLossy); |
| 3918 | return ir_lval_wrap(irb, scope, ir_gen_assign_op(irb, scope, node, IrBinOpBitShiftRightLossy), lval, result_loc); |
| 3893 | 3919 | case BinOpTypeAssignBitAnd: |
| 3894 | | return ir_gen_assign_op(irb, scope, node, IrBinOpBinAnd); |
| 3920 | return ir_lval_wrap(irb, scope, ir_gen_assign_op(irb, scope, node, IrBinOpBinAnd), lval, result_loc); |
| 3895 | 3921 | case BinOpTypeAssignBitXor: |
| 3896 | | return ir_gen_assign_op(irb, scope, node, IrBinOpBinXor); |
| 3922 | return ir_lval_wrap(irb, scope, ir_gen_assign_op(irb, scope, node, IrBinOpBinXor), lval, result_loc); |
| 3897 | 3923 | case BinOpTypeAssignBitOr: |
| 3898 | | return ir_gen_assign_op(irb, scope, node, IrBinOpBinOr); |
| 3924 | return ir_lval_wrap(irb, scope, ir_gen_assign_op(irb, scope, node, IrBinOpBinOr), lval, result_loc); |
| 3899 | 3925 | case BinOpTypeAssignMergeErrorSets: |
| 3900 | | return ir_gen_assign_op(irb, scope, node, IrBinOpMergeErrorSets); |
| 3926 | return ir_lval_wrap(irb, scope, ir_gen_assign_op(irb, scope, node, IrBinOpMergeErrorSets), lval, result_loc); |
| 3901 | 3927 | case BinOpTypeBoolOr: |
| 3902 | | return ir_gen_bool_or(irb, scope, node); |
| 3928 | return ir_lval_wrap(irb, scope, ir_gen_bool_or(irb, scope, node), lval, result_loc); |
| 3903 | 3929 | case BinOpTypeBoolAnd: |
| 3904 | | return ir_gen_bool_and(irb, scope, node); |
| 3930 | return ir_lval_wrap(irb, scope, ir_gen_bool_and(irb, scope, node), lval, result_loc); |
| 3905 | 3931 | case BinOpTypeCmpEq: |
| 3906 | | return ir_gen_bin_op_id(irb, scope, node, IrBinOpCmpEq); |
| 3932 | return ir_lval_wrap(irb, scope, ir_gen_bin_op_id(irb, scope, node, IrBinOpCmpEq), lval, result_loc); |
| 3907 | 3933 | case BinOpTypeCmpNotEq: |
| 3908 | | return ir_gen_bin_op_id(irb, scope, node, IrBinOpCmpNotEq); |
| 3934 | return ir_lval_wrap(irb, scope, ir_gen_bin_op_id(irb, scope, node, IrBinOpCmpNotEq), lval, result_loc); |
| 3909 | 3935 | case BinOpTypeCmpLessThan: |
| 3910 | | return ir_gen_bin_op_id(irb, scope, node, IrBinOpCmpLessThan); |
| 3936 | return ir_lval_wrap(irb, scope, ir_gen_bin_op_id(irb, scope, node, IrBinOpCmpLessThan), lval, result_loc); |
| 3911 | 3937 | case BinOpTypeCmpGreaterThan: |
| 3912 | | return ir_gen_bin_op_id(irb, scope, node, IrBinOpCmpGreaterThan); |
| 3938 | return ir_lval_wrap(irb, scope, ir_gen_bin_op_id(irb, scope, node, IrBinOpCmpGreaterThan), lval, result_loc); |
| 3913 | 3939 | case BinOpTypeCmpLessOrEq: |
| 3914 | | return ir_gen_bin_op_id(irb, scope, node, IrBinOpCmpLessOrEq); |
| 3940 | return ir_lval_wrap(irb, scope, ir_gen_bin_op_id(irb, scope, node, IrBinOpCmpLessOrEq), lval, result_loc); |
| 3915 | 3941 | case BinOpTypeCmpGreaterOrEq: |
| 3916 | | return ir_gen_bin_op_id(irb, scope, node, IrBinOpCmpGreaterOrEq); |
| 3942 | return ir_lval_wrap(irb, scope, ir_gen_bin_op_id(irb, scope, node, IrBinOpCmpGreaterOrEq), lval, result_loc); |
| 3917 | 3943 | case BinOpTypeBinOr: |
| 3918 | | return ir_gen_bin_op_id(irb, scope, node, IrBinOpBinOr); |
| 3944 | return ir_lval_wrap(irb, scope, ir_gen_bin_op_id(irb, scope, node, IrBinOpBinOr), lval, result_loc); |
| 3919 | 3945 | case BinOpTypeBinXor: |
| 3920 | | return ir_gen_bin_op_id(irb, scope, node, IrBinOpBinXor); |
| 3946 | return ir_lval_wrap(irb, scope, ir_gen_bin_op_id(irb, scope, node, IrBinOpBinXor), lval, result_loc); |
| 3921 | 3947 | case BinOpTypeBinAnd: |
| 3922 | | return ir_gen_bin_op_id(irb, scope, node, IrBinOpBinAnd); |
| 3948 | return ir_lval_wrap(irb, scope, ir_gen_bin_op_id(irb, scope, node, IrBinOpBinAnd), lval, result_loc); |
| 3923 | 3949 | case BinOpTypeBitShiftLeft: |
| 3924 | | return ir_gen_bin_op_id(irb, scope, node, IrBinOpBitShiftLeftLossy); |
| 3950 | return ir_lval_wrap(irb, scope, ir_gen_bin_op_id(irb, scope, node, IrBinOpBitShiftLeftLossy), lval, result_loc); |
| 3925 | 3951 | case BinOpTypeBitShiftRight: |
| 3926 | | return ir_gen_bin_op_id(irb, scope, node, IrBinOpBitShiftRightLossy); |
| 3952 | return ir_lval_wrap(irb, scope, ir_gen_bin_op_id(irb, scope, node, IrBinOpBitShiftRightLossy), lval, result_loc); |
| 3927 | 3953 | case BinOpTypeAdd: |
| 3928 | | return ir_gen_bin_op_id(irb, scope, node, IrBinOpAdd); |
| 3954 | return ir_lval_wrap(irb, scope, ir_gen_bin_op_id(irb, scope, node, IrBinOpAdd), lval, result_loc); |
| 3929 | 3955 | case BinOpTypeAddWrap: |
| 3930 | | return ir_gen_bin_op_id(irb, scope, node, IrBinOpAddWrap); |
| 3956 | return ir_lval_wrap(irb, scope, ir_gen_bin_op_id(irb, scope, node, IrBinOpAddWrap), lval, result_loc); |
| 3931 | 3957 | case BinOpTypeSub: |
| 3932 | | return ir_gen_bin_op_id(irb, scope, node, IrBinOpSub); |
| 3958 | return ir_lval_wrap(irb, scope, ir_gen_bin_op_id(irb, scope, node, IrBinOpSub), lval, result_loc); |
| 3933 | 3959 | case BinOpTypeSubWrap: |
| 3934 | | return ir_gen_bin_op_id(irb, scope, node, IrBinOpSubWrap); |
| 3960 | return ir_lval_wrap(irb, scope, ir_gen_bin_op_id(irb, scope, node, IrBinOpSubWrap), lval, result_loc); |
| 3935 | 3961 | case BinOpTypeMult: |
| 3936 | | return ir_gen_bin_op_id(irb, scope, node, IrBinOpMult); |
| 3962 | return ir_lval_wrap(irb, scope, ir_gen_bin_op_id(irb, scope, node, IrBinOpMult), lval, result_loc); |
| 3937 | 3963 | case BinOpTypeMultWrap: |
| 3938 | | return ir_gen_bin_op_id(irb, scope, node, IrBinOpMultWrap); |
| 3964 | return ir_lval_wrap(irb, scope, ir_gen_bin_op_id(irb, scope, node, IrBinOpMultWrap), lval, result_loc); |
| 3939 | 3965 | case BinOpTypeDiv: |
| 3940 | | return ir_gen_bin_op_id(irb, scope, node, IrBinOpDivUnspecified); |
| 3966 | return ir_lval_wrap(irb, scope, ir_gen_bin_op_id(irb, scope, node, IrBinOpDivUnspecified), lval, result_loc); |
| 3941 | 3967 | case BinOpTypeMod: |
| 3942 | | return ir_gen_bin_op_id(irb, scope, node, IrBinOpRemUnspecified); |
| 3968 | return ir_lval_wrap(irb, scope, ir_gen_bin_op_id(irb, scope, node, IrBinOpRemUnspecified), lval, result_loc); |
| 3943 | 3969 | case BinOpTypeArrayCat: |
| 3944 | | return ir_gen_bin_op_id(irb, scope, node, IrBinOpArrayCat); |
| 3970 | return ir_lval_wrap(irb, scope, ir_gen_bin_op_id(irb, scope, node, IrBinOpArrayCat), lval, result_loc); |
| 3945 | 3971 | case BinOpTypeArrayMult: |
| 3946 | | return ir_gen_bin_op_id(irb, scope, node, IrBinOpArrayMult); |
| 3972 | return ir_lval_wrap(irb, scope, ir_gen_bin_op_id(irb, scope, node, IrBinOpArrayMult), lval, result_loc); |
| 3947 | 3973 | case BinOpTypeMergeErrorSets: |
| 3948 | | return ir_gen_bin_op_id(irb, scope, node, IrBinOpMergeErrorSets); |
| 3974 | return ir_lval_wrap(irb, scope, ir_gen_bin_op_id(irb, scope, node, IrBinOpMergeErrorSets), lval, result_loc); |
| 3949 | 3975 | case BinOpTypeUnwrapOptional: |
| 3950 | | return ir_gen_orelse(irb, scope, node); |
| 3976 | return ir_gen_orelse(irb, scope, node, lval, result_loc); |
| 3951 | 3977 | case BinOpTypeErrorUnion: |
| 3952 | | return ir_gen_error_union(irb, scope, node); |
| 3978 | return ir_lval_wrap(irb, scope, ir_gen_error_union(irb, scope, node), lval, result_loc); |
| 3953 | 3979 | } |
| 3954 | 3980 | zig_unreachable(); |
| 3955 | 3981 | } |
| ... | ... | @@ -5290,26 +5316,6 @@ static IrInstruction *ir_gen_fn_call(IrBuilder *irb, Scope *scope, AstNode *node |
| 5290 | 5316 | return ir_lval_wrap(irb, scope, fn_call, lval, result_loc); |
| 5291 | 5317 | } |
| 5292 | 5318 | |
| 5293 | | static ResultLocPeerParent *create_binary_result_peers(IrInstruction *cond_br_inst, |
| 5294 | | IrBasicBlock *else_block, IrBasicBlock *endif_block, ResultLoc *parent) |
| 5295 | | { |
| 5296 | | ResultLocPeerParent *peer_parent = allocate<ResultLocPeerParent>(1); |
| 5297 | | peer_parent->base.id = ResultLocIdPeerParent; |
| 5298 | | peer_parent->base.source_instruction = cond_br_inst; |
| 5299 | | peer_parent->parent = parent; |
| 5300 | | peer_parent->peer_count = 2; |
| 5301 | | peer_parent->peers = allocate<ResultLocPeer>(2); |
| 5302 | | peer_parent->peers[0].base.id = ResultLocIdPeer; |
| 5303 | | peer_parent->peers[0].base.source_instruction = cond_br_inst; |
| 5304 | | peer_parent->peers[0].parent = peer_parent; |
| 5305 | | peer_parent->peers[0].next_bb = else_block; |
| 5306 | | peer_parent->peers[1].base.id = ResultLocIdPeer; |
| 5307 | | peer_parent->peers[1].base.source_instruction = cond_br_inst; |
| 5308 | | peer_parent->peers[1].parent = peer_parent; |
| 5309 | | peer_parent->peers[1].next_bb = endif_block; |
| 5310 | | return peer_parent; |
| 5311 | | } |
| 5312 | | |
| 5313 | 5319 | static IrInstruction *ir_gen_if_bool_expr(IrBuilder *irb, Scope *scope, AstNode *node, LVal lval, |
| 5314 | 5320 | ResultLoc *result_loc) |
| 5315 | 5321 | { |
| ... | ... | @@ -7863,7 +7869,7 @@ static IrInstruction *ir_gen_node_raw(IrBuilder *irb, AstNode *node, Scope *scop |
| 7863 | 7869 | case NodeTypeGroupedExpr: |
| 7864 | 7870 | return ir_gen_node_raw(irb, node->data.grouped_expr, scope, lval, result_loc); |
| 7865 | 7871 | case NodeTypeBinOpExpr: |
| 7866 | | return ir_lval_wrap(irb, scope, ir_gen_bin_op(irb, scope, node), lval, result_loc); |
| 7872 | return ir_gen_bin_op(irb, scope, node, lval, result_loc); |
| 7867 | 7873 | case NodeTypeIntLiteral: |
| 7868 | 7874 | return ir_lval_wrap(irb, scope, ir_gen_int_lit(irb, scope, node), lval, result_loc); |
| 7869 | 7875 | case NodeTypeFloatLiteral: |