| ... | @@ -38,6 +38,7 @@ struct IrAnalyze { | ... | @@ -38,6 +38,7 @@ struct IrAnalyze { |
| 38 | ZigType *explicit_return_type; | 38 | ZigType *explicit_return_type; |
| 39 | AstNode *explicit_return_type_source_node; | 39 | AstNode *explicit_return_type_source_node; |
| 40 | ZigList<IrInstruction *> src_implicit_return_type_list; | 40 | ZigList<IrInstruction *> src_implicit_return_type_list; |
| | 41 | ZigList<IrSuspendPosition> resume_stack; |
| 41 | IrBasicBlock *const_predecessor_bb; | 42 | IrBasicBlock *const_predecessor_bb; |
| 42 | }; | 43 | }; |
| 43 | | 44 | |
| ... | @@ -157,16 +158,19 @@ enum UndefAllowed { | ... | @@ -157,16 +158,19 @@ enum UndefAllowed { |
| 157 | }; | 158 | }; |
| 158 | | 159 | |
| 159 | static IrInstruction *ir_gen_node(IrBuilder *irb, AstNode *node, Scope *scope); | 160 | static IrInstruction *ir_gen_node(IrBuilder *irb, AstNode *node, Scope *scope); |
| 160 | static IrInstruction *ir_gen_node_extra(IrBuilder *irb, AstNode *node, Scope *scope, LVal lval); | 161 | static IrInstruction *ir_gen_node_extra(IrBuilder *irb, AstNode *node, Scope *scope, LVal lval, |
| 161 | static IrInstruction *ir_analyze_instruction(IrAnalyze *ira, IrInstruction *instruction); | 162 | ResultLoc *result_loc); |
| 162 | static IrInstruction *ir_implicit_cast(IrAnalyze *ira, IrInstruction *value, ZigType *expected_type); | 163 | static IrInstruction *ir_implicit_cast(IrAnalyze *ira, IrInstruction *value, ZigType *expected_type); |
| 163 | static IrInstruction *ir_get_deref(IrAnalyze *ira, IrInstruction *source_instruction, IrInstruction *ptr); | 164 | static IrInstruction *ir_get_deref(IrAnalyze *ira, IrInstruction *source_instruction, IrInstruction *ptr, |
| | 165 | ResultLoc *result_loc); |
| 164 | static ErrorMsg *exec_add_error_node(CodeGen *codegen, IrExecutable *exec, AstNode *source_node, Buf *msg); | 166 | static ErrorMsg *exec_add_error_node(CodeGen *codegen, IrExecutable *exec, AstNode *source_node, Buf *msg); |
| 165 | static IrInstruction *ir_analyze_container_field_ptr(IrAnalyze *ira, Buf *field_name, | 167 | static IrInstruction *ir_analyze_container_field_ptr(IrAnalyze *ira, Buf *field_name, |
| 166 | IrInstruction *source_instr, IrInstruction *container_ptr, ZigType *container_type); | 168 | IrInstruction *source_instr, IrInstruction *container_ptr, ZigType *container_type, bool initializing); |
| | 169 | static void ir_assert(bool ok, IrInstruction *source_instruction); |
| 167 | static IrInstruction *ir_get_var_ptr(IrAnalyze *ira, IrInstruction *instruction, ZigVar *var); | 170 | static IrInstruction *ir_get_var_ptr(IrAnalyze *ira, IrInstruction *instruction, ZigVar *var); |
| 168 | static ZigType *ir_resolve_atomic_operand_type(IrAnalyze *ira, IrInstruction *op); | 171 | static ZigType *ir_resolve_atomic_operand_type(IrAnalyze *ira, IrInstruction *op); |
| 169 | static IrInstruction *ir_lval_wrap(IrBuilder *irb, Scope *scope, IrInstruction *value, LVal lval); | 172 | static IrInstruction *ir_lval_wrap(IrBuilder *irb, Scope *scope, IrInstruction *value, LVal lval, ResultLoc *result_loc); |
| | 173 | static IrInstruction *ir_expr_wrap(IrBuilder *irb, Scope *scope, IrInstruction *inst, ResultLoc *result_loc); |
| 170 | static ZigType *adjust_ptr_align(CodeGen *g, ZigType *ptr_type, uint32_t new_align); | 174 | static ZigType *adjust_ptr_align(CodeGen *g, ZigType *ptr_type, uint32_t new_align); |
| 171 | static ZigType *adjust_slice_align(CodeGen *g, ZigType *slice_type, uint32_t new_align); | 175 | static ZigType *adjust_slice_align(CodeGen *g, ZigType *slice_type, uint32_t new_align); |
| 172 | static Error buf_read_value_bytes(IrAnalyze *ira, CodeGen *codegen, AstNode *source_node, uint8_t *buf, ConstExprValue *val); | 176 | static Error buf_read_value_bytes(IrAnalyze *ira, CodeGen *codegen, AstNode *source_node, uint8_t *buf, ConstExprValue *val); |
| ... | @@ -178,17 +182,28 @@ static IrInstruction *ir_analyze_ptr_cast(IrAnalyze *ira, IrInstruction *source_ | ... | @@ -178,17 +182,28 @@ static IrInstruction *ir_analyze_ptr_cast(IrAnalyze *ira, IrInstruction *source_ |
| 178 | static ConstExprValue *ir_resolve_const(IrAnalyze *ira, IrInstruction *value, UndefAllowed undef_allowed); | 182 | static ConstExprValue *ir_resolve_const(IrAnalyze *ira, IrInstruction *value, UndefAllowed undef_allowed); |
| 179 | static void copy_const_val(ConstExprValue *dest, ConstExprValue *src, bool same_global_refs); | 183 | static void copy_const_val(ConstExprValue *dest, ConstExprValue *src, bool same_global_refs); |
| 180 | static Error resolve_ptr_align(IrAnalyze *ira, ZigType *ty, uint32_t *result_align); | 184 | static Error resolve_ptr_align(IrAnalyze *ira, ZigType *ty, uint32_t *result_align); |
| 181 | static void ir_add_alloca(IrAnalyze *ira, IrInstruction *instruction, ZigType *type_entry); | | |
| 182 | static IrInstruction *ir_analyze_int_to_ptr(IrAnalyze *ira, IrInstruction *source_instr, IrInstruction *target, | 185 | static IrInstruction *ir_analyze_int_to_ptr(IrAnalyze *ira, IrInstruction *source_instr, IrInstruction *target, |
| 183 | ZigType *ptr_type); | 186 | ZigType *ptr_type); |
| 184 | static IrInstruction *ir_analyze_bit_cast(IrAnalyze *ira, IrInstruction *source_instr, IrInstruction *value, | 187 | static IrInstruction *ir_analyze_bit_cast(IrAnalyze *ira, IrInstruction *source_instr, IrInstruction *value, |
| 185 | ZigType *dest_type); | 188 | ZigType *dest_type); |
| | 189 | static IrInstruction *ir_resolve_result_raw(IrAnalyze *ira, IrInstruction *suspend_source_instr, |
| | 190 | ResultLoc *result_loc, ZigType *value_type, IrInstruction *value, bool force_runtime, bool non_null_comptime); |
| | 191 | static IrInstruction *ir_resolve_result(IrAnalyze *ira, IrInstruction *suspend_source_instr, |
| | 192 | ResultLoc *result_loc, ZigType *value_type, IrInstruction *value, bool force_runtime, bool non_null_comptime); |
| | 193 | static IrInstruction *ir_analyze_unwrap_optional_payload(IrAnalyze *ira, IrInstruction *source_instr, |
| | 194 | IrInstruction *base_ptr, bool safety_check_on, bool initializing); |
| | 195 | static IrInstruction *ir_analyze_unwrap_error_payload(IrAnalyze *ira, IrInstruction *source_instr, |
| | 196 | IrInstruction *base_ptr, bool safety_check_on, bool initializing); |
| | 197 | static IrInstruction *ir_analyze_unwrap_err_code(IrAnalyze *ira, IrInstruction *source_instr, |
| | 198 | IrInstruction *base_ptr, bool initializing); |
| | 199 | static IrInstruction *ir_analyze_store_ptr(IrAnalyze *ira, IrInstruction *source_instr, |
| | 200 | IrInstruction *ptr, IrInstruction *uncasted_value); |
| 186 | | 201 | |
| 187 | static ConstExprValue *const_ptr_pointee_unchecked(CodeGen *g, ConstExprValue *const_val) { | 202 | static ConstExprValue *const_ptr_pointee_unchecked(CodeGen *g, ConstExprValue *const_val) { |
| 188 | assert(get_src_ptr_type(const_val->type) != nullptr); | 203 | assert(get_src_ptr_type(const_val->type) != nullptr); |
| 189 | assert(const_val->special == ConstValSpecialStatic); | 204 | assert(const_val->special == ConstValSpecialStatic); |
| 190 | ConstExprValue *result; | 205 | ConstExprValue *result; |
| 191 | | 206 | |
| 192 | switch (type_has_one_possible_value(g, const_val->type->data.pointer.child_type)) { | 207 | switch (type_has_one_possible_value(g, const_val->type->data.pointer.child_type)) { |
| 193 | case OnePossibleValueInvalid: | 208 | case OnePossibleValueInvalid: |
| 194 | zig_unreachable(); | 209 | zig_unreachable(); |
| ... | @@ -200,7 +215,7 @@ static ConstExprValue *const_ptr_pointee_unchecked(CodeGen *g, ConstExprValue *c | ... | @@ -200,7 +215,7 @@ static ConstExprValue *const_ptr_pointee_unchecked(CodeGen *g, ConstExprValue *c |
| 200 | case OnePossibleValueNo: | 215 | case OnePossibleValueNo: |
| 201 | break; | 216 | break; |
| 202 | } | 217 | } |
| 203 | | 218 | |
| 204 | switch (const_val->data.x_ptr.special) { | 219 | switch (const_val->data.x_ptr.special) { |
| 205 | case ConstPtrSpecialInvalid: | 220 | case ConstPtrSpecialInvalid: |
| 206 | zig_unreachable(); | 221 | zig_unreachable(); |
| ... | @@ -246,6 +261,15 @@ static bool is_opt_err_set(ZigType *ty) { | ... | @@ -246,6 +261,15 @@ static bool is_opt_err_set(ZigType *ty) { |
| 246 | (ty->id == ZigTypeIdOptional && ty->data.maybe.child_type->id == ZigTypeIdErrorSet); | 261 | (ty->id == ZigTypeIdOptional && ty->data.maybe.child_type->id == ZigTypeIdErrorSet); |
| 247 | } | 262 | } |
| 248 | | 263 | |
| | 264 | static bool is_slice(ZigType *type) { |
| | 265 | return type->id == ZigTypeIdStruct && type->data.structure.is_slice; |
| | 266 | } |
| | 267 | |
| | 268 | static bool slice_is_const(ZigType *type) { |
| | 269 | assert(is_slice(type)); |
| | 270 | return type->data.structure.fields[slice_ptr_index].type_entry->data.pointer.is_const; |
| | 271 | } |
| | 272 | |
| 249 | // This function returns true when you can change the type of a ConstExprValue and the | 273 | // This function returns true when you can change the type of a ConstExprValue and the |
| 250 | // value remains meaningful. | 274 | // value remains meaningful. |
| 251 | static bool types_have_same_zig_comptime_repr(ZigType *a, ZigType *b) { | 275 | static bool types_have_same_zig_comptime_repr(ZigType *a, ZigType *b) { |
| ... | @@ -282,8 +306,9 @@ static bool types_have_same_zig_comptime_repr(ZigType *a, ZigType *b) { | ... | @@ -282,8 +306,9 @@ static bool types_have_same_zig_comptime_repr(ZigType *a, ZigType *b) { |
| 282 | return a->data.floating.bit_count == b->data.floating.bit_count; | 306 | return a->data.floating.bit_count == b->data.floating.bit_count; |
| 283 | case ZigTypeIdInt: | 307 | case ZigTypeIdInt: |
| 284 | return a->data.integral.is_signed == b->data.integral.is_signed; | 308 | return a->data.integral.is_signed == b->data.integral.is_signed; |
| 285 | case ZigTypeIdArray: | | |
| 286 | case ZigTypeIdStruct: | 309 | case ZigTypeIdStruct: |
| | 310 | return is_slice(a) && is_slice(b); |
| | 311 | case ZigTypeIdArray: |
| 287 | case ZigTypeIdOptional: | 312 | case ZigTypeIdOptional: |
| 288 | case ZigTypeIdErrorUnion: | 313 | case ZigTypeIdErrorUnion: |
| 289 | case ZigTypeIdEnum: | 314 | case ZigTypeIdEnum: |
| ... | @@ -386,6 +411,7 @@ static IrBasicBlock *ir_create_basic_block(IrBuilder *irb, Scope *scope, const c | ... | @@ -386,6 +411,7 @@ static IrBasicBlock *ir_create_basic_block(IrBuilder *irb, Scope *scope, const c |
| 386 | result->scope = scope; | 411 | result->scope = scope; |
| 387 | result->name_hint = name_hint; | 412 | result->name_hint = name_hint; |
| 388 | result->debug_id = exec_next_debug_id(irb->exec); | 413 | result->debug_id = exec_next_debug_id(irb->exec); |
| | 414 | result->index = SIZE_MAX; // set later |
| 389 | return result; | 415 | return result; |
| 390 | } | 416 | } |
| 391 | | 417 | |
| ... | @@ -475,8 +501,16 @@ static constexpr IrInstructionId ir_instruction_id(IrInstructionVarPtr *) { | ... | @@ -475,8 +501,16 @@ static constexpr IrInstructionId ir_instruction_id(IrInstructionVarPtr *) { |
| 475 | return IrInstructionIdVarPtr; | 501 | return IrInstructionIdVarPtr; |
| 476 | } | 502 | } |
| 477 | | 503 | |
| 478 | static constexpr IrInstructionId ir_instruction_id(IrInstructionCall *) { | 504 | static constexpr IrInstructionId ir_instruction_id(IrInstructionReturnPtr *) { |
| 479 | return IrInstructionIdCall; | 505 | return IrInstructionIdReturnPtr; |
| | 506 | } |
| | 507 | |
| | 508 | static constexpr IrInstructionId ir_instruction_id(IrInstructionCallSrc *) { |
| | 509 | return IrInstructionIdCallSrc; |
| | 510 | } |
| | 511 | |
| | 512 | static constexpr IrInstructionId ir_instruction_id(IrInstructionCallGen *) { |
| | 513 | return IrInstructionIdCallGen; |
| 480 | } | 514 | } |
| 481 | | 515 | |
| 482 | static constexpr IrInstructionId ir_instruction_id(IrInstructionConst *) { | 516 | static constexpr IrInstructionId ir_instruction_id(IrInstructionConst *) { |
| ... | @@ -511,14 +545,6 @@ static constexpr IrInstructionId ir_instruction_id(IrInstructionTypeOf *) { | ... | @@ -511,14 +545,6 @@ static constexpr IrInstructionId ir_instruction_id(IrInstructionTypeOf *) { |
| 511 | return IrInstructionIdTypeOf; | 545 | return IrInstructionIdTypeOf; |
| 512 | } | 546 | } |
| 513 | | 547 | |
| 514 | static constexpr IrInstructionId ir_instruction_id(IrInstructionToPtrType *) { | | |
| 515 | return IrInstructionIdToPtrType; | | |
| 516 | } | | |
| 517 | | | |
| 518 | static constexpr IrInstructionId ir_instruction_id(IrInstructionPtrTypeChild *) { | | |
| 519 | return IrInstructionIdPtrTypeChild; | | |
| 520 | } | | |
| 521 | | | |
| 522 | static constexpr IrInstructionId ir_instruction_id(IrInstructionSetCold *) { | 548 | static constexpr IrInstructionId ir_instruction_id(IrInstructionSetCold *) { |
| 523 | return IrInstructionIdSetCold; | 549 | return IrInstructionIdSetCold; |
| 524 | } | 550 | } |
| ... | @@ -611,12 +637,8 @@ static constexpr IrInstructionId ir_instruction_id(IrInstructionRef *) { | ... | @@ -611,12 +637,8 @@ static constexpr IrInstructionId ir_instruction_id(IrInstructionRef *) { |
| 611 | return IrInstructionIdRef; | 637 | return IrInstructionIdRef; |
| 612 | } | 638 | } |
| 613 | | 639 | |
| 614 | static constexpr IrInstructionId ir_instruction_id(IrInstructionStructInit *) { | 640 | static constexpr IrInstructionId ir_instruction_id(IrInstructionRefGen *) { |
| 615 | return IrInstructionIdStructInit; | 641 | return IrInstructionIdRefGen; |
| 616 | } | | |
| 617 | | | |
| 618 | static constexpr IrInstructionId ir_instruction_id(IrInstructionUnionInit *) { | | |
| 619 | return IrInstructionIdUnionInit; | | |
| 620 | } | 642 | } |
| 621 | | 643 | |
| 622 | static constexpr IrInstructionId ir_instruction_id(IrInstructionCompileErr *) { | 644 | static constexpr IrInstructionId ir_instruction_id(IrInstructionCompileErr *) { |
| ... | @@ -703,8 +725,12 @@ static constexpr IrInstructionId ir_instruction_id(IrInstructionMemcpy *) { | ... | @@ -703,8 +725,12 @@ static constexpr IrInstructionId ir_instruction_id(IrInstructionMemcpy *) { |
| 703 | return IrInstructionIdMemcpy; | 725 | return IrInstructionIdMemcpy; |
| 704 | } | 726 | } |
| 705 | | 727 | |
| 706 | static constexpr IrInstructionId ir_instruction_id(IrInstructionSlice *) { | 728 | static constexpr IrInstructionId ir_instruction_id(IrInstructionSliceSrc *) { |
| 707 | return IrInstructionIdSlice; | 729 | return IrInstructionIdSliceSrc; |
| | 730 | } |
| | 731 | |
| | 732 | static constexpr IrInstructionId ir_instruction_id(IrInstructionSliceGen *) { |
| | 733 | return IrInstructionIdSliceGen; |
| 708 | } | 734 | } |
| 709 | | 735 | |
| 710 | static constexpr IrInstructionId ir_instruction_id(IrInstructionMemberCount *) { | 736 | static constexpr IrInstructionId ir_instruction_id(IrInstructionMemberCount *) { |
| ... | @@ -743,8 +769,16 @@ static constexpr IrInstructionId ir_instruction_id(IrInstructionOverflowOp *) { | ... | @@ -743,8 +769,16 @@ static constexpr IrInstructionId ir_instruction_id(IrInstructionOverflowOp *) { |
| 743 | return IrInstructionIdOverflowOp; | 769 | return IrInstructionIdOverflowOp; |
| 744 | } | 770 | } |
| 745 | | 771 | |
| 746 | static constexpr IrInstructionId ir_instruction_id(IrInstructionTestErr *) { | 772 | static constexpr IrInstructionId ir_instruction_id(IrInstructionTestErrSrc *) { |
| 747 | return IrInstructionIdTestErr; | 773 | return IrInstructionIdTestErrSrc; |
| | 774 | } |
| | 775 | |
| | 776 | static constexpr IrInstructionId ir_instruction_id(IrInstructionTestErrGen *) { |
| | 777 | return IrInstructionIdTestErrGen; |
| | 778 | } |
| | 779 | |
| | 780 | static constexpr IrInstructionId ir_instruction_id(IrInstructionMulAdd *) { |
| | 781 | return IrInstructionIdMulAdd; |
| 748 | } | 782 | } |
| 749 | | 783 | |
| 750 | static constexpr IrInstructionId ir_instruction_id(IrInstructionUnwrapErrCode *) { | 784 | static constexpr IrInstructionId ir_instruction_id(IrInstructionUnwrapErrCode *) { |
| ... | @@ -783,8 +817,8 @@ static constexpr IrInstructionId ir_instruction_id(IrInstructionPtrCastGen *) { | ... | @@ -783,8 +817,8 @@ static constexpr IrInstructionId ir_instruction_id(IrInstructionPtrCastGen *) { |
| 783 | return IrInstructionIdPtrCastGen; | 817 | return IrInstructionIdPtrCastGen; |
| 784 | } | 818 | } |
| 785 | | 819 | |
| 786 | static constexpr IrInstructionId ir_instruction_id(IrInstructionBitCast *) { | 820 | static constexpr IrInstructionId ir_instruction_id(IrInstructionBitCastSrc *) { |
| 787 | return IrInstructionIdBitCast; | 821 | return IrInstructionIdBitCastSrc; |
| 788 | } | 822 | } |
| 789 | | 823 | |
| 790 | static constexpr IrInstructionId ir_instruction_id(IrInstructionBitCastGen *) { | 824 | static constexpr IrInstructionId ir_instruction_id(IrInstructionBitCastGen *) { |
| ... | @@ -879,6 +913,26 @@ static constexpr IrInstructionId ir_instruction_id(IrInstructionAlignCast *) { | ... | @@ -879,6 +913,26 @@ static constexpr IrInstructionId ir_instruction_id(IrInstructionAlignCast *) { |
| 879 | return IrInstructionIdAlignCast; | 913 | return IrInstructionIdAlignCast; |
| 880 | } | 914 | } |
| 881 | | 915 | |
| | 916 | static constexpr IrInstructionId ir_instruction_id(IrInstructionImplicitCast *) { |
| | 917 | return IrInstructionIdImplicitCast; |
| | 918 | } |
| | 919 | |
| | 920 | static constexpr IrInstructionId ir_instruction_id(IrInstructionResolveResult *) { |
| | 921 | return IrInstructionIdResolveResult; |
| | 922 | } |
| | 923 | |
| | 924 | static constexpr IrInstructionId ir_instruction_id(IrInstructionResetResult *) { |
| | 925 | return IrInstructionIdResetResult; |
| | 926 | } |
| | 927 | |
| | 928 | static constexpr IrInstructionId ir_instruction_id(IrInstructionResultPtr *) { |
| | 929 | return IrInstructionIdResultPtr; |
| | 930 | } |
| | 931 | |
| | 932 | static constexpr IrInstructionId ir_instruction_id(IrInstructionPtrOfArrayToSlice *) { |
| | 933 | return IrInstructionIdPtrOfArrayToSlice; |
| | 934 | } |
| | 935 | |
| 882 | static constexpr IrInstructionId ir_instruction_id(IrInstructionOpaqueType *) { | 936 | static constexpr IrInstructionId ir_instruction_id(IrInstructionOpaqueType *) { |
| 883 | return IrInstructionIdOpaqueType; | 937 | return IrInstructionIdOpaqueType; |
| 884 | } | 938 | } |
| ... | @@ -987,8 +1041,8 @@ static constexpr IrInstructionId ir_instruction_id(IrInstructionMarkErrRetTraceP | ... | @@ -987,8 +1041,8 @@ static constexpr IrInstructionId ir_instruction_id(IrInstructionMarkErrRetTraceP |
| 987 | return IrInstructionIdMarkErrRetTracePtr; | 1041 | return IrInstructionIdMarkErrRetTracePtr; |
| 988 | } | 1042 | } |
| 989 | | 1043 | |
| 990 | static constexpr IrInstructionId ir_instruction_id(IrInstructionSqrt *) { | 1044 | static constexpr IrInstructionId ir_instruction_id(IrInstructionFloatOp *) { |
| 991 | return IrInstructionIdSqrt; | 1045 | return IrInstructionIdFloatOp; |
| 992 | } | 1046 | } |
| 993 | | 1047 | |
| 994 | static constexpr IrInstructionId ir_instruction_id(IrInstructionCheckRuntimeScope *) { | 1048 | static constexpr IrInstructionId ir_instruction_id(IrInstructionCheckRuntimeScope *) { |
| ... | @@ -1019,6 +1073,18 @@ static constexpr IrInstructionId ir_instruction_id(IrInstructionUndeclaredIdent | ... | @@ -1019,6 +1073,18 @@ static constexpr IrInstructionId ir_instruction_id(IrInstructionUndeclaredIdent |
| 1019 | return IrInstructionIdUndeclaredIdent; | 1073 | return IrInstructionIdUndeclaredIdent; |
| 1020 | } | 1074 | } |
| 1021 | | 1075 | |
| | 1076 | static constexpr IrInstructionId ir_instruction_id(IrInstructionAllocaSrc *) { |
| | 1077 | return IrInstructionIdAllocaSrc; |
| | 1078 | } |
| | 1079 | |
| | 1080 | static constexpr IrInstructionId ir_instruction_id(IrInstructionAllocaGen *) { |
| | 1081 | return IrInstructionIdAllocaGen; |
| | 1082 | } |
| | 1083 | |
| | 1084 | static constexpr IrInstructionId ir_instruction_id(IrInstructionEndExpr *) { |
| | 1085 | return IrInstructionIdEndExpr; |
| | 1086 | } |
| | 1087 | |
| 1022 | template<typename T> | 1088 | template<typename T> |
| 1023 | static T *ir_create_instruction(IrBuilder *irb, Scope *scope, AstNode *source_node) { | 1089 | static T *ir_create_instruction(IrBuilder *irb, Scope *scope, AstNode *source_node) { |
| 1024 | T *special_instruction = allocate<T>(1); | 1090 | T *special_instruction = allocate<T>(1); |
| ... | @@ -1070,13 +1136,15 @@ static IrInstruction *ir_build_cond_br(IrBuilder *irb, Scope *scope, AstNode *so | ... | @@ -1070,13 +1136,15 @@ static IrInstruction *ir_build_cond_br(IrBuilder *irb, Scope *scope, AstNode *so |
| 1070 | return &cond_br_instruction->base; | 1136 | return &cond_br_instruction->base; |
| 1071 | } | 1137 | } |
| 1072 | | 1138 | |
| 1073 | static IrInstruction *ir_build_return(IrBuilder *irb, Scope *scope, AstNode *source_node, IrInstruction *return_value) { | 1139 | static IrInstruction *ir_build_return(IrBuilder *irb, Scope *scope, AstNode *source_node, |
| | 1140 | IrInstruction *return_value) |
| | 1141 | { |
| 1074 | IrInstructionReturn *return_instruction = ir_build_instruction<IrInstructionReturn>(irb, scope, source_node); | 1142 | IrInstructionReturn *return_instruction = ir_build_instruction<IrInstructionReturn>(irb, scope, source_node); |
| 1075 | return_instruction->base.value.type = irb->codegen->builtin_types.entry_unreachable; | 1143 | return_instruction->base.value.type = irb->codegen->builtin_types.entry_unreachable; |
| 1076 | return_instruction->base.value.special = ConstValSpecialStatic; | 1144 | return_instruction->base.value.special = ConstValSpecialStatic; |
| 1077 | return_instruction->value = return_value; | 1145 | return_instruction->value = return_value; |
| 1078 | | 1146 | |
| 1079 | ir_ref_instruction(return_value, irb->current_basic_block); | 1147 | if (return_value != nullptr) ir_ref_instruction(return_value, irb->current_basic_block); |
| 1080 | | 1148 | |
| 1081 | return &return_instruction->base; | 1149 | return &return_instruction->base; |
| 1082 | } | 1150 | } |
| ... | @@ -1254,17 +1322,27 @@ static IrInstruction *ir_build_var_ptr(IrBuilder *irb, Scope *scope, AstNode *so | ... | @@ -1254,17 +1322,27 @@ static IrInstruction *ir_build_var_ptr(IrBuilder *irb, Scope *scope, AstNode *so |
| 1254 | return ir_build_var_ptr_x(irb, scope, source_node, var, nullptr); | 1322 | return ir_build_var_ptr_x(irb, scope, source_node, var, nullptr); |
| 1255 | } | 1323 | } |
| 1256 | | 1324 | |
| 1257 | static IrInstruction *ir_build_elem_ptr(IrBuilder *irb, Scope *scope, AstNode *source_node, IrInstruction *array_ptr, | 1325 | static IrInstruction *ir_build_return_ptr(IrAnalyze *ira, IrInstruction *source_instruction, ZigType *ty) { |
| 1258 | IrInstruction *elem_index, bool safety_check_on, PtrLen ptr_len) | 1326 | IrInstructionReturnPtr *instruction = ir_build_instruction<IrInstructionReturnPtr>(&ira->new_irb, |
| | 1327 | source_instruction->scope, source_instruction->source_node); |
| | 1328 | instruction->base.value.type = ty; |
| | 1329 | return &instruction->base; |
| | 1330 | } |
| | 1331 | |
| | 1332 | static IrInstruction *ir_build_elem_ptr(IrBuilder *irb, Scope *scope, AstNode *source_node, |
| | 1333 | IrInstruction *array_ptr, IrInstruction *elem_index, bool safety_check_on, PtrLen ptr_len, |
| | 1334 | IrInstruction *init_array_type) |
| 1259 | { | 1335 | { |
| 1260 | IrInstructionElemPtr *instruction = ir_build_instruction<IrInstructionElemPtr>(irb, scope, source_node); | 1336 | IrInstructionElemPtr *instruction = ir_build_instruction<IrInstructionElemPtr>(irb, scope, source_node); |
| 1261 | instruction->array_ptr = array_ptr; | 1337 | instruction->array_ptr = array_ptr; |
| 1262 | instruction->elem_index = elem_index; | 1338 | instruction->elem_index = elem_index; |
| 1263 | instruction->safety_check_on = safety_check_on; | 1339 | instruction->safety_check_on = safety_check_on; |
| 1264 | instruction->ptr_len = ptr_len; | 1340 | instruction->ptr_len = ptr_len; |
| | 1341 | instruction->init_array_type = init_array_type; |
| 1265 | | 1342 | |
| 1266 | ir_ref_instruction(array_ptr, irb->current_basic_block); | 1343 | ir_ref_instruction(array_ptr, irb->current_basic_block); |
| 1267 | ir_ref_instruction(elem_index, irb->current_basic_block); | 1344 | ir_ref_instruction(elem_index, irb->current_basic_block); |
| | 1345 | if (init_array_type != nullptr) ir_ref_instruction(init_array_type, irb->current_basic_block); |
| 1268 | | 1346 | |
| 1269 | return &instruction->base; | 1347 | return &instruction->base; |
| 1270 | } | 1348 | } |
| ... | @@ -1284,12 +1362,13 @@ static IrInstruction *ir_build_field_ptr_instruction(IrBuilder *irb, Scope *scop | ... | @@ -1284,12 +1362,13 @@ static IrInstruction *ir_build_field_ptr_instruction(IrBuilder *irb, Scope *scop |
| 1284 | } | 1362 | } |
| 1285 | | 1363 | |
| 1286 | static IrInstruction *ir_build_field_ptr(IrBuilder *irb, Scope *scope, AstNode *source_node, | 1364 | static IrInstruction *ir_build_field_ptr(IrBuilder *irb, Scope *scope, AstNode *source_node, |
| 1287 | IrInstruction *container_ptr, Buf *field_name) | 1365 | IrInstruction *container_ptr, Buf *field_name, bool initializing) |
| 1288 | { | 1366 | { |
| 1289 | IrInstructionFieldPtr *instruction = ir_build_instruction<IrInstructionFieldPtr>(irb, scope, source_node); | 1367 | IrInstructionFieldPtr *instruction = ir_build_instruction<IrInstructionFieldPtr>(irb, scope, source_node); |
| 1290 | instruction->container_ptr = container_ptr; | 1368 | instruction->container_ptr = container_ptr; |
| 1291 | instruction->field_name_buffer = field_name; | 1369 | instruction->field_name_buffer = field_name; |
| 1292 | instruction->field_name_expr = nullptr; | 1370 | instruction->field_name_expr = nullptr; |
| | 1371 | instruction->initializing = initializing; |
| 1293 | | 1372 | |
| 1294 | ir_ref_instruction(container_ptr, irb->current_basic_block); | 1373 | ir_ref_instruction(container_ptr, irb->current_basic_block); |
| 1295 | | 1374 | |
| ... | @@ -1309,9 +1388,11 @@ static IrInstruction *ir_build_struct_field_ptr(IrBuilder *irb, Scope *scope, As | ... | @@ -1309,9 +1388,11 @@ static IrInstruction *ir_build_struct_field_ptr(IrBuilder *irb, Scope *scope, As |
| 1309 | } | 1388 | } |
| 1310 | | 1389 | |
| 1311 | static IrInstruction *ir_build_union_field_ptr(IrBuilder *irb, Scope *scope, AstNode *source_node, | 1390 | static IrInstruction *ir_build_union_field_ptr(IrBuilder *irb, Scope *scope, AstNode *source_node, |
| 1312 | IrInstruction *union_ptr, TypeUnionField *field) | 1391 | IrInstruction *union_ptr, TypeUnionField *field, bool safety_check_on, bool initializing) |
| 1313 | { | 1392 | { |
| 1314 | IrInstructionUnionFieldPtr *instruction = ir_build_instruction<IrInstructionUnionFieldPtr>(irb, scope, source_node); | 1393 | IrInstructionUnionFieldPtr *instruction = ir_build_instruction<IrInstructionUnionFieldPtr>(irb, scope, source_node); |
| | 1394 | instruction->initializing = initializing; |
| | 1395 | instruction->safety_check_on = safety_check_on; |
| 1315 | instruction->union_ptr = union_ptr; | 1396 | instruction->union_ptr = union_ptr; |
| 1316 | instruction->field = field; | 1397 | instruction->field = field; |
| 1317 | | 1398 | |
| ... | @@ -1320,12 +1401,12 @@ static IrInstruction *ir_build_union_field_ptr(IrBuilder *irb, Scope *scope, Ast | ... | @@ -1320,12 +1401,12 @@ static IrInstruction *ir_build_union_field_ptr(IrBuilder *irb, Scope *scope, Ast |
| 1320 | return &instruction->base; | 1401 | return &instruction->base; |
| 1321 | } | 1402 | } |
| 1322 | | 1403 | |
| 1323 | static IrInstruction *ir_build_call(IrBuilder *irb, Scope *scope, AstNode *source_node, | 1404 | static IrInstruction *ir_build_call_src(IrBuilder *irb, Scope *scope, AstNode *source_node, |
| 1324 | ZigFn *fn_entry, IrInstruction *fn_ref, size_t arg_count, IrInstruction **args, | 1405 | ZigFn *fn_entry, IrInstruction *fn_ref, size_t arg_count, IrInstruction **args, |
| 1325 | bool is_comptime, FnInline fn_inline, bool is_async, IrInstruction *async_allocator, | 1406 | bool is_comptime, FnInline fn_inline, bool is_async, IrInstruction *async_allocator, |
| 1326 | IrInstruction *new_stack) | 1407 | IrInstruction *new_stack, ResultLoc *result_loc) |
| 1327 | { | 1408 | { |
| 1328 | IrInstructionCall *call_instruction = ir_build_instruction<IrInstructionCall>(irb, scope, source_node); | 1409 | IrInstructionCallSrc *call_instruction = ir_build_instruction<IrInstructionCallSrc>(irb, scope, source_node); |
| 1329 | call_instruction->fn_entry = fn_entry; | 1410 | call_instruction->fn_entry = fn_entry; |
| 1330 | call_instruction->fn_ref = fn_ref; | 1411 | call_instruction->fn_ref = fn_ref; |
| 1331 | call_instruction->is_comptime = is_comptime; | 1412 | call_instruction->is_comptime = is_comptime; |
| ... | @@ -1335,6 +1416,7 @@ static IrInstruction *ir_build_call(IrBuilder *irb, Scope *scope, AstNode *sourc | ... | @@ -1335,6 +1416,7 @@ static IrInstruction *ir_build_call(IrBuilder *irb, Scope *scope, AstNode *sourc |
| 1335 | call_instruction->is_async = is_async; | 1416 | call_instruction->is_async = is_async; |
| 1336 | call_instruction->async_allocator = async_allocator; | 1417 | call_instruction->async_allocator = async_allocator; |
| 1337 | call_instruction->new_stack = new_stack; | 1418 | call_instruction->new_stack = new_stack; |
| | 1419 | call_instruction->result_loc = result_loc; |
| 1338 | | 1420 | |
| 1339 | if (fn_ref != nullptr) ir_ref_instruction(fn_ref, irb->current_basic_block); | 1421 | if (fn_ref != nullptr) ir_ref_instruction(fn_ref, irb->current_basic_block); |
| 1340 | for (size_t i = 0; i < arg_count; i += 1) | 1422 | for (size_t i = 0; i < arg_count; i += 1) |
| ... | @@ -1345,8 +1427,37 @@ static IrInstruction *ir_build_call(IrBuilder *irb, Scope *scope, AstNode *sourc | ... | @@ -1345,8 +1427,37 @@ static IrInstruction *ir_build_call(IrBuilder *irb, Scope *scope, AstNode *sourc |
| 1345 | return &call_instruction->base; | 1427 | return &call_instruction->base; |
| 1346 | } | 1428 | } |
| 1347 | | 1429 | |
| | 1430 | static IrInstruction *ir_build_call_gen(IrAnalyze *ira, IrInstruction *source_instruction, |
| | 1431 | ZigFn *fn_entry, IrInstruction *fn_ref, size_t arg_count, IrInstruction **args, |
| | 1432 | FnInline fn_inline, bool is_async, IrInstruction *async_allocator, IrInstruction *new_stack, |
| | 1433 | IrInstruction *result_loc, ZigType *return_type) |
| | 1434 | { |
| | 1435 | IrInstructionCallGen *call_instruction = ir_build_instruction<IrInstructionCallGen>(&ira->new_irb, |
| | 1436 | source_instruction->scope, source_instruction->source_node); |
| | 1437 | call_instruction->base.value.type = return_type; |
| | 1438 | call_instruction->fn_entry = fn_entry; |
| | 1439 | call_instruction->fn_ref = fn_ref; |
| | 1440 | call_instruction->fn_inline = fn_inline; |
| | 1441 | call_instruction->args = args; |
| | 1442 | call_instruction->arg_count = arg_count; |
| | 1443 | call_instruction->is_async = is_async; |
| | 1444 | call_instruction->async_allocator = async_allocator; |
| | 1445 | call_instruction->new_stack = new_stack; |
| | 1446 | call_instruction->result_loc = result_loc; |
| | 1447 | |
| | 1448 | if (fn_ref != nullptr) ir_ref_instruction(fn_ref, ira->new_irb.current_basic_block); |
| | 1449 | for (size_t i = 0; i < arg_count; i += 1) |
| | 1450 | ir_ref_instruction(args[i], ira->new_irb.current_basic_block); |
| | 1451 | if (async_allocator != nullptr) ir_ref_instruction(async_allocator, ira->new_irb.current_basic_block); |
| | 1452 | if (new_stack != nullptr) ir_ref_instruction(new_stack, ira->new_irb.current_basic_block); |
| | 1453 | if (result_loc != nullptr) ir_ref_instruction(result_loc, ira->new_irb.current_basic_block); |
| | 1454 | |
| | 1455 | return &call_instruction->base; |
| | 1456 | } |
| | 1457 | |
| 1348 | static IrInstruction *ir_build_phi(IrBuilder *irb, Scope *scope, AstNode *source_node, | 1458 | static IrInstruction *ir_build_phi(IrBuilder *irb, Scope *scope, AstNode *source_node, |
| 1349 | size_t incoming_count, IrBasicBlock **incoming_blocks, IrInstruction **incoming_values) | 1459 | size_t incoming_count, IrBasicBlock **incoming_blocks, IrInstruction **incoming_values, |
| | 1460 | ResultLocPeerParent *peer_parent) |
| 1350 | { | 1461 | { |
| 1351 | assert(incoming_count != 0); | 1462 | assert(incoming_count != 0); |
| 1352 | assert(incoming_count != SIZE_MAX); | 1463 | assert(incoming_count != SIZE_MAX); |
| ... | @@ -1355,6 +1466,7 @@ static IrInstruction *ir_build_phi(IrBuilder *irb, Scope *scope, AstNode *source | ... | @@ -1355,6 +1466,7 @@ static IrInstruction *ir_build_phi(IrBuilder *irb, Scope *scope, AstNode *source |
| 1355 | phi_instruction->incoming_count = incoming_count; | 1466 | phi_instruction->incoming_count = incoming_count; |
| 1356 | phi_instruction->incoming_blocks = incoming_blocks; | 1467 | phi_instruction->incoming_blocks = incoming_blocks; |
| 1357 | phi_instruction->incoming_values = incoming_values; | 1468 | phi_instruction->incoming_values = incoming_values; |
| | 1469 | phi_instruction->peer_parent = peer_parent; |
| 1358 | | 1470 | |
| 1359 | for (size_t i = 0; i < incoming_count; i += 1) { | 1471 | for (size_t i = 0; i < incoming_count; i += 1) { |
| 1360 | ir_ref_bb(incoming_blocks[i]); | 1472 | ir_ref_bb(incoming_blocks[i]); |
| ... | @@ -1408,12 +1520,13 @@ static IrInstruction *ir_build_ptr_type(IrBuilder *irb, Scope *scope, AstNode *s | ... | @@ -1408,12 +1520,13 @@ static IrInstruction *ir_build_ptr_type(IrBuilder *irb, Scope *scope, AstNode *s |
| 1408 | } | 1520 | } |
| 1409 | | 1521 | |
| 1410 | static IrInstruction *ir_build_un_op_lval(IrBuilder *irb, Scope *scope, AstNode *source_node, IrUnOp op_id, | 1522 | static IrInstruction *ir_build_un_op_lval(IrBuilder *irb, Scope *scope, AstNode *source_node, IrUnOp op_id, |
| 1411 | IrInstruction *value, LVal lval) | 1523 | IrInstruction *value, LVal lval, ResultLoc *result_loc) |
| 1412 | { | 1524 | { |
| 1413 | IrInstructionUnOp *instruction = ir_build_instruction<IrInstructionUnOp>(irb, scope, source_node); | 1525 | IrInstructionUnOp *instruction = ir_build_instruction<IrInstructionUnOp>(irb, scope, source_node); |
| 1414 | instruction->op_id = op_id; | 1526 | instruction->op_id = op_id; |
| 1415 | instruction->value = value; | 1527 | instruction->value = value; |
| 1416 | instruction->lval = lval; | 1528 | instruction->lval = lval; |
| | 1529 | instruction->result_loc = result_loc; |
| 1417 | | 1530 | |
| 1418 | ir_ref_instruction(value, irb->current_basic_block); | 1531 | ir_ref_instruction(value, irb->current_basic_block); |
| 1419 | | 1532 | |
| ... | @@ -1423,72 +1536,49 @@ static IrInstruction *ir_build_un_op_lval(IrBuilder *irb, Scope *scope, AstNode | ... | @@ -1423,72 +1536,49 @@ static IrInstruction *ir_build_un_op_lval(IrBuilder *irb, Scope *scope, AstNode |
| 1423 | static IrInstruction *ir_build_un_op(IrBuilder *irb, Scope *scope, AstNode *source_node, IrUnOp op_id, | 1536 | static IrInstruction *ir_build_un_op(IrBuilder *irb, Scope *scope, AstNode *source_node, IrUnOp op_id, |
| 1424 | IrInstruction *value) | 1537 | IrInstruction *value) |
| 1425 | { | 1538 | { |
| 1426 | return ir_build_un_op_lval(irb, scope, source_node, op_id, value, LValNone); | 1539 | return ir_build_un_op_lval(irb, scope, source_node, op_id, value, LValNone, nullptr); |
| 1427 | } | 1540 | } |
| 1428 | | 1541 | |
| 1429 | static IrInstruction *ir_build_container_init_list(IrBuilder *irb, Scope *scope, AstNode *source_node, | 1542 | static IrInstruction *ir_build_container_init_list(IrBuilder *irb, Scope *scope, AstNode *source_node, |
| 1430 | IrInstruction *container_type, IrInstruction *elem_type, size_t item_count, IrInstruction **items) | 1543 | IrInstruction *container_type, size_t item_count, IrInstruction **elem_result_loc_list, |
| | 1544 | IrInstruction *result_loc) |
| 1431 | { | 1545 | { |
| 1432 | IrInstructionContainerInitList *container_init_list_instruction = | 1546 | IrInstructionContainerInitList *container_init_list_instruction = |
| 1433 | ir_build_instruction<IrInstructionContainerInitList>(irb, scope, source_node); | 1547 | ir_build_instruction<IrInstructionContainerInitList>(irb, scope, source_node); |
| 1434 | container_init_list_instruction->container_type = container_type; | 1548 | container_init_list_instruction->container_type = container_type; |
| 1435 | container_init_list_instruction->elem_type = elem_type; | | |
| 1436 | container_init_list_instruction->item_count = item_count; | 1549 | container_init_list_instruction->item_count = item_count; |
| 1437 | container_init_list_instruction->items = items; | 1550 | container_init_list_instruction->elem_result_loc_list = elem_result_loc_list; |
| | 1551 | container_init_list_instruction->result_loc = result_loc; |
| 1438 | | 1552 | |
| 1439 | if (container_type != nullptr) ir_ref_instruction(container_type, irb->current_basic_block); | 1553 | ir_ref_instruction(container_type, irb->current_basic_block); |
| 1440 | if (elem_type != nullptr) ir_ref_instruction(elem_type, irb->current_basic_block); | | |
| 1441 | for (size_t i = 0; i < item_count; i += 1) { | 1554 | for (size_t i = 0; i < item_count; i += 1) { |
| 1442 | ir_ref_instruction(items[i], irb->current_basic_block); | 1555 | ir_ref_instruction(elem_result_loc_list[i], irb->current_basic_block); |
| 1443 | } | 1556 | } |
| | 1557 | if (result_loc != nullptr) ir_ref_instruction(result_loc, irb->current_basic_block); |
| 1444 | | 1558 | |
| 1445 | return &container_init_list_instruction->base; | 1559 | return &container_init_list_instruction->base; |
| 1446 | } | 1560 | } |
| 1447 | | 1561 | |
| 1448 | static IrInstruction *ir_build_container_init_fields(IrBuilder *irb, Scope *scope, AstNode *source_node, | 1562 | static IrInstruction *ir_build_container_init_fields(IrBuilder *irb, Scope *scope, AstNode *source_node, |
| 1449 | IrInstruction *container_type, size_t field_count, IrInstructionContainerInitFieldsField *fields) | 1563 | IrInstruction *container_type, size_t field_count, IrInstructionContainerInitFieldsField *fields, |
| | 1564 | IrInstruction *result_loc) |
| 1450 | { | 1565 | { |
| 1451 | IrInstructionContainerInitFields *container_init_fields_instruction = | 1566 | IrInstructionContainerInitFields *container_init_fields_instruction = |
| 1452 | ir_build_instruction<IrInstructionContainerInitFields>(irb, scope, source_node); | 1567 | ir_build_instruction<IrInstructionContainerInitFields>(irb, scope, source_node); |
| 1453 | container_init_fields_instruction->container_type = container_type; | 1568 | container_init_fields_instruction->container_type = container_type; |
| 1454 | container_init_fields_instruction->field_count = field_count; | 1569 | container_init_fields_instruction->field_count = field_count; |
| 1455 | container_init_fields_instruction->fields = fields; | 1570 | container_init_fields_instruction->fields = fields; |
| | 1571 | container_init_fields_instruction->result_loc = result_loc; |
| 1456 | | 1572 | |
| 1457 | ir_ref_instruction(container_type, irb->current_basic_block); | 1573 | ir_ref_instruction(container_type, irb->current_basic_block); |
| 1458 | for (size_t i = 0; i < field_count; i += 1) { | 1574 | for (size_t i = 0; i < field_count; i += 1) { |
| 1459 | ir_ref_instruction(fields[i].value, irb->current_basic_block); | 1575 | ir_ref_instruction(fields[i].result_loc, irb->current_basic_block); |
| 1460 | } | 1576 | } |
| | 1577 | if (result_loc != nullptr) ir_ref_instruction(result_loc, irb->current_basic_block); |
| 1461 | | 1578 | |
| 1462 | return &container_init_fields_instruction->base; | 1579 | return &container_init_fields_instruction->base; |
| 1463 | } | 1580 | } |
| 1464 | | 1581 | |
| 1465 | static IrInstruction *ir_build_struct_init(IrBuilder *irb, Scope *scope, AstNode *source_node, | | |
| 1466 | ZigType *struct_type, size_t field_count, IrInstructionStructInitField *fields) | | |
| 1467 | { | | |
| 1468 | IrInstructionStructInit *struct_init_instruction = ir_build_instruction<IrInstructionStructInit>(irb, scope, source_node); | | |
| 1469 | struct_init_instruction->struct_type = struct_type; | | |
| 1470 | struct_init_instruction->field_count = field_count; | | |
| 1471 | struct_init_instruction->fields = fields; | | |
| 1472 | | | |
| 1473 | for (size_t i = 0; i < field_count; i += 1) | | |
| 1474 | ir_ref_instruction(fields[i].value, irb->current_basic_block); | | |
| 1475 | | | |
| 1476 | return &struct_init_instruction->base; | | |
| 1477 | } | | |
| 1478 | | | |
| 1479 | static IrInstruction *ir_build_union_init(IrBuilder *irb, Scope *scope, AstNode *source_node, | | |
| 1480 | ZigType *union_type, TypeUnionField *field, IrInstruction *init_value) | | |
| 1481 | { | | |
| 1482 | IrInstructionUnionInit *union_init_instruction = ir_build_instruction<IrInstructionUnionInit>(irb, scope, source_node); | | |
| 1483 | union_init_instruction->union_type = union_type; | | |
| 1484 | union_init_instruction->field = field; | | |
| 1485 | union_init_instruction->init_value = init_value; | | |
| 1486 | | | |
| 1487 | ir_ref_instruction(init_value, irb->current_basic_block); | | |
| 1488 | | | |
| 1489 | return &union_init_instruction->base; | | |
| 1490 | } | | |
| 1491 | | | |
| 1492 | static IrInstruction *ir_build_unreachable(IrBuilder *irb, Scope *scope, AstNode *source_node) { | 1582 | static IrInstruction *ir_build_unreachable(IrBuilder *irb, Scope *scope, AstNode *source_node) { |
| 1493 | IrInstructionUnreachable *unreachable_instruction = | 1583 | IrInstructionUnreachable *unreachable_instruction = |
| 1494 | ir_build_instruction<IrInstructionUnreachable>(irb, scope, source_node); | 1584 | ir_build_instruction<IrInstructionUnreachable>(irb, scope, source_node); |
| ... | @@ -1513,47 +1603,47 @@ static IrInstruction *ir_build_store_ptr(IrBuilder *irb, Scope *scope, AstNode * | ... | @@ -1513,47 +1603,47 @@ static IrInstruction *ir_build_store_ptr(IrBuilder *irb, Scope *scope, AstNode * |
| 1513 | } | 1603 | } |
| 1514 | | 1604 | |
| 1515 | static IrInstruction *ir_build_var_decl_src(IrBuilder *irb, Scope *scope, AstNode *source_node, | 1605 | static IrInstruction *ir_build_var_decl_src(IrBuilder *irb, Scope *scope, AstNode *source_node, |
| 1516 | ZigVar *var, IrInstruction *var_type, IrInstruction *align_value, IrInstruction *init_value) | 1606 | ZigVar *var, IrInstruction *align_value, IrInstruction *ptr) |
| 1517 | { | 1607 | { |
| 1518 | IrInstructionDeclVarSrc *decl_var_instruction = ir_build_instruction<IrInstructionDeclVarSrc>(irb, scope, source_node); | 1608 | IrInstructionDeclVarSrc *decl_var_instruction = ir_build_instruction<IrInstructionDeclVarSrc>(irb, scope, source_node); |
| 1519 | decl_var_instruction->base.value.special = ConstValSpecialStatic; | 1609 | decl_var_instruction->base.value.special = ConstValSpecialStatic; |
| 1520 | decl_var_instruction->base.value.type = irb->codegen->builtin_types.entry_void; | 1610 | decl_var_instruction->base.value.type = irb->codegen->builtin_types.entry_void; |
| 1521 | decl_var_instruction->var = var; | 1611 | decl_var_instruction->var = var; |
| 1522 | decl_var_instruction->var_type = var_type; | | |
| 1523 | decl_var_instruction->align_value = align_value; | 1612 | decl_var_instruction->align_value = align_value; |
| 1524 | decl_var_instruction->init_value = init_value; | 1613 | decl_var_instruction->ptr = ptr; |
| 1525 | | 1614 | |
| 1526 | if (var_type != nullptr) ir_ref_instruction(var_type, irb->current_basic_block); | | |
| 1527 | if (align_value != nullptr) ir_ref_instruction(align_value, irb->current_basic_block); | 1615 | if (align_value != nullptr) ir_ref_instruction(align_value, irb->current_basic_block); |
| 1528 | ir_ref_instruction(init_value, irb->current_basic_block); | 1616 | ir_ref_instruction(ptr, irb->current_basic_block); |
| 1529 | | 1617 | |
| 1530 | return &decl_var_instruction->base; | 1618 | return &decl_var_instruction->base; |
| 1531 | } | 1619 | } |
| 1532 | | 1620 | |
| 1533 | static IrInstruction *ir_build_var_decl_gen(IrAnalyze *ira, IrInstruction *source_instruction, | 1621 | static IrInstruction *ir_build_var_decl_gen(IrAnalyze *ira, IrInstruction *source_instruction, |
| 1534 | ZigVar *var, IrInstruction *init_value) | 1622 | ZigVar *var, IrInstruction *var_ptr) |
| 1535 | { | 1623 | { |
| 1536 | IrInstructionDeclVarGen *decl_var_instruction = ir_build_instruction<IrInstructionDeclVarGen>(&ira->new_irb, | 1624 | IrInstructionDeclVarGen *decl_var_instruction = ir_build_instruction<IrInstructionDeclVarGen>(&ira->new_irb, |
| 1537 | source_instruction->scope, source_instruction->source_node); | 1625 | source_instruction->scope, source_instruction->source_node); |
| 1538 | decl_var_instruction->base.value.special = ConstValSpecialStatic; | 1626 | decl_var_instruction->base.value.special = ConstValSpecialStatic; |
| 1539 | decl_var_instruction->base.value.type = ira->codegen->builtin_types.entry_void; | 1627 | decl_var_instruction->base.value.type = ira->codegen->builtin_types.entry_void; |
| 1540 | decl_var_instruction->var = var; | 1628 | decl_var_instruction->var = var; |
| 1541 | decl_var_instruction->init_value = init_value; | 1629 | decl_var_instruction->var_ptr = var_ptr; |
| 1542 | | 1630 | |
| 1543 | ir_ref_instruction(init_value, ira->new_irb.current_basic_block); | 1631 | ir_ref_instruction(var_ptr, ira->new_irb.current_basic_block); |
| 1544 | | 1632 | |
| 1545 | return &decl_var_instruction->base; | 1633 | return &decl_var_instruction->base; |
| 1546 | } | 1634 | } |
| 1547 | | 1635 | |
| 1548 | static IrInstruction *ir_build_resize_slice(IrAnalyze *ira, IrInstruction *source_instruction, | 1636 | static IrInstruction *ir_build_resize_slice(IrAnalyze *ira, IrInstruction *source_instruction, |
| 1549 | IrInstruction *operand, ZigType *ty) | 1637 | IrInstruction *operand, ZigType *ty, IrInstruction *result_loc) |
| 1550 | { | 1638 | { |
| 1551 | IrInstructionResizeSlice *instruction = ir_build_instruction<IrInstructionResizeSlice>(&ira->new_irb, | 1639 | IrInstructionResizeSlice *instruction = ir_build_instruction<IrInstructionResizeSlice>(&ira->new_irb, |
| 1552 | source_instruction->scope, source_instruction->source_node); | 1640 | source_instruction->scope, source_instruction->source_node); |
| 1553 | instruction->base.value.type = ty; | 1641 | instruction->base.value.type = ty; |
| 1554 | instruction->operand = operand; | 1642 | instruction->operand = operand; |
| | 1643 | instruction->result_loc = result_loc; |
| 1555 | | 1644 | |
| 1556 | ir_ref_instruction(operand, ira->new_irb.current_basic_block); | 1645 | ir_ref_instruction(operand, ira->new_irb.current_basic_block); |
| | 1646 | ir_ref_instruction(result_loc, ira->new_irb.current_basic_block); |
| 1557 | | 1647 | |
| 1558 | return &instruction->base; | 1648 | return &instruction->base; |
| 1559 | } | 1649 | } |
| ... | @@ -1594,27 +1684,6 @@ static IrInstruction *ir_build_typeof(IrBuilder *irb, Scope *scope, AstNode *sou | ... | @@ -1594,27 +1684,6 @@ static IrInstruction *ir_build_typeof(IrBuilder *irb, Scope *scope, AstNode *sou |
| 1594 | return &instruction->base; | 1684 | return &instruction->base; |
| 1595 | } | 1685 | } |
| 1596 | | 1686 | |
| 1597 | static IrInstruction *ir_build_to_ptr_type(IrBuilder *irb, Scope *scope, AstNode *source_node, IrInstruction *ptr) { | | |
| 1598 | IrInstructionToPtrType *instruction = ir_build_instruction<IrInstructionToPtrType>(irb, scope, source_node); | | |
| 1599 | instruction->ptr = ptr; | | |
| 1600 | | | |
| 1601 | ir_ref_instruction(ptr, irb->current_basic_block); | | |
| 1602 | | | |
| 1603 | return &instruction->base; | | |
| 1604 | } | | |
| 1605 | | | |
| 1606 | static IrInstruction *ir_build_ptr_type_child(IrBuilder *irb, Scope *scope, AstNode *source_node, | | |
| 1607 | IrInstruction *value) | | |
| 1608 | { | | |
| 1609 | IrInstructionPtrTypeChild *instruction = ir_build_instruction<IrInstructionPtrTypeChild>( | | |
| 1610 | irb, scope, source_node); | | |
| 1611 | instruction->value = value; | | |
| 1612 | | | |
| 1613 | ir_ref_instruction(value, irb->current_basic_block); | | |
| 1614 | | | |
| 1615 | return &instruction->base; | | |
| 1616 | } | | |
| 1617 | | | |
| 1618 | static IrInstruction *ir_build_set_cold(IrBuilder *irb, Scope *scope, AstNode *source_node, IrInstruction *is_cold) { | 1687 | static IrInstruction *ir_build_set_cold(IrBuilder *irb, Scope *scope, AstNode *source_node, IrInstruction *is_cold) { |
| 1619 | IrInstructionSetCold *instruction = ir_build_instruction<IrInstructionSetCold>(irb, scope, source_node); | 1688 | IrInstructionSetCold *instruction = ir_build_instruction<IrInstructionSetCold>(irb, scope, source_node); |
| 1620 | instruction->is_cold = is_cold; | 1689 | instruction->is_cold = is_cold; |
| ... | @@ -1740,40 +1809,59 @@ static IrInstruction *ir_build_test_nonnull(IrBuilder *irb, Scope *scope, AstNod | ... | @@ -1740,40 +1809,59 @@ static IrInstruction *ir_build_test_nonnull(IrBuilder *irb, Scope *scope, AstNod |
| 1740 | } | 1809 | } |
| 1741 | | 1810 | |
| 1742 | static IrInstruction *ir_build_optional_unwrap_ptr(IrBuilder *irb, Scope *scope, AstNode *source_node, | 1811 | static IrInstruction *ir_build_optional_unwrap_ptr(IrBuilder *irb, Scope *scope, AstNode *source_node, |
| 1743 | IrInstruction *base_ptr, bool safety_check_on) | 1812 | IrInstruction *base_ptr, bool safety_check_on, bool initializing) |
| 1744 | { | 1813 | { |
| 1745 | IrInstructionOptionalUnwrapPtr *instruction = ir_build_instruction<IrInstructionOptionalUnwrapPtr>(irb, scope, source_node); | 1814 | IrInstructionOptionalUnwrapPtr *instruction = ir_build_instruction<IrInstructionOptionalUnwrapPtr>(irb, scope, source_node); |
| 1746 | instruction->base_ptr = base_ptr; | 1815 | instruction->base_ptr = base_ptr; |
| 1747 | instruction->safety_check_on = safety_check_on; | 1816 | instruction->safety_check_on = safety_check_on; |
| | 1817 | instruction->initializing = initializing; |
| 1748 | | 1818 | |
| 1749 | ir_ref_instruction(base_ptr, irb->current_basic_block); | 1819 | ir_ref_instruction(base_ptr, irb->current_basic_block); |
| 1750 | | 1820 | |
| 1751 | return &instruction->base; | 1821 | return &instruction->base; |
| 1752 | } | 1822 | } |
| 1753 | | 1823 | |
| 1754 | static IrInstruction *ir_build_maybe_wrap(IrBuilder *irb, Scope *scope, AstNode *source_node, IrInstruction *value) { | 1824 | static IrInstruction *ir_build_optional_wrap(IrAnalyze *ira, IrInstruction *source_instruction, ZigType *result_ty, |
| 1755 | IrInstructionOptionalWrap *instruction = ir_build_instruction<IrInstructionOptionalWrap>(irb, scope, source_node); | 1825 | IrInstruction *operand, IrInstruction *result_loc) |
| 1756 | instruction->value = value; | 1826 | { |
| | 1827 | IrInstructionOptionalWrap *instruction = ir_build_instruction<IrInstructionOptionalWrap>( |
| | 1828 | &ira->new_irb, source_instruction->scope, source_instruction->source_node); |
| | 1829 | instruction->base.value.type = result_ty; |
| | 1830 | instruction->operand = operand; |
| | 1831 | instruction->result_loc = result_loc; |
| 1757 | | 1832 | |
| 1758 | ir_ref_instruction(value, irb->current_basic_block); | 1833 | ir_ref_instruction(operand, ira->new_irb.current_basic_block); |
| | 1834 | if (result_loc != nullptr) ir_ref_instruction(result_loc, ira->new_irb.current_basic_block); |
| 1759 | | 1835 | |
| 1760 | return &instruction->base; | 1836 | return &instruction->base; |
| 1761 | } | 1837 | } |
| 1762 | | 1838 | |
| 1763 | static IrInstruction *ir_build_err_wrap_payload(IrBuilder *irb, Scope *scope, AstNode *source_node, IrInstruction *value) { | 1839 | static IrInstruction *ir_build_err_wrap_payload(IrAnalyze *ira, IrInstruction *source_instruction, |
| 1764 | IrInstructionErrWrapPayload *instruction = ir_build_instruction<IrInstructionErrWrapPayload>(irb, scope, source_node); | 1840 | ZigType *result_type, IrInstruction *operand, IrInstruction *result_loc) |
| 1765 | instruction->value = value; | 1841 | { |
| | 1842 | IrInstructionErrWrapPayload *instruction = ir_build_instruction<IrInstructionErrWrapPayload>( |
| | 1843 | &ira->new_irb, source_instruction->scope, source_instruction->source_node); |
| | 1844 | instruction->base.value.type = result_type; |
| | 1845 | instruction->operand = operand; |
| | 1846 | instruction->result_loc = result_loc; |
| 1766 | | 1847 | |
| 1767 | ir_ref_instruction(value, irb->current_basic_block); | 1848 | ir_ref_instruction(operand, ira->new_irb.current_basic_block); |
| | 1849 | if (result_loc != nullptr) ir_ref_instruction(result_loc, ira->new_irb.current_basic_block); |
| 1768 | | 1850 | |
| 1769 | return &instruction->base; | 1851 | return &instruction->base; |
| 1770 | } | 1852 | } |
| 1771 | | 1853 | |
| 1772 | static IrInstruction *ir_build_err_wrap_code(IrBuilder *irb, Scope *scope, AstNode *source_node, IrInstruction *value) { | 1854 | static IrInstruction *ir_build_err_wrap_code(IrAnalyze *ira, IrInstruction *source_instruction, |
| 1773 | IrInstructionErrWrapCode *instruction = ir_build_instruction<IrInstructionErrWrapCode>(irb, scope, source_node); | 1855 | ZigType *result_type, IrInstruction *operand, IrInstruction *result_loc) |
| 1774 | instruction->value = value; | 1856 | { |
| | 1857 | IrInstructionErrWrapCode *instruction = ir_build_instruction<IrInstructionErrWrapCode>( |
| | 1858 | &ira->new_irb, source_instruction->scope, source_instruction->source_node); |
| | 1859 | instruction->base.value.type = result_type; |
| | 1860 | instruction->operand = operand; |
| | 1861 | instruction->result_loc = result_loc; |
| 1775 | | 1862 | |
| 1776 | ir_ref_instruction(value, irb->current_basic_block); | 1863 | ir_ref_instruction(operand, ira->new_irb.current_basic_block); |
| | 1864 | if (result_loc != nullptr) ir_ref_instruction(result_loc, ira->new_irb.current_basic_block); |
| 1777 | | 1865 | |
| 1778 | return &instruction->base; | 1866 | return &instruction->base; |
| 1779 | } | 1867 | } |
| ... | @@ -1930,6 +2018,21 @@ static IrInstruction *ir_build_ref(IrBuilder *irb, Scope *scope, AstNode *source | ... | @@ -1930,6 +2018,21 @@ static IrInstruction *ir_build_ref(IrBuilder *irb, Scope *scope, AstNode *source |
| 1930 | return &instruction->base; | 2018 | return &instruction->base; |
| 1931 | } | 2019 | } |
| 1932 | | 2020 | |
| | 2021 | static IrInstruction *ir_build_ref_gen(IrAnalyze *ira, IrInstruction *source_instruction, ZigType *result_type, |
| | 2022 | IrInstruction *operand, IrInstruction *result_loc) |
| | 2023 | { |
| | 2024 | IrInstructionRefGen *instruction = ir_build_instruction<IrInstructionRefGen>(&ira->new_irb, |
| | 2025 | source_instruction->scope, source_instruction->source_node); |
| | 2026 | instruction->base.value.type = result_type; |
| | 2027 | instruction->operand = operand; |
| | 2028 | instruction->result_loc = result_loc; |
| | 2029 | |
| | 2030 | ir_ref_instruction(operand, ira->new_irb.current_basic_block); |
| | 2031 | if (result_loc != nullptr) ir_ref_instruction(result_loc, ira->new_irb.current_basic_block); |
| | 2032 | |
| | 2033 | return &instruction->base; |
| | 2034 | } |
| | 2035 | |
| 1933 | static IrInstruction *ir_build_compile_err(IrBuilder *irb, Scope *scope, AstNode *source_node, IrInstruction *msg) { | 2036 | static IrInstruction *ir_build_compile_err(IrBuilder *irb, Scope *scope, AstNode *source_node, IrInstruction *msg) { |
| 1934 | IrInstructionCompileErr *instruction = ir_build_instruction<IrInstructionCompileErr>(irb, scope, source_node); | 2037 | IrInstructionCompileErr *instruction = ir_build_instruction<IrInstructionCompileErr>(irb, scope, source_node); |
| 1935 | instruction->msg = msg; | 2038 | instruction->msg = msg; |
| ... | @@ -2007,8 +2110,7 @@ static IrInstruction *ir_build_embed_file(IrBuilder *irb, Scope *scope, AstNode | ... | @@ -2007,8 +2110,7 @@ static IrInstruction *ir_build_embed_file(IrBuilder *irb, Scope *scope, AstNode |
| 2007 | | 2110 | |
| 2008 | static IrInstruction *ir_build_cmpxchg_src(IrBuilder *irb, Scope *scope, AstNode *source_node, | 2111 | static IrInstruction *ir_build_cmpxchg_src(IrBuilder *irb, Scope *scope, AstNode *source_node, |
| 2009 | IrInstruction *type_value, IrInstruction *ptr, IrInstruction *cmp_value, IrInstruction *new_value, | 2112 | IrInstruction *type_value, IrInstruction *ptr, IrInstruction *cmp_value, IrInstruction *new_value, |
| 2010 | IrInstruction *success_order_value, IrInstruction *failure_order_value, | 2113 | IrInstruction *success_order_value, IrInstruction *failure_order_value, bool is_weak, ResultLoc *result_loc) |
| 2011 | bool is_weak) | | |
| 2012 | { | 2114 | { |
| 2013 | IrInstructionCmpxchgSrc *instruction = ir_build_instruction<IrInstructionCmpxchgSrc>(irb, scope, source_node); | 2115 | IrInstructionCmpxchgSrc *instruction = ir_build_instruction<IrInstructionCmpxchgSrc>(irb, scope, source_node); |
| 2014 | instruction->type_value = type_value; | 2116 | instruction->type_value = type_value; |
| ... | @@ -2018,6 +2120,7 @@ static IrInstruction *ir_build_cmpxchg_src(IrBuilder *irb, Scope *scope, AstNode | ... | @@ -2018,6 +2120,7 @@ static IrInstruction *ir_build_cmpxchg_src(IrBuilder *irb, Scope *scope, AstNode |
| 2018 | instruction->success_order_value = success_order_value; | 2120 | instruction->success_order_value = success_order_value; |
| 2019 | instruction->failure_order_value = failure_order_value; | 2121 | instruction->failure_order_value = failure_order_value; |
| 2020 | instruction->is_weak = is_weak; | 2122 | instruction->is_weak = is_weak; |
| | 2123 | instruction->result_loc = result_loc; |
| 2021 | | 2124 | |
| 2022 | ir_ref_instruction(type_value, irb->current_basic_block); | 2125 | ir_ref_instruction(type_value, irb->current_basic_block); |
| 2023 | ir_ref_instruction(ptr, irb->current_basic_block); | 2126 | ir_ref_instruction(ptr, irb->current_basic_block); |
| ... | @@ -2029,22 +2132,25 @@ static IrInstruction *ir_build_cmpxchg_src(IrBuilder *irb, Scope *scope, AstNode | ... | @@ -2029,22 +2132,25 @@ static IrInstruction *ir_build_cmpxchg_src(IrBuilder *irb, Scope *scope, AstNode |
| 2029 | return &instruction->base; | 2132 | return &instruction->base; |
| 2030 | } | 2133 | } |
| 2031 | | 2134 | |
| 2032 | static IrInstruction *ir_build_cmpxchg_gen(IrAnalyze *ira, IrInstruction *source_instruction, | 2135 | static IrInstruction *ir_build_cmpxchg_gen(IrAnalyze *ira, IrInstruction *source_instruction, ZigType *result_type, |
| 2033 | IrInstruction *ptr, IrInstruction *cmp_value, IrInstruction *new_value, | 2136 | IrInstruction *ptr, IrInstruction *cmp_value, IrInstruction *new_value, |
| 2034 | AtomicOrder success_order, AtomicOrder failure_order, bool is_weak) | 2137 | AtomicOrder success_order, AtomicOrder failure_order, bool is_weak, IrInstruction *result_loc) |
| 2035 | { | 2138 | { |
| 2036 | IrInstructionCmpxchgGen *instruction = ir_build_instruction<IrInstructionCmpxchgGen>(&ira->new_irb, | 2139 | IrInstructionCmpxchgGen *instruction = ir_build_instruction<IrInstructionCmpxchgGen>(&ira->new_irb, |
| 2037 | source_instruction->scope, source_instruction->source_node); | 2140 | source_instruction->scope, source_instruction->source_node); |
| | 2141 | instruction->base.value.type = result_type; |
| 2038 | instruction->ptr = ptr; | 2142 | instruction->ptr = ptr; |
| 2039 | instruction->cmp_value = cmp_value; | 2143 | instruction->cmp_value = cmp_value; |
| 2040 | instruction->new_value = new_value; | 2144 | instruction->new_value = new_value; |
| 2041 | instruction->success_order = success_order; | 2145 | instruction->success_order = success_order; |
| 2042 | instruction->failure_order = failure_order; | 2146 | instruction->failure_order = failure_order; |
| 2043 | instruction->is_weak = is_weak; | 2147 | instruction->is_weak = is_weak; |
| | 2148 | instruction->result_loc = result_loc; |
| 2044 | | 2149 | |
| 2045 | ir_ref_instruction(ptr, ira->new_irb.current_basic_block); | 2150 | ir_ref_instruction(ptr, ira->new_irb.current_basic_block); |
| 2046 | ir_ref_instruction(cmp_value, ira->new_irb.current_basic_block); | 2151 | ir_ref_instruction(cmp_value, ira->new_irb.current_basic_block); |
| 2047 | ir_ref_instruction(new_value, ira->new_irb.current_basic_block); | 2152 | ir_ref_instruction(new_value, ira->new_irb.current_basic_block); |
| | 2153 | if (result_loc != nullptr) ir_ref_instruction(result_loc, ira->new_irb.current_basic_block); |
| 2048 | | 2154 | |
| 2049 | return &instruction->base; | 2155 | return &instruction->base; |
| 2050 | } | 2156 | } |
| ... | @@ -2103,19 +2209,25 @@ static IrInstruction *ir_build_err_set_cast(IrBuilder *irb, Scope *scope, AstNod | ... | @@ -2103,19 +2209,25 @@ static IrInstruction *ir_build_err_set_cast(IrBuilder *irb, Scope *scope, AstNod |
| 2103 | return &instruction->base; | 2209 | return &instruction->base; |
| 2104 | } | 2210 | } |
| 2105 | | 2211 | |
| 2106 | static IrInstruction *ir_build_to_bytes(IrBuilder *irb, Scope *scope, AstNode *source_node, IrInstruction *target) { | 2212 | static IrInstruction *ir_build_to_bytes(IrBuilder *irb, Scope *scope, AstNode *source_node, IrInstruction *target, |
| | 2213 | ResultLoc *result_loc) |
| | 2214 | { |
| 2107 | IrInstructionToBytes *instruction = ir_build_instruction<IrInstructionToBytes>(irb, scope, source_node); | 2215 | IrInstructionToBytes *instruction = ir_build_instruction<IrInstructionToBytes>(irb, scope, source_node); |
| 2108 | instruction->target = target; | 2216 | instruction->target = target; |
| | 2217 | instruction->result_loc = result_loc; |
| 2109 | | 2218 | |
| 2110 | ir_ref_instruction(target, irb->current_basic_block); | 2219 | ir_ref_instruction(target, irb->current_basic_block); |
| 2111 | | 2220 | |
| 2112 | return &instruction->base; | 2221 | return &instruction->base; |
| 2113 | } | 2222 | } |
| 2114 | | 2223 | |
| 2115 | static IrInstruction *ir_build_from_bytes(IrBuilder *irb, Scope *scope, AstNode *source_node, IrInstruction *dest_child_type, IrInstruction *target) { | 2224 | static IrInstruction *ir_build_from_bytes(IrBuilder *irb, Scope *scope, AstNode *source_node, |
| | 2225 | IrInstruction *dest_child_type, IrInstruction *target, ResultLoc *result_loc) |
| | 2226 | { |
| 2116 | IrInstructionFromBytes *instruction = ir_build_instruction<IrInstructionFromBytes>(irb, scope, source_node); | 2227 | IrInstructionFromBytes *instruction = ir_build_instruction<IrInstructionFromBytes>(irb, scope, source_node); |
| 2117 | instruction->dest_child_type = dest_child_type; | 2228 | instruction->dest_child_type = dest_child_type; |
| 2118 | instruction->target = target; | 2229 | instruction->target = target; |
| | 2230 | instruction->result_loc = result_loc; |
| 2119 | | 2231 | |
| 2120 | ir_ref_instruction(dest_child_type, irb->current_basic_block); | 2232 | ir_ref_instruction(dest_child_type, irb->current_basic_block); |
| 2121 | ir_ref_instruction(target, irb->current_basic_block); | 2233 | ir_ref_instruction(target, irb->current_basic_block); |
| ... | @@ -2217,14 +2329,15 @@ static IrInstruction *ir_build_memcpy(IrBuilder *irb, Scope *scope, AstNode *sou | ... | @@ -2217,14 +2329,15 @@ static IrInstruction *ir_build_memcpy(IrBuilder *irb, Scope *scope, AstNode *sou |
| 2217 | return &instruction->base; | 2329 | return &instruction->base; |
| 2218 | } | 2330 | } |
| 2219 | | 2331 | |
| 2220 | static IrInstruction *ir_build_slice(IrBuilder *irb, Scope *scope, AstNode *source_node, | 2332 | static IrInstruction *ir_build_slice_src(IrBuilder *irb, Scope *scope, AstNode *source_node, |
| 2221 | IrInstruction *ptr, IrInstruction *start, IrInstruction *end, bool safety_check_on) | 2333 | IrInstruction *ptr, IrInstruction *start, IrInstruction *end, bool safety_check_on, ResultLoc *result_loc) |
| 2222 | { | 2334 | { |
| 2223 | IrInstructionSlice *instruction = ir_build_instruction<IrInstructionSlice>(irb, scope, source_node); | 2335 | IrInstructionSliceSrc *instruction = ir_build_instruction<IrInstructionSliceSrc>(irb, scope, source_node); |
| 2224 | instruction->ptr = ptr; | 2336 | instruction->ptr = ptr; |
| 2225 | instruction->start = start; | 2337 | instruction->start = start; |
| 2226 | instruction->end = end; | 2338 | instruction->end = end; |
| 2227 | instruction->safety_check_on = safety_check_on; | 2339 | instruction->safety_check_on = safety_check_on; |
| | 2340 | instruction->result_loc = result_loc; |
| 2228 | | 2341 | |
| 2229 | ir_ref_instruction(ptr, irb->current_basic_block); | 2342 | ir_ref_instruction(ptr, irb->current_basic_block); |
| 2230 | ir_ref_instruction(start, irb->current_basic_block); | 2343 | ir_ref_instruction(start, irb->current_basic_block); |
| ... | @@ -2233,6 +2346,26 @@ static IrInstruction *ir_build_slice(IrBuilder *irb, Scope *scope, AstNode *sour | ... | @@ -2233,6 +2346,26 @@ static IrInstruction *ir_build_slice(IrBuilder *irb, Scope *scope, AstNode *sour |
| 2233 | return &instruction->base; | 2346 | return &instruction->base; |
| 2234 | } | 2347 | } |
| 2235 | | 2348 | |
| | 2349 | static IrInstruction *ir_build_slice_gen(IrAnalyze *ira, IrInstruction *source_instruction, ZigType *slice_type, |
| | 2350 | IrInstruction *ptr, IrInstruction *start, IrInstruction *end, bool safety_check_on, IrInstruction *result_loc) |
| | 2351 | { |
| | 2352 | IrInstructionSliceGen *instruction = ir_build_instruction<IrInstructionSliceGen>( |
| | 2353 | &ira->new_irb, source_instruction->scope, source_instruction->source_node); |
| | 2354 | instruction->base.value.type = slice_type; |
| | 2355 | instruction->ptr = ptr; |
| | 2356 | instruction->start = start; |
| | 2357 | instruction->end = end; |
| | 2358 | instruction->safety_check_on = safety_check_on; |
| | 2359 | instruction->result_loc = result_loc; |
| | 2360 | |
| | 2361 | ir_ref_instruction(ptr, ira->new_irb.current_basic_block); |
| | 2362 | ir_ref_instruction(start, ira->new_irb.current_basic_block); |
| | 2363 | if (end) ir_ref_instruction(end, ira->new_irb.current_basic_block); |
| | 2364 | ir_ref_instruction(result_loc, ira->new_irb.current_basic_block); |
| | 2365 | |
| | 2366 | return &instruction->base; |
| | 2367 | } |
| | 2368 | |
| 2236 | static IrInstruction *ir_build_member_count(IrBuilder *irb, Scope *scope, AstNode *source_node, IrInstruction *container) { | 2369 | static IrInstruction *ir_build_member_count(IrBuilder *irb, Scope *scope, AstNode *source_node, IrInstruction *container) { |
| 2237 | IrInstructionMemberCount *instruction = ir_build_instruction<IrInstructionMemberCount>(irb, scope, source_node); | 2370 | IrInstructionMemberCount *instruction = ir_build_instruction<IrInstructionMemberCount>(irb, scope, source_node); |
| 2238 | instruction->container = container; | 2371 | instruction->container = container; |
| ... | @@ -2308,6 +2441,75 @@ static IrInstruction *ir_build_overflow_op(IrBuilder *irb, Scope *scope, AstNode | ... | @@ -2308,6 +2441,75 @@ static IrInstruction *ir_build_overflow_op(IrBuilder *irb, Scope *scope, AstNode |
| 2308 | return &instruction->base; | 2441 | return &instruction->base; |
| 2309 | } | 2442 | } |
| 2310 | | 2443 | |
| | 2444 | |
| | 2445 | //TODO Powi, Pow, minnum, maxnum, maximum, minimum, copysign, |
| | 2446 | // lround, llround, lrint, llrint |
| | 2447 | // So far this is only non-complicated type functions. |
| | 2448 | const char *float_op_to_name(BuiltinFnId op, bool llvm_name) { |
| | 2449 | const bool b = llvm_name; |
| | 2450 | |
| | 2451 | switch (op) { |
| | 2452 | case BuiltinFnIdSqrt: |
| | 2453 | return "sqrt"; |
| | 2454 | case BuiltinFnIdSin: |
| | 2455 | return "sin"; |
| | 2456 | case BuiltinFnIdCos: |
| | 2457 | return "cos"; |
| | 2458 | case BuiltinFnIdExp: |
| | 2459 | return "exp"; |
| | 2460 | case BuiltinFnIdExp2: |
| | 2461 | return "exp2"; |
| | 2462 | case BuiltinFnIdLn: |
| | 2463 | return b ? "log" : "ln"; |
| | 2464 | case BuiltinFnIdLog10: |
| | 2465 | return "log10"; |
| | 2466 | case BuiltinFnIdLog2: |
| | 2467 | return "log2"; |
| | 2468 | case BuiltinFnIdFabs: |
| | 2469 | return "fabs"; |
| | 2470 | case BuiltinFnIdFloor: |
| | 2471 | return "floor"; |
| | 2472 | case BuiltinFnIdCeil: |
| | 2473 | return "ceil"; |
| | 2474 | case BuiltinFnIdTrunc: |
| | 2475 | return "trunc"; |
| | 2476 | case BuiltinFnIdNearbyInt: |
| | 2477 | return b ? "nearbyint" : "nearbyInt"; |
| | 2478 | case BuiltinFnIdRound: |
| | 2479 | return "round"; |
| | 2480 | default: |
| | 2481 | zig_unreachable(); |
| | 2482 | } |
| | 2483 | } |
| | 2484 | |
| | 2485 | static IrInstruction *ir_build_float_op(IrBuilder *irb, Scope *scope, AstNode *source_node, IrInstruction *type, IrInstruction *op1, BuiltinFnId op) { |
| | 2486 | IrInstructionFloatOp *instruction = ir_build_instruction<IrInstructionFloatOp>(irb, scope, source_node); |
| | 2487 | instruction->type = type; |
| | 2488 | instruction->op1 = op1; |
| | 2489 | instruction->op = op; |
| | 2490 | |
| | 2491 | if (type != nullptr) ir_ref_instruction(type, irb->current_basic_block); |
| | 2492 | ir_ref_instruction(op1, irb->current_basic_block); |
| | 2493 | |
| | 2494 | return &instruction->base; |
| | 2495 | } |
| | 2496 | |
| | 2497 | static IrInstruction *ir_build_mul_add(IrBuilder *irb, Scope *scope, AstNode *source_node, |
| | 2498 | IrInstruction *type_value, IrInstruction *op1, IrInstruction *op2, IrInstruction *op3) { |
| | 2499 | IrInstructionMulAdd *instruction = ir_build_instruction<IrInstructionMulAdd>(irb, scope, source_node); |
| | 2500 | instruction->type_value = type_value; |
| | 2501 | instruction->op1 = op1; |
| | 2502 | instruction->op2 = op2; |
| | 2503 | instruction->op3 = op3; |
| | 2504 | |
| | 2505 | ir_ref_instruction(type_value, irb->current_basic_block); |
| | 2506 | ir_ref_instruction(op1, irb->current_basic_block); |
| | 2507 | ir_ref_instruction(op2, irb->current_basic_block); |
| | 2508 | ir_ref_instruction(op3, irb->current_basic_block); |
| | 2509 | |
| | 2510 | return &instruction->base; |
| | 2511 | } |
| | 2512 | |
| 2311 | static IrInstruction *ir_build_align_of(IrBuilder *irb, Scope *scope, AstNode *source_node, IrInstruction *type_value) { | 2513 | static IrInstruction *ir_build_align_of(IrBuilder *irb, Scope *scope, AstNode *source_node, IrInstruction *type_value) { |
| 2312 | IrInstructionAlignOf *instruction = ir_build_instruction<IrInstructionAlignOf>(irb, scope, source_node); | 2514 | IrInstructionAlignOf *instruction = ir_build_instruction<IrInstructionAlignOf>(irb, scope, source_node); |
| 2313 | instruction->type_value = type_value; | 2515 | instruction->type_value = type_value; |
| ... | @@ -2317,34 +2519,49 @@ static IrInstruction *ir_build_align_of(IrBuilder *irb, Scope *scope, AstNode *s | ... | @@ -2317,34 +2519,49 @@ static IrInstruction *ir_build_align_of(IrBuilder *irb, Scope *scope, AstNode *s |
| 2317 | return &instruction->base; | 2519 | return &instruction->base; |
| 2318 | } | 2520 | } |
| 2319 | | 2521 | |
| 2320 | static IrInstruction *ir_build_test_err(IrBuilder *irb, Scope *scope, AstNode *source_node, | 2522 | static IrInstruction *ir_build_test_err_src(IrBuilder *irb, Scope *scope, AstNode *source_node, |
| 2321 | IrInstruction *value) | 2523 | IrInstruction *base_ptr, bool resolve_err_set) |
| 2322 | { | 2524 | { |
| 2323 | IrInstructionTestErr *instruction = ir_build_instruction<IrInstructionTestErr>(irb, scope, source_node); | 2525 | IrInstructionTestErrSrc *instruction = ir_build_instruction<IrInstructionTestErrSrc>(irb, scope, source_node); |
| 2324 | instruction->value = value; | 2526 | instruction->base_ptr = base_ptr; |
| | 2527 | instruction->resolve_err_set = resolve_err_set; |
| 2325 | | 2528 | |
| 2326 | ir_ref_instruction(value, irb->current_basic_block); | 2529 | ir_ref_instruction(base_ptr, irb->current_basic_block); |
| 2327 | | 2530 | |
| 2328 | return &instruction->base; | 2531 | return &instruction->base; |
| 2329 | } | 2532 | } |
| 2330 | | 2533 | |
| 2331 | static IrInstruction *ir_build_unwrap_err_code(IrBuilder *irb, Scope *scope, AstNode *source_node, | 2534 | static IrInstruction *ir_build_test_err_gen(IrAnalyze *ira, IrInstruction *source_instruction, |
| 2332 | IrInstruction *err_union) | 2535 | IrInstruction *err_union) |
| 2333 | { | 2536 | { |
| 2334 | IrInstructionUnwrapErrCode *instruction = ir_build_instruction<IrInstructionUnwrapErrCode>(irb, scope, source_node); | 2537 | IrInstructionTestErrGen *instruction = ir_build_instruction<IrInstructionTestErrGen>( |
| | 2538 | &ira->new_irb, source_instruction->scope, source_instruction->source_node); |
| | 2539 | instruction->base.value.type = ira->codegen->builtin_types.entry_bool; |
| 2335 | instruction->err_union = err_union; | 2540 | instruction->err_union = err_union; |
| 2336 | | 2541 | |
| 2337 | ir_ref_instruction(err_union, irb->current_basic_block); | 2542 | ir_ref_instruction(err_union, ira->new_irb.current_basic_block); |
| | 2543 | |
| | 2544 | return &instruction->base; |
| | 2545 | } |
| | 2546 | |
| | 2547 | static IrInstruction *ir_build_unwrap_err_code(IrBuilder *irb, Scope *scope, AstNode *source_node, |
| | 2548 | IrInstruction *err_union_ptr) |
| | 2549 | { |
| | 2550 | IrInstructionUnwrapErrCode *instruction = ir_build_instruction<IrInstructionUnwrapErrCode>(irb, scope, source_node); |
| | 2551 | instruction->err_union_ptr = err_union_ptr; |
| | 2552 | |
| | 2553 | ir_ref_instruction(err_union_ptr, irb->current_basic_block); |
| 2338 | | 2554 | |
| 2339 | return &instruction->base; | 2555 | return &instruction->base; |
| 2340 | } | 2556 | } |
| 2341 | | 2557 | |
| 2342 | static IrInstruction *ir_build_unwrap_err_payload(IrBuilder *irb, Scope *scope, AstNode *source_node, | 2558 | static IrInstruction *ir_build_unwrap_err_payload(IrBuilder *irb, Scope *scope, AstNode *source_node, |
| 2343 | IrInstruction *value, bool safety_check_on) | 2559 | IrInstruction *value, bool safety_check_on, bool initializing) |
| 2344 | { | 2560 | { |
| 2345 | IrInstructionUnwrapErrPayload *instruction = ir_build_instruction<IrInstructionUnwrapErrPayload>(irb, scope, source_node); | 2561 | IrInstructionUnwrapErrPayload *instruction = ir_build_instruction<IrInstructionUnwrapErrPayload>(irb, scope, source_node); |
| 2346 | instruction->value = value; | 2562 | instruction->value = value; |
| 2347 | instruction->safety_check_on = safety_check_on; | 2563 | instruction->safety_check_on = safety_check_on; |
| | 2564 | instruction->initializing = initializing; |
| 2348 | | 2565 | |
| 2349 | ir_ref_instruction(value, irb->current_basic_block); | 2566 | ir_ref_instruction(value, irb->current_basic_block); |
| 2350 | | 2567 | |
| ... | @@ -2414,28 +2631,28 @@ static IrInstruction *ir_build_ptr_cast_gen(IrAnalyze *ira, IrInstruction *sourc | ... | @@ -2414,28 +2631,28 @@ static IrInstruction *ir_build_ptr_cast_gen(IrAnalyze *ira, IrInstruction *sourc |
| 2414 | } | 2631 | } |
| 2415 | | 2632 | |
| 2416 | static IrInstruction *ir_build_load_ptr_gen(IrAnalyze *ira, IrInstruction *source_instruction, | 2633 | static IrInstruction *ir_build_load_ptr_gen(IrAnalyze *ira, IrInstruction *source_instruction, |
| 2417 | IrInstruction *ptr, ZigType *ty) | 2634 | IrInstruction *ptr, ZigType *ty, IrInstruction *result_loc) |
| 2418 | { | 2635 | { |
| 2419 | IrInstructionLoadPtrGen *instruction = ir_build_instruction<IrInstructionLoadPtrGen>( | 2636 | IrInstructionLoadPtrGen *instruction = ir_build_instruction<IrInstructionLoadPtrGen>( |
| 2420 | &ira->new_irb, source_instruction->scope, source_instruction->source_node); | 2637 | &ira->new_irb, source_instruction->scope, source_instruction->source_node); |
| 2421 | instruction->base.value.type = ty; | 2638 | instruction->base.value.type = ty; |
| 2422 | instruction->ptr = ptr; | 2639 | instruction->ptr = ptr; |
| | 2640 | instruction->result_loc = result_loc; |
| 2423 | | 2641 | |
| 2424 | ir_ref_instruction(ptr, ira->new_irb.current_basic_block); | 2642 | ir_ref_instruction(ptr, ira->new_irb.current_basic_block); |
| | 2643 | if (result_loc != nullptr) ir_ref_instruction(result_loc, ira->new_irb.current_basic_block); |
| 2425 | | 2644 | |
| 2426 | return &instruction->base; | 2645 | return &instruction->base; |
| 2427 | } | 2646 | } |
| 2428 | | 2647 | |
| 2429 | static IrInstruction *ir_build_bit_cast(IrBuilder *irb, Scope *scope, AstNode *source_node, | 2648 | static IrInstruction *ir_build_bit_cast_src(IrBuilder *irb, Scope *scope, AstNode *source_node, |
| 2430 | IrInstruction *dest_type, IrInstruction *value) | 2649 | IrInstruction *operand, ResultLocBitCast *result_loc_bit_cast) |
| 2431 | { | 2650 | { |
| 2432 | IrInstructionBitCast *instruction = ir_build_instruction<IrInstructionBitCast>( | 2651 | IrInstructionBitCastSrc *instruction = ir_build_instruction<IrInstructionBitCastSrc>(irb, scope, source_node); |
| 2433 | irb, scope, source_node); | 2652 | instruction->operand = operand; |
| 2434 | instruction->dest_type = dest_type; | 2653 | instruction->result_loc_bit_cast = result_loc_bit_cast; |
| 2435 | instruction->value = value; | | |
| 2436 | | 2654 | |
| 2437 | ir_ref_instruction(dest_type, irb->current_basic_block); | 2655 | ir_ref_instruction(operand, irb->current_basic_block); |
| 2438 | ir_ref_instruction(value, irb->current_basic_block); | | |
| 2439 | | 2656 | |
| 2440 | return &instruction->base; | 2657 | return &instruction->base; |
| 2441 | } | 2658 | } |
| ... | @@ -2587,11 +2804,8 @@ static IrInstruction *ir_build_type_name(IrBuilder *irb, Scope *scope, AstNode * | ... | @@ -2587,11 +2804,8 @@ static IrInstruction *ir_build_type_name(IrBuilder *irb, Scope *scope, AstNode * |
| 2587 | return &instruction->base; | 2804 | return &instruction->base; |
| 2588 | } | 2805 | } |
| 2589 | | 2806 | |
| 2590 | static IrInstruction *ir_build_decl_ref(IrBuilder *irb, Scope *scope, AstNode *source_node, | 2807 | static IrInstruction *ir_build_decl_ref(IrBuilder *irb, Scope *scope, AstNode *source_node, Tld *tld, LVal lval) { |
| 2591 | Tld *tld, LVal lval) | 2808 | IrInstructionDeclRef *instruction = ir_build_instruction<IrInstructionDeclRef>(irb, scope, source_node); |
| 2592 | { | | |
| 2593 | IrInstructionDeclRef *instruction = ir_build_instruction<IrInstructionDeclRef>( | | |
| 2594 | irb, scope, source_node); | | |
| 2595 | instruction->tld = tld; | 2809 | instruction->tld = tld; |
| 2596 | instruction->lval = lval; | 2810 | instruction->lval = lval; |
| 2597 | | 2811 | |
| ... | @@ -2719,6 +2933,53 @@ static IrInstruction *ir_build_align_cast(IrBuilder *irb, Scope *scope, AstNode | ... | @@ -2719,6 +2933,53 @@ static IrInstruction *ir_build_align_cast(IrBuilder *irb, Scope *scope, AstNode |
| 2719 | return &instruction->base; | 2933 | return &instruction->base; |
| 2720 | } | 2934 | } |
| 2721 | | 2935 | |
| | 2936 | static IrInstruction *ir_build_implicit_cast(IrBuilder *irb, Scope *scope, AstNode *source_node, |
| | 2937 | IrInstruction *dest_type, IrInstruction *target, ResultLoc *result_loc) |
| | 2938 | { |
| | 2939 | IrInstructionImplicitCast *instruction = ir_build_instruction<IrInstructionImplicitCast>(irb, scope, source_node); |
| | 2940 | instruction->dest_type = dest_type; |
| | 2941 | instruction->target = target; |
| | 2942 | instruction->result_loc = result_loc; |
| | 2943 | |
| | 2944 | ir_ref_instruction(dest_type, irb->current_basic_block); |
| | 2945 | ir_ref_instruction(target, irb->current_basic_block); |
| | 2946 | |
| | 2947 | return &instruction->base; |
| | 2948 | } |
| | 2949 | |
| | 2950 | static IrInstruction *ir_build_resolve_result(IrBuilder *irb, Scope *scope, AstNode *source_node, |
| | 2951 | ResultLoc *result_loc, IrInstruction *ty) |
| | 2952 | { |
| | 2953 | IrInstructionResolveResult *instruction = ir_build_instruction<IrInstructionResolveResult>(irb, scope, source_node); |
| | 2954 | instruction->result_loc = result_loc; |
| | 2955 | instruction->ty = ty; |
| | 2956 | |
| | 2957 | ir_ref_instruction(ty, irb->current_basic_block); |
| | 2958 | |
| | 2959 | return &instruction->base; |
| | 2960 | } |
| | 2961 | |
| | 2962 | static IrInstruction *ir_build_reset_result(IrBuilder *irb, Scope *scope, AstNode *source_node, |
| | 2963 | ResultLoc *result_loc) |
| | 2964 | { |
| | 2965 | IrInstructionResetResult *instruction = ir_build_instruction<IrInstructionResetResult>(irb, scope, source_node); |
| | 2966 | instruction->result_loc = result_loc; |
| | 2967 | |
| | 2968 | return &instruction->base; |
| | 2969 | } |
| | 2970 | |
| | 2971 | static IrInstruction *ir_build_result_ptr(IrBuilder *irb, Scope *scope, AstNode *source_node, |
| | 2972 | ResultLoc *result_loc, IrInstruction *result) |
| | 2973 | { |
| | 2974 | IrInstructionResultPtr *instruction = ir_build_instruction<IrInstructionResultPtr>(irb, scope, source_node); |
| | 2975 | instruction->result_loc = result_loc; |
| | 2976 | instruction->result = result; |
| | 2977 | |
| | 2978 | ir_ref_instruction(result, irb->current_basic_block); |
| | 2979 | |
| | 2980 | return &instruction->base; |
| | 2981 | } |
| | 2982 | |
| 2722 | static IrInstruction *ir_build_opaque_type(IrBuilder *irb, Scope *scope, AstNode *source_node) { | 2983 | static IrInstruction *ir_build_opaque_type(IrBuilder *irb, Scope *scope, AstNode *source_node) { |
| 2723 | IrInstructionOpaqueType *instruction = ir_build_instruction<IrInstructionOpaqueType>(irb, scope, source_node); | 2984 | IrInstructionOpaqueType *instruction = ir_build_instruction<IrInstructionOpaqueType>(irb, scope, source_node); |
| 2724 | | 2985 | |
| ... | @@ -3013,17 +3274,6 @@ static IrInstruction *ir_build_mark_err_ret_trace_ptr(IrBuilder *irb, Scope *sco | ... | @@ -3013,17 +3274,6 @@ static IrInstruction *ir_build_mark_err_ret_trace_ptr(IrBuilder *irb, Scope *sco |
| 3013 | return &instruction->base; | 3274 | return &instruction->base; |
| 3014 | } | 3275 | } |
| 3015 | | 3276 | |
| 3016 | static IrInstruction *ir_build_sqrt(IrBuilder *irb, Scope *scope, AstNode *source_node, IrInstruction *type, IrInstruction *op) { | | |
| 3017 | IrInstructionSqrt *instruction = ir_build_instruction<IrInstructionSqrt>(irb, scope, source_node); | | |
| 3018 | instruction->type = type; | | |
| 3019 | instruction->op = op; | | |
| 3020 | | | |
| 3021 | if (type != nullptr) ir_ref_instruction(type, irb->current_basic_block); | | |
| 3022 | ir_ref_instruction(op, irb->current_basic_block); | | |
| 3023 | | | |
| 3024 | return &instruction->base; | | |
| 3025 | } | | |
| 3026 | | | |
| 3027 | static IrInstruction *ir_build_has_decl(IrBuilder *irb, Scope *scope, AstNode *source_node, | 3277 | static IrInstruction *ir_build_has_decl(IrBuilder *irb, Scope *scope, AstNode *source_node, |
| 3028 | IrInstruction *container, IrInstruction *name) | 3278 | IrInstruction *container, IrInstruction *name) |
| 3029 | { | 3279 | { |
| ... | @@ -3058,16 +3308,31 @@ static IrInstruction *ir_build_check_runtime_scope(IrBuilder *irb, Scope *scope, | ... | @@ -3058,16 +3308,31 @@ static IrInstruction *ir_build_check_runtime_scope(IrBuilder *irb, Scope *scope, |
| 3058 | } | 3308 | } |
| 3059 | | 3309 | |
| 3060 | static IrInstruction *ir_build_vector_to_array(IrAnalyze *ira, IrInstruction *source_instruction, | 3310 | static IrInstruction *ir_build_vector_to_array(IrAnalyze *ira, IrInstruction *source_instruction, |
| 3061 | IrInstruction *vector, ZigType *result_type) | 3311 | ZigType *result_type, IrInstruction *vector, IrInstruction *result_loc) |
| 3062 | { | 3312 | { |
| 3063 | IrInstructionVectorToArray *instruction = ir_build_instruction<IrInstructionVectorToArray>(&ira->new_irb, | 3313 | IrInstructionVectorToArray *instruction = ir_build_instruction<IrInstructionVectorToArray>(&ira->new_irb, |
| 3064 | source_instruction->scope, source_instruction->source_node); | 3314 | source_instruction->scope, source_instruction->source_node); |
| 3065 | instruction->base.value.type = result_type; | 3315 | instruction->base.value.type = result_type; |
| 3066 | instruction->vector = vector; | 3316 | instruction->vector = vector; |
| | 3317 | instruction->result_loc = result_loc; |
| 3067 | | 3318 | |
| 3068 | ir_ref_instruction(vector, ira->new_irb.current_basic_block); | 3319 | ir_ref_instruction(vector, ira->new_irb.current_basic_block); |
| | 3320 | ir_ref_instruction(result_loc, ira->new_irb.current_basic_block); |
| | 3321 | |
| | 3322 | return &instruction->base; |
| | 3323 | } |
| | 3324 | |
| | 3325 | static IrInstruction *ir_build_ptr_of_array_to_slice(IrAnalyze *ira, IrInstruction *source_instruction, |
| | 3326 | ZigType *result_type, IrInstruction *operand, IrInstruction *result_loc) |
| | 3327 | { |
| | 3328 | IrInstructionPtrOfArrayToSlice *instruction = ir_build_instruction<IrInstructionPtrOfArrayToSlice>(&ira->new_irb, |
| | 3329 | source_instruction->scope, source_instruction->source_node); |
| | 3330 | instruction->base.value.type = result_type; |
| | 3331 | instruction->operand = operand; |
| | 3332 | instruction->result_loc = result_loc; |
| 3069 | | 3333 | |
| 3070 | ir_add_alloca(ira, &instruction->base, result_type); | 3334 | ir_ref_instruction(operand, ira->new_irb.current_basic_block); |
| | 3335 | ir_ref_instruction(result_loc, ira->new_irb.current_basic_block); |
| 3071 | | 3336 | |
| 3072 | return &instruction->base; | 3337 | return &instruction->base; |
| 3073 | } | 3338 | } |
| ... | @@ -3111,18 +3376,57 @@ static IrInstruction *ir_build_assert_non_null(IrAnalyze *ira, IrInstruction *so | ... | @@ -3111,18 +3376,57 @@ static IrInstruction *ir_build_assert_non_null(IrAnalyze *ira, IrInstruction *so |
| 3111 | return &instruction->base; | 3376 | return &instruction->base; |
| 3112 | } | 3377 | } |
| 3113 | | 3378 | |
| 3114 | static void ir_count_defers(IrBuilder *irb, Scope *inner_scope, Scope *outer_scope, size_t *results) { | 3379 | static IrInstruction *ir_build_alloca_src(IrBuilder *irb, Scope *scope, AstNode *source_node, |
| 3115 | results[ReturnKindUnconditional] = 0; | 3380 | IrInstruction *align, const char *name_hint, IrInstruction *is_comptime) |
| 3116 | results[ReturnKindError] = 0; | 3381 | { |
| | 3382 | IrInstructionAllocaSrc *instruction = ir_build_instruction<IrInstructionAllocaSrc>(irb, scope, source_node); |
| | 3383 | instruction->base.is_gen = true; |
| | 3384 | instruction->align = align; |
| | 3385 | instruction->name_hint = name_hint; |
| | 3386 | instruction->is_comptime = is_comptime; |
| 3117 | | 3387 | |
| 3118 | Scope *scope = inner_scope; | 3388 | if (align != nullptr) ir_ref_instruction(align, irb->current_basic_block); |
| | 3389 | if (is_comptime != nullptr) ir_ref_instruction(is_comptime, irb->current_basic_block); |
| 3119 | | 3390 | |
| 3120 | while (scope != outer_scope) { | 3391 | return &instruction->base; |
| 3121 | assert(scope); | 3392 | } |
| 3122 | switch (scope->id) { | 3393 | |
| 3123 | case ScopeIdDefer: { | 3394 | static IrInstructionAllocaGen *ir_create_alloca_gen(IrAnalyze *ira, IrInstruction *source_instruction, |
| 3124 | AstNode *defer_node = scope->source_node; | 3395 | uint32_t align, const char *name_hint) |
| 3125 | assert(defer_node->type == NodeTypeDefer); | 3396 | { |
| | 3397 | IrInstructionAllocaGen *instruction = ir_create_instruction<IrInstructionAllocaGen>(&ira->new_irb, |
| | 3398 | source_instruction->scope, source_instruction->source_node); |
| | 3399 | instruction->align = align; |
| | 3400 | instruction->name_hint = name_hint; |
| | 3401 | |
| | 3402 | return instruction; |
| | 3403 | } |
| | 3404 | |
| | 3405 | static IrInstruction *ir_build_end_expr(IrBuilder *irb, Scope *scope, AstNode *source_node, |
| | 3406 | IrInstruction *value, ResultLoc *result_loc) |
| | 3407 | { |
| | 3408 | IrInstructionEndExpr *instruction = ir_build_instruction<IrInstructionEndExpr>(irb, scope, source_node); |
| | 3409 | instruction->base.is_gen = true; |
| | 3410 | instruction->value = value; |
| | 3411 | instruction->result_loc = result_loc; |
| | 3412 | |
| | 3413 | ir_ref_instruction(value, irb->current_basic_block); |
| | 3414 | |
| | 3415 | return &instruction->base; |
| | 3416 | } |
| | 3417 | |
| | 3418 | static void ir_count_defers(IrBuilder *irb, Scope *inner_scope, Scope *outer_scope, size_t *results) { |
| | 3419 | results[ReturnKindUnconditional] = 0; |
| | 3420 | results[ReturnKindError] = 0; |
| | 3421 | |
| | 3422 | Scope *scope = inner_scope; |
| | 3423 | |
| | 3424 | while (scope != outer_scope) { |
| | 3425 | assert(scope); |
| | 3426 | switch (scope->id) { |
| | 3427 | case ScopeIdDefer: { |
| | 3428 | AstNode *defer_node = scope->source_node; |
| | 3429 | assert(defer_node->type == NodeTypeDefer); |
| 3126 | ReturnKind defer_kind = defer_node->data.defer.kind; | 3430 | ReturnKind defer_kind = defer_node->data.defer.kind; |
| 3127 | results[defer_kind] += 1; | 3431 | results[defer_kind] += 1; |
| 3128 | scope = scope->parent; | 3432 | scope = scope->parent; |
| ... | @@ -3211,6 +3515,7 @@ static void ir_set_cursor_at_end(IrBuilder *irb, IrBasicBlock *basic_block) { | ... | @@ -3211,6 +3515,7 @@ static void ir_set_cursor_at_end(IrBuilder *irb, IrBasicBlock *basic_block) { |
| 3211 | } | 3515 | } |
| 3212 | | 3516 | |
| 3213 | static void ir_set_cursor_at_end_and_append_block(IrBuilder *irb, IrBasicBlock *basic_block) { | 3517 | static void ir_set_cursor_at_end_and_append_block(IrBuilder *irb, IrBasicBlock *basic_block) { |
| | 3518 | basic_block->index = irb->exec->basic_block_list.length; |
| 3214 | irb->exec->basic_block_list.append(basic_block); | 3519 | irb->exec->basic_block_list.append(basic_block); |
| 3215 | ir_set_cursor_at_end(irb, basic_block); | 3520 | ir_set_cursor_at_end(irb, basic_block); |
| 3216 | } | 3521 | } |
| ... | @@ -3299,7 +3604,7 @@ static IrInstruction *ir_gen_async_return(IrBuilder *irb, Scope *scope, AstNode | ... | @@ -3299,7 +3604,7 @@ static IrInstruction *ir_gen_async_return(IrBuilder *irb, Scope *scope, AstNode |
| 3299 | return ir_build_cond_br(irb, scope, node, is_canceled_bool, irb->exec->coro_final_cleanup_block, irb->exec->coro_early_final, is_comptime); | 3604 | return ir_build_cond_br(irb, scope, node, is_canceled_bool, irb->exec->coro_final_cleanup_block, irb->exec->coro_early_final, is_comptime); |
| 3300 | } | 3605 | } |
| 3301 | | 3606 | |
| 3302 | static IrInstruction *ir_gen_return(IrBuilder *irb, Scope *scope, AstNode *node, LVal lval) { | 3607 | static IrInstruction *ir_gen_return(IrBuilder *irb, Scope *scope, AstNode *node, LVal lval, ResultLoc *result_loc) { |
| 3303 | assert(node->type == NodeTypeReturnExpr); | 3608 | assert(node->type == NodeTypeReturnExpr); |
| 3304 | | 3609 | |
| 3305 | ZigFn *fn_entry = exec_fn_entry(irb->exec); | 3610 | ZigFn *fn_entry = exec_fn_entry(irb->exec); |
| ... | @@ -3323,12 +3628,16 @@ static IrInstruction *ir_gen_return(IrBuilder *irb, Scope *scope, AstNode *node, | ... | @@ -3323,12 +3628,16 @@ static IrInstruction *ir_gen_return(IrBuilder *irb, Scope *scope, AstNode *node, |
| 3323 | switch (node->data.return_expr.kind) { | 3628 | switch (node->data.return_expr.kind) { |
| 3324 | case ReturnKindUnconditional: | 3629 | case ReturnKindUnconditional: |
| 3325 | { | 3630 | { |
| | 3631 | ResultLocReturn *result_loc_ret = allocate<ResultLocReturn>(1); |
| | 3632 | result_loc_ret->base.id = ResultLocIdReturn; |
| | 3633 | ir_build_reset_result(irb, scope, node, &result_loc_ret->base); |
| | 3634 | |
| 3326 | IrInstruction *return_value; | 3635 | IrInstruction *return_value; |
| 3327 | if (expr_node) { | 3636 | if (expr_node) { |
| 3328 | // Temporarily set this so that if we return a type it gets the name of the function | 3637 | // Temporarily set this so that if we return a type it gets the name of the function |
| 3329 | ZigFn *prev_name_fn = irb->exec->name_fn; | 3638 | ZigFn *prev_name_fn = irb->exec->name_fn; |
| 3330 | irb->exec->name_fn = exec_fn_entry(irb->exec); | 3639 | irb->exec->name_fn = exec_fn_entry(irb->exec); |
| 3331 | return_value = ir_gen_node(irb, expr_node, scope); | 3640 | return_value = ir_gen_node_extra(irb, expr_node, scope, LValNone, &result_loc_ret->base); |
| 3332 | irb->exec->name_fn = prev_name_fn; | 3641 | irb->exec->name_fn = prev_name_fn; |
| 3333 | if (return_value == irb->codegen->invalid_instruction) | 3642 | if (return_value == irb->codegen->invalid_instruction) |
| 3334 | return irb->codegen->invalid_instruction; | 3643 | return irb->codegen->invalid_instruction; |
| ... | @@ -3346,7 +3655,9 @@ static IrInstruction *ir_gen_return(IrBuilder *irb, Scope *scope, AstNode *node, | ... | @@ -3346,7 +3655,9 @@ static IrInstruction *ir_gen_return(IrBuilder *irb, Scope *scope, AstNode *node, |
| 3346 | ir_gen_defers_for_block(irb, scope, outer_scope, false); | 3655 | ir_gen_defers_for_block(irb, scope, outer_scope, false); |
| 3347 | } | 3656 | } |
| 3348 | | 3657 | |
| 3349 | IrInstruction *is_err = ir_build_test_err(irb, scope, node, return_value); | 3658 | IrInstruction *ret_ptr = ir_build_result_ptr(irb, scope, node, &result_loc_ret->base, |
| | 3659 | return_value); |
| | 3660 | IrInstruction *is_err = ir_build_test_err_src(irb, scope, node, ret_ptr, false); |
| 3350 | | 3661 | |
| 3351 | bool should_inline = ir_should_inline(irb->exec, scope); | 3662 | bool should_inline = ir_should_inline(irb->exec, scope); |
| 3352 | IrInstruction *is_comptime; | 3663 | IrInstruction *is_comptime; |
| ... | @@ -3375,21 +3686,24 @@ static IrInstruction *ir_gen_return(IrBuilder *irb, Scope *scope, AstNode *node, | ... | @@ -3375,21 +3686,24 @@ static IrInstruction *ir_gen_return(IrBuilder *irb, Scope *scope, AstNode *node, |
| 3375 | ir_build_br(irb, scope, node, ret_stmt_block, is_comptime); | 3686 | ir_build_br(irb, scope, node, ret_stmt_block, is_comptime); |
| 3376 | | 3687 | |
| 3377 | ir_set_cursor_at_end_and_append_block(irb, ret_stmt_block); | 3688 | ir_set_cursor_at_end_and_append_block(irb, ret_stmt_block); |
| 3378 | return ir_gen_async_return(irb, scope, node, return_value, false); | 3689 | IrInstruction *result = ir_gen_async_return(irb, scope, node, return_value, false); |
| | 3690 | result_loc_ret->base.source_instruction = result; |
| | 3691 | return result; |
| 3379 | } else { | 3692 | } else { |
| 3380 | // generate unconditional defers | 3693 | // generate unconditional defers |
| 3381 | ir_gen_defers_for_block(irb, scope, outer_scope, false); | 3694 | ir_gen_defers_for_block(irb, scope, outer_scope, false); |
| 3382 | return ir_gen_async_return(irb, scope, node, return_value, false); | 3695 | IrInstruction *result = ir_gen_async_return(irb, scope, node, return_value, false); |
| | 3696 | result_loc_ret->base.source_instruction = result; |
| | 3697 | return result; |
| 3383 | } | 3698 | } |
| 3384 | } | 3699 | } |
| 3385 | case ReturnKindError: | 3700 | case ReturnKindError: |
| 3386 | { | 3701 | { |
| 3387 | assert(expr_node); | 3702 | assert(expr_node); |
| 3388 | IrInstruction *err_union_ptr = ir_gen_node_extra(irb, expr_node, scope, LValPtr); | 3703 | IrInstruction *err_union_ptr = ir_gen_node_extra(irb, expr_node, scope, LValPtr, nullptr); |
| 3389 | if (err_union_ptr == irb->codegen->invalid_instruction) | 3704 | if (err_union_ptr == irb->codegen->invalid_instruction) |
| 3390 | return irb->codegen->invalid_instruction; | 3705 | return irb->codegen->invalid_instruction; |
| 3391 | IrInstruction *err_union_val = ir_build_load_ptr(irb, scope, node, err_union_ptr); | 3706 | IrInstruction *is_err_val = ir_build_test_err_src(irb, scope, node, err_union_ptr, true); |
| 3392 | IrInstruction *is_err_val = ir_build_test_err(irb, scope, node, err_union_val); | | |
| 3393 | | 3707 | |
| 3394 | IrBasicBlock *return_block = ir_create_basic_block(irb, scope, "ErrRetReturn"); | 3708 | IrBasicBlock *return_block = ir_create_basic_block(irb, scope, "ErrRetReturn"); |
| 3395 | IrBasicBlock *continue_block = ir_create_basic_block(irb, scope, "ErrRetContinue"); | 3709 | IrBasicBlock *continue_block = ir_create_basic_block(irb, scope, "ErrRetContinue"); |
| ... | @@ -3404,19 +3718,27 @@ static IrInstruction *ir_gen_return(IrBuilder *irb, Scope *scope, AstNode *node, | ... | @@ -3404,19 +3718,27 @@ static IrInstruction *ir_gen_return(IrBuilder *irb, Scope *scope, AstNode *node, |
| 3404 | | 3718 | |
| 3405 | ir_set_cursor_at_end_and_append_block(irb, return_block); | 3719 | ir_set_cursor_at_end_and_append_block(irb, return_block); |
| 3406 | if (!ir_gen_defers_for_block(irb, scope, outer_scope, true)) { | 3720 | if (!ir_gen_defers_for_block(irb, scope, outer_scope, true)) { |
| 3407 | IrInstruction *err_val = ir_build_unwrap_err_code(irb, scope, node, err_union_ptr); | 3721 | IrInstruction *err_val_ptr = ir_build_unwrap_err_code(irb, scope, node, err_union_ptr); |
| | 3722 | IrInstruction *err_val = ir_build_load_ptr(irb, scope, node, err_val_ptr); |
| | 3723 | |
| | 3724 | ResultLocReturn *result_loc_ret = allocate<ResultLocReturn>(1); |
| | 3725 | result_loc_ret->base.id = ResultLocIdReturn; |
| | 3726 | ir_build_reset_result(irb, scope, node, &result_loc_ret->base); |
| | 3727 | ir_build_end_expr(irb, scope, node, err_val, &result_loc_ret->base); |
| | 3728 | |
| 3408 | if (irb->codegen->have_err_ret_tracing && !should_inline) { | 3729 | if (irb->codegen->have_err_ret_tracing && !should_inline) { |
| 3409 | ir_build_save_err_ret_addr(irb, scope, node); | 3730 | ir_build_save_err_ret_addr(irb, scope, node); |
| 3410 | } | 3731 | } |
| 3411 | ir_gen_async_return(irb, scope, node, err_val, false); | 3732 | IrInstruction *ret_inst = ir_gen_async_return(irb, scope, node, err_val, false); |
| | 3733 | result_loc_ret->base.source_instruction = ret_inst; |
| 3412 | } | 3734 | } |
| 3413 | | 3735 | |
| 3414 | ir_set_cursor_at_end_and_append_block(irb, continue_block); | 3736 | ir_set_cursor_at_end_and_append_block(irb, continue_block); |
| 3415 | IrInstruction *unwrapped_ptr = ir_build_unwrap_err_payload(irb, scope, node, err_union_ptr, false); | 3737 | IrInstruction *unwrapped_ptr = ir_build_unwrap_err_payload(irb, scope, node, err_union_ptr, false, false); |
| 3416 | if (lval == LValPtr) | 3738 | if (lval == LValPtr) |
| 3417 | return unwrapped_ptr; | 3739 | return unwrapped_ptr; |
| 3418 | else | 3740 | else |
| 3419 | return ir_build_load_ptr(irb, scope, node, unwrapped_ptr); | 3741 | return ir_expr_wrap(irb, scope, ir_build_load_ptr(irb, scope, node, unwrapped_ptr), result_loc); |
| 3420 | } | 3742 | } |
| 3421 | } | 3743 | } |
| 3422 | zig_unreachable(); | 3744 | zig_unreachable(); |
| ... | @@ -3500,7 +3822,17 @@ static ZigVar *ir_create_var(IrBuilder *irb, AstNode *node, Scope *scope, Buf *n | ... | @@ -3500,7 +3822,17 @@ static ZigVar *ir_create_var(IrBuilder *irb, AstNode *node, Scope *scope, Buf *n |
| 3500 | return var; | 3822 | return var; |
| 3501 | } | 3823 | } |
| 3502 | | 3824 | |
| 3503 | static IrInstruction *ir_gen_block(IrBuilder *irb, Scope *parent_scope, AstNode *block_node) { | 3825 | static ResultLocPeer *create_peer_result(ResultLocPeerParent *peer_parent) { |
| | 3826 | ResultLocPeer *result = allocate<ResultLocPeer>(1); |
| | 3827 | result->base.id = ResultLocIdPeer; |
| | 3828 | result->base.source_instruction = peer_parent->base.source_instruction; |
| | 3829 | result->parent = peer_parent; |
| | 3830 | return result; |
| | 3831 | } |
| | 3832 | |
| | 3833 | static IrInstruction *ir_gen_block(IrBuilder *irb, Scope *parent_scope, AstNode *block_node, LVal lval, |
| | 3834 | ResultLoc *result_loc) |
| | 3835 | { |
| 3504 | assert(block_node->type == NodeTypeBlock); | 3836 | assert(block_node->type == NodeTypeBlock); |
| 3505 | | 3837 | |
| 3506 | ZigList<IrInstruction *> incoming_values = {0}; | 3838 | ZigList<IrInstruction *> incoming_values = {0}; |
| ... | @@ -3518,15 +3850,24 @@ static IrInstruction *ir_gen_block(IrBuilder *irb, Scope *parent_scope, AstNode | ... | @@ -3518,15 +3850,24 @@ static IrInstruction *ir_gen_block(IrBuilder *irb, Scope *parent_scope, AstNode |
| 3518 | | 3850 | |
| 3519 | if (block_node->data.block.statements.length == 0) { | 3851 | if (block_node->data.block.statements.length == 0) { |
| 3520 | // {} | 3852 | // {} |
| 3521 | return ir_build_const_void(irb, child_scope, block_node); | 3853 | return ir_lval_wrap(irb, parent_scope, ir_build_const_void(irb, child_scope, block_node), lval, result_loc); |
| 3522 | } | 3854 | } |
| 3523 | | 3855 | |
| 3524 | if (block_node->data.block.name != nullptr) { | 3856 | if (block_node->data.block.name != nullptr) { |
| | 3857 | scope_block->lval = lval; |
| 3525 | scope_block->incoming_blocks = &incoming_blocks; | 3858 | scope_block->incoming_blocks = &incoming_blocks; |
| 3526 | scope_block->incoming_values = &incoming_values; | 3859 | scope_block->incoming_values = &incoming_values; |
| 3527 | scope_block->end_block = ir_create_basic_block(irb, parent_scope, "BlockEnd"); | 3860 | scope_block->end_block = ir_create_basic_block(irb, parent_scope, "BlockEnd"); |
| 3528 | scope_block->is_comptime = ir_build_const_bool(irb, parent_scope, block_node, | 3861 | scope_block->is_comptime = ir_build_const_bool(irb, parent_scope, block_node, |
| 3529 | ir_should_inline(irb->exec, parent_scope)); | 3862 | ir_should_inline(irb->exec, parent_scope)); |
| | 3863 | |
| | 3864 | scope_block->peer_parent = allocate<ResultLocPeerParent>(1); |
| | 3865 | scope_block->peer_parent->base.id = ResultLocIdPeerParent; |
| | 3866 | scope_block->peer_parent->base.source_instruction = scope_block->is_comptime; |
| | 3867 | scope_block->peer_parent->end_bb = scope_block->end_block; |
| | 3868 | scope_block->peer_parent->is_comptime = scope_block->is_comptime; |
| | 3869 | scope_block->peer_parent->parent = result_loc; |
| | 3870 | ir_build_reset_result(irb, parent_scope, block_node, &scope_block->peer_parent->base); |
| 3530 | } | 3871 | } |
| 3531 | | 3872 | |
| 3532 | bool is_continuation_unreachable = false; | 3873 | bool is_continuation_unreachable = false; |
| ... | @@ -3540,6 +3881,8 @@ static IrInstruction *ir_gen_block(IrBuilder *irb, Scope *parent_scope, AstNode | ... | @@ -3540,6 +3881,8 @@ static IrInstruction *ir_gen_block(IrBuilder *irb, Scope *parent_scope, AstNode |
| 3540 | // keep the last noreturn statement value around in case we need to return it | 3881 | // keep the last noreturn statement value around in case we need to return it |
| 3541 | noreturn_return_value = statement_value; | 3882 | noreturn_return_value = statement_value; |
| 3542 | } | 3883 | } |
| | 3884 | // This logic must be kept in sync with |
| | 3885 | // [STMT_EXPR_TEST_THING] <--- (search this token) |
| 3543 | if (statement_node->type == NodeTypeDefer && statement_value != irb->codegen->invalid_instruction) { | 3886 | if (statement_node->type == NodeTypeDefer && statement_value != irb->codegen->invalid_instruction) { |
| 3544 | // defer starts a new scope | 3887 | // defer starts a new scope |
| 3545 | child_scope = statement_node->data.defer.child_scope; | 3888 | child_scope = statement_node->data.defer.child_scope; |
| ... | @@ -3560,21 +3903,41 @@ static IrInstruction *ir_gen_block(IrBuilder *irb, Scope *parent_scope, AstNode | ... | @@ -3560,21 +3903,41 @@ static IrInstruction *ir_gen_block(IrBuilder *irb, Scope *parent_scope, AstNode |
| 3560 | return noreturn_return_value; | 3903 | return noreturn_return_value; |
| 3561 | } | 3904 | } |
| 3562 | | 3905 | |
| | 3906 | if (scope_block->peer_parent != nullptr && scope_block->peer_parent->peers.length != 0) { |
| | 3907 | scope_block->peer_parent->peers.last()->next_bb = scope_block->end_block; |
| | 3908 | } |
| 3563 | ir_set_cursor_at_end_and_append_block(irb, scope_block->end_block); | 3909 | ir_set_cursor_at_end_and_append_block(irb, scope_block->end_block); |
| 3564 | return ir_build_phi(irb, parent_scope, block_node, incoming_blocks.length, incoming_blocks.items, incoming_values.items); | 3910 | IrInstruction *phi = ir_build_phi(irb, parent_scope, block_node, incoming_blocks.length, |
| | 3911 | incoming_blocks.items, incoming_values.items, scope_block->peer_parent); |
| | 3912 | return ir_expr_wrap(irb, parent_scope, phi, result_loc); |
| 3565 | } else { | 3913 | } else { |
| 3566 | incoming_blocks.append(irb->current_basic_block); | 3914 | incoming_blocks.append(irb->current_basic_block); |
| 3567 | incoming_values.append(ir_mark_gen(ir_build_const_void(irb, parent_scope, block_node))); | 3915 | IrInstruction *else_expr_result = ir_mark_gen(ir_build_const_void(irb, parent_scope, block_node)); |
| | 3916 | |
| | 3917 | if (scope_block->peer_parent != nullptr) { |
| | 3918 | ResultLocPeer *peer_result = create_peer_result(scope_block->peer_parent); |
| | 3919 | scope_block->peer_parent->peers.append(peer_result); |
| | 3920 | ir_build_end_expr(irb, parent_scope, block_node, else_expr_result, &peer_result->base); |
| | 3921 | |
| | 3922 | if (scope_block->peer_parent->peers.length != 0) { |
| | 3923 | scope_block->peer_parent->peers.last()->next_bb = scope_block->end_block; |
| | 3924 | } |
| | 3925 | } |
| | 3926 | |
| | 3927 | incoming_values.append(else_expr_result); |
| 3568 | } | 3928 | } |
| 3569 | | 3929 | |
| 3570 | if (block_node->data.block.name != nullptr) { | 3930 | if (block_node->data.block.name != nullptr) { |
| 3571 | ir_gen_defers_for_block(irb, child_scope, outer_block_scope, false); | 3931 | ir_gen_defers_for_block(irb, child_scope, outer_block_scope, false); |
| 3572 | ir_mark_gen(ir_build_br(irb, parent_scope, block_node, scope_block->end_block, scope_block->is_comptime)); | 3932 | ir_mark_gen(ir_build_br(irb, parent_scope, block_node, scope_block->end_block, scope_block->is_comptime)); |
| 3573 | ir_set_cursor_at_end_and_append_block(irb, scope_block->end_block); | 3933 | ir_set_cursor_at_end_and_append_block(irb, scope_block->end_block); |
| 3574 | return ir_build_phi(irb, parent_scope, block_node, incoming_blocks.length, incoming_blocks.items, incoming_values.items); | 3934 | IrInstruction *phi = ir_build_phi(irb, parent_scope, block_node, incoming_blocks.length, |
| | 3935 | incoming_blocks.items, incoming_values.items, scope_block->peer_parent); |
| | 3936 | return ir_expr_wrap(irb, parent_scope, phi, result_loc); |
| 3575 | } else { | 3937 | } else { |
| 3576 | ir_gen_defers_for_block(irb, child_scope, outer_block_scope, false); | 3938 | ir_gen_defers_for_block(irb, child_scope, outer_block_scope, false); |
| 3577 | return ir_mark_gen(ir_mark_gen(ir_build_const_void(irb, child_scope, block_node))); | 3939 | IrInstruction *void_inst = ir_mark_gen(ir_build_const_void(irb, child_scope, block_node)); |
| | 3940 | return ir_lval_wrap(irb, parent_scope, void_inst, lval, result_loc); |
| 3578 | } | 3941 | } |
| 3579 | } | 3942 | } |
| 3580 | | 3943 | |
| ... | @@ -3594,7 +3957,7 @@ static IrInstruction *ir_gen_bin_op_id(IrBuilder *irb, Scope *scope, AstNode *no | ... | @@ -3594,7 +3957,7 @@ static IrInstruction *ir_gen_bin_op_id(IrBuilder *irb, Scope *scope, AstNode *no |
| 3594 | } | 3957 | } |
| 3595 | | 3958 | |
| 3596 | static IrInstruction *ir_gen_assign(IrBuilder *irb, Scope *scope, AstNode *node) { | 3959 | static IrInstruction *ir_gen_assign(IrBuilder *irb, Scope *scope, AstNode *node) { |
| 3597 | IrInstruction *lvalue = ir_gen_node_extra(irb, node->data.bin_op_expr.op1, scope, LValPtr); | 3960 | IrInstruction *lvalue = ir_gen_node_extra(irb, node->data.bin_op_expr.op1, scope, LValPtr, nullptr); |
| 3598 | IrInstruction *rvalue = ir_gen_node(irb, node->data.bin_op_expr.op2, scope); | 3961 | IrInstruction *rvalue = ir_gen_node(irb, node->data.bin_op_expr.op2, scope); |
| 3599 | | 3962 | |
| 3600 | if (lvalue == irb->codegen->invalid_instruction || rvalue == irb->codegen->invalid_instruction) | 3963 | if (lvalue == irb->codegen->invalid_instruction || rvalue == irb->codegen->invalid_instruction) |
| ... | @@ -3605,7 +3968,7 @@ static IrInstruction *ir_gen_assign(IrBuilder *irb, Scope *scope, AstNode *node) | ... | @@ -3605,7 +3968,7 @@ static IrInstruction *ir_gen_assign(IrBuilder *irb, Scope *scope, AstNode *node) |
| 3605 | } | 3968 | } |
| 3606 | | 3969 | |
| 3607 | static IrInstruction *ir_gen_assign_op(IrBuilder *irb, Scope *scope, AstNode *node, IrBinOp op_id) { | 3970 | static IrInstruction *ir_gen_assign_op(IrBuilder *irb, Scope *scope, AstNode *node, IrBinOp op_id) { |
| 3608 | IrInstruction *lvalue = ir_gen_node_extra(irb, node->data.bin_op_expr.op1, scope, LValPtr); | 3971 | IrInstruction *lvalue = ir_gen_node_extra(irb, node->data.bin_op_expr.op1, scope, LValPtr, nullptr); |
| 3609 | if (lvalue == irb->codegen->invalid_instruction) | 3972 | if (lvalue == irb->codegen->invalid_instruction) |
| 3610 | return lvalue; | 3973 | return lvalue; |
| 3611 | IrInstruction *op1 = ir_build_load_ptr(irb, scope, node->data.bin_op_expr.op1, lvalue); | 3974 | IrInstruction *op1 = ir_build_load_ptr(irb, scope, node->data.bin_op_expr.op1, lvalue); |
| ... | @@ -3656,7 +4019,7 @@ static IrInstruction *ir_gen_bool_or(IrBuilder *irb, Scope *scope, AstNode *node | ... | @@ -3656,7 +4019,7 @@ static IrInstruction *ir_gen_bool_or(IrBuilder *irb, Scope *scope, AstNode *node |
| 3656 | incoming_blocks[0] = post_val1_block; | 4019 | incoming_blocks[0] = post_val1_block; |
| 3657 | incoming_blocks[1] = post_val2_block; | 4020 | incoming_blocks[1] = post_val2_block; |
| 3658 | | 4021 | |
| 3659 | return ir_build_phi(irb, scope, node, 2, incoming_blocks, incoming_values); | 4022 | return ir_build_phi(irb, scope, node, 2, incoming_blocks, incoming_values, nullptr); |
| 3660 | } | 4023 | } |
| 3661 | | 4024 | |
| 3662 | static IrInstruction *ir_gen_bool_and(IrBuilder *irb, Scope *scope, AstNode *node) { | 4025 | static IrInstruction *ir_gen_bool_and(IrBuilder *irb, Scope *scope, AstNode *node) { |
| ... | @@ -3698,16 +4061,51 @@ static IrInstruction *ir_gen_bool_and(IrBuilder *irb, Scope *scope, AstNode *nod | ... | @@ -3698,16 +4061,51 @@ static IrInstruction *ir_gen_bool_and(IrBuilder *irb, Scope *scope, AstNode *nod |
| 3698 | incoming_blocks[0] = post_val1_block; | 4061 | incoming_blocks[0] = post_val1_block; |
| 3699 | incoming_blocks[1] = post_val2_block; | 4062 | incoming_blocks[1] = post_val2_block; |
| 3700 | | 4063 | |
| 3701 | return ir_build_phi(irb, scope, node, 2, incoming_blocks, incoming_values); | 4064 | return ir_build_phi(irb, scope, node, 2, incoming_blocks, incoming_values, nullptr); |
| | 4065 | } |
| | 4066 | |
| | 4067 | static ResultLocPeerParent *ir_build_result_peers(IrBuilder *irb, IrInstruction *cond_br_inst, |
| | 4068 | IrBasicBlock *end_block, ResultLoc *parent, IrInstruction *is_comptime) |
| | 4069 | { |
| | 4070 | ResultLocPeerParent *peer_parent = allocate<ResultLocPeerParent>(1); |
| | 4071 | peer_parent->base.id = ResultLocIdPeerParent; |
| | 4072 | peer_parent->base.source_instruction = cond_br_inst; |
| | 4073 | peer_parent->end_bb = end_block; |
| | 4074 | peer_parent->is_comptime = is_comptime; |
| | 4075 | peer_parent->parent = parent; |
| | 4076 | |
| | 4077 | IrInstruction *popped_inst = irb->current_basic_block->instruction_list.pop(); |
| | 4078 | ir_assert(popped_inst == cond_br_inst, cond_br_inst); |
| | 4079 | |
| | 4080 | ir_build_reset_result(irb, cond_br_inst->scope, cond_br_inst->source_node, &peer_parent->base); |
| | 4081 | irb->current_basic_block->instruction_list.append(popped_inst); |
| | 4082 | |
| | 4083 | return peer_parent; |
| | 4084 | } |
| | 4085 | |
| | 4086 | static ResultLocPeerParent *ir_build_binary_result_peers(IrBuilder *irb, IrInstruction *cond_br_inst, |
| | 4087 | IrBasicBlock *else_block, IrBasicBlock *end_block, ResultLoc *parent, IrInstruction *is_comptime) |
| | 4088 | { |
| | 4089 | ResultLocPeerParent *peer_parent = ir_build_result_peers(irb, cond_br_inst, end_block, parent, is_comptime); |
| | 4090 | |
| | 4091 | peer_parent->peers.append(create_peer_result(peer_parent)); |
| | 4092 | peer_parent->peers.last()->next_bb = else_block; |
| | 4093 | |
| | 4094 | peer_parent->peers.append(create_peer_result(peer_parent)); |
| | 4095 | peer_parent->peers.last()->next_bb = end_block; |
| | 4096 | |
| | 4097 | return peer_parent; |
| 3702 | } | 4098 | } |
| 3703 | | 4099 | |
| 3704 | static IrInstruction *ir_gen_orelse(IrBuilder *irb, Scope *parent_scope, AstNode *node) { | 4100 | static IrInstruction *ir_gen_orelse(IrBuilder *irb, Scope *parent_scope, AstNode *node, LVal lval, |
| | 4101 | ResultLoc *result_loc) |
| | 4102 | { |
| 3705 | assert(node->type == NodeTypeBinOpExpr); | 4103 | assert(node->type == NodeTypeBinOpExpr); |
| 3706 | | 4104 | |
| 3707 | AstNode *op1_node = node->data.bin_op_expr.op1; | 4105 | AstNode *op1_node = node->data.bin_op_expr.op1; |
| 3708 | AstNode *op2_node = node->data.bin_op_expr.op2; | 4106 | AstNode *op2_node = node->data.bin_op_expr.op2; |
| 3709 | | 4107 | |
| 3710 | IrInstruction *maybe_ptr = ir_gen_node_extra(irb, op1_node, parent_scope, LValPtr); | 4108 | IrInstruction *maybe_ptr = ir_gen_node_extra(irb, op1_node, parent_scope, LValPtr, nullptr); |
| 3711 | if (maybe_ptr == irb->codegen->invalid_instruction) | 4109 | if (maybe_ptr == irb->codegen->invalid_instruction) |
| 3712 | return irb->codegen->invalid_instruction; | 4110 | return irb->codegen->invalid_instruction; |
| 3713 | | 4111 | |
| ... | @@ -3724,10 +4122,14 @@ static IrInstruction *ir_gen_orelse(IrBuilder *irb, Scope *parent_scope, AstNode | ... | @@ -3724,10 +4122,14 @@ static IrInstruction *ir_gen_orelse(IrBuilder *irb, Scope *parent_scope, AstNode |
| 3724 | IrBasicBlock *ok_block = ir_create_basic_block(irb, parent_scope, "OptionalNonNull"); | 4122 | IrBasicBlock *ok_block = ir_create_basic_block(irb, parent_scope, "OptionalNonNull"); |
| 3725 | IrBasicBlock *null_block = ir_create_basic_block(irb, parent_scope, "OptionalNull"); | 4123 | IrBasicBlock *null_block = ir_create_basic_block(irb, parent_scope, "OptionalNull"); |
| 3726 | IrBasicBlock *end_block = ir_create_basic_block(irb, parent_scope, "OptionalEnd"); | 4124 | IrBasicBlock *end_block = ir_create_basic_block(irb, parent_scope, "OptionalEnd"); |
| 3727 | ir_build_cond_br(irb, parent_scope, node, is_non_null, ok_block, null_block, is_comptime); | 4125 | IrInstruction *cond_br_inst = ir_build_cond_br(irb, parent_scope, node, is_non_null, ok_block, null_block, is_comptime); |
| | 4126 | |
| | 4127 | ResultLocPeerParent *peer_parent = ir_build_binary_result_peers(irb, cond_br_inst, ok_block, end_block, |
| | 4128 | result_loc, is_comptime); |
| 3728 | | 4129 | |
| 3729 | ir_set_cursor_at_end_and_append_block(irb, null_block); | 4130 | ir_set_cursor_at_end_and_append_block(irb, null_block); |
| 3730 | IrInstruction *null_result = ir_gen_node(irb, op2_node, parent_scope); | 4131 | IrInstruction *null_result = ir_gen_node_extra(irb, op2_node, parent_scope, LValNone, |
| | 4132 | &peer_parent->peers.at(0)->base); |
| 3731 | if (null_result == irb->codegen->invalid_instruction) | 4133 | if (null_result == irb->codegen->invalid_instruction) |
| 3732 | return irb->codegen->invalid_instruction; | 4134 | return irb->codegen->invalid_instruction; |
| 3733 | IrBasicBlock *after_null_block = irb->current_basic_block; | 4135 | IrBasicBlock *after_null_block = irb->current_basic_block; |
| ... | @@ -3735,8 +4137,9 @@ static IrInstruction *ir_gen_orelse(IrBuilder *irb, Scope *parent_scope, AstNode | ... | @@ -3735,8 +4137,9 @@ static IrInstruction *ir_gen_orelse(IrBuilder *irb, Scope *parent_scope, AstNode |
| 3735 | ir_mark_gen(ir_build_br(irb, parent_scope, node, end_block, is_comptime)); | 4137 | ir_mark_gen(ir_build_br(irb, parent_scope, node, end_block, is_comptime)); |
| 3736 | | 4138 | |
| 3737 | ir_set_cursor_at_end_and_append_block(irb, ok_block); | 4139 | ir_set_cursor_at_end_and_append_block(irb, ok_block); |
| 3738 | IrInstruction *unwrapped_ptr = ir_build_optional_unwrap_ptr(irb, parent_scope, node, maybe_ptr, false); | 4140 | IrInstruction *unwrapped_ptr = ir_build_optional_unwrap_ptr(irb, parent_scope, node, maybe_ptr, false, false); |
| 3739 | IrInstruction *unwrapped_payload = ir_build_load_ptr(irb, parent_scope, node, unwrapped_ptr); | 4141 | IrInstruction *unwrapped_payload = ir_build_load_ptr(irb, parent_scope, node, unwrapped_ptr); |
| | 4142 | ir_build_end_expr(irb, parent_scope, node, unwrapped_payload, &peer_parent->peers.at(1)->base); |
| 3740 | IrBasicBlock *after_ok_block = irb->current_basic_block; | 4143 | IrBasicBlock *after_ok_block = irb->current_basic_block; |
| 3741 | ir_build_br(irb, parent_scope, node, end_block, is_comptime); | 4144 | ir_build_br(irb, parent_scope, node, end_block, is_comptime); |
| 3742 | | 4145 | |
| ... | @@ -3747,7 +4150,8 @@ static IrInstruction *ir_gen_orelse(IrBuilder *irb, Scope *parent_scope, AstNode | ... | @@ -3747,7 +4150,8 @@ static IrInstruction *ir_gen_orelse(IrBuilder *irb, Scope *parent_scope, AstNode |
| 3747 | IrBasicBlock **incoming_blocks = allocate<IrBasicBlock *>(2); | 4150 | IrBasicBlock **incoming_blocks = allocate<IrBasicBlock *>(2); |
| 3748 | incoming_blocks[0] = after_null_block; | 4151 | incoming_blocks[0] = after_null_block; |
| 3749 | incoming_blocks[1] = after_ok_block; | 4152 | incoming_blocks[1] = after_ok_block; |
| 3750 | return ir_build_phi(irb, parent_scope, node, 2, incoming_blocks, incoming_values); | 4153 | IrInstruction *phi = ir_build_phi(irb, parent_scope, node, 2, incoming_blocks, incoming_values, peer_parent); |
| | 4154 | return ir_lval_wrap(irb, parent_scope, phi, lval, result_loc); |
| 3751 | } | 4155 | } |
| 3752 | | 4156 | |
| 3753 | static IrInstruction *ir_gen_error_union(IrBuilder *irb, Scope *parent_scope, AstNode *node) { | 4157 | static IrInstruction *ir_gen_error_union(IrBuilder *irb, Scope *parent_scope, AstNode *node) { |
| ... | @@ -3767,7 +4171,7 @@ static IrInstruction *ir_gen_error_union(IrBuilder *irb, Scope *parent_scope, As | ... | @@ -3767,7 +4171,7 @@ static IrInstruction *ir_gen_error_union(IrBuilder *irb, Scope *parent_scope, As |
| 3767 | return ir_build_error_union(irb, parent_scope, node, err_set, payload); | 4171 | return ir_build_error_union(irb, parent_scope, node, err_set, payload); |
| 3768 | } | 4172 | } |
| 3769 | | 4173 | |
| 3770 | static IrInstruction *ir_gen_bin_op(IrBuilder *irb, Scope *scope, AstNode *node) { | 4174 | static IrInstruction *ir_gen_bin_op(IrBuilder *irb, Scope *scope, AstNode *node, LVal lval, ResultLoc *result_loc) { |
| 3771 | assert(node->type == NodeTypeBinOpExpr); | 4175 | assert(node->type == NodeTypeBinOpExpr); |
| 3772 | | 4176 | |
| 3773 | BinOpType bin_op_type = node->data.bin_op_expr.bin_op; | 4177 | BinOpType bin_op_type = node->data.bin_op_expr.bin_op; |
| ... | @@ -3775,87 +4179,87 @@ static IrInstruction *ir_gen_bin_op(IrBuilder *irb, Scope *scope, AstNode *node) | ... | @@ -3775,87 +4179,87 @@ static IrInstruction *ir_gen_bin_op(IrBuilder *irb, Scope *scope, AstNode *node) |
| 3775 | case BinOpTypeInvalid: | 4179 | case BinOpTypeInvalid: |
| 3776 | zig_unreachable(); | 4180 | zig_unreachable(); |
| 3777 | case BinOpTypeAssign: | 4181 | case BinOpTypeAssign: |
| 3778 | return ir_gen_assign(irb, scope, node); | 4182 | return ir_lval_wrap(irb, scope, ir_gen_assign(irb, scope, node), lval, result_loc); |
| 3779 | case BinOpTypeAssignTimes: | 4183 | case BinOpTypeAssignTimes: |
| 3780 | return ir_gen_assign_op(irb, scope, node, IrBinOpMult); | 4184 | return ir_lval_wrap(irb, scope, ir_gen_assign_op(irb, scope, node, IrBinOpMult), lval, result_loc); |
| 3781 | case BinOpTypeAssignTimesWrap: | 4185 | case BinOpTypeAssignTimesWrap: |
| 3782 | return ir_gen_assign_op(irb, scope, node, IrBinOpMultWrap); | 4186 | return ir_lval_wrap(irb, scope, ir_gen_assign_op(irb, scope, node, IrBinOpMultWrap), lval, result_loc); |
| 3783 | case BinOpTypeAssignDiv: | 4187 | case BinOpTypeAssignDiv: |
| 3784 | return ir_gen_assign_op(irb, scope, node, IrBinOpDivUnspecified); | 4188 | return ir_lval_wrap(irb, scope, ir_gen_assign_op(irb, scope, node, IrBinOpDivUnspecified), lval, result_loc); |
| 3785 | case BinOpTypeAssignMod: | 4189 | case BinOpTypeAssignMod: |
| 3786 | return ir_gen_assign_op(irb, scope, node, IrBinOpRemUnspecified); | 4190 | return ir_lval_wrap(irb, scope, ir_gen_assign_op(irb, scope, node, IrBinOpRemUnspecified), lval, result_loc); |
| 3787 | case BinOpTypeAssignPlus: | 4191 | case BinOpTypeAssignPlus: |
| 3788 | return ir_gen_assign_op(irb, scope, node, IrBinOpAdd); | 4192 | return ir_lval_wrap(irb, scope, ir_gen_assign_op(irb, scope, node, IrBinOpAdd), lval, result_loc); |
| 3789 | case BinOpTypeAssignPlusWrap: | 4193 | case BinOpTypeAssignPlusWrap: |
| 3790 | return ir_gen_assign_op(irb, scope, node, IrBinOpAddWrap); | 4194 | return ir_lval_wrap(irb, scope, ir_gen_assign_op(irb, scope, node, IrBinOpAddWrap), lval, result_loc); |
| 3791 | case BinOpTypeAssignMinus: | 4195 | case BinOpTypeAssignMinus: |
| 3792 | return ir_gen_assign_op(irb, scope, node, IrBinOpSub); | 4196 | return ir_lval_wrap(irb, scope, ir_gen_assign_op(irb, scope, node, IrBinOpSub), lval, result_loc); |
| 3793 | case BinOpTypeAssignMinusWrap: | 4197 | case BinOpTypeAssignMinusWrap: |
| 3794 | return ir_gen_assign_op(irb, scope, node, IrBinOpSubWrap); | 4198 | return ir_lval_wrap(irb, scope, ir_gen_assign_op(irb, scope, node, IrBinOpSubWrap), lval, result_loc); |
| 3795 | case BinOpTypeAssignBitShiftLeft: | 4199 | case BinOpTypeAssignBitShiftLeft: |
| 3796 | return ir_gen_assign_op(irb, scope, node, IrBinOpBitShiftLeftLossy); | 4200 | return ir_lval_wrap(irb, scope, ir_gen_assign_op(irb, scope, node, IrBinOpBitShiftLeftLossy), lval, result_loc); |
| 3797 | case BinOpTypeAssignBitShiftRight: | 4201 | case BinOpTypeAssignBitShiftRight: |
| 3798 | return ir_gen_assign_op(irb, scope, node, IrBinOpBitShiftRightLossy); | 4202 | return ir_lval_wrap(irb, scope, ir_gen_assign_op(irb, scope, node, IrBinOpBitShiftRightLossy), lval, result_loc); |
| 3799 | case BinOpTypeAssignBitAnd: | 4203 | case BinOpTypeAssignBitAnd: |
| 3800 | return ir_gen_assign_op(irb, scope, node, IrBinOpBinAnd); | 4204 | return ir_lval_wrap(irb, scope, ir_gen_assign_op(irb, scope, node, IrBinOpBinAnd), lval, result_loc); |
| 3801 | case BinOpTypeAssignBitXor: | 4205 | case BinOpTypeAssignBitXor: |
| 3802 | return ir_gen_assign_op(irb, scope, node, IrBinOpBinXor); | 4206 | return ir_lval_wrap(irb, scope, ir_gen_assign_op(irb, scope, node, IrBinOpBinXor), lval, result_loc); |
| 3803 | case BinOpTypeAssignBitOr: | 4207 | case BinOpTypeAssignBitOr: |
| 3804 | return ir_gen_assign_op(irb, scope, node, IrBinOpBinOr); | 4208 | return ir_lval_wrap(irb, scope, ir_gen_assign_op(irb, scope, node, IrBinOpBinOr), lval, result_loc); |
| 3805 | case BinOpTypeAssignMergeErrorSets: | 4209 | case BinOpTypeAssignMergeErrorSets: |
| 3806 | return ir_gen_assign_op(irb, scope, node, IrBinOpMergeErrorSets); | 4210 | return ir_lval_wrap(irb, scope, ir_gen_assign_op(irb, scope, node, IrBinOpMergeErrorSets), lval, result_loc); |
| 3807 | case BinOpTypeBoolOr: | 4211 | case BinOpTypeBoolOr: |
| 3808 | return ir_gen_bool_or(irb, scope, node); | 4212 | return ir_lval_wrap(irb, scope, ir_gen_bool_or(irb, scope, node), lval, result_loc); |
| 3809 | case BinOpTypeBoolAnd: | 4213 | case BinOpTypeBoolAnd: |
| 3810 | return ir_gen_bool_and(irb, scope, node); | 4214 | return ir_lval_wrap(irb, scope, ir_gen_bool_and(irb, scope, node), lval, result_loc); |
| 3811 | case BinOpTypeCmpEq: | 4215 | case BinOpTypeCmpEq: |
| 3812 | return ir_gen_bin_op_id(irb, scope, node, IrBinOpCmpEq); | 4216 | return ir_lval_wrap(irb, scope, ir_gen_bin_op_id(irb, scope, node, IrBinOpCmpEq), lval, result_loc); |
| 3813 | case BinOpTypeCmpNotEq: | 4217 | case BinOpTypeCmpNotEq: |
| 3814 | return ir_gen_bin_op_id(irb, scope, node, IrBinOpCmpNotEq); | 4218 | return ir_lval_wrap(irb, scope, ir_gen_bin_op_id(irb, scope, node, IrBinOpCmpNotEq), lval, result_loc); |
| 3815 | case BinOpTypeCmpLessThan: | 4219 | case BinOpTypeCmpLessThan: |
| 3816 | return ir_gen_bin_op_id(irb, scope, node, IrBinOpCmpLessThan); | 4220 | return ir_lval_wrap(irb, scope, ir_gen_bin_op_id(irb, scope, node, IrBinOpCmpLessThan), lval, result_loc); |
| 3817 | case BinOpTypeCmpGreaterThan: | 4221 | case BinOpTypeCmpGreaterThan: |
| 3818 | return ir_gen_bin_op_id(irb, scope, node, IrBinOpCmpGreaterThan); | 4222 | return ir_lval_wrap(irb, scope, ir_gen_bin_op_id(irb, scope, node, IrBinOpCmpGreaterThan), lval, result_loc); |
| 3819 | case BinOpTypeCmpLessOrEq: | 4223 | case BinOpTypeCmpLessOrEq: |
| 3820 | return ir_gen_bin_op_id(irb, scope, node, IrBinOpCmpLessOrEq); | 4224 | return ir_lval_wrap(irb, scope, ir_gen_bin_op_id(irb, scope, node, IrBinOpCmpLessOrEq), lval, result_loc); |
| 3821 | case BinOpTypeCmpGreaterOrEq: | 4225 | case BinOpTypeCmpGreaterOrEq: |
| 3822 | return ir_gen_bin_op_id(irb, scope, node, IrBinOpCmpGreaterOrEq); | 4226 | return ir_lval_wrap(irb, scope, ir_gen_bin_op_id(irb, scope, node, IrBinOpCmpGreaterOrEq), lval, result_loc); |
| 3823 | case BinOpTypeBinOr: | 4227 | case BinOpTypeBinOr: |
| 3824 | return ir_gen_bin_op_id(irb, scope, node, IrBinOpBinOr); | 4228 | return ir_lval_wrap(irb, scope, ir_gen_bin_op_id(irb, scope, node, IrBinOpBinOr), lval, result_loc); |
| 3825 | case BinOpTypeBinXor: | 4229 | case BinOpTypeBinXor: |
| 3826 | return ir_gen_bin_op_id(irb, scope, node, IrBinOpBinXor); | 4230 | return ir_lval_wrap(irb, scope, ir_gen_bin_op_id(irb, scope, node, IrBinOpBinXor), lval, result_loc); |
| 3827 | case BinOpTypeBinAnd: | 4231 | case BinOpTypeBinAnd: |
| 3828 | return ir_gen_bin_op_id(irb, scope, node, IrBinOpBinAnd); | 4232 | return ir_lval_wrap(irb, scope, ir_gen_bin_op_id(irb, scope, node, IrBinOpBinAnd), lval, result_loc); |
| 3829 | case BinOpTypeBitShiftLeft: | 4233 | case BinOpTypeBitShiftLeft: |
| 3830 | return ir_gen_bin_op_id(irb, scope, node, IrBinOpBitShiftLeftLossy); | 4234 | return ir_lval_wrap(irb, scope, ir_gen_bin_op_id(irb, scope, node, IrBinOpBitShiftLeftLossy), lval, result_loc); |
| 3831 | case BinOpTypeBitShiftRight: | 4235 | case BinOpTypeBitShiftRight: |
| 3832 | return ir_gen_bin_op_id(irb, scope, node, IrBinOpBitShiftRightLossy); | 4236 | return ir_lval_wrap(irb, scope, ir_gen_bin_op_id(irb, scope, node, IrBinOpBitShiftRightLossy), lval, result_loc); |
| 3833 | case BinOpTypeAdd: | 4237 | case BinOpTypeAdd: |
| 3834 | return ir_gen_bin_op_id(irb, scope, node, IrBinOpAdd); | 4238 | return ir_lval_wrap(irb, scope, ir_gen_bin_op_id(irb, scope, node, IrBinOpAdd), lval, result_loc); |
| 3835 | case BinOpTypeAddWrap: | 4239 | case BinOpTypeAddWrap: |
| 3836 | return ir_gen_bin_op_id(irb, scope, node, IrBinOpAddWrap); | 4240 | return ir_lval_wrap(irb, scope, ir_gen_bin_op_id(irb, scope, node, IrBinOpAddWrap), lval, result_loc); |
| 3837 | case BinOpTypeSub: | 4241 | case BinOpTypeSub: |
| 3838 | return ir_gen_bin_op_id(irb, scope, node, IrBinOpSub); | 4242 | return ir_lval_wrap(irb, scope, ir_gen_bin_op_id(irb, scope, node, IrBinOpSub), lval, result_loc); |
| 3839 | case BinOpTypeSubWrap: | 4243 | case BinOpTypeSubWrap: |
| 3840 | return ir_gen_bin_op_id(irb, scope, node, IrBinOpSubWrap); | 4244 | return ir_lval_wrap(irb, scope, ir_gen_bin_op_id(irb, scope, node, IrBinOpSubWrap), lval, result_loc); |
| 3841 | case BinOpTypeMult: | 4245 | case BinOpTypeMult: |
| 3842 | return ir_gen_bin_op_id(irb, scope, node, IrBinOpMult); | 4246 | return ir_lval_wrap(irb, scope, ir_gen_bin_op_id(irb, scope, node, IrBinOpMult), lval, result_loc); |
| 3843 | case BinOpTypeMultWrap: | 4247 | case BinOpTypeMultWrap: |
| 3844 | return ir_gen_bin_op_id(irb, scope, node, IrBinOpMultWrap); | 4248 | return ir_lval_wrap(irb, scope, ir_gen_bin_op_id(irb, scope, node, IrBinOpMultWrap), lval, result_loc); |
| 3845 | case BinOpTypeDiv: | 4249 | case BinOpTypeDiv: |
| 3846 | return ir_gen_bin_op_id(irb, scope, node, IrBinOpDivUnspecified); | 4250 | return ir_lval_wrap(irb, scope, ir_gen_bin_op_id(irb, scope, node, IrBinOpDivUnspecified), lval, result_loc); |
| 3847 | case BinOpTypeMod: | 4251 | case BinOpTypeMod: |
| 3848 | return ir_gen_bin_op_id(irb, scope, node, IrBinOpRemUnspecified); | 4252 | return ir_lval_wrap(irb, scope, ir_gen_bin_op_id(irb, scope, node, IrBinOpRemUnspecified), lval, result_loc); |
| 3849 | case BinOpTypeArrayCat: | 4253 | case BinOpTypeArrayCat: |
| 3850 | return ir_gen_bin_op_id(irb, scope, node, IrBinOpArrayCat); | 4254 | return ir_lval_wrap(irb, scope, ir_gen_bin_op_id(irb, scope, node, IrBinOpArrayCat), lval, result_loc); |
| 3851 | case BinOpTypeArrayMult: | 4255 | case BinOpTypeArrayMult: |
| 3852 | return ir_gen_bin_op_id(irb, scope, node, IrBinOpArrayMult); | 4256 | return ir_lval_wrap(irb, scope, ir_gen_bin_op_id(irb, scope, node, IrBinOpArrayMult), lval, result_loc); |
| 3853 | case BinOpTypeMergeErrorSets: | 4257 | case BinOpTypeMergeErrorSets: |
| 3854 | return ir_gen_bin_op_id(irb, scope, node, IrBinOpMergeErrorSets); | 4258 | return ir_lval_wrap(irb, scope, ir_gen_bin_op_id(irb, scope, node, IrBinOpMergeErrorSets), lval, result_loc); |
| 3855 | case BinOpTypeUnwrapOptional: | 4259 | case BinOpTypeUnwrapOptional: |
| 3856 | return ir_gen_orelse(irb, scope, node); | 4260 | return ir_gen_orelse(irb, scope, node, lval, result_loc); |
| 3857 | case BinOpTypeErrorUnion: | 4261 | case BinOpTypeErrorUnion: |
| 3858 | return ir_gen_error_union(irb, scope, node); | 4262 | return ir_lval_wrap(irb, scope, ir_gen_error_union(irb, scope, node), lval, result_loc); |
| 3859 | } | 4263 | } |
| 3860 | zig_unreachable(); | 4264 | zig_unreachable(); |
| 3861 | } | 4265 | } |
| ... | @@ -3900,12 +4304,12 @@ static void populate_invalid_variable_in_scope(CodeGen *g, Scope *scope, AstNode | ... | @@ -3900,12 +4304,12 @@ static void populate_invalid_variable_in_scope(CodeGen *g, Scope *scope, AstNode |
| 3900 | TldVar *tld_var = allocate<TldVar>(1); | 4304 | TldVar *tld_var = allocate<TldVar>(1); |
| 3901 | init_tld(&tld_var->base, TldIdVar, var_name, VisibModPub, node, &scope_decls->base); | 4305 | init_tld(&tld_var->base, TldIdVar, var_name, VisibModPub, node, &scope_decls->base); |
| 3902 | tld_var->base.resolution = TldResolutionInvalid; | 4306 | tld_var->base.resolution = TldResolutionInvalid; |
| 3903 | tld_var->var = add_variable(g, node, &scope_decls->base, var_name, false, | 4307 | tld_var->var = add_variable(g, node, &scope_decls->base, var_name, false, |
| 3904 | &g->invalid_instruction->value, &tld_var->base, g->builtin_types.entry_invalid); | 4308 | &g->invalid_instruction->value, &tld_var->base, g->builtin_types.entry_invalid); |
| 3905 | scope_decls->decl_table.put(var_name, &tld_var->base); | 4309 | scope_decls->decl_table.put(var_name, &tld_var->base); |
| 3906 | } | 4310 | } |
| 3907 | | 4311 | |
| 3908 | static IrInstruction *ir_gen_symbol(IrBuilder *irb, Scope *scope, AstNode *node, LVal lval) { | 4312 | static IrInstruction *ir_gen_symbol(IrBuilder *irb, Scope *scope, AstNode *node, LVal lval, ResultLoc *result_loc) { |
| 3909 | Error err; | 4313 | Error err; |
| 3910 | assert(node->type == NodeTypeSymbol); | 4314 | assert(node->type == NodeTypeSymbol); |
| 3911 | | 4315 | |
| ... | @@ -3939,7 +4343,7 @@ static IrInstruction *ir_gen_symbol(IrBuilder *irb, Scope *scope, AstNode *node, | ... | @@ -3939,7 +4343,7 @@ static IrInstruction *ir_gen_symbol(IrBuilder *irb, Scope *scope, AstNode *node, |
| 3939 | if (lval == LValPtr) { | 4343 | if (lval == LValPtr) { |
| 3940 | return ir_build_ref(irb, scope, node, value, false, false); | 4344 | return ir_build_ref(irb, scope, node, value, false, false); |
| 3941 | } else { | 4345 | } else { |
| 3942 | return value; | 4346 | return ir_expr_wrap(irb, scope, value, result_loc); |
| 3943 | } | 4347 | } |
| 3944 | } | 4348 | } |
| 3945 | | 4349 | |
| ... | @@ -3947,15 +4351,22 @@ static IrInstruction *ir_gen_symbol(IrBuilder *irb, Scope *scope, AstNode *node, | ... | @@ -3947,15 +4351,22 @@ static IrInstruction *ir_gen_symbol(IrBuilder *irb, Scope *scope, AstNode *node, |
| 3947 | ZigVar *var = find_variable(irb->codegen, scope, variable_name, &crossed_fndef_scope); | 4351 | ZigVar *var = find_variable(irb->codegen, scope, variable_name, &crossed_fndef_scope); |
| 3948 | if (var) { | 4352 | if (var) { |
| 3949 | IrInstruction *var_ptr = ir_build_var_ptr_x(irb, scope, node, var, crossed_fndef_scope); | 4353 | IrInstruction *var_ptr = ir_build_var_ptr_x(irb, scope, node, var, crossed_fndef_scope); |
| 3950 | if (lval == LValPtr) | 4354 | if (lval == LValPtr) { |
| 3951 | return var_ptr; | 4355 | return var_ptr; |
| 3952 | else | 4356 | } else { |
| 3953 | return ir_build_load_ptr(irb, scope, node, var_ptr); | 4357 | return ir_expr_wrap(irb, scope, ir_build_load_ptr(irb, scope, node, var_ptr), result_loc); |
| | 4358 | } |
| 3954 | } | 4359 | } |
| 3955 | | 4360 | |
| 3956 | Tld *tld = find_decl(irb->codegen, scope, variable_name); | 4361 | Tld *tld = find_decl(irb->codegen, scope, variable_name); |
| 3957 | if (tld) | 4362 | if (tld) { |
| 3958 | return ir_build_decl_ref(irb, scope, node, tld, lval); | 4363 | IrInstruction *decl_ref = ir_build_decl_ref(irb, scope, node, tld, lval); |
| | 4364 | if (lval == LValPtr) { |
| | 4365 | return decl_ref; |
| | 4366 | } else { |
| | 4367 | return ir_expr_wrap(irb, scope, decl_ref, result_loc); |
| | 4368 | } |
| | 4369 | } |
| 3959 | | 4370 | |
| 3960 | if (get_container_scope(node->owner)->any_imports_failed) { | 4371 | if (get_container_scope(node->owner)->any_imports_failed) { |
| 3961 | // skip the error message since we had a failing import in this file | 4372 | // skip the error message since we had a failing import in this file |
| ... | @@ -3966,11 +4377,13 @@ static IrInstruction *ir_gen_symbol(IrBuilder *irb, Scope *scope, AstNode *node, | ... | @@ -3966,11 +4377,13 @@ static IrInstruction *ir_gen_symbol(IrBuilder *irb, Scope *scope, AstNode *node, |
| 3966 | return ir_build_undeclared_identifier(irb, scope, node, variable_name); | 4377 | return ir_build_undeclared_identifier(irb, scope, node, variable_name); |
| 3967 | } | 4378 | } |
| 3968 | | 4379 | |
| 3969 | static IrInstruction *ir_gen_array_access(IrBuilder *irb, Scope *scope, AstNode *node, LVal lval) { | 4380 | static IrInstruction *ir_gen_array_access(IrBuilder *irb, Scope *scope, AstNode *node, LVal lval, |
| | 4381 | ResultLoc *result_loc) |
| | 4382 | { |
| 3970 | assert(node->type == NodeTypeArrayAccessExpr); | 4383 | assert(node->type == NodeTypeArrayAccessExpr); |
| 3971 | | 4384 | |
| 3972 | AstNode *array_ref_node = node->data.array_access_expr.array_ref_expr; | 4385 | AstNode *array_ref_node = node->data.array_access_expr.array_ref_expr; |
| 3973 | IrInstruction *array_ref_instruction = ir_gen_node_extra(irb, array_ref_node, scope, LValPtr); | 4386 | IrInstruction *array_ref_instruction = ir_gen_node_extra(irb, array_ref_node, scope, LValPtr, nullptr); |
| 3974 | if (array_ref_instruction == irb->codegen->invalid_instruction) | 4387 | if (array_ref_instruction == irb->codegen->invalid_instruction) |
| 3975 | return array_ref_instruction; | 4388 | return array_ref_instruction; |
| 3976 | | 4389 | |
| ... | @@ -3980,11 +4393,12 @@ static IrInstruction *ir_gen_array_access(IrBuilder *irb, Scope *scope, AstNode | ... | @@ -3980,11 +4393,12 @@ static IrInstruction *ir_gen_array_access(IrBuilder *irb, Scope *scope, AstNode |
| 3980 | return subscript_instruction; | 4393 | return subscript_instruction; |
| 3981 | | 4394 | |
| 3982 | IrInstruction *ptr_instruction = ir_build_elem_ptr(irb, scope, node, array_ref_instruction, | 4395 | IrInstruction *ptr_instruction = ir_build_elem_ptr(irb, scope, node, array_ref_instruction, |
| 3983 | subscript_instruction, true, PtrLenSingle); | 4396 | subscript_instruction, true, PtrLenSingle, nullptr); |
| 3984 | if (lval == LValPtr) | 4397 | if (lval == LValPtr) |
| 3985 | return ptr_instruction; | 4398 | return ptr_instruction; |
| 3986 | | 4399 | |
| 3987 | return ir_build_load_ptr(irb, scope, node, ptr_instruction); | 4400 | IrInstruction *load_ptr = ir_build_load_ptr(irb, scope, node, ptr_instruction); |
| | 4401 | return ir_expr_wrap(irb, scope, load_ptr, result_loc); |
| 3988 | } | 4402 | } |
| 3989 | | 4403 | |
| 3990 | static IrInstruction *ir_gen_field_access(IrBuilder *irb, Scope *scope, AstNode *node) { | 4404 | static IrInstruction *ir_gen_field_access(IrBuilder *irb, Scope *scope, AstNode *node) { |
| ... | @@ -3993,11 +4407,11 @@ static IrInstruction *ir_gen_field_access(IrBuilder *irb, Scope *scope, AstNode | ... | @@ -3993,11 +4407,11 @@ static IrInstruction *ir_gen_field_access(IrBuilder *irb, Scope *scope, AstNode |
| 3993 | AstNode *container_ref_node = node->data.field_access_expr.struct_expr; | 4407 | AstNode *container_ref_node = node->data.field_access_expr.struct_expr; |
| 3994 | Buf *field_name = node->data.field_access_expr.field_name; | 4408 | Buf *field_name = node->data.field_access_expr.field_name; |
| 3995 | | 4409 | |
| 3996 | IrInstruction *container_ref_instruction = ir_gen_node_extra(irb, container_ref_node, scope, LValPtr); | 4410 | IrInstruction *container_ref_instruction = ir_gen_node_extra(irb, container_ref_node, scope, LValPtr, nullptr); |
| 3997 | if (container_ref_instruction == irb->codegen->invalid_instruction) | 4411 | if (container_ref_instruction == irb->codegen->invalid_instruction) |
| 3998 | return container_ref_instruction; | 4412 | return container_ref_instruction; |
| 3999 | | 4413 | |
| 4000 | return ir_build_field_ptr(irb, scope, node, container_ref_instruction, field_name); | 4414 | return ir_build_field_ptr(irb, scope, node, container_ref_instruction, field_name, false); |
| 4001 | } | 4415 | } |
| 4002 | | 4416 | |
| 4003 | static IrInstruction *ir_gen_overflow_op(IrBuilder *irb, Scope *scope, AstNode *node, IrOverflowOp op) { | 4417 | static IrInstruction *ir_gen_overflow_op(IrBuilder *irb, Scope *scope, AstNode *node, IrOverflowOp op) { |
| ... | @@ -4028,6 +4442,33 @@ static IrInstruction *ir_gen_overflow_op(IrBuilder *irb, Scope *scope, AstNode * | ... | @@ -4028,6 +4442,33 @@ static IrInstruction *ir_gen_overflow_op(IrBuilder *irb, Scope *scope, AstNode * |
| 4028 | return ir_build_overflow_op(irb, scope, node, op, type_value, op1, op2, result_ptr, nullptr); | 4442 | return ir_build_overflow_op(irb, scope, node, op, type_value, op1, op2, result_ptr, nullptr); |
| 4029 | } | 4443 | } |
| 4030 | | 4444 | |
| | 4445 | static IrInstruction *ir_gen_mul_add(IrBuilder *irb, Scope *scope, AstNode *node) { |
| | 4446 | assert(node->type == NodeTypeFnCallExpr); |
| | 4447 | |
| | 4448 | AstNode *type_node = node->data.fn_call_expr.params.at(0); |
| | 4449 | AstNode *op1_node = node->data.fn_call_expr.params.at(1); |
| | 4450 | AstNode *op2_node = node->data.fn_call_expr.params.at(2); |
| | 4451 | AstNode *op3_node = node->data.fn_call_expr.params.at(3); |
| | 4452 | |
| | 4453 | IrInstruction *type_value = ir_gen_node(irb, type_node, scope); |
| | 4454 | if (type_value == irb->codegen->invalid_instruction) |
| | 4455 | return irb->codegen->invalid_instruction; |
| | 4456 | |
| | 4457 | IrInstruction *op1 = ir_gen_node(irb, op1_node, scope); |
| | 4458 | if (op1 == irb->codegen->invalid_instruction) |
| | 4459 | return irb->codegen->invalid_instruction; |
| | 4460 | |
| | 4461 | IrInstruction *op2 = ir_gen_node(irb, op2_node, scope); |
| | 4462 | if (op2 == irb->codegen->invalid_instruction) |
| | 4463 | return irb->codegen->invalid_instruction; |
| | 4464 | |
| | 4465 | IrInstruction *op3 = ir_gen_node(irb, op3_node, scope); |
| | 4466 | if (op3 == irb->codegen->invalid_instruction) |
| | 4467 | return irb->codegen->invalid_instruction; |
| | 4468 | |
| | 4469 | return ir_build_mul_add(irb, scope, node, type_value, op1, op2, op3); |
| | 4470 | } |
| | 4471 | |
| 4031 | static IrInstruction *ir_gen_this(IrBuilder *irb, Scope *orig_scope, AstNode *node) { | 4472 | static IrInstruction *ir_gen_this(IrBuilder *irb, Scope *orig_scope, AstNode *node) { |
| 4032 | for (Scope *it_scope = orig_scope; it_scope != nullptr; it_scope = it_scope->parent) { | 4473 | for (Scope *it_scope = orig_scope; it_scope != nullptr; it_scope = it_scope->parent) { |
| 4033 | if (it_scope->id == ScopeIdDecls) { | 4474 | if (it_scope->id == ScopeIdDecls) { |
| ... | @@ -4043,7 +4484,9 @@ static IrInstruction *ir_gen_this(IrBuilder *irb, Scope *orig_scope, AstNode *no | ... | @@ -4043,7 +4484,9 @@ static IrInstruction *ir_gen_this(IrBuilder *irb, Scope *orig_scope, AstNode *no |
| 4043 | zig_unreachable(); | 4484 | zig_unreachable(); |
| 4044 | } | 4485 | } |
| 4045 | | 4486 | |
| 4046 | static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNode *node, LVal lval) { | 4487 | static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNode *node, LVal lval, |
| | 4488 | ResultLoc *result_loc) |
| | 4489 | { |
| 4047 | assert(node->type == NodeTypeFnCallExpr); | 4490 | assert(node->type == NodeTypeFnCallExpr); |
| 4048 | | 4491 | |
| 4049 | AstNode *fn_ref_expr = node->data.fn_call_expr.fn_ref_expr; | 4492 | AstNode *fn_ref_expr = node->data.fn_call_expr.fn_ref_expr; |
| ... | @@ -4079,7 +4522,7 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo | ... | @@ -4079,7 +4522,7 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo |
| 4079 | return arg; | 4522 | return arg; |
| 4080 | | 4523 | |
| 4081 | IrInstruction *type_of = ir_build_typeof(irb, scope, node, arg); | 4524 | IrInstruction *type_of = ir_build_typeof(irb, scope, node, arg); |
| 4082 | return ir_lval_wrap(irb, scope, type_of, lval); | 4525 | return ir_lval_wrap(irb, scope, type_of, lval, result_loc); |
| 4083 | } | 4526 | } |
| 4084 | case BuiltinFnIdSetCold: | 4527 | case BuiltinFnIdSetCold: |
| 4085 | { | 4528 | { |
| ... | @@ -4089,7 +4532,7 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo | ... | @@ -4089,7 +4532,7 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo |
| 4089 | return arg0_value; | 4532 | return arg0_value; |
| 4090 | | 4533 | |
| 4091 | IrInstruction *set_cold = ir_build_set_cold(irb, scope, node, arg0_value); | 4534 | IrInstruction *set_cold = ir_build_set_cold(irb, scope, node, arg0_value); |
| 4092 | return ir_lval_wrap(irb, scope, set_cold, lval); | 4535 | return ir_lval_wrap(irb, scope, set_cold, lval, result_loc); |
| 4093 | } | 4536 | } |
| 4094 | case BuiltinFnIdSetRuntimeSafety: | 4537 | case BuiltinFnIdSetRuntimeSafety: |
| 4095 | { | 4538 | { |
| ... | @@ -4099,7 +4542,7 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo | ... | @@ -4099,7 +4542,7 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo |
| 4099 | return arg0_value; | 4542 | return arg0_value; |
| 4100 | | 4543 | |
| 4101 | IrInstruction *set_safety = ir_build_set_runtime_safety(irb, scope, node, arg0_value); | 4544 | IrInstruction *set_safety = ir_build_set_runtime_safety(irb, scope, node, arg0_value); |
| 4102 | return ir_lval_wrap(irb, scope, set_safety, lval); | 4545 | return ir_lval_wrap(irb, scope, set_safety, lval, result_loc); |
| 4103 | } | 4546 | } |
| 4104 | case BuiltinFnIdSetFloatMode: | 4547 | case BuiltinFnIdSetFloatMode: |
| 4105 | { | 4548 | { |
| ... | @@ -4109,7 +4552,7 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo | ... | @@ -4109,7 +4552,7 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo |
| 4109 | return arg0_value; | 4552 | return arg0_value; |
| 4110 | | 4553 | |
| 4111 | IrInstruction *set_float_mode = ir_build_set_float_mode(irb, scope, node, arg0_value); | 4554 | IrInstruction *set_float_mode = ir_build_set_float_mode(irb, scope, node, arg0_value); |
| 4112 | return ir_lval_wrap(irb, scope, set_float_mode, lval); | 4555 | return ir_lval_wrap(irb, scope, set_float_mode, lval, result_loc); |
| 4113 | } | 4556 | } |
| 4114 | case BuiltinFnIdSizeof: | 4557 | case BuiltinFnIdSizeof: |
| 4115 | { | 4558 | { |
| ... | @@ -4119,7 +4562,7 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo | ... | @@ -4119,7 +4562,7 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo |
| 4119 | return arg0_value; | 4562 | return arg0_value; |
| 4120 | | 4563 | |
| 4121 | IrInstruction *size_of = ir_build_size_of(irb, scope, node, arg0_value); | 4564 | IrInstruction *size_of = ir_build_size_of(irb, scope, node, arg0_value); |
| 4122 | return ir_lval_wrap(irb, scope, size_of, lval); | 4565 | return ir_lval_wrap(irb, scope, size_of, lval, result_loc); |
| 4123 | } | 4566 | } |
| 4124 | case BuiltinFnIdImport: | 4567 | case BuiltinFnIdImport: |
| 4125 | { | 4568 | { |
| ... | @@ -4129,12 +4572,12 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo | ... | @@ -4129,12 +4572,12 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo |
| 4129 | return arg0_value; | 4572 | return arg0_value; |
| 4130 | | 4573 | |
| 4131 | IrInstruction *import = ir_build_import(irb, scope, node, arg0_value); | 4574 | IrInstruction *import = ir_build_import(irb, scope, node, arg0_value); |
| 4132 | return ir_lval_wrap(irb, scope, import, lval); | 4575 | return ir_lval_wrap(irb, scope, import, lval, result_loc); |
| 4133 | } | 4576 | } |
| 4134 | case BuiltinFnIdCImport: | 4577 | case BuiltinFnIdCImport: |
| 4135 | { | 4578 | { |
| 4136 | IrInstruction *c_import = ir_build_c_import(irb, scope, node); | 4579 | IrInstruction *c_import = ir_build_c_import(irb, scope, node); |
| 4137 | return ir_lval_wrap(irb, scope, c_import, lval); | 4580 | return ir_lval_wrap(irb, scope, c_import, lval, result_loc); |
| 4138 | } | 4581 | } |
| 4139 | case BuiltinFnIdCInclude: | 4582 | case BuiltinFnIdCInclude: |
| 4140 | { | 4583 | { |
| ... | @@ -4149,7 +4592,7 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo | ... | @@ -4149,7 +4592,7 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo |
| 4149 | } | 4592 | } |
| 4150 | | 4593 | |
| 4151 | IrInstruction *c_include = ir_build_c_include(irb, scope, node, arg0_value); | 4594 | IrInstruction *c_include = ir_build_c_include(irb, scope, node, arg0_value); |
| 4152 | return ir_lval_wrap(irb, scope, c_include, lval); | 4595 | return ir_lval_wrap(irb, scope, c_include, lval, result_loc); |
| 4153 | } | 4596 | } |
| 4154 | case BuiltinFnIdCDefine: | 4597 | case BuiltinFnIdCDefine: |
| 4155 | { | 4598 | { |
| ... | @@ -4169,7 +4612,7 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo | ... | @@ -4169,7 +4612,7 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo |
| 4169 | } | 4612 | } |
| 4170 | | 4613 | |
| 4171 | IrInstruction *c_define = ir_build_c_define(irb, scope, node, arg0_value, arg1_value); | 4614 | IrInstruction *c_define = ir_build_c_define(irb, scope, node, arg0_value, arg1_value); |
| 4172 | return ir_lval_wrap(irb, scope, c_define, lval); | 4615 | return ir_lval_wrap(irb, scope, c_define, lval, result_loc); |
| 4173 | } | 4616 | } |
| 4174 | case BuiltinFnIdCUndef: | 4617 | case BuiltinFnIdCUndef: |
| 4175 | { | 4618 | { |
| ... | @@ -4184,7 +4627,7 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo | ... | @@ -4184,7 +4627,7 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo |
| 4184 | } | 4627 | } |
| 4185 | | 4628 | |
| 4186 | IrInstruction *c_undef = ir_build_c_undef(irb, scope, node, arg0_value); | 4629 | IrInstruction *c_undef = ir_build_c_undef(irb, scope, node, arg0_value); |
| 4187 | return ir_lval_wrap(irb, scope, c_undef, lval); | 4630 | return ir_lval_wrap(irb, scope, c_undef, lval, result_loc); |
| 4188 | } | 4631 | } |
| 4189 | case BuiltinFnIdCompileErr: | 4632 | case BuiltinFnIdCompileErr: |
| 4190 | { | 4633 | { |
| ... | @@ -4194,7 +4637,7 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo | ... | @@ -4194,7 +4637,7 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo |
| 4194 | return arg0_value; | 4637 | return arg0_value; |
| 4195 | | 4638 | |
| 4196 | IrInstruction *compile_err = ir_build_compile_err(irb, scope, node, arg0_value); | 4639 | IrInstruction *compile_err = ir_build_compile_err(irb, scope, node, arg0_value); |
| 4197 | return ir_lval_wrap(irb, scope, compile_err, lval); | 4640 | return ir_lval_wrap(irb, scope, compile_err, lval, result_loc); |
| 4198 | } | 4641 | } |
| 4199 | case BuiltinFnIdCompileLog: | 4642 | case BuiltinFnIdCompileLog: |
| 4200 | { | 4643 | { |
| ... | @@ -4208,7 +4651,7 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo | ... | @@ -4208,7 +4651,7 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo |
| 4208 | } | 4651 | } |
| 4209 | | 4652 | |
| 4210 | IrInstruction *compile_log = ir_build_compile_log(irb, scope, node, actual_param_count, args); | 4653 | IrInstruction *compile_log = ir_build_compile_log(irb, scope, node, actual_param_count, args); |
| 4211 | return ir_lval_wrap(irb, scope, compile_log, lval); | 4654 | return ir_lval_wrap(irb, scope, compile_log, lval, result_loc); |
| 4212 | } | 4655 | } |
| 4213 | case BuiltinFnIdErrName: | 4656 | case BuiltinFnIdErrName: |
| 4214 | { | 4657 | { |
| ... | @@ -4218,7 +4661,7 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo | ... | @@ -4218,7 +4661,7 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo |
| 4218 | return arg0_value; | 4661 | return arg0_value; |
| 4219 | | 4662 | |
| 4220 | IrInstruction *err_name = ir_build_err_name(irb, scope, node, arg0_value); | 4663 | IrInstruction *err_name = ir_build_err_name(irb, scope, node, arg0_value); |
| 4221 | return ir_lval_wrap(irb, scope, err_name, lval); | 4664 | return ir_lval_wrap(irb, scope, err_name, lval, result_loc); |
| 4222 | } | 4665 | } |
| 4223 | case BuiltinFnIdEmbedFile: | 4666 | case BuiltinFnIdEmbedFile: |
| 4224 | { | 4667 | { |
| ... | @@ -4228,7 +4671,7 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo | ... | @@ -4228,7 +4671,7 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo |
| 4228 | return arg0_value; | 4671 | return arg0_value; |
| 4229 | | 4672 | |
| 4230 | IrInstruction *embed_file = ir_build_embed_file(irb, scope, node, arg0_value); | 4673 | IrInstruction *embed_file = ir_build_embed_file(irb, scope, node, arg0_value); |
| 4231 | return ir_lval_wrap(irb, scope, embed_file, lval); | 4674 | return ir_lval_wrap(irb, scope, embed_file, lval, result_loc); |
| 4232 | } | 4675 | } |
| 4233 | case BuiltinFnIdCmpxchgWeak: | 4676 | case BuiltinFnIdCmpxchgWeak: |
| 4234 | case BuiltinFnIdCmpxchgStrong: | 4677 | case BuiltinFnIdCmpxchgStrong: |
| ... | @@ -4264,8 +4707,9 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo | ... | @@ -4264,8 +4707,9 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo |
| 4264 | return arg5_value; | 4707 | return arg5_value; |
| 4265 | | 4708 | |
| 4266 | IrInstruction *cmpxchg = ir_build_cmpxchg_src(irb, scope, node, arg0_value, arg1_value, | 4709 | IrInstruction *cmpxchg = ir_build_cmpxchg_src(irb, scope, node, arg0_value, arg1_value, |
| 4267 | arg2_value, arg3_value, arg4_value, arg5_value, (builtin_fn->id == BuiltinFnIdCmpxchgWeak)); | 4710 | arg2_value, arg3_value, arg4_value, arg5_value, (builtin_fn->id == BuiltinFnIdCmpxchgWeak), |
| 4268 | return ir_lval_wrap(irb, scope, cmpxchg, lval); | 4711 | result_loc); |
| | 4712 | return ir_lval_wrap(irb, scope, cmpxchg, lval, result_loc); |
| 4269 | } | 4713 | } |
| 4270 | case BuiltinFnIdFence: | 4714 | case BuiltinFnIdFence: |
| 4271 | { | 4715 | { |
| ... | @@ -4275,7 +4719,7 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo | ... | @@ -4275,7 +4719,7 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo |
| 4275 | return arg0_value; | 4719 | return arg0_value; |
| 4276 | | 4720 | |
| 4277 | IrInstruction *fence = ir_build_fence(irb, scope, node, arg0_value, AtomicOrderUnordered); | 4721 | IrInstruction *fence = ir_build_fence(irb, scope, node, arg0_value, AtomicOrderUnordered); |
| 4278 | return ir_lval_wrap(irb, scope, fence, lval); | 4722 | return ir_lval_wrap(irb, scope, fence, lval, result_loc); |
| 4279 | } | 4723 | } |
| 4280 | case BuiltinFnIdDivExact: | 4724 | case BuiltinFnIdDivExact: |
| 4281 | { | 4725 | { |
| ... | @@ -4290,7 +4734,7 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo | ... | @@ -4290,7 +4734,7 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo |
| 4290 | return arg1_value; | 4734 | return arg1_value; |
| 4291 | | 4735 | |
| 4292 | IrInstruction *bin_op = ir_build_bin_op(irb, scope, node, IrBinOpDivExact, arg0_value, arg1_value, true); | 4736 | IrInstruction *bin_op = ir_build_bin_op(irb, scope, node, IrBinOpDivExact, arg0_value, arg1_value, true); |
| 4293 | return ir_lval_wrap(irb, scope, bin_op, lval); | 4737 | return ir_lval_wrap(irb, scope, bin_op, lval, result_loc); |
| 4294 | } | 4738 | } |
| 4295 | case BuiltinFnIdDivTrunc: | 4739 | case BuiltinFnIdDivTrunc: |
| 4296 | { | 4740 | { |
| ... | @@ -4305,7 +4749,7 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo | ... | @@ -4305,7 +4749,7 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo |
| 4305 | return arg1_value; | 4749 | return arg1_value; |
| 4306 | | 4750 | |
| 4307 | IrInstruction *bin_op = ir_build_bin_op(irb, scope, node, IrBinOpDivTrunc, arg0_value, arg1_value, true); | 4751 | IrInstruction *bin_op = ir_build_bin_op(irb, scope, node, IrBinOpDivTrunc, arg0_value, arg1_value, true); |
| 4308 | return ir_lval_wrap(irb, scope, bin_op, lval); | 4752 | return ir_lval_wrap(irb, scope, bin_op, lval, result_loc); |
| 4309 | } | 4753 | } |
| 4310 | case BuiltinFnIdDivFloor: | 4754 | case BuiltinFnIdDivFloor: |
| 4311 | { | 4755 | { |
| ... | @@ -4320,7 +4764,7 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo | ... | @@ -4320,7 +4764,7 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo |
| 4320 | return arg1_value; | 4764 | return arg1_value; |
| 4321 | | 4765 | |
| 4322 | IrInstruction *bin_op = ir_build_bin_op(irb, scope, node, IrBinOpDivFloor, arg0_value, arg1_value, true); | 4766 | IrInstruction *bin_op = ir_build_bin_op(irb, scope, node, IrBinOpDivFloor, arg0_value, arg1_value, true); |
| 4323 | return ir_lval_wrap(irb, scope, bin_op, lval); | 4767 | return ir_lval_wrap(irb, scope, bin_op, lval, result_loc); |
| 4324 | } | 4768 | } |
| 4325 | case BuiltinFnIdRem: | 4769 | case BuiltinFnIdRem: |
| 4326 | { | 4770 | { |
| ... | @@ -4335,7 +4779,7 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo | ... | @@ -4335,7 +4779,7 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo |
| 4335 | return arg1_value; | 4779 | return arg1_value; |
| 4336 | | 4780 | |
| 4337 | IrInstruction *bin_op = ir_build_bin_op(irb, scope, node, IrBinOpRemRem, arg0_value, arg1_value, true); | 4781 | IrInstruction *bin_op = ir_build_bin_op(irb, scope, node, IrBinOpRemRem, arg0_value, arg1_value, true); |
| 4338 | return ir_lval_wrap(irb, scope, bin_op, lval); | 4782 | return ir_lval_wrap(irb, scope, bin_op, lval, result_loc); |
| 4339 | } | 4783 | } |
| 4340 | case BuiltinFnIdMod: | 4784 | case BuiltinFnIdMod: |
| 4341 | { | 4785 | { |
| ... | @@ -4350,9 +4794,22 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo | ... | @@ -4350,9 +4794,22 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo |
| 4350 | return arg1_value; | 4794 | return arg1_value; |
| 4351 | | 4795 | |
| 4352 | IrInstruction *bin_op = ir_build_bin_op(irb, scope, node, IrBinOpRemMod, arg0_value, arg1_value, true); | 4796 | IrInstruction *bin_op = ir_build_bin_op(irb, scope, node, IrBinOpRemMod, arg0_value, arg1_value, true); |
| 4353 | return ir_lval_wrap(irb, scope, bin_op, lval); | 4797 | return ir_lval_wrap(irb, scope, bin_op, lval, result_loc); |
| 4354 | } | 4798 | } |
| 4355 | case BuiltinFnIdSqrt: | 4799 | case BuiltinFnIdSqrt: |
| | 4800 | case BuiltinFnIdSin: |
| | 4801 | case BuiltinFnIdCos: |
| | 4802 | case BuiltinFnIdExp: |
| | 4803 | case BuiltinFnIdExp2: |
| | 4804 | case BuiltinFnIdLn: |
| | 4805 | case BuiltinFnIdLog2: |
| | 4806 | case BuiltinFnIdLog10: |
| | 4807 | case BuiltinFnIdFabs: |
| | 4808 | case BuiltinFnIdFloor: |
| | 4809 | case BuiltinFnIdCeil: |
| | 4810 | case BuiltinFnIdTrunc: |
| | 4811 | case BuiltinFnIdNearbyInt: |
| | 4812 | case BuiltinFnIdRound: |
| 4356 | { | 4813 | { |
| 4357 | AstNode *arg0_node = node->data.fn_call_expr.params.at(0); | 4814 | AstNode *arg0_node = node->data.fn_call_expr.params.at(0); |
| 4358 | IrInstruction *arg0_value = ir_gen_node(irb, arg0_node, scope); | 4815 | IrInstruction *arg0_value = ir_gen_node(irb, arg0_node, scope); |
| ... | @@ -4364,8 +4821,8 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo | ... | @@ -4364,8 +4821,8 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo |
| 4364 | if (arg1_value == irb->codegen->invalid_instruction) | 4821 | if (arg1_value == irb->codegen->invalid_instruction) |
| 4365 | return arg1_value; | 4822 | return arg1_value; |
| 4366 | | 4823 | |
| 4367 | IrInstruction *ir_sqrt = ir_build_sqrt(irb, scope, node, arg0_value, arg1_value); | 4824 | IrInstruction *ir_sqrt = ir_build_float_op(irb, scope, node, arg0_value, arg1_value, builtin_fn->id); |
| 4368 | return ir_lval_wrap(irb, scope, ir_sqrt, lval); | 4825 | return ir_lval_wrap(irb, scope, ir_sqrt, lval, result_loc); |
| 4369 | } | 4826 | } |
| 4370 | case BuiltinFnIdTruncate: | 4827 | case BuiltinFnIdTruncate: |
| 4371 | { | 4828 | { |
| ... | @@ -4380,7 +4837,7 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo | ... | @@ -4380,7 +4837,7 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo |
| 4380 | return arg1_value; | 4837 | return arg1_value; |
| 4381 | | 4838 | |
| 4382 | IrInstruction *truncate = ir_build_truncate(irb, scope, node, arg0_value, arg1_value); | 4839 | IrInstruction *truncate = ir_build_truncate(irb, scope, node, arg0_value, arg1_value); |
| 4383 | return ir_lval_wrap(irb, scope, truncate, lval); | 4840 | return ir_lval_wrap(irb, scope, truncate, lval, result_loc); |
| 4384 | } | 4841 | } |
| 4385 | case BuiltinFnIdIntCast: | 4842 | case BuiltinFnIdIntCast: |
| 4386 | { | 4843 | { |
| ... | @@ -4395,7 +4852,7 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo | ... | @@ -4395,7 +4852,7 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo |
| 4395 | return arg1_value; | 4852 | return arg1_value; |
| 4396 | | 4853 | |
| 4397 | IrInstruction *result = ir_build_int_cast(irb, scope, node, arg0_value, arg1_value); | 4854 | IrInstruction *result = ir_build_int_cast(irb, scope, node, arg0_value, arg1_value); |
| 4398 | return ir_lval_wrap(irb, scope, result, lval); | 4855 | return ir_lval_wrap(irb, scope, result, lval, result_loc); |
| 4399 | } | 4856 | } |
| 4400 | case BuiltinFnIdFloatCast: | 4857 | case BuiltinFnIdFloatCast: |
| 4401 | { | 4858 | { |
| ... | @@ -4410,7 +4867,7 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo | ... | @@ -4410,7 +4867,7 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo |
| 4410 | return arg1_value; | 4867 | return arg1_value; |
| 4411 | | 4868 | |
| 4412 | IrInstruction *result = ir_build_float_cast(irb, scope, node, arg0_value, arg1_value); | 4869 | IrInstruction *result = ir_build_float_cast(irb, scope, node, arg0_value, arg1_value); |
| 4413 | return ir_lval_wrap(irb, scope, result, lval); | 4870 | return ir_lval_wrap(irb, scope, result, lval, result_loc); |
| 4414 | } | 4871 | } |
| 4415 | case BuiltinFnIdErrSetCast: | 4872 | case BuiltinFnIdErrSetCast: |
| 4416 | { | 4873 | { |
| ... | @@ -4425,7 +4882,7 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo | ... | @@ -4425,7 +4882,7 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo |
| 4425 | return arg1_value; | 4882 | return arg1_value; |
| 4426 | | 4883 | |
| 4427 | IrInstruction *result = ir_build_err_set_cast(irb, scope, node, arg0_value, arg1_value); | 4884 | IrInstruction *result = ir_build_err_set_cast(irb, scope, node, arg0_value, arg1_value); |
| 4428 | return ir_lval_wrap(irb, scope, result, lval); | 4885 | return ir_lval_wrap(irb, scope, result, lval, result_loc); |
| 4429 | } | 4886 | } |
| 4430 | case BuiltinFnIdFromBytes: | 4887 | case BuiltinFnIdFromBytes: |
| 4431 | { | 4888 | { |
| ... | @@ -4439,8 +4896,8 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo | ... | @@ -4439,8 +4896,8 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo |
| 4439 | if (arg1_value == irb->codegen->invalid_instruction) | 4896 | if (arg1_value == irb->codegen->invalid_instruction) |
| 4440 | return arg1_value; | 4897 | return arg1_value; |
| 4441 | | 4898 | |
| 4442 | IrInstruction *result = ir_build_from_bytes(irb, scope, node, arg0_value, arg1_value); | 4899 | IrInstruction *result = ir_build_from_bytes(irb, scope, node, arg0_value, arg1_value, result_loc); |
| 4443 | return ir_lval_wrap(irb, scope, result, lval); | 4900 | return ir_lval_wrap(irb, scope, result, lval, result_loc); |
| 4444 | } | 4901 | } |
| 4445 | case BuiltinFnIdToBytes: | 4902 | case BuiltinFnIdToBytes: |
| 4446 | { | 4903 | { |
| ... | @@ -4449,8 +4906,8 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo | ... | @@ -4449,8 +4906,8 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo |
| 4449 | if (arg0_value == irb->codegen->invalid_instruction) | 4906 | if (arg0_value == irb->codegen->invalid_instruction) |
| 4450 | return arg0_value; | 4907 | return arg0_value; |
| 4451 | | 4908 | |
| 4452 | IrInstruction *result = ir_build_to_bytes(irb, scope, node, arg0_value); | 4909 | IrInstruction *result = ir_build_to_bytes(irb, scope, node, arg0_value, result_loc); |
| 4453 | return ir_lval_wrap(irb, scope, result, lval); | 4910 | return ir_lval_wrap(irb, scope, result, lval, result_loc); |
| 4454 | } | 4911 | } |
| 4455 | case BuiltinFnIdIntToFloat: | 4912 | case BuiltinFnIdIntToFloat: |
| 4456 | { | 4913 | { |
| ... | @@ -4465,7 +4922,7 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo | ... | @@ -4465,7 +4922,7 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo |
| 4465 | return arg1_value; | 4922 | return arg1_value; |
| 4466 | | 4923 | |
| 4467 | IrInstruction *result = ir_build_int_to_float(irb, scope, node, arg0_value, arg1_value); | 4924 | IrInstruction *result = ir_build_int_to_float(irb, scope, node, arg0_value, arg1_value); |
| 4468 | return ir_lval_wrap(irb, scope, result, lval); | 4925 | return ir_lval_wrap(irb, scope, result, lval, result_loc); |
| 4469 | } | 4926 | } |
| 4470 | case BuiltinFnIdFloatToInt: | 4927 | case BuiltinFnIdFloatToInt: |
| 4471 | { | 4928 | { |
| ... | @@ -4480,7 +4937,7 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo | ... | @@ -4480,7 +4937,7 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo |
| 4480 | return arg1_value; | 4937 | return arg1_value; |
| 4481 | | 4938 | |
| 4482 | IrInstruction *result = ir_build_float_to_int(irb, scope, node, arg0_value, arg1_value); | 4939 | IrInstruction *result = ir_build_float_to_int(irb, scope, node, arg0_value, arg1_value); |
| 4483 | return ir_lval_wrap(irb, scope, result, lval); | 4940 | return ir_lval_wrap(irb, scope, result, lval, result_loc); |
| 4484 | } | 4941 | } |
| 4485 | case BuiltinFnIdErrToInt: | 4942 | case BuiltinFnIdErrToInt: |
| 4486 | { | 4943 | { |
| ... | @@ -4490,7 +4947,7 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo | ... | @@ -4490,7 +4947,7 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo |
| 4490 | return arg0_value; | 4947 | return arg0_value; |
| 4491 | | 4948 | |
| 4492 | IrInstruction *result = ir_build_err_to_int(irb, scope, node, arg0_value); | 4949 | IrInstruction *result = ir_build_err_to_int(irb, scope, node, arg0_value); |
| 4493 | return ir_lval_wrap(irb, scope, result, lval); | 4950 | return ir_lval_wrap(irb, scope, result, lval, result_loc); |
| 4494 | } | 4951 | } |
| 4495 | case BuiltinFnIdIntToErr: | 4952 | case BuiltinFnIdIntToErr: |
| 4496 | { | 4953 | { |
| ... | @@ -4500,7 +4957,7 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo | ... | @@ -4500,7 +4957,7 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo |
| 4500 | return arg0_value; | 4957 | return arg0_value; |
| 4501 | | 4958 | |
| 4502 | IrInstruction *result = ir_build_int_to_err(irb, scope, node, arg0_value); | 4959 | IrInstruction *result = ir_build_int_to_err(irb, scope, node, arg0_value); |
| 4503 | return ir_lval_wrap(irb, scope, result, lval); | 4960 | return ir_lval_wrap(irb, scope, result, lval, result_loc); |
| 4504 | } | 4961 | } |
| 4505 | case BuiltinFnIdBoolToInt: | 4962 | case BuiltinFnIdBoolToInt: |
| 4506 | { | 4963 | { |
| ... | @@ -4510,7 +4967,7 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo | ... | @@ -4510,7 +4967,7 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo |
| 4510 | return arg0_value; | 4967 | return arg0_value; |
| 4511 | | 4968 | |
| 4512 | IrInstruction *result = ir_build_bool_to_int(irb, scope, node, arg0_value); | 4969 | IrInstruction *result = ir_build_bool_to_int(irb, scope, node, arg0_value); |
| 4513 | return ir_lval_wrap(irb, scope, result, lval); | 4970 | return ir_lval_wrap(irb, scope, result, lval, result_loc); |
| 4514 | } | 4971 | } |
| 4515 | case BuiltinFnIdIntType: | 4972 | case BuiltinFnIdIntType: |
| 4516 | { | 4973 | { |
| ... | @@ -4525,7 +4982,7 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo | ... | @@ -4525,7 +4982,7 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo |
| 4525 | return arg1_value; | 4982 | return arg1_value; |
| 4526 | | 4983 | |
| 4527 | IrInstruction *int_type = ir_build_int_type(irb, scope, node, arg0_value, arg1_value); | 4984 | IrInstruction *int_type = ir_build_int_type(irb, scope, node, arg0_value, arg1_value); |
| 4528 | return ir_lval_wrap(irb, scope, int_type, lval); | 4985 | return ir_lval_wrap(irb, scope, int_type, lval, result_loc); |
| 4529 | } | 4986 | } |
| 4530 | case BuiltinFnIdVectorType: | 4987 | case BuiltinFnIdVectorType: |
| 4531 | { | 4988 | { |
| ... | @@ -4540,7 +4997,7 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo | ... | @@ -4540,7 +4997,7 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo |
| 4540 | return arg1_value; | 4997 | return arg1_value; |
| 4541 | | 4998 | |
| 4542 | IrInstruction *vector_type = ir_build_vector_type(irb, scope, node, arg0_value, arg1_value); | 4999 | IrInstruction *vector_type = ir_build_vector_type(irb, scope, node, arg0_value, arg1_value); |
| 4543 | return ir_lval_wrap(irb, scope, vector_type, lval); | 5000 | return ir_lval_wrap(irb, scope, vector_type, lval, result_loc); |
| 4544 | } | 5001 | } |
| 4545 | case BuiltinFnIdMemcpy: | 5002 | case BuiltinFnIdMemcpy: |
| 4546 | { | 5003 | { |
| ... | @@ -4560,7 +5017,7 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo | ... | @@ -4560,7 +5017,7 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo |
| 4560 | return arg2_value; | 5017 | return arg2_value; |
| 4561 | | 5018 | |
| 4562 | IrInstruction *ir_memcpy = ir_build_memcpy(irb, scope, node, arg0_value, arg1_value, arg2_value); | 5019 | IrInstruction *ir_memcpy = ir_build_memcpy(irb, scope, node, arg0_value, arg1_value, arg2_value); |
| 4563 | return ir_lval_wrap(irb, scope, ir_memcpy, lval); | 5020 | return ir_lval_wrap(irb, scope, ir_memcpy, lval, result_loc); |
| 4564 | } | 5021 | } |
| 4565 | case BuiltinFnIdMemset: | 5022 | case BuiltinFnIdMemset: |
| 4566 | { | 5023 | { |
| ... | @@ -4580,7 +5037,7 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo | ... | @@ -4580,7 +5037,7 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo |
| 4580 | return arg2_value; | 5037 | return arg2_value; |
| 4581 | | 5038 | |
| 4582 | IrInstruction *ir_memset = ir_build_memset(irb, scope, node, arg0_value, arg1_value, arg2_value); | 5039 | IrInstruction *ir_memset = ir_build_memset(irb, scope, node, arg0_value, arg1_value, arg2_value); |
| 4583 | return ir_lval_wrap(irb, scope, ir_memset, lval); | 5040 | return ir_lval_wrap(irb, scope, ir_memset, lval, result_loc); |
| 4584 | } | 5041 | } |
| 4585 | case BuiltinFnIdMemberCount: | 5042 | case BuiltinFnIdMemberCount: |
| 4586 | { | 5043 | { |
| ... | @@ -4590,7 +5047,7 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo | ... | @@ -4590,7 +5047,7 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo |
| 4590 | return arg0_value; | 5047 | return arg0_value; |
| 4591 | | 5048 | |
| 4592 | IrInstruction *member_count = ir_build_member_count(irb, scope, node, arg0_value); | 5049 | IrInstruction *member_count = ir_build_member_count(irb, scope, node, arg0_value); |
| 4593 | return ir_lval_wrap(irb, scope, member_count, lval); | 5050 | return ir_lval_wrap(irb, scope, member_count, lval, result_loc); |
| 4594 | } | 5051 | } |
| 4595 | case BuiltinFnIdMemberType: | 5052 | case BuiltinFnIdMemberType: |
| 4596 | { | 5053 | { |
| ... | @@ -4606,7 +5063,7 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo | ... | @@ -4606,7 +5063,7 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo |
| 4606 | | 5063 | |
| 4607 | | 5064 | |
| 4608 | IrInstruction *member_type = ir_build_member_type(irb, scope, node, arg0_value, arg1_value); | 5065 | IrInstruction *member_type = ir_build_member_type(irb, scope, node, arg0_value, arg1_value); |
| 4609 | return ir_lval_wrap(irb, scope, member_type, lval); | 5066 | return ir_lval_wrap(irb, scope, member_type, lval, result_loc); |
| 4610 | } | 5067 | } |
| 4611 | case BuiltinFnIdMemberName: | 5068 | case BuiltinFnIdMemberName: |
| 4612 | { | 5069 | { |
| ... | @@ -4622,12 +5079,12 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo | ... | @@ -4622,12 +5079,12 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo |
| 4622 | | 5079 | |
| 4623 | | 5080 | |
| 4624 | IrInstruction *member_name = ir_build_member_name(irb, scope, node, arg0_value, arg1_value); | 5081 | IrInstruction *member_name = ir_build_member_name(irb, scope, node, arg0_value, arg1_value); |
| 4625 | return ir_lval_wrap(irb, scope, member_name, lval); | 5082 | return ir_lval_wrap(irb, scope, member_name, lval, result_loc); |
| 4626 | } | 5083 | } |
| 4627 | case BuiltinFnIdField: | 5084 | case BuiltinFnIdField: |
| 4628 | { | 5085 | { |
| 4629 | AstNode *arg0_node = node->data.fn_call_expr.params.at(0); | 5086 | AstNode *arg0_node = node->data.fn_call_expr.params.at(0); |
| 4630 | IrInstruction *arg0_value = ir_gen_node_extra(irb, arg0_node, scope, LValPtr); | 5087 | IrInstruction *arg0_value = ir_gen_node_extra(irb, arg0_node, scope, LValPtr, nullptr); |
| 4631 | if (arg0_value == irb->codegen->invalid_instruction) | 5088 | if (arg0_value == irb->codegen->invalid_instruction) |
| 4632 | return arg0_value; | 5089 | return arg0_value; |
| 4633 | | 5090 | |
| ... | @@ -4641,7 +5098,8 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo | ... | @@ -4641,7 +5098,8 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo |
| 4641 | if (lval == LValPtr) | 5098 | if (lval == LValPtr) |
| 4642 | return ptr_instruction; | 5099 | return ptr_instruction; |
| 4643 | | 5100 | |
| 4644 | return ir_build_load_ptr(irb, scope, node, ptr_instruction); | 5101 | IrInstruction *load_ptr = ir_build_load_ptr(irb, scope, node, ptr_instruction); |
| | 5102 | return ir_expr_wrap(irb, scope, load_ptr, result_loc); |
| 4645 | } | 5103 | } |
| 4646 | case BuiltinFnIdTypeInfo: | 5104 | case BuiltinFnIdTypeInfo: |
| 4647 | { | 5105 | { |
| ... | @@ -4651,14 +5109,14 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo | ... | @@ -4651,14 +5109,14 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo |
| 4651 | return arg0_value; | 5109 | return arg0_value; |
| 4652 | | 5110 | |
| 4653 | IrInstruction *type_info = ir_build_type_info(irb, scope, node, arg0_value); | 5111 | IrInstruction *type_info = ir_build_type_info(irb, scope, node, arg0_value); |
| 4654 | return ir_lval_wrap(irb, scope, type_info, lval); | 5112 | return ir_lval_wrap(irb, scope, type_info, lval, result_loc); |
| 4655 | } | 5113 | } |
| 4656 | case BuiltinFnIdBreakpoint: | 5114 | case BuiltinFnIdBreakpoint: |
| 4657 | return ir_lval_wrap(irb, scope, ir_build_breakpoint(irb, scope, node), lval); | 5115 | return ir_lval_wrap(irb, scope, ir_build_breakpoint(irb, scope, node), lval, result_loc); |
| 4658 | case BuiltinFnIdReturnAddress: | 5116 | case BuiltinFnIdReturnAddress: |
| 4659 | return ir_lval_wrap(irb, scope, ir_build_return_address(irb, scope, node), lval); | 5117 | return ir_lval_wrap(irb, scope, ir_build_return_address(irb, scope, node), lval, result_loc); |
| 4660 | case BuiltinFnIdFrameAddress: | 5118 | case BuiltinFnIdFrameAddress: |
| 4661 | return ir_lval_wrap(irb, scope, ir_build_frame_address(irb, scope, node), lval); | 5119 | return ir_lval_wrap(irb, scope, ir_build_frame_address(irb, scope, node), lval, result_loc); |
| 4662 | case BuiltinFnIdHandle: | 5120 | case BuiltinFnIdHandle: |
| 4663 | if (!irb->exec->fn_entry) { | 5121 | if (!irb->exec->fn_entry) { |
| 4664 | add_node_error(irb->codegen, node, buf_sprintf("@handle() called outside of function definition")); | 5122 | add_node_error(irb->codegen, node, buf_sprintf("@handle() called outside of function definition")); |
| ... | @@ -4668,7 +5126,7 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo | ... | @@ -4668,7 +5126,7 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo |
| 4668 | add_node_error(irb->codegen, node, buf_sprintf("@handle() in non-async function")); | 5126 | add_node_error(irb->codegen, node, buf_sprintf("@handle() in non-async function")); |
| 4669 | return irb->codegen->invalid_instruction; | 5127 | return irb->codegen->invalid_instruction; |
| 4670 | } | 5128 | } |
| 4671 | return ir_lval_wrap(irb, scope, ir_build_handle(irb, scope, node), lval); | 5129 | return ir_lval_wrap(irb, scope, ir_build_handle(irb, scope, node), lval, result_loc); |
| 4672 | case BuiltinFnIdAlignOf: | 5130 | case BuiltinFnIdAlignOf: |
| 4673 | { | 5131 | { |
| 4674 | AstNode *arg0_node = node->data.fn_call_expr.params.at(0); | 5132 | AstNode *arg0_node = node->data.fn_call_expr.params.at(0); |
| ... | @@ -4677,16 +5135,18 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo | ... | @@ -4677,16 +5135,18 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo |
| 4677 | return arg0_value; | 5135 | return arg0_value; |
| 4678 | | 5136 | |
| 4679 | IrInstruction *align_of = ir_build_align_of(irb, scope, node, arg0_value); | 5137 | IrInstruction *align_of = ir_build_align_of(irb, scope, node, arg0_value); |
| 4680 | return ir_lval_wrap(irb, scope, align_of, lval); | 5138 | return ir_lval_wrap(irb, scope, align_of, lval, result_loc); |
| 4681 | } | 5139 | } |
| 4682 | case BuiltinFnIdAddWithOverflow: | 5140 | case BuiltinFnIdAddWithOverflow: |
| 4683 | return ir_lval_wrap(irb, scope, ir_gen_overflow_op(irb, scope, node, IrOverflowOpAdd), lval); | 5141 | return ir_lval_wrap(irb, scope, ir_gen_overflow_op(irb, scope, node, IrOverflowOpAdd), lval, result_loc); |
| 4684 | case BuiltinFnIdSubWithOverflow: | 5142 | case BuiltinFnIdSubWithOverflow: |
| 4685 | return ir_lval_wrap(irb, scope, ir_gen_overflow_op(irb, scope, node, IrOverflowOpSub), lval); | 5143 | return ir_lval_wrap(irb, scope, ir_gen_overflow_op(irb, scope, node, IrOverflowOpSub), lval, result_loc); |
| 4686 | case BuiltinFnIdMulWithOverflow: | 5144 | case BuiltinFnIdMulWithOverflow: |
| 4687 | return ir_lval_wrap(irb, scope, ir_gen_overflow_op(irb, scope, node, IrOverflowOpMul), lval); | 5145 | return ir_lval_wrap(irb, scope, ir_gen_overflow_op(irb, scope, node, IrOverflowOpMul), lval, result_loc); |
| 4688 | case BuiltinFnIdShlWithOverflow: | 5146 | case BuiltinFnIdShlWithOverflow: |
| 4689 | return ir_lval_wrap(irb, scope, ir_gen_overflow_op(irb, scope, node, IrOverflowOpShl), lval); | 5147 | return ir_lval_wrap(irb, scope, ir_gen_overflow_op(irb, scope, node, IrOverflowOpShl), lval, result_loc); |
| | 5148 | case BuiltinFnIdMulAdd: |
| | 5149 | return ir_lval_wrap(irb, scope, ir_gen_mul_add(irb, scope, node), lval, result_loc); |
| 4690 | case BuiltinFnIdTypeName: | 5150 | case BuiltinFnIdTypeName: |
| 4691 | { | 5151 | { |
| 4692 | AstNode *arg0_node = node->data.fn_call_expr.params.at(0); | 5152 | AstNode *arg0_node = node->data.fn_call_expr.params.at(0); |
| ... | @@ -4695,7 +5155,7 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo | ... | @@ -4695,7 +5155,7 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo |
| 4695 | return arg0_value; | 5155 | return arg0_value; |
| 4696 | | 5156 | |
| 4697 | IrInstruction *type_name = ir_build_type_name(irb, scope, node, arg0_value); | 5157 | IrInstruction *type_name = ir_build_type_name(irb, scope, node, arg0_value); |
| 4698 | return ir_lval_wrap(irb, scope, type_name, lval); | 5158 | return ir_lval_wrap(irb, scope, type_name, lval, result_loc); |
| 4699 | } | 5159 | } |
| 4700 | case BuiltinFnIdPanic: | 5160 | case BuiltinFnIdPanic: |
| 4701 | { | 5161 | { |
| ... | @@ -4705,7 +5165,7 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo | ... | @@ -4705,7 +5165,7 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo |
| 4705 | return arg0_value; | 5165 | return arg0_value; |
| 4706 | | 5166 | |
| 4707 | IrInstruction *panic = ir_build_panic(irb, scope, node, arg0_value); | 5167 | IrInstruction *panic = ir_build_panic(irb, scope, node, arg0_value); |
| 4708 | return ir_lval_wrap(irb, scope, panic, lval); | 5168 | return ir_lval_wrap(irb, scope, panic, lval, result_loc); |
| 4709 | } | 5169 | } |
| 4710 | case BuiltinFnIdPtrCast: | 5170 | case BuiltinFnIdPtrCast: |
| 4711 | { | 5171 | { |
| ... | @@ -4720,22 +5180,31 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo | ... | @@ -4720,22 +5180,31 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo |
| 4720 | return arg1_value; | 5180 | return arg1_value; |
| 4721 | | 5181 | |
| 4722 | IrInstruction *ptr_cast = ir_build_ptr_cast_src(irb, scope, node, arg0_value, arg1_value, true); | 5182 | IrInstruction *ptr_cast = ir_build_ptr_cast_src(irb, scope, node, arg0_value, arg1_value, true); |
| 4723 | return ir_lval_wrap(irb, scope, ptr_cast, lval); | 5183 | return ir_lval_wrap(irb, scope, ptr_cast, lval, result_loc); |
| 4724 | } | 5184 | } |
| 4725 | case BuiltinFnIdBitCast: | 5185 | case BuiltinFnIdBitCast: |
| 4726 | { | 5186 | { |
| 4727 | AstNode *arg0_node = node->data.fn_call_expr.params.at(0); | 5187 | AstNode *dest_type_node = node->data.fn_call_expr.params.at(0); |
| 4728 | IrInstruction *arg0_value = ir_gen_node(irb, arg0_node, scope); | 5188 | IrInstruction *dest_type = ir_gen_node(irb, dest_type_node, scope); |
| 4729 | if (arg0_value == irb->codegen->invalid_instruction) | 5189 | if (dest_type == irb->codegen->invalid_instruction) |
| 4730 | return arg0_value; | 5190 | return dest_type; |
| | 5191 | |
| | 5192 | ResultLocBitCast *result_loc_bit_cast = allocate<ResultLocBitCast>(1); |
| | 5193 | result_loc_bit_cast->base.id = ResultLocIdBitCast; |
| | 5194 | result_loc_bit_cast->base.source_instruction = dest_type; |
| | 5195 | ir_ref_instruction(dest_type, irb->current_basic_block); |
| | 5196 | result_loc_bit_cast->parent = result_loc; |
| | 5197 | |
| | 5198 | ir_build_reset_result(irb, scope, node, &result_loc_bit_cast->base); |
| 4731 | | 5199 | |
| 4732 | AstNode *arg1_node = node->data.fn_call_expr.params.at(1); | 5200 | AstNode *arg1_node = node->data.fn_call_expr.params.at(1); |
| 4733 | IrInstruction *arg1_value = ir_gen_node(irb, arg1_node, scope); | 5201 | IrInstruction *arg1_value = ir_gen_node_extra(irb, arg1_node, scope, LValNone, |
| | 5202 | &result_loc_bit_cast->base); |
| 4734 | if (arg1_value == irb->codegen->invalid_instruction) | 5203 | if (arg1_value == irb->codegen->invalid_instruction) |
| 4735 | return arg1_value; | 5204 | return arg1_value; |
| 4736 | | 5205 | |
| 4737 | IrInstruction *bit_cast = ir_build_bit_cast(irb, scope, node, arg0_value, arg1_value); | 5206 | IrInstruction *bitcast = ir_build_bit_cast_src(irb, scope, arg1_node, arg1_value, result_loc_bit_cast); |
| 4738 | return ir_lval_wrap(irb, scope, bit_cast, lval); | 5207 | return ir_lval_wrap(irb, scope, bitcast, lval, result_loc); |
| 4739 | } | 5208 | } |
| 4740 | case BuiltinFnIdIntToPtr: | 5209 | case BuiltinFnIdIntToPtr: |
| 4741 | { | 5210 | { |
| ... | @@ -4750,7 +5219,7 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo | ... | @@ -4750,7 +5219,7 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo |
| 4750 | return arg1_value; | 5219 | return arg1_value; |
| 4751 | | 5220 | |
| 4752 | IrInstruction *int_to_ptr = ir_build_int_to_ptr(irb, scope, node, arg0_value, arg1_value); | 5221 | IrInstruction *int_to_ptr = ir_build_int_to_ptr(irb, scope, node, arg0_value, arg1_value); |
| 4753 | return ir_lval_wrap(irb, scope, int_to_ptr, lval); | 5222 | return ir_lval_wrap(irb, scope, int_to_ptr, lval, result_loc); |
| 4754 | } | 5223 | } |
| 4755 | case BuiltinFnIdPtrToInt: | 5224 | case BuiltinFnIdPtrToInt: |
| 4756 | { | 5225 | { |
| ... | @@ -4760,7 +5229,7 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo | ... | @@ -4760,7 +5229,7 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo |
| 4760 | return arg0_value; | 5229 | return arg0_value; |
| 4761 | | 5230 | |
| 4762 | IrInstruction *ptr_to_int = ir_build_ptr_to_int(irb, scope, node, arg0_value); | 5231 | IrInstruction *ptr_to_int = ir_build_ptr_to_int(irb, scope, node, arg0_value); |
| 4763 | return ir_lval_wrap(irb, scope, ptr_to_int, lval); | 5232 | return ir_lval_wrap(irb, scope, ptr_to_int, lval, result_loc); |
| 4764 | } | 5233 | } |
| 4765 | case BuiltinFnIdTagName: | 5234 | case BuiltinFnIdTagName: |
| 4766 | { | 5235 | { |
| ... | @@ -4771,7 +5240,7 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo | ... | @@ -4771,7 +5240,7 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo |
| 4771 | | 5240 | |
| 4772 | IrInstruction *actual_tag = ir_build_union_tag(irb, scope, node, arg0_value); | 5241 | IrInstruction *actual_tag = ir_build_union_tag(irb, scope, node, arg0_value); |
| 4773 | IrInstruction *tag_name = ir_build_tag_name(irb, scope, node, actual_tag); | 5242 | IrInstruction *tag_name = ir_build_tag_name(irb, scope, node, actual_tag); |
| 4774 | return ir_lval_wrap(irb, scope, tag_name, lval); | 5243 | return ir_lval_wrap(irb, scope, tag_name, lval, result_loc); |
| 4775 | } | 5244 | } |
| 4776 | case BuiltinFnIdTagType: | 5245 | case BuiltinFnIdTagType: |
| 4777 | { | 5246 | { |
| ... | @@ -4781,7 +5250,7 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo | ... | @@ -4781,7 +5250,7 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo |
| 4781 | return arg0_value; | 5250 | return arg0_value; |
| 4782 | | 5251 | |
| 4783 | IrInstruction *tag_type = ir_build_tag_type(irb, scope, node, arg0_value); | 5252 | IrInstruction *tag_type = ir_build_tag_type(irb, scope, node, arg0_value); |
| 4784 | return ir_lval_wrap(irb, scope, tag_type, lval); | 5253 | return ir_lval_wrap(irb, scope, tag_type, lval, result_loc); |
| 4785 | } | 5254 | } |
| 4786 | case BuiltinFnIdFieldParentPtr: | 5255 | case BuiltinFnIdFieldParentPtr: |
| 4787 | { | 5256 | { |
| ... | @@ -4801,7 +5270,7 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo | ... | @@ -4801,7 +5270,7 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo |
| 4801 | return arg2_value; | 5270 | return arg2_value; |
| 4802 | | 5271 | |
| 4803 | IrInstruction *field_parent_ptr = ir_build_field_parent_ptr(irb, scope, node, arg0_value, arg1_value, arg2_value, nullptr); | 5272 | IrInstruction *field_parent_ptr = ir_build_field_parent_ptr(irb, scope, node, arg0_value, arg1_value, arg2_value, nullptr); |
| 4804 | return ir_lval_wrap(irb, scope, field_parent_ptr, lval); | 5273 | return ir_lval_wrap(irb, scope, field_parent_ptr, lval, result_loc); |
| 4805 | } | 5274 | } |
| 4806 | case BuiltinFnIdByteOffsetOf: | 5275 | case BuiltinFnIdByteOffsetOf: |
| 4807 | { | 5276 | { |
| ... | @@ -4816,7 +5285,7 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo | ... | @@ -4816,7 +5285,7 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo |
| 4816 | return arg1_value; | 5285 | return arg1_value; |
| 4817 | | 5286 | |
| 4818 | IrInstruction *offset_of = ir_build_byte_offset_of(irb, scope, node, arg0_value, arg1_value); | 5287 | IrInstruction *offset_of = ir_build_byte_offset_of(irb, scope, node, arg0_value, arg1_value); |
| 4819 | return ir_lval_wrap(irb, scope, offset_of, lval); | 5288 | return ir_lval_wrap(irb, scope, offset_of, lval, result_loc); |
| 4820 | } | 5289 | } |
| 4821 | case BuiltinFnIdBitOffsetOf: | 5290 | case BuiltinFnIdBitOffsetOf: |
| 4822 | { | 5291 | { |
| ... | @@ -4831,7 +5300,7 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo | ... | @@ -4831,7 +5300,7 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo |
| 4831 | return arg1_value; | 5300 | return arg1_value; |
| 4832 | | 5301 | |
| 4833 | IrInstruction *offset_of = ir_build_bit_offset_of(irb, scope, node, arg0_value, arg1_value); | 5302 | IrInstruction *offset_of = ir_build_bit_offset_of(irb, scope, node, arg0_value, arg1_value); |
| 4834 | return ir_lval_wrap(irb, scope, offset_of, lval); | 5303 | return ir_lval_wrap(irb, scope, offset_of, lval, result_loc); |
| 4835 | } | 5304 | } |
| 4836 | case BuiltinFnIdInlineCall: | 5305 | case BuiltinFnIdInlineCall: |
| 4837 | case BuiltinFnIdNoInlineCall: | 5306 | case BuiltinFnIdNoInlineCall: |
| ... | @@ -4857,8 +5326,9 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo | ... | @@ -4857,8 +5326,9 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo |
| 4857 | } | 5326 | } |
| 4858 | FnInline fn_inline = (builtin_fn->id == BuiltinFnIdInlineCall) ? FnInlineAlways : FnInlineNever; | 5327 | FnInline fn_inline = (builtin_fn->id == BuiltinFnIdInlineCall) ? FnInlineAlways : FnInlineNever; |
| 4859 | | 5328 | |
| 4860 | IrInstruction *call = ir_build_call(irb, scope, node, nullptr, fn_ref, arg_count, args, false, fn_inline, false, nullptr, nullptr); | 5329 | IrInstruction *call = ir_build_call_src(irb, scope, node, nullptr, fn_ref, arg_count, args, false, |
| 4861 | return ir_lval_wrap(irb, scope, call, lval); | 5330 | fn_inline, false, nullptr, nullptr, result_loc); |
| | 5331 | return ir_lval_wrap(irb, scope, call, lval, result_loc); |
| 4862 | } | 5332 | } |
| 4863 | case BuiltinFnIdNewStackCall: | 5333 | case BuiltinFnIdNewStackCall: |
| 4864 | { | 5334 | { |
| ... | @@ -4887,8 +5357,9 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo | ... | @@ -4887,8 +5357,9 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo |
| 4887 | return args[i]; | 5357 | return args[i]; |
| 4888 | } | 5358 | } |
| 4889 | | 5359 | |
| 4890 | IrInstruction *call = ir_build_call(irb, scope, node, nullptr, fn_ref, arg_count, args, false, FnInlineAuto, false, nullptr, new_stack); | 5360 | IrInstruction *call = ir_build_call_src(irb, scope, node, nullptr, fn_ref, arg_count, args, false, |
| 4891 | return ir_lval_wrap(irb, scope, call, lval); | 5361 | FnInlineAuto, false, nullptr, new_stack, result_loc); |
| | 5362 | return ir_lval_wrap(irb, scope, call, lval, result_loc); |
| 4892 | } | 5363 | } |
| 4893 | case BuiltinFnIdTypeId: | 5364 | case BuiltinFnIdTypeId: |
| 4894 | { | 5365 | { |
| ... | @@ -4898,7 +5369,7 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo | ... | @@ -4898,7 +5369,7 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo |
| 4898 | return arg0_value; | 5369 | return arg0_value; |
| 4899 | | 5370 | |
| 4900 | IrInstruction *type_id = ir_build_type_id(irb, scope, node, arg0_value); | 5371 | IrInstruction *type_id = ir_build_type_id(irb, scope, node, arg0_value); |
| 4901 | return ir_lval_wrap(irb, scope, type_id, lval); | 5372 | return ir_lval_wrap(irb, scope, type_id, lval, result_loc); |
| 4902 | } | 5373 | } |
| 4903 | case BuiltinFnIdShlExact: | 5374 | case BuiltinFnIdShlExact: |
| 4904 | { | 5375 | { |
| ... | @@ -4913,7 +5384,7 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo | ... | @@ -4913,7 +5384,7 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo |
| 4913 | return arg1_value; | 5384 | return arg1_value; |
| 4914 | | 5385 | |
| 4915 | IrInstruction *bin_op = ir_build_bin_op(irb, scope, node, IrBinOpBitShiftLeftExact, arg0_value, arg1_value, true); | 5386 | IrInstruction *bin_op = ir_build_bin_op(irb, scope, node, IrBinOpBitShiftLeftExact, arg0_value, arg1_value, true); |
| 4916 | return ir_lval_wrap(irb, scope, bin_op, lval); | 5387 | return ir_lval_wrap(irb, scope, bin_op, lval, result_loc); |
| 4917 | } | 5388 | } |
| 4918 | case BuiltinFnIdShrExact: | 5389 | case BuiltinFnIdShrExact: |
| 4919 | { | 5390 | { |
| ... | @@ -4928,7 +5399,7 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo | ... | @@ -4928,7 +5399,7 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo |
| 4928 | return arg1_value; | 5399 | return arg1_value; |
| 4929 | | 5400 | |
| 4930 | IrInstruction *bin_op = ir_build_bin_op(irb, scope, node, IrBinOpBitShiftRightExact, arg0_value, arg1_value, true); | 5401 | IrInstruction *bin_op = ir_build_bin_op(irb, scope, node, IrBinOpBitShiftRightExact, arg0_value, arg1_value, true); |
| 4931 | return ir_lval_wrap(irb, scope, bin_op, lval); | 5402 | return ir_lval_wrap(irb, scope, bin_op, lval, result_loc); |
| 4932 | } | 5403 | } |
| 4933 | case BuiltinFnIdSetEvalBranchQuota: | 5404 | case BuiltinFnIdSetEvalBranchQuota: |
| 4934 | { | 5405 | { |
| ... | @@ -4938,7 +5409,7 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo | ... | @@ -4938,7 +5409,7 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo |
| 4938 | return arg0_value; | 5409 | return arg0_value; |
| 4939 | | 5410 | |
| 4940 | IrInstruction *set_eval_branch_quota = ir_build_set_eval_branch_quota(irb, scope, node, arg0_value); | 5411 | IrInstruction *set_eval_branch_quota = ir_build_set_eval_branch_quota(irb, scope, node, arg0_value); |
| 4941 | return ir_lval_wrap(irb, scope, set_eval_branch_quota, lval); | 5412 | return ir_lval_wrap(irb, scope, set_eval_branch_quota, lval, result_loc); |
| 4942 | } | 5413 | } |
| 4943 | case BuiltinFnIdAlignCast: | 5414 | case BuiltinFnIdAlignCast: |
| 4944 | { | 5415 | { |
| ... | @@ -4953,17 +5424,17 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo | ... | @@ -4953,17 +5424,17 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo |
| 4953 | return arg1_value; | 5424 | return arg1_value; |
| 4954 | | 5425 | |
| 4955 | IrInstruction *align_cast = ir_build_align_cast(irb, scope, node, arg0_value, arg1_value); | 5426 | IrInstruction *align_cast = ir_build_align_cast(irb, scope, node, arg0_value, arg1_value); |
| 4956 | return ir_lval_wrap(irb, scope, align_cast, lval); | 5427 | return ir_lval_wrap(irb, scope, align_cast, lval, result_loc); |
| 4957 | } | 5428 | } |
| 4958 | case BuiltinFnIdOpaqueType: | 5429 | case BuiltinFnIdOpaqueType: |
| 4959 | { | 5430 | { |
| 4960 | IrInstruction *opaque_type = ir_build_opaque_type(irb, scope, node); | 5431 | IrInstruction *opaque_type = ir_build_opaque_type(irb, scope, node); |
| 4961 | return ir_lval_wrap(irb, scope, opaque_type, lval); | 5432 | return ir_lval_wrap(irb, scope, opaque_type, lval, result_loc); |
| 4962 | } | 5433 | } |
| 4963 | case BuiltinFnIdThis: | 5434 | case BuiltinFnIdThis: |
| 4964 | { | 5435 | { |
| 4965 | IrInstruction *this_inst = ir_gen_this(irb, scope, node); | 5436 | IrInstruction *this_inst = ir_gen_this(irb, scope, node); |
| 4966 | return ir_lval_wrap(irb, scope, this_inst, lval); | 5437 | return ir_lval_wrap(irb, scope, this_inst, lval, result_loc); |
| 4967 | } | 5438 | } |
| 4968 | case BuiltinFnIdSetAlignStack: | 5439 | case BuiltinFnIdSetAlignStack: |
| 4969 | { | 5440 | { |
| ... | @@ -4973,7 +5444,7 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo | ... | @@ -4973,7 +5444,7 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo |
| 4973 | return arg0_value; | 5444 | return arg0_value; |
| 4974 | | 5445 | |
| 4975 | IrInstruction *set_align_stack = ir_build_set_align_stack(irb, scope, node, arg0_value); | 5446 | IrInstruction *set_align_stack = ir_build_set_align_stack(irb, scope, node, arg0_value); |
| 4976 | return ir_lval_wrap(irb, scope, set_align_stack, lval); | 5447 | return ir_lval_wrap(irb, scope, set_align_stack, lval, result_loc); |
| 4977 | } | 5448 | } |
| 4978 | case BuiltinFnIdArgType: | 5449 | case BuiltinFnIdArgType: |
| 4979 | { | 5450 | { |
| ... | @@ -4988,7 +5459,7 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo | ... | @@ -4988,7 +5459,7 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo |
| 4988 | return arg1_value; | 5459 | return arg1_value; |
| 4989 | | 5460 | |
| 4990 | IrInstruction *arg_type = ir_build_arg_type(irb, scope, node, arg0_value, arg1_value); | 5461 | IrInstruction *arg_type = ir_build_arg_type(irb, scope, node, arg0_value, arg1_value); |
| 4991 | return ir_lval_wrap(irb, scope, arg_type, lval); | 5462 | return ir_lval_wrap(irb, scope, arg_type, lval, result_loc); |
| 4992 | } | 5463 | } |
| 4993 | case BuiltinFnIdExport: | 5464 | case BuiltinFnIdExport: |
| 4994 | { | 5465 | { |
| ... | @@ -5008,12 +5479,12 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo | ... | @@ -5008,12 +5479,12 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo |
| 5008 | return arg2_value; | 5479 | return arg2_value; |
| 5009 | | 5480 | |
| 5010 | IrInstruction *ir_export = ir_build_export(irb, scope, node, arg0_value, arg1_value, arg2_value); | 5481 | IrInstruction *ir_export = ir_build_export(irb, scope, node, arg0_value, arg1_value, arg2_value); |
| 5011 | return ir_lval_wrap(irb, scope, ir_export, lval); | 5482 | return ir_lval_wrap(irb, scope, ir_export, lval, result_loc); |
| 5012 | } | 5483 | } |
| 5013 | case BuiltinFnIdErrorReturnTrace: | 5484 | case BuiltinFnIdErrorReturnTrace: |
| 5014 | { | 5485 | { |
| 5015 | IrInstruction *error_return_trace = ir_build_error_return_trace(irb, scope, node, IrInstructionErrorReturnTrace::Null); | 5486 | IrInstruction *error_return_trace = ir_build_error_return_trace(irb, scope, node, IrInstructionErrorReturnTrace::Null); |
| 5016 | return ir_lval_wrap(irb, scope, error_return_trace, lval); | 5487 | return ir_lval_wrap(irb, scope, error_return_trace, lval, result_loc); |
| 5017 | } | 5488 | } |
| 5018 | case BuiltinFnIdAtomicRmw: | 5489 | case BuiltinFnIdAtomicRmw: |
| 5019 | { | 5490 | { |
| ... | @@ -5042,10 +5513,11 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo | ... | @@ -5042,10 +5513,11 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo |
| 5042 | if (arg4_value == irb->codegen->invalid_instruction) | 5513 | if (arg4_value == irb->codegen->invalid_instruction) |
| 5043 | return arg4_value; | 5514 | return arg4_value; |
| 5044 | | 5515 | |
| 5045 | return ir_build_atomic_rmw(irb, scope, node, arg0_value, arg1_value, arg2_value, arg3_value, | 5516 | IrInstruction *inst = ir_build_atomic_rmw(irb, scope, node, arg0_value, arg1_value, arg2_value, arg3_value, |
| 5046 | arg4_value, | 5517 | arg4_value, |
| 5047 | // these 2 values don't mean anything since we passed non-null values for other args | 5518 | // these 2 values don't mean anything since we passed non-null values for other args |
| 5048 | AtomicRmwOp_xchg, AtomicOrderMonotonic); | 5519 | AtomicRmwOp_xchg, AtomicOrderMonotonic); |
| | 5520 | return ir_lval_wrap(irb, scope, inst, lval, result_loc); |
| 5049 | } | 5521 | } |
| 5050 | case BuiltinFnIdAtomicLoad: | 5522 | case BuiltinFnIdAtomicLoad: |
| 5051 | { | 5523 | { |
| ... | @@ -5064,9 +5536,10 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo | ... | @@ -5064,9 +5536,10 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo |
| 5064 | if (arg2_value == irb->codegen->invalid_instruction) | 5536 | if (arg2_value == irb->codegen->invalid_instruction) |
| 5065 | return arg2_value; | 5537 | return arg2_value; |
| 5066 | | 5538 | |
| 5067 | return ir_build_atomic_load(irb, scope, node, arg0_value, arg1_value, arg2_value, | 5539 | IrInstruction *inst = ir_build_atomic_load(irb, scope, node, arg0_value, arg1_value, arg2_value, |
| 5068 | // this value does not mean anything since we passed non-null values for other arg | 5540 | // this value does not mean anything since we passed non-null values for other arg |
| 5069 | AtomicOrderMonotonic); | 5541 | AtomicOrderMonotonic); |
| | 5542 | return ir_lval_wrap(irb, scope, inst, lval, result_loc); |
| 5070 | } | 5543 | } |
| 5071 | case BuiltinFnIdIntToEnum: | 5544 | case BuiltinFnIdIntToEnum: |
| 5072 | { | 5545 | { |
| ... | @@ -5081,7 +5554,7 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo | ... | @@ -5081,7 +5554,7 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo |
| 5081 | return arg1_value; | 5554 | return arg1_value; |
| 5082 | | 5555 | |
| 5083 | IrInstruction *result = ir_build_int_to_enum(irb, scope, node, arg0_value, arg1_value); | 5556 | IrInstruction *result = ir_build_int_to_enum(irb, scope, node, arg0_value, arg1_value); |
| 5084 | return ir_lval_wrap(irb, scope, result, lval); | 5557 | return ir_lval_wrap(irb, scope, result, lval, result_loc); |
| 5085 | } | 5558 | } |
| 5086 | case BuiltinFnIdEnumToInt: | 5559 | case BuiltinFnIdEnumToInt: |
| 5087 | { | 5560 | { |
| ... | @@ -5091,7 +5564,7 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo | ... | @@ -5091,7 +5564,7 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo |
| 5091 | return arg0_value; | 5564 | return arg0_value; |
| 5092 | | 5565 | |
| 5093 | IrInstruction *result = ir_build_enum_to_int(irb, scope, node, arg0_value); | 5566 | IrInstruction *result = ir_build_enum_to_int(irb, scope, node, arg0_value); |
| 5094 | return ir_lval_wrap(irb, scope, result, lval); | 5567 | return ir_lval_wrap(irb, scope, result, lval, result_loc); |
| 5095 | } | 5568 | } |
| 5096 | case BuiltinFnIdCtz: | 5569 | case BuiltinFnIdCtz: |
| 5097 | case BuiltinFnIdPopCount: | 5570 | case BuiltinFnIdPopCount: |
| ... | @@ -5129,7 +5602,7 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo | ... | @@ -5129,7 +5602,7 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo |
| 5129 | default: | 5602 | default: |
| 5130 | zig_unreachable(); | 5603 | zig_unreachable(); |
| 5131 | } | 5604 | } |
| 5132 | return ir_lval_wrap(irb, scope, result, lval); | 5605 | return ir_lval_wrap(irb, scope, result, lval, result_loc); |
| 5133 | } | 5606 | } |
| 5134 | case BuiltinFnIdHasDecl: | 5607 | case BuiltinFnIdHasDecl: |
| 5135 | { | 5608 | { |
| ... | @@ -5144,17 +5617,19 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo | ... | @@ -5144,17 +5617,19 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo |
| 5144 | return arg1_value; | 5617 | return arg1_value; |
| 5145 | | 5618 | |
| 5146 | IrInstruction *has_decl = ir_build_has_decl(irb, scope, node, arg0_value, arg1_value); | 5619 | IrInstruction *has_decl = ir_build_has_decl(irb, scope, node, arg0_value, arg1_value); |
| 5147 | return ir_lval_wrap(irb, scope, has_decl, lval); | 5620 | return ir_lval_wrap(irb, scope, has_decl, lval, result_loc); |
| 5148 | } | 5621 | } |
| 5149 | } | 5622 | } |
| 5150 | zig_unreachable(); | 5623 | zig_unreachable(); |
| 5151 | } | 5624 | } |
| 5152 | | 5625 | |
| 5153 | static IrInstruction *ir_gen_fn_call(IrBuilder *irb, Scope *scope, AstNode *node, LVal lval) { | 5626 | static IrInstruction *ir_gen_fn_call(IrBuilder *irb, Scope *scope, AstNode *node, LVal lval, |
| | 5627 | ResultLoc *result_loc) |
| | 5628 | { |
| 5154 | assert(node->type == NodeTypeFnCallExpr); | 5629 | assert(node->type == NodeTypeFnCallExpr); |
| 5155 | | 5630 | |
| 5156 | if (node->data.fn_call_expr.is_builtin) | 5631 | if (node->data.fn_call_expr.is_builtin) |
| 5157 | return ir_gen_builtin_fn_call(irb, scope, node, lval); | 5632 | return ir_gen_builtin_fn_call(irb, scope, node, lval, result_loc); |
| 5158 | | 5633 | |
| 5159 | AstNode *fn_ref_node = node->data.fn_call_expr.fn_ref_expr; | 5634 | AstNode *fn_ref_node = node->data.fn_call_expr.fn_ref_expr; |
| 5160 | IrInstruction *fn_ref = ir_gen_node(irb, fn_ref_node, scope); | 5635 | IrInstruction *fn_ref = ir_gen_node(irb, fn_ref_node, scope); |
| ... | @@ -5180,12 +5655,14 @@ static IrInstruction *ir_gen_fn_call(IrBuilder *irb, Scope *scope, AstNode *node | ... | @@ -5180,12 +5655,14 @@ static IrInstruction *ir_gen_fn_call(IrBuilder *irb, Scope *scope, AstNode *node |
| 5180 | } | 5655 | } |
| 5181 | } | 5656 | } |
| 5182 | | 5657 | |
| 5183 | IrInstruction *fn_call = ir_build_call(irb, scope, node, nullptr, fn_ref, arg_count, args, false, FnInlineAuto, | 5658 | IrInstruction *fn_call = ir_build_call_src(irb, scope, node, nullptr, fn_ref, arg_count, args, false, FnInlineAuto, |
| 5184 | is_async, async_allocator, nullptr); | 5659 | is_async, async_allocator, nullptr, result_loc); |
| 5185 | return ir_lval_wrap(irb, scope, fn_call, lval); | 5660 | return ir_lval_wrap(irb, scope, fn_call, lval, result_loc); |
| 5186 | } | 5661 | } |
| 5187 | | 5662 | |
| 5188 | static IrInstruction *ir_gen_if_bool_expr(IrBuilder *irb, Scope *scope, AstNode *node) { | 5663 | static IrInstruction *ir_gen_if_bool_expr(IrBuilder *irb, Scope *scope, AstNode *node, LVal lval, |
| | 5664 | ResultLoc *result_loc) |
| | 5665 | { |
| 5189 | assert(node->type == NodeTypeIfBoolExpr); | 5666 | assert(node->type == NodeTypeIfBoolExpr); |
| 5190 | | 5667 | |
| 5191 | IrInstruction *condition = ir_gen_node(irb, node->data.if_bool_expr.condition, scope); | 5668 | IrInstruction *condition = ir_gen_node(irb, node->data.if_bool_expr.condition, scope); |
| ... | @@ -5206,12 +5683,16 @@ static IrInstruction *ir_gen_if_bool_expr(IrBuilder *irb, Scope *scope, AstNode | ... | @@ -5206,12 +5683,16 @@ static IrInstruction *ir_gen_if_bool_expr(IrBuilder *irb, Scope *scope, AstNode |
| 5206 | IrBasicBlock *else_block = ir_create_basic_block(irb, scope, "Else"); | 5683 | IrBasicBlock *else_block = ir_create_basic_block(irb, scope, "Else"); |
| 5207 | IrBasicBlock *endif_block = ir_create_basic_block(irb, scope, "EndIf"); | 5684 | IrBasicBlock *endif_block = ir_create_basic_block(irb, scope, "EndIf"); |
| 5208 | | 5685 | |
| 5209 | ir_build_cond_br(irb, scope, condition->source_node, condition, then_block, else_block, is_comptime); | 5686 | IrInstruction *cond_br_inst = ir_build_cond_br(irb, scope, node, condition, |
| | 5687 | then_block, else_block, is_comptime); |
| | 5688 | ResultLocPeerParent *peer_parent = ir_build_binary_result_peers(irb, cond_br_inst, else_block, endif_block, |
| | 5689 | result_loc, is_comptime); |
| 5210 | | 5690 | |
| 5211 | ir_set_cursor_at_end_and_append_block(irb, then_block); | 5691 | ir_set_cursor_at_end_and_append_block(irb, then_block); |
| 5212 | | 5692 | |
| 5213 | Scope *subexpr_scope = create_runtime_scope(irb->codegen, node, scope, is_comptime); | 5693 | Scope *subexpr_scope = create_runtime_scope(irb->codegen, node, scope, is_comptime); |
| 5214 | IrInstruction *then_expr_result = ir_gen_node(irb, then_node, subexpr_scope); | 5694 | IrInstruction *then_expr_result = ir_gen_node_extra(irb, then_node, subexpr_scope, lval, |
| | 5695 | &peer_parent->peers.at(0)->base); |
| 5215 | if (then_expr_result == irb->codegen->invalid_instruction) | 5696 | if (then_expr_result == irb->codegen->invalid_instruction) |
| 5216 | return irb->codegen->invalid_instruction; | 5697 | return irb->codegen->invalid_instruction; |
| 5217 | IrBasicBlock *after_then_block = irb->current_basic_block; | 5698 | IrBasicBlock *after_then_block = irb->current_basic_block; |
| ... | @@ -5221,11 +5702,12 @@ static IrInstruction *ir_gen_if_bool_expr(IrBuilder *irb, Scope *scope, AstNode | ... | @@ -5221,11 +5702,12 @@ static IrInstruction *ir_gen_if_bool_expr(IrBuilder *irb, Scope *scope, AstNode |
| 5221 | ir_set_cursor_at_end_and_append_block(irb, else_block); | 5702 | ir_set_cursor_at_end_and_append_block(irb, else_block); |
| 5222 | IrInstruction *else_expr_result; | 5703 | IrInstruction *else_expr_result; |
| 5223 | if (else_node) { | 5704 | if (else_node) { |
| 5224 | else_expr_result = ir_gen_node(irb, else_node, subexpr_scope); | 5705 | else_expr_result = ir_gen_node_extra(irb, else_node, subexpr_scope, lval, &peer_parent->peers.at(1)->base); |
| 5225 | if (else_expr_result == irb->codegen->invalid_instruction) | 5706 | if (else_expr_result == irb->codegen->invalid_instruction) |
| 5226 | return irb->codegen->invalid_instruction; | 5707 | return irb->codegen->invalid_instruction; |
| 5227 | } else { | 5708 | } else { |
| 5228 | else_expr_result = ir_build_const_void(irb, scope, node); | 5709 | else_expr_result = ir_build_const_void(irb, scope, node); |
| | 5710 | ir_build_end_expr(irb, scope, node, else_expr_result, &peer_parent->peers.at(1)->base); |
| 5229 | } | 5711 | } |
| 5230 | IrBasicBlock *after_else_block = irb->current_basic_block; | 5712 | IrBasicBlock *after_else_block = irb->current_basic_block; |
| 5231 | if (!instr_is_unreachable(else_expr_result)) | 5713 | if (!instr_is_unreachable(else_expr_result)) |
| ... | @@ -5239,14 +5721,15 @@ static IrInstruction *ir_gen_if_bool_expr(IrBuilder *irb, Scope *scope, AstNode | ... | @@ -5239,14 +5721,15 @@ static IrInstruction *ir_gen_if_bool_expr(IrBuilder *irb, Scope *scope, AstNode |
| 5239 | incoming_blocks[0] = after_then_block; | 5721 | incoming_blocks[0] = after_then_block; |
| 5240 | incoming_blocks[1] = after_else_block; | 5722 | incoming_blocks[1] = after_else_block; |
| 5241 | | 5723 | |
| 5242 | return ir_build_phi(irb, scope, node, 2, incoming_blocks, incoming_values); | 5724 | IrInstruction *phi = ir_build_phi(irb, scope, node, 2, incoming_blocks, incoming_values, peer_parent); |
| | 5725 | return ir_expr_wrap(irb, scope, phi, result_loc); |
| 5243 | } | 5726 | } |
| 5244 | | 5727 | |
| 5245 | static IrInstruction *ir_gen_prefix_op_id_lval(IrBuilder *irb, Scope *scope, AstNode *node, IrUnOp op_id, LVal lval) { | 5728 | static IrInstruction *ir_gen_prefix_op_id_lval(IrBuilder *irb, Scope *scope, AstNode *node, IrUnOp op_id, LVal lval) { |
| 5246 | assert(node->type == NodeTypePrefixOpExpr); | 5729 | assert(node->type == NodeTypePrefixOpExpr); |
| 5247 | AstNode *expr_node = node->data.prefix_op_expr.primary_expr; | 5730 | AstNode *expr_node = node->data.prefix_op_expr.primary_expr; |
| 5248 | | 5731 | |
| 5249 | IrInstruction *value = ir_gen_node_extra(irb, expr_node, scope, lval); | 5732 | IrInstruction *value = ir_gen_node_extra(irb, expr_node, scope, lval, nullptr); |
| 5250 | if (value == irb->codegen->invalid_instruction) | 5733 | if (value == irb->codegen->invalid_instruction) |
| 5251 | return value; | 5734 | return value; |
| 5252 | | 5735 | |
| ... | @@ -5257,15 +5740,34 @@ static IrInstruction *ir_gen_prefix_op_id(IrBuilder *irb, Scope *scope, AstNode | ... | @@ -5257,15 +5740,34 @@ static IrInstruction *ir_gen_prefix_op_id(IrBuilder *irb, Scope *scope, AstNode |
| 5257 | return ir_gen_prefix_op_id_lval(irb, scope, node, op_id, LValNone); | 5740 | return ir_gen_prefix_op_id_lval(irb, scope, node, op_id, LValNone); |
| 5258 | } | 5741 | } |
| 5259 | | 5742 | |
| 5260 | static IrInstruction *ir_lval_wrap(IrBuilder *irb, Scope *scope, IrInstruction *value, LVal lval) { | 5743 | static IrInstruction *ir_expr_wrap(IrBuilder *irb, Scope *scope, IrInstruction *inst, ResultLoc *result_loc) { |
| 5261 | if (lval != LValPtr) | 5744 | ir_build_end_expr(irb, scope, inst->source_node, inst, result_loc); |
| | 5745 | return inst; |
| | 5746 | } |
| | 5747 | |
| | 5748 | static IrInstruction *ir_lval_wrap(IrBuilder *irb, Scope *scope, IrInstruction *value, LVal lval, |
| | 5749 | ResultLoc *result_loc) |
| | 5750 | { |
| | 5751 | // This logic must be kept in sync with |
| | 5752 | // [STMT_EXPR_TEST_THING] <--- (search this token) |
| | 5753 | if (value == irb->codegen->invalid_instruction || |
| | 5754 | instr_is_unreachable(value) || |
| | 5755 | value->source_node->type == NodeTypeDefer || |
| | 5756 | value->id == IrInstructionIdDeclVarSrc) |
| | 5757 | { |
| 5262 | return value; | 5758 | return value; |
| 5263 | if (value == irb->codegen->invalid_instruction) | 5759 | } |
| | 5760 | |
| | 5761 | if (lval == LValPtr) { |
| | 5762 | // We needed a pointer to a value, but we got a value. So we create |
| | 5763 | // an instruction which just makes a pointer of it. |
| | 5764 | return ir_build_ref(irb, scope, value->source_node, value, false, false); |
| | 5765 | } else if (result_loc != nullptr) { |
| | 5766 | return ir_expr_wrap(irb, scope, value, result_loc); |
| | 5767 | } else { |
| 5264 | return value; | 5768 | return value; |
| | 5769 | } |
| 5265 | | 5770 | |
| 5266 | // We needed a pointer to a value, but we got a value. So we create | | |
| 5267 | // an instruction which just makes a const pointer of it. | | |
| 5268 | return ir_build_ref(irb, scope, value->source_node, value, false, false); | | |
| 5269 | } | 5771 | } |
| 5270 | | 5772 | |
| 5271 | static PtrLen star_token_to_ptr_len(TokenId token_id) { | 5773 | static PtrLen star_token_to_ptr_len(TokenId token_id) { |
| ... | @@ -5338,21 +5840,22 @@ static IrInstruction *ir_gen_pointer_type(IrBuilder *irb, Scope *scope, AstNode | ... | @@ -5338,21 +5840,22 @@ static IrInstruction *ir_gen_pointer_type(IrBuilder *irb, Scope *scope, AstNode |
| 5338 | ptr_len, align_value, bit_offset_start, host_int_bytes, is_allow_zero); | 5840 | ptr_len, align_value, bit_offset_start, host_int_bytes, is_allow_zero); |
| 5339 | } | 5841 | } |
| 5340 | | 5842 | |
| 5341 | static IrInstruction *ir_gen_catch_unreachable(IrBuilder *irb, Scope *scope, AstNode *source_node, AstNode *expr_node, | 5843 | static IrInstruction *ir_gen_catch_unreachable(IrBuilder *irb, Scope *scope, AstNode *source_node, |
| 5342 | LVal lval) | 5844 | AstNode *expr_node, LVal lval, ResultLoc *result_loc) |
| 5343 | { | 5845 | { |
| 5344 | IrInstruction *err_union_ptr = ir_gen_node_extra(irb, expr_node, scope, LValPtr); | 5846 | IrInstruction *err_union_ptr = ir_gen_node_extra(irb, expr_node, scope, LValPtr, nullptr); |
| 5345 | if (err_union_ptr == irb->codegen->invalid_instruction) | 5847 | if (err_union_ptr == irb->codegen->invalid_instruction) |
| 5346 | return irb->codegen->invalid_instruction; | 5848 | return irb->codegen->invalid_instruction; |
| 5347 | | 5849 | |
| 5348 | IrInstruction *payload_ptr = ir_build_unwrap_err_payload(irb, scope, source_node, err_union_ptr, true); | 5850 | IrInstruction *payload_ptr = ir_build_unwrap_err_payload(irb, scope, source_node, err_union_ptr, true, false); |
| 5349 | if (payload_ptr == irb->codegen->invalid_instruction) | 5851 | if (payload_ptr == irb->codegen->invalid_instruction) |
| 5350 | return irb->codegen->invalid_instruction; | 5852 | return irb->codegen->invalid_instruction; |
| 5351 | | 5853 | |
| 5352 | if (lval == LValPtr) | 5854 | if (lval == LValPtr) |
| 5353 | return payload_ptr; | 5855 | return payload_ptr; |
| 5354 | | 5856 | |
| 5355 | return ir_build_load_ptr(irb, scope, source_node, payload_ptr); | 5857 | IrInstruction *load_ptr = ir_build_load_ptr(irb, scope, source_node, payload_ptr); |
| | 5858 | return ir_expr_wrap(irb, scope, load_ptr, result_loc); |
| 5356 | } | 5859 | } |
| 5357 | | 5860 | |
| 5358 | static IrInstruction *ir_gen_bool_not(IrBuilder *irb, Scope *scope, AstNode *node) { | 5861 | static IrInstruction *ir_gen_bool_not(IrBuilder *irb, Scope *scope, AstNode *node) { |
| ... | @@ -5366,7 +5869,9 @@ static IrInstruction *ir_gen_bool_not(IrBuilder *irb, Scope *scope, AstNode *nod | ... | @@ -5366,7 +5869,9 @@ static IrInstruction *ir_gen_bool_not(IrBuilder *irb, Scope *scope, AstNode *nod |
| 5366 | return ir_build_bool_not(irb, scope, node, value); | 5869 | return ir_build_bool_not(irb, scope, node, value); |
| 5367 | } | 5870 | } |
| 5368 | | 5871 | |
| 5369 | static IrInstruction *ir_gen_prefix_op_expr(IrBuilder *irb, Scope *scope, AstNode *node, LVal lval) { | 5872 | static IrInstruction *ir_gen_prefix_op_expr(IrBuilder *irb, Scope *scope, AstNode *node, LVal lval, |
| | 5873 | ResultLoc *result_loc) |
| | 5874 | { |
| 5370 | assert(node->type == NodeTypePrefixOpExpr); | 5875 | assert(node->type == NodeTypePrefixOpExpr); |
| 5371 | | 5876 | |
| 5372 | PrefixOp prefix_op = node->data.prefix_op_expr.prefix_op; | 5877 | PrefixOp prefix_op = node->data.prefix_op_expr.prefix_op; |
| ... | @@ -5375,24 +5880,26 @@ static IrInstruction *ir_gen_prefix_op_expr(IrBuilder *irb, Scope *scope, AstNod | ... | @@ -5375,24 +5880,26 @@ static IrInstruction *ir_gen_prefix_op_expr(IrBuilder *irb, Scope *scope, AstNod |
| 5375 | case PrefixOpInvalid: | 5880 | case PrefixOpInvalid: |
| 5376 | zig_unreachable(); | 5881 | zig_unreachable(); |
| 5377 | case PrefixOpBoolNot: | 5882 | case PrefixOpBoolNot: |
| 5378 | return ir_lval_wrap(irb, scope, ir_gen_bool_not(irb, scope, node), lval); | 5883 | return ir_lval_wrap(irb, scope, ir_gen_bool_not(irb, scope, node), lval, result_loc); |
| 5379 | case PrefixOpBinNot: | 5884 | case PrefixOpBinNot: |
| 5380 | return ir_lval_wrap(irb, scope, ir_gen_prefix_op_id(irb, scope, node, IrUnOpBinNot), lval); | 5885 | return ir_lval_wrap(irb, scope, ir_gen_prefix_op_id(irb, scope, node, IrUnOpBinNot), lval, result_loc); |
| 5381 | case PrefixOpNegation: | 5886 | case PrefixOpNegation: |
| 5382 | return ir_lval_wrap(irb, scope, ir_gen_prefix_op_id(irb, scope, node, IrUnOpNegation), lval); | 5887 | return ir_lval_wrap(irb, scope, ir_gen_prefix_op_id(irb, scope, node, IrUnOpNegation), lval, result_loc); |
| 5383 | case PrefixOpNegationWrap: | 5888 | case PrefixOpNegationWrap: |
| 5384 | return ir_lval_wrap(irb, scope, ir_gen_prefix_op_id(irb, scope, node, IrUnOpNegationWrap), lval); | 5889 | return ir_lval_wrap(irb, scope, ir_gen_prefix_op_id(irb, scope, node, IrUnOpNegationWrap), lval, result_loc); |
| 5385 | case PrefixOpOptional: | 5890 | case PrefixOpOptional: |
| 5386 | return ir_lval_wrap(irb, scope, ir_gen_prefix_op_id(irb, scope, node, IrUnOpOptional), lval); | 5891 | return ir_lval_wrap(irb, scope, ir_gen_prefix_op_id(irb, scope, node, IrUnOpOptional), lval, result_loc); |
| 5387 | case PrefixOpAddrOf: { | 5892 | case PrefixOpAddrOf: { |
| 5388 | AstNode *expr_node = node->data.prefix_op_expr.primary_expr; | 5893 | AstNode *expr_node = node->data.prefix_op_expr.primary_expr; |
| 5389 | return ir_lval_wrap(irb, scope, ir_gen_node_extra(irb, expr_node, scope, LValPtr), lval); | 5894 | return ir_lval_wrap(irb, scope, ir_gen_node_extra(irb, expr_node, scope, LValPtr, nullptr), lval, result_loc); |
| 5390 | } | 5895 | } |
| 5391 | } | 5896 | } |
| 5392 | zig_unreachable(); | 5897 | zig_unreachable(); |
| 5393 | } | 5898 | } |
| 5394 | | 5899 | |
| 5395 | static IrInstruction *ir_gen_container_init_expr(IrBuilder *irb, Scope *scope, AstNode *node) { | 5900 | static IrInstruction *ir_gen_container_init_expr(IrBuilder *irb, Scope *scope, AstNode *node, LVal lval, |
| | 5901 | ResultLoc *parent_result_loc) |
| | 5902 | { |
| 5396 | assert(node->type == NodeTypeContainerInitExpr); | 5903 | assert(node->type == NodeTypeContainerInitExpr); |
| 5397 | | 5904 | |
| 5398 | AstNodeContainerInitExpr *container_init_expr = &node->data.container_init_expr; | 5905 | AstNodeContainerInitExpr *container_init_expr = &node->data.container_init_expr; |
| ... | @@ -5410,45 +5917,104 @@ static IrInstruction *ir_gen_container_init_expr(IrBuilder *irb, Scope *scope, A | ... | @@ -5410,45 +5917,104 @@ static IrInstruction *ir_gen_container_init_expr(IrBuilder *irb, Scope *scope, A |
| 5410 | return container_type; | 5917 | return container_type; |
| 5411 | } | 5918 | } |
| 5412 | | 5919 | |
| 5413 | if (kind == ContainerInitKindStruct) { | 5920 | switch (kind) { |
| 5414 | if (elem_type != nullptr) { | 5921 | case ContainerInitKindStruct: { |
| 5415 | add_node_error(irb->codegen, container_init_expr->type, | 5922 | if (elem_type != nullptr) { |
| 5416 | buf_sprintf("initializing array with struct syntax")); | 5923 | add_node_error(irb->codegen, container_init_expr->type, |
| 5417 | return irb->codegen->invalid_instruction; | 5924 | buf_sprintf("initializing array with struct syntax")); |
| 5418 | } | 5925 | return irb->codegen->invalid_instruction; |
| | 5926 | } |
| | 5927 | |
| | 5928 | IrInstruction *container_ptr = ir_build_resolve_result(irb, scope, node, parent_result_loc, |
| | 5929 | container_type); |
| | 5930 | |
| | 5931 | size_t field_count = container_init_expr->entries.length; |
| | 5932 | IrInstructionContainerInitFieldsField *fields = allocate<IrInstructionContainerInitFieldsField>(field_count); |
| | 5933 | for (size_t i = 0; i < field_count; i += 1) { |
| | 5934 | AstNode *entry_node = container_init_expr->entries.at(i); |
| | 5935 | assert(entry_node->type == NodeTypeStructValueField); |
| 5419 | | 5936 | |
| 5420 | size_t field_count = container_init_expr->entries.length; | 5937 | Buf *name = entry_node->data.struct_val_field.name; |
| 5421 | IrInstructionContainerInitFieldsField *fields = allocate<IrInstructionContainerInitFieldsField>(field_count); | 5938 | AstNode *expr_node = entry_node->data.struct_val_field.expr; |
| 5422 | for (size_t i = 0; i < field_count; i += 1) { | | |
| 5423 | AstNode *entry_node = container_init_expr->entries.at(i); | | |
| 5424 | assert(entry_node->type == NodeTypeStructValueField); | | |
| 5425 | | 5939 | |
| 5426 | Buf *name = entry_node->data.struct_val_field.name; | 5940 | IrInstruction *field_ptr = ir_build_field_ptr(irb, scope, entry_node, container_ptr, name, true); |
| 5427 | AstNode *expr_node = entry_node->data.struct_val_field.expr; | 5941 | ResultLocInstruction *result_loc_inst = allocate<ResultLocInstruction>(1); |
| 5428 | IrInstruction *expr_value = ir_gen_node(irb, expr_node, scope); | 5942 | result_loc_inst->base.id = ResultLocIdInstruction; |
| 5429 | if (expr_value == irb->codegen->invalid_instruction) | 5943 | result_loc_inst->base.source_instruction = field_ptr; |
| 5430 | return expr_value; | 5944 | ir_ref_instruction(field_ptr, irb->current_basic_block); |
| | 5945 | ir_build_reset_result(irb, scope, expr_node, &result_loc_inst->base); |
| 5431 | | 5946 | |
| 5432 | fields[i].name = name; | 5947 | IrInstruction *expr_value = ir_gen_node_extra(irb, expr_node, scope, LValNone, |
| 5433 | fields[i].value = expr_value; | 5948 | &result_loc_inst->base); |
| 5434 | fields[i].source_node = entry_node; | 5949 | if (expr_value == irb->codegen->invalid_instruction) |
| | 5950 | return expr_value; |
| | 5951 | |
| | 5952 | fields[i].name = name; |
| | 5953 | fields[i].source_node = entry_node; |
| | 5954 | fields[i].result_loc = field_ptr; |
| | 5955 | } |
| | 5956 | IrInstruction *init_fields = ir_build_container_init_fields(irb, scope, node, container_type, |
| | 5957 | field_count, fields, container_ptr); |
| | 5958 | |
| | 5959 | return ir_lval_wrap(irb, scope, init_fields, lval, parent_result_loc); |
| 5435 | } | 5960 | } |
| 5436 | return ir_build_container_init_fields(irb, scope, node, container_type, field_count, fields); | 5961 | case ContainerInitKindArray: { |
| 5437 | } else if (kind == ContainerInitKindArray) { | 5962 | size_t item_count = container_init_expr->entries.length; |
| 5438 | size_t item_count = container_init_expr->entries.length; | 5963 | |
| 5439 | IrInstruction **values = allocate<IrInstruction *>(item_count); | 5964 | if (container_type == nullptr) { |
| 5440 | for (size_t i = 0; i < item_count; i += 1) { | 5965 | IrInstruction *item_count_inst = ir_build_const_usize(irb, scope, node, item_count); |
| 5441 | AstNode *expr_node = container_init_expr->entries.at(i); | 5966 | container_type = ir_build_array_type(irb, scope, node, item_count_inst, elem_type); |
| 5442 | IrInstruction *expr_value = ir_gen_node(irb, expr_node, scope); | 5967 | } |
| 5443 | if (expr_value == irb->codegen->invalid_instruction) | 5968 | |
| 5444 | return expr_value; | 5969 | IrInstruction *container_ptr = ir_build_resolve_result(irb, scope, node, parent_result_loc, |
| | 5970 | container_type); |
| | 5971 | |
| | 5972 | IrInstruction **result_locs = allocate<IrInstruction *>(item_count); |
| | 5973 | for (size_t i = 0; i < item_count; i += 1) { |
| | 5974 | AstNode *expr_node = container_init_expr->entries.at(i); |
| | 5975 | |
| | 5976 | IrInstruction *elem_index = ir_build_const_usize(irb, scope, expr_node, i); |
| | 5977 | IrInstruction *elem_ptr = ir_build_elem_ptr(irb, scope, expr_node, container_ptr, elem_index, |
| | 5978 | false, PtrLenSingle, container_type); |
| | 5979 | ResultLocInstruction *result_loc_inst = allocate<ResultLocInstruction>(1); |
| | 5980 | result_loc_inst->base.id = ResultLocIdInstruction; |
| | 5981 | result_loc_inst->base.source_instruction = elem_ptr; |
| | 5982 | ir_ref_instruction(elem_ptr, irb->current_basic_block); |
| | 5983 | ir_build_reset_result(irb, scope, expr_node, &result_loc_inst->base); |
| 5445 | | 5984 | |
| 5446 | values[i] = expr_value; | 5985 | IrInstruction *expr_value = ir_gen_node_extra(irb, expr_node, scope, LValNone, |
| | 5986 | &result_loc_inst->base); |
| | 5987 | if (expr_value == irb->codegen->invalid_instruction) |
| | 5988 | return expr_value; |
| | 5989 | |
| | 5990 | result_locs[i] = elem_ptr; |
| | 5991 | } |
| | 5992 | IrInstruction *init_list = ir_build_container_init_list(irb, scope, node, container_type, |
| | 5993 | item_count, result_locs, container_ptr); |
| | 5994 | return ir_lval_wrap(irb, scope, init_list, lval, parent_result_loc); |
| 5447 | } | 5995 | } |
| 5448 | return ir_build_container_init_list(irb, scope, node, container_type, elem_type, item_count, values); | | |
| 5449 | } else { | | |
| 5450 | zig_unreachable(); | | |
| 5451 | } | 5996 | } |
| | 5997 | zig_unreachable(); |
| | 5998 | } |
| | 5999 | |
| | 6000 | static ResultLocVar *ir_build_var_result_loc(IrBuilder *irb, IrInstruction *alloca, ZigVar *var) { |
| | 6001 | ResultLocVar *result_loc_var = allocate<ResultLocVar>(1); |
| | 6002 | result_loc_var->base.id = ResultLocIdVar; |
| | 6003 | result_loc_var->base.source_instruction = alloca; |
| | 6004 | result_loc_var->var = var; |
| | 6005 | |
| | 6006 | ir_build_reset_result(irb, alloca->scope, alloca->source_node, &result_loc_var->base); |
| | 6007 | |
| | 6008 | return result_loc_var; |
| | 6009 | } |
| | 6010 | |
| | 6011 | static void build_decl_var_and_init(IrBuilder *irb, Scope *scope, AstNode *source_node, ZigVar *var, |
| | 6012 | IrInstruction *init, const char *name_hint, IrInstruction *is_comptime) |
| | 6013 | { |
| | 6014 | IrInstruction *alloca = ir_build_alloca_src(irb, scope, source_node, nullptr, name_hint, is_comptime); |
| | 6015 | ResultLocVar *var_result_loc = ir_build_var_result_loc(irb, alloca, var); |
| | 6016 | ir_build_end_expr(irb, scope, source_node, init, &var_result_loc->base); |
| | 6017 | ir_build_var_decl_src(irb, scope, source_node, var, nullptr, alloca); |
| 5452 | } | 6018 | } |
| 5453 | | 6019 | |
| 5454 | static IrInstruction *ir_gen_var_decl(IrBuilder *irb, Scope *scope, AstNode *node) { | 6020 | static IrInstruction *ir_gen_var_decl(IrBuilder *irb, Scope *scope, AstNode *node) { |
| ... | @@ -5461,9 +6027,12 @@ static IrInstruction *ir_gen_var_decl(IrBuilder *irb, Scope *scope, AstNode *nod | ... | @@ -5461,9 +6027,12 @@ static IrInstruction *ir_gen_var_decl(IrBuilder *irb, Scope *scope, AstNode *nod |
| 5461 | return irb->codegen->invalid_instruction; | 6027 | return irb->codegen->invalid_instruction; |
| 5462 | } | 6028 | } |
| 5463 | | 6029 | |
| | 6030 | // Used for the type expr and the align expr |
| | 6031 | Scope *comptime_scope = create_comptime_scope(irb->codegen, node, scope); |
| | 6032 | |
| 5464 | IrInstruction *type_instruction; | 6033 | IrInstruction *type_instruction; |
| 5465 | if (variable_declaration->type != nullptr) { | 6034 | if (variable_declaration->type != nullptr) { |
| 5466 | type_instruction = ir_gen_node(irb, variable_declaration->type, scope); | 6035 | type_instruction = ir_gen_node(irb, variable_declaration->type, comptime_scope); |
| 5467 | if (type_instruction == irb->codegen->invalid_instruction) | 6036 | if (type_instruction == irb->codegen->invalid_instruction) |
| 5468 | return type_instruction; | 6037 | return type_instruction; |
| 5469 | } else { | 6038 | } else { |
| ... | @@ -5474,8 +6043,8 @@ static IrInstruction *ir_gen_var_decl(IrBuilder *irb, Scope *scope, AstNode *nod | ... | @@ -5474,8 +6043,8 @@ static IrInstruction *ir_gen_var_decl(IrBuilder *irb, Scope *scope, AstNode *nod |
| 5474 | bool is_const = variable_declaration->is_const; | 6043 | bool is_const = variable_declaration->is_const; |
| 5475 | bool is_extern = variable_declaration->is_extern; | 6044 | bool is_extern = variable_declaration->is_extern; |
| 5476 | | 6045 | |
| 5477 | IrInstruction *is_comptime = ir_build_const_bool(irb, scope, node, | 6046 | bool is_comptime_scalar = ir_should_inline(irb->exec, scope) || variable_declaration->is_comptime; |
| 5478 | ir_should_inline(irb->exec, scope) || variable_declaration->is_comptime); | 6047 | IrInstruction *is_comptime = ir_build_const_bool(irb, scope, node, is_comptime_scalar); |
| 5479 | ZigVar *var = ir_create_var(irb, node, scope, variable_declaration->symbol, | 6048 | ZigVar *var = ir_create_var(irb, node, scope, variable_declaration->symbol, |
| 5480 | is_const, is_const, is_shadowable, is_comptime); | 6049 | is_const, is_const, is_shadowable, is_comptime); |
| 5481 | // we detect IrInstructionIdDeclVarSrc in gen_block to make sure the next node | 6050 | // we detect IrInstructionIdDeclVarSrc in gen_block to make sure the next node |
| ... | @@ -5489,7 +6058,7 @@ static IrInstruction *ir_gen_var_decl(IrBuilder *irb, Scope *scope, AstNode *nod | ... | @@ -5489,7 +6058,7 @@ static IrInstruction *ir_gen_var_decl(IrBuilder *irb, Scope *scope, AstNode *nod |
| 5489 | | 6058 | |
| 5490 | IrInstruction *align_value = nullptr; | 6059 | IrInstruction *align_value = nullptr; |
| 5491 | if (variable_declaration->align_expr != nullptr) { | 6060 | if (variable_declaration->align_expr != nullptr) { |
| 5492 | align_value = ir_gen_node(irb, variable_declaration->align_expr, scope); | 6061 | align_value = ir_gen_node(irb, variable_declaration->align_expr, comptime_scope); |
| 5493 | if (align_value == irb->codegen->invalid_instruction) | 6062 | if (align_value == irb->codegen->invalid_instruction) |
| 5494 | return align_value; | 6063 | return align_value; |
| 5495 | } | 6064 | } |
| ... | @@ -5502,20 +6071,39 @@ static IrInstruction *ir_gen_var_decl(IrBuilder *irb, Scope *scope, AstNode *nod | ... | @@ -5502,20 +6071,39 @@ static IrInstruction *ir_gen_var_decl(IrBuilder *irb, Scope *scope, AstNode *nod |
| 5502 | // Parser should ensure that this never happens | 6071 | // Parser should ensure that this never happens |
| 5503 | assert(variable_declaration->threadlocal_tok == nullptr); | 6072 | assert(variable_declaration->threadlocal_tok == nullptr); |
| 5504 | | 6073 | |
| | 6074 | IrInstruction *alloca = ir_build_alloca_src(irb, scope, node, align_value, |
| | 6075 | buf_ptr(variable_declaration->symbol), is_comptime); |
| | 6076 | |
| | 6077 | // Create a result location for the initialization expression. |
| | 6078 | ResultLocVar *result_loc_var = ir_build_var_result_loc(irb, alloca, var); |
| | 6079 | ResultLoc *init_result_loc = (type_instruction == nullptr) ? &result_loc_var->base : nullptr; |
| | 6080 | |
| | 6081 | Scope *init_scope = is_comptime_scalar ? |
| | 6082 | create_comptime_scope(irb->codegen, variable_declaration->expr, scope) : scope; |
| | 6083 | |
| 5505 | // Temporarily set the name of the IrExecutable to the VariableDeclaration | 6084 | // Temporarily set the name of the IrExecutable to the VariableDeclaration |
| 5506 | // so that the struct or enum from the init expression inherits the name. | 6085 | // so that the struct or enum from the init expression inherits the name. |
| 5507 | Buf *old_exec_name = irb->exec->name; | 6086 | Buf *old_exec_name = irb->exec->name; |
| 5508 | irb->exec->name = variable_declaration->symbol; | 6087 | irb->exec->name = variable_declaration->symbol; |
| 5509 | IrInstruction *init_value = ir_gen_node(irb, variable_declaration->expr, scope); | 6088 | IrInstruction *init_value = ir_gen_node_extra(irb, variable_declaration->expr, init_scope, |
| | 6089 | LValNone, init_result_loc); |
| 5510 | irb->exec->name = old_exec_name; | 6090 | irb->exec->name = old_exec_name; |
| 5511 | | 6091 | |
| 5512 | if (init_value == irb->codegen->invalid_instruction) | 6092 | if (init_value == irb->codegen->invalid_instruction) |
| 5513 | return init_value; | 6093 | return irb->codegen->invalid_instruction; |
| | 6094 | |
| | 6095 | if (type_instruction != nullptr) { |
| | 6096 | IrInstruction *implicit_cast = ir_build_implicit_cast(irb, scope, node, type_instruction, init_value, |
| | 6097 | &result_loc_var->base); |
| | 6098 | ir_build_end_expr(irb, scope, node, implicit_cast, &result_loc_var->base); |
| | 6099 | } |
| 5514 | | 6100 | |
| 5515 | return ir_build_var_decl_src(irb, scope, node, var, type_instruction, align_value, init_value); | 6101 | return ir_build_var_decl_src(irb, scope, node, var, align_value, alloca); |
| 5516 | } | 6102 | } |
| 5517 | | 6103 | |
| 5518 | static IrInstruction *ir_gen_while_expr(IrBuilder *irb, Scope *scope, AstNode *node) { | 6104 | static IrInstruction *ir_gen_while_expr(IrBuilder *irb, Scope *scope, AstNode *node, LVal lval, |
| | 6105 | ResultLoc *result_loc) |
| | 6106 | { |
| 5519 | assert(node->type == NodeTypeWhileExpr); | 6107 | assert(node->type == NodeTypeWhileExpr); |
| 5520 | | 6108 | |
| 5521 | AstNode *continue_expr_node = node->data.while_expr.continue_expr; | 6109 | AstNode *continue_expr_node = node->data.while_expr.continue_expr; |
| ... | @@ -5550,25 +6138,33 @@ static IrInstruction *ir_gen_while_expr(IrBuilder *irb, Scope *scope, AstNode *n | ... | @@ -5550,25 +6138,33 @@ static IrInstruction *ir_gen_while_expr(IrBuilder *irb, Scope *scope, AstNode *n |
| 5550 | } else { | 6138 | } else { |
| 5551 | payload_scope = subexpr_scope; | 6139 | payload_scope = subexpr_scope; |
| 5552 | } | 6140 | } |
| 5553 | IrInstruction *err_val_ptr = ir_gen_node_extra(irb, node->data.while_expr.condition, subexpr_scope, LValPtr); | 6141 | IrInstruction *err_val_ptr = ir_gen_node_extra(irb, node->data.while_expr.condition, subexpr_scope, |
| | 6142 | LValPtr, nullptr); |
| 5554 | if (err_val_ptr == irb->codegen->invalid_instruction) | 6143 | if (err_val_ptr == irb->codegen->invalid_instruction) |
| 5555 | return err_val_ptr; | 6144 | return err_val_ptr; |
| 5556 | IrInstruction *err_val = ir_build_load_ptr(irb, scope, node->data.while_expr.condition, err_val_ptr); | 6145 | IrInstruction *is_err = ir_build_test_err_src(irb, scope, node->data.while_expr.condition, err_val_ptr, true); |
| 5557 | IrInstruction *is_err = ir_build_test_err(irb, scope, node->data.while_expr.condition, err_val); | | |
| 5558 | IrBasicBlock *after_cond_block = irb->current_basic_block; | 6146 | IrBasicBlock *after_cond_block = irb->current_basic_block; |
| 5559 | IrInstruction *void_else_result = else_node ? nullptr : ir_mark_gen(ir_build_const_void(irb, scope, node)); | 6147 | IrInstruction *void_else_result = else_node ? nullptr : ir_mark_gen(ir_build_const_void(irb, scope, node)); |
| | 6148 | IrInstruction *cond_br_inst; |
| 5560 | if (!instr_is_unreachable(is_err)) { | 6149 | if (!instr_is_unreachable(is_err)) { |
| 5561 | ir_mark_gen(ir_build_cond_br(irb, scope, node->data.while_expr.condition, is_err, | 6150 | cond_br_inst = ir_build_cond_br(irb, scope, node->data.while_expr.condition, is_err, |
| 5562 | else_block, body_block, is_comptime)); | 6151 | else_block, body_block, is_comptime); |
| | 6152 | cond_br_inst->is_gen = true; |
| | 6153 | } else { |
| | 6154 | // for the purposes of the source instruction to ir_build_result_peers |
| | 6155 | cond_br_inst = irb->current_basic_block->instruction_list.last(); |
| 5563 | } | 6156 | } |
| 5564 | | 6157 | |
| | 6158 | ResultLocPeerParent *peer_parent = ir_build_result_peers(irb, cond_br_inst, end_block, result_loc, |
| | 6159 | is_comptime); |
| | 6160 | |
| 5565 | ir_set_cursor_at_end_and_append_block(irb, body_block); | 6161 | ir_set_cursor_at_end_and_append_block(irb, body_block); |
| 5566 | if (var_symbol) { | 6162 | if (var_symbol) { |
| 5567 | IrInstruction *var_ptr_value = ir_build_unwrap_err_payload(irb, payload_scope, symbol_node, | 6163 | IrInstruction *payload_ptr = ir_build_unwrap_err_payload(irb, payload_scope, symbol_node, |
| 5568 | err_val_ptr, false); | 6164 | err_val_ptr, false, false); |
| 5569 | IrInstruction *var_value = node->data.while_expr.var_is_ptr ? | 6165 | IrInstruction *var_ptr = node->data.while_expr.var_is_ptr ? |
| 5570 | var_ptr_value : ir_build_load_ptr(irb, payload_scope, symbol_node, var_ptr_value); | 6166 | ir_build_ref(irb, payload_scope, symbol_node, payload_ptr, true, false) : payload_ptr; |
| 5571 | ir_build_var_decl_src(irb, payload_scope, symbol_node, payload_var, nullptr, nullptr, var_value); | 6167 | ir_build_var_decl_src(irb, payload_scope, symbol_node, payload_var, nullptr, var_ptr); |
| 5572 | } | 6168 | } |
| 5573 | | 6169 | |
| 5574 | ZigList<IrInstruction *> incoming_values = {0}; | 6170 | ZigList<IrInstruction *> incoming_values = {0}; |
| ... | @@ -5580,7 +6176,12 @@ static IrInstruction *ir_gen_while_expr(IrBuilder *irb, Scope *scope, AstNode *n | ... | @@ -5580,7 +6176,12 @@ static IrInstruction *ir_gen_while_expr(IrBuilder *irb, Scope *scope, AstNode *n |
| 5580 | loop_scope->is_comptime = is_comptime; | 6176 | loop_scope->is_comptime = is_comptime; |
| 5581 | loop_scope->incoming_blocks = &incoming_blocks; | 6177 | loop_scope->incoming_blocks = &incoming_blocks; |
| 5582 | loop_scope->incoming_values = &incoming_values; | 6178 | loop_scope->incoming_values = &incoming_values; |
| | 6179 | loop_scope->lval = lval; |
| | 6180 | loop_scope->peer_parent = peer_parent; |
| 5583 | | 6181 | |
| | 6182 | // Note the body block of the loop is not the place that lval and result_loc are used - |
| | 6183 | // it's actually in break statements, handled similarly to return statements. |
| | 6184 | // That is why we set those values in loop_scope above and not in this ir_gen_node call. |
| 5584 | IrInstruction *body_result = ir_gen_node(irb, node->data.while_expr.body, &loop_scope->base); | 6185 | IrInstruction *body_result = ir_gen_node(irb, node->data.while_expr.body, &loop_scope->base); |
| 5585 | if (body_result == irb->codegen->invalid_instruction) | 6186 | if (body_result == irb->codegen->invalid_instruction) |
| 5586 | return body_result; | 6187 | return body_result; |
| ... | @@ -5609,10 +6210,15 @@ static IrInstruction *ir_gen_while_expr(IrBuilder *irb, Scope *scope, AstNode *n | ... | @@ -5609,10 +6210,15 @@ static IrInstruction *ir_gen_while_expr(IrBuilder *irb, Scope *scope, AstNode *n |
| 5609 | ZigVar *err_var = ir_create_var(irb, err_symbol_node, scope, err_symbol, | 6210 | ZigVar *err_var = ir_create_var(irb, err_symbol_node, scope, err_symbol, |
| 5610 | true, false, false, is_comptime); | 6211 | true, false, false, is_comptime); |
| 5611 | Scope *err_scope = err_var->child_scope; | 6212 | Scope *err_scope = err_var->child_scope; |
| 5612 | IrInstruction *err_var_value = ir_build_unwrap_err_code(irb, err_scope, err_symbol_node, err_val_ptr); | 6213 | IrInstruction *err_ptr = ir_build_unwrap_err_code(irb, err_scope, err_symbol_node, err_val_ptr); |
| 5613 | ir_build_var_decl_src(irb, err_scope, symbol_node, err_var, nullptr, nullptr, err_var_value); | 6214 | ir_build_var_decl_src(irb, err_scope, symbol_node, err_var, nullptr, err_ptr); |
| 5614 | | 6215 | |
| 5615 | IrInstruction *else_result = ir_gen_node(irb, else_node, err_scope); | 6216 | if (peer_parent->peers.length != 0) { |
| | 6217 | peer_parent->peers.last()->next_bb = else_block; |
| | 6218 | } |
| | 6219 | ResultLocPeer *peer_result = create_peer_result(peer_parent); |
| | 6220 | peer_parent->peers.append(peer_result); |
| | 6221 | IrInstruction *else_result = ir_gen_node_extra(irb, else_node, err_scope, lval, &peer_result->base); |
| 5616 | if (else_result == irb->codegen->invalid_instruction) | 6222 | if (else_result == irb->codegen->invalid_instruction) |
| 5617 | return else_result; | 6223 | return else_result; |
| 5618 | if (!instr_is_unreachable(else_result)) | 6224 | if (!instr_is_unreachable(else_result)) |
| ... | @@ -5626,8 +6232,13 @@ static IrInstruction *ir_gen_while_expr(IrBuilder *irb, Scope *scope, AstNode *n | ... | @@ -5626,8 +6232,13 @@ static IrInstruction *ir_gen_while_expr(IrBuilder *irb, Scope *scope, AstNode *n |
| 5626 | incoming_blocks.append(after_cond_block); | 6232 | incoming_blocks.append(after_cond_block); |
| 5627 | incoming_values.append(void_else_result); | 6233 | incoming_values.append(void_else_result); |
| 5628 | } | 6234 | } |
| | 6235 | if (peer_parent->peers.length != 0) { |
| | 6236 | peer_parent->peers.last()->next_bb = end_block; |
| | 6237 | } |
| 5629 | | 6238 | |
| 5630 | return ir_build_phi(irb, scope, node, incoming_blocks.length, incoming_blocks.items, incoming_values.items); | 6239 | IrInstruction *phi = ir_build_phi(irb, scope, node, incoming_blocks.length, |
| | 6240 | incoming_blocks.items, incoming_values.items, peer_parent); |
| | 6241 | return ir_expr_wrap(irb, scope, phi, result_loc); |
| 5631 | } else if (var_symbol != nullptr) { | 6242 | } else if (var_symbol != nullptr) { |
| 5632 | ir_set_cursor_at_end_and_append_block(irb, cond_block); | 6243 | ir_set_cursor_at_end_and_append_block(irb, cond_block); |
| 5633 | Scope *subexpr_scope = create_runtime_scope(irb->codegen, node, scope, is_comptime); | 6244 | Scope *subexpr_scope = create_runtime_scope(irb->codegen, node, scope, is_comptime); |
| ... | @@ -5637,23 +6248,32 @@ static IrInstruction *ir_gen_while_expr(IrBuilder *irb, Scope *scope, AstNode *n | ... | @@ -5637,23 +6248,32 @@ static IrInstruction *ir_gen_while_expr(IrBuilder *irb, Scope *scope, AstNode *n |
| 5637 | ZigVar *payload_var = ir_create_var(irb, symbol_node, subexpr_scope, var_symbol, | 6248 | ZigVar *payload_var = ir_create_var(irb, symbol_node, subexpr_scope, var_symbol, |
| 5638 | true, false, false, is_comptime); | 6249 | true, false, false, is_comptime); |
| 5639 | Scope *child_scope = payload_var->child_scope; | 6250 | Scope *child_scope = payload_var->child_scope; |
| 5640 | IrInstruction *maybe_val_ptr = ir_gen_node_extra(irb, node->data.while_expr.condition, subexpr_scope, LValPtr); | 6251 | IrInstruction *maybe_val_ptr = ir_gen_node_extra(irb, node->data.while_expr.condition, subexpr_scope, |
| | 6252 | LValPtr, nullptr); |
| 5641 | if (maybe_val_ptr == irb->codegen->invalid_instruction) | 6253 | if (maybe_val_ptr == irb->codegen->invalid_instruction) |
| 5642 | return maybe_val_ptr; | 6254 | return maybe_val_ptr; |
| 5643 | IrInstruction *maybe_val = ir_build_load_ptr(irb, scope, node->data.while_expr.condition, maybe_val_ptr); | 6255 | IrInstruction *maybe_val = ir_build_load_ptr(irb, scope, node->data.while_expr.condition, maybe_val_ptr); |
| 5644 | IrInstruction *is_non_null = ir_build_test_nonnull(irb, scope, node->data.while_expr.condition, maybe_val); | 6256 | IrInstruction *is_non_null = ir_build_test_nonnull(irb, scope, node->data.while_expr.condition, maybe_val); |
| 5645 | IrBasicBlock *after_cond_block = irb->current_basic_block; | 6257 | IrBasicBlock *after_cond_block = irb->current_basic_block; |
| 5646 | IrInstruction *void_else_result = else_node ? nullptr : ir_mark_gen(ir_build_const_void(irb, scope, node)); | 6258 | IrInstruction *void_else_result = else_node ? nullptr : ir_mark_gen(ir_build_const_void(irb, scope, node)); |
| | 6259 | IrInstruction *cond_br_inst; |
| 5647 | if (!instr_is_unreachable(is_non_null)) { | 6260 | if (!instr_is_unreachable(is_non_null)) { |
| 5648 | ir_mark_gen(ir_build_cond_br(irb, scope, node->data.while_expr.condition, is_non_null, | 6261 | cond_br_inst = ir_build_cond_br(irb, scope, node->data.while_expr.condition, is_non_null, |
| 5649 | body_block, else_block, is_comptime)); | 6262 | body_block, else_block, is_comptime); |
| | 6263 | cond_br_inst->is_gen = true; |
| | 6264 | } else { |
| | 6265 | // for the purposes of the source instruction to ir_build_result_peers |
| | 6266 | cond_br_inst = irb->current_basic_block->instruction_list.last(); |
| 5650 | } | 6267 | } |
| 5651 | | 6268 | |
| | 6269 | ResultLocPeerParent *peer_parent = ir_build_result_peers(irb, cond_br_inst, end_block, result_loc, |
| | 6270 | is_comptime); |
| | 6271 | |
| 5652 | ir_set_cursor_at_end_and_append_block(irb, body_block); | 6272 | ir_set_cursor_at_end_and_append_block(irb, body_block); |
| 5653 | IrInstruction *var_ptr_value = ir_build_optional_unwrap_ptr(irb, child_scope, symbol_node, maybe_val_ptr, false); | 6273 | IrInstruction *payload_ptr = ir_build_optional_unwrap_ptr(irb, child_scope, symbol_node, maybe_val_ptr, false, false); |
| 5654 | IrInstruction *var_value = node->data.while_expr.var_is_ptr ? | 6274 | IrInstruction *var_ptr = node->data.while_expr.var_is_ptr ? |
| 5655 | var_ptr_value : ir_build_load_ptr(irb, child_scope, symbol_node, var_ptr_value); | 6275 | ir_build_ref(irb, child_scope, symbol_node, payload_ptr, true, false) : payload_ptr; |
| 5656 | ir_build_var_decl_src(irb, child_scope, symbol_node, payload_var, nullptr, nullptr, var_value); | 6276 | ir_build_var_decl_src(irb, child_scope, symbol_node, payload_var, nullptr, var_ptr); |
| 5657 | | 6277 | |
| 5658 | ZigList<IrInstruction *> incoming_values = {0}; | 6278 | ZigList<IrInstruction *> incoming_values = {0}; |
| 5659 | ZigList<IrBasicBlock *> incoming_blocks = {0}; | 6279 | ZigList<IrBasicBlock *> incoming_blocks = {0}; |
| ... | @@ -5664,7 +6284,12 @@ static IrInstruction *ir_gen_while_expr(IrBuilder *irb, Scope *scope, AstNode *n | ... | @@ -5664,7 +6284,12 @@ static IrInstruction *ir_gen_while_expr(IrBuilder *irb, Scope *scope, AstNode *n |
| 5664 | loop_scope->is_comptime = is_comptime; | 6284 | loop_scope->is_comptime = is_comptime; |
| 5665 | loop_scope->incoming_blocks = &incoming_blocks; | 6285 | loop_scope->incoming_blocks = &incoming_blocks; |
| 5666 | loop_scope->incoming_values = &incoming_values; | 6286 | loop_scope->incoming_values = &incoming_values; |
| | 6287 | loop_scope->lval = lval; |
| | 6288 | loop_scope->peer_parent = peer_parent; |
| 5667 | | 6289 | |
| | 6290 | // Note the body block of the loop is not the place that lval and result_loc are used - |
| | 6291 | // it's actually in break statements, handled similarly to return statements. |
| | 6292 | // That is why we set those values in loop_scope above and not in this ir_gen_node call. |
| 5668 | IrInstruction *body_result = ir_gen_node(irb, node->data.while_expr.body, &loop_scope->base); | 6293 | IrInstruction *body_result = ir_gen_node(irb, node->data.while_expr.body, &loop_scope->base); |
| 5669 | if (body_result == irb->codegen->invalid_instruction) | 6294 | if (body_result == irb->codegen->invalid_instruction) |
| 5670 | return body_result; | 6295 | return body_result; |
| ... | @@ -5689,7 +6314,12 @@ static IrInstruction *ir_gen_while_expr(IrBuilder *irb, Scope *scope, AstNode *n | ... | @@ -5689,7 +6314,12 @@ static IrInstruction *ir_gen_while_expr(IrBuilder *irb, Scope *scope, AstNode *n |
| 5689 | if (else_node) { | 6314 | if (else_node) { |
| 5690 | ir_set_cursor_at_end_and_append_block(irb, else_block); | 6315 | ir_set_cursor_at_end_and_append_block(irb, else_block); |
| 5691 | | 6316 | |
| 5692 | else_result = ir_gen_node(irb, else_node, scope); | 6317 | if (peer_parent->peers.length != 0) { |
| | 6318 | peer_parent->peers.last()->next_bb = else_block; |
| | 6319 | } |
| | 6320 | ResultLocPeer *peer_result = create_peer_result(peer_parent); |
| | 6321 | peer_parent->peers.append(peer_result); |
| | 6322 | else_result = ir_gen_node_extra(irb, else_node, scope, lval, &peer_result->base); |
| 5693 | if (else_result == irb->codegen->invalid_instruction) | 6323 | if (else_result == irb->codegen->invalid_instruction) |
| 5694 | return else_result; | 6324 | return else_result; |
| 5695 | if (!instr_is_unreachable(else_result)) | 6325 | if (!instr_is_unreachable(else_result)) |
| ... | @@ -5704,8 +6334,13 @@ static IrInstruction *ir_gen_while_expr(IrBuilder *irb, Scope *scope, AstNode *n | ... | @@ -5704,8 +6334,13 @@ static IrInstruction *ir_gen_while_expr(IrBuilder *irb, Scope *scope, AstNode *n |
| 5704 | incoming_blocks.append(after_cond_block); | 6334 | incoming_blocks.append(after_cond_block); |
| 5705 | incoming_values.append(void_else_result); | 6335 | incoming_values.append(void_else_result); |
| 5706 | } | 6336 | } |
| | 6337 | if (peer_parent->peers.length != 0) { |
| | 6338 | peer_parent->peers.last()->next_bb = end_block; |
| | 6339 | } |
| 5707 | | 6340 | |
| 5708 | return ir_build_phi(irb, scope, node, incoming_blocks.length, incoming_blocks.items, incoming_values.items); | 6341 | IrInstruction *phi = ir_build_phi(irb, scope, node, incoming_blocks.length, |
| | 6342 | incoming_blocks.items, incoming_values.items, peer_parent); |
| | 6343 | return ir_expr_wrap(irb, scope, phi, result_loc); |
| 5709 | } else { | 6344 | } else { |
| 5710 | ir_set_cursor_at_end_and_append_block(irb, cond_block); | 6345 | ir_set_cursor_at_end_and_append_block(irb, cond_block); |
| 5711 | IrInstruction *cond_val = ir_gen_node(irb, node->data.while_expr.condition, scope); | 6346 | IrInstruction *cond_val = ir_gen_node(irb, node->data.while_expr.condition, scope); |
| ... | @@ -5713,11 +6348,18 @@ static IrInstruction *ir_gen_while_expr(IrBuilder *irb, Scope *scope, AstNode *n | ... | @@ -5713,11 +6348,18 @@ static IrInstruction *ir_gen_while_expr(IrBuilder *irb, Scope *scope, AstNode *n |
| 5713 | return cond_val; | 6348 | return cond_val; |
| 5714 | IrBasicBlock *after_cond_block = irb->current_basic_block; | 6349 | IrBasicBlock *after_cond_block = irb->current_basic_block; |
| 5715 | IrInstruction *void_else_result = else_node ? nullptr : ir_mark_gen(ir_build_const_void(irb, scope, node)); | 6350 | IrInstruction *void_else_result = else_node ? nullptr : ir_mark_gen(ir_build_const_void(irb, scope, node)); |
| | 6351 | IrInstruction *cond_br_inst; |
| 5716 | if (!instr_is_unreachable(cond_val)) { | 6352 | if (!instr_is_unreachable(cond_val)) { |
| 5717 | ir_mark_gen(ir_build_cond_br(irb, scope, node->data.while_expr.condition, cond_val, | 6353 | cond_br_inst = ir_build_cond_br(irb, scope, node->data.while_expr.condition, cond_val, |
| 5718 | body_block, else_block, is_comptime)); | 6354 | body_block, else_block, is_comptime); |
| | 6355 | cond_br_inst->is_gen = true; |
| | 6356 | } else { |
| | 6357 | // for the purposes of the source instruction to ir_build_result_peers |
| | 6358 | cond_br_inst = irb->current_basic_block->instruction_list.last(); |
| 5719 | } | 6359 | } |
| 5720 | | 6360 | |
| | 6361 | ResultLocPeerParent *peer_parent = ir_build_result_peers(irb, cond_br_inst, end_block, result_loc, |
| | 6362 | is_comptime); |
| 5721 | ir_set_cursor_at_end_and_append_block(irb, body_block); | 6363 | ir_set_cursor_at_end_and_append_block(irb, body_block); |
| 5722 | | 6364 | |
| 5723 | ZigList<IrInstruction *> incoming_values = {0}; | 6365 | ZigList<IrInstruction *> incoming_values = {0}; |
| ... | @@ -5731,7 +6373,12 @@ static IrInstruction *ir_gen_while_expr(IrBuilder *irb, Scope *scope, AstNode *n | ... | @@ -5731,7 +6373,12 @@ static IrInstruction *ir_gen_while_expr(IrBuilder *irb, Scope *scope, AstNode *n |
| 5731 | loop_scope->is_comptime = is_comptime; | 6373 | loop_scope->is_comptime = is_comptime; |
| 5732 | loop_scope->incoming_blocks = &incoming_blocks; | 6374 | loop_scope->incoming_blocks = &incoming_blocks; |
| 5733 | loop_scope->incoming_values = &incoming_values; | 6375 | loop_scope->incoming_values = &incoming_values; |
| | 6376 | loop_scope->lval = lval; |
| | 6377 | loop_scope->peer_parent = peer_parent; |
| 5734 | | 6378 | |
| | 6379 | // Note the body block of the loop is not the place that lval and result_loc are used - |
| | 6380 | // it's actually in break statements, handled similarly to return statements. |
| | 6381 | // That is why we set those values in loop_scope above and not in this ir_gen_node call. |
| 5735 | IrInstruction *body_result = ir_gen_node(irb, node->data.while_expr.body, &loop_scope->base); | 6382 | IrInstruction *body_result = ir_gen_node(irb, node->data.while_expr.body, &loop_scope->base); |
| 5736 | if (body_result == irb->codegen->invalid_instruction) | 6383 | if (body_result == irb->codegen->invalid_instruction) |
| 5737 | return body_result; | 6384 | return body_result; |
| ... | @@ -5756,7 +6403,13 @@ static IrInstruction *ir_gen_while_expr(IrBuilder *irb, Scope *scope, AstNode *n | ... | @@ -5756,7 +6403,13 @@ static IrInstruction *ir_gen_while_expr(IrBuilder *irb, Scope *scope, AstNode *n |
| 5756 | if (else_node) { | 6403 | if (else_node) { |
| 5757 | ir_set_cursor_at_end_and_append_block(irb, else_block); | 6404 | ir_set_cursor_at_end_and_append_block(irb, else_block); |
| 5758 | | 6405 | |
| 5759 | else_result = ir_gen_node(irb, else_node, subexpr_scope); | 6406 | if (peer_parent->peers.length != 0) { |
| | 6407 | peer_parent->peers.last()->next_bb = else_block; |
| | 6408 | } |
| | 6409 | ResultLocPeer *peer_result = create_peer_result(peer_parent); |
| | 6410 | peer_parent->peers.append(peer_result); |
| | 6411 | |
| | 6412 | else_result = ir_gen_node_extra(irb, else_node, subexpr_scope, lval, &peer_result->base); |
| 5760 | if (else_result == irb->codegen->invalid_instruction) | 6413 | if (else_result == irb->codegen->invalid_instruction) |
| 5761 | return else_result; | 6414 | return else_result; |
| 5762 | if (!instr_is_unreachable(else_result)) | 6415 | if (!instr_is_unreachable(else_result)) |
| ... | @@ -5771,12 +6424,19 @@ static IrInstruction *ir_gen_while_expr(IrBuilder *irb, Scope *scope, AstNode *n | ... | @@ -5771,12 +6424,19 @@ static IrInstruction *ir_gen_while_expr(IrBuilder *irb, Scope *scope, AstNode *n |
| 5771 | incoming_blocks.append(after_cond_block); | 6424 | incoming_blocks.append(after_cond_block); |
| 5772 | incoming_values.append(void_else_result); | 6425 | incoming_values.append(void_else_result); |
| 5773 | } | 6426 | } |
| | 6427 | if (peer_parent->peers.length != 0) { |
| | 6428 | peer_parent->peers.last()->next_bb = end_block; |
| | 6429 | } |
| 5774 | | 6430 | |
| 5775 | return ir_build_phi(irb, scope, node, incoming_blocks.length, incoming_blocks.items, incoming_values.items); | 6431 | IrInstruction *phi = ir_build_phi(irb, scope, node, incoming_blocks.length, |
| | 6432 | incoming_blocks.items, incoming_values.items, peer_parent); |
| | 6433 | return ir_expr_wrap(irb, scope, phi, result_loc); |
| 5776 | } | 6434 | } |
| 5777 | } | 6435 | } |
| 5778 | | 6436 | |
| 5779 | static IrInstruction *ir_gen_for_expr(IrBuilder *irb, Scope *parent_scope, AstNode *node) { | 6437 | static IrInstruction *ir_gen_for_expr(IrBuilder *irb, Scope *parent_scope, AstNode *node, LVal lval, |
| | 6438 | ResultLoc *result_loc) |
| | 6439 | { |
| 5780 | assert(node->type == NodeTypeForExpr); | 6440 | assert(node->type == NodeTypeForExpr); |
| 5781 | | 6441 | |
| 5782 | AstNode *array_node = node->data.for_expr.array_expr; | 6442 | AstNode *array_node = node->data.for_expr.array_expr; |
| ... | @@ -5791,76 +6451,67 @@ static IrInstruction *ir_gen_for_expr(IrBuilder *irb, Scope *parent_scope, AstNo | ... | @@ -5791,76 +6451,67 @@ static IrInstruction *ir_gen_for_expr(IrBuilder *irb, Scope *parent_scope, AstNo |
| 5791 | } | 6451 | } |
| 5792 | assert(elem_node->type == NodeTypeSymbol); | 6452 | assert(elem_node->type == NodeTypeSymbol); |
| 5793 | | 6453 | |
| 5794 | IrInstruction *array_val_ptr = ir_gen_node_extra(irb, array_node, parent_scope, LValPtr); | 6454 | IrInstruction *array_val_ptr = ir_gen_node_extra(irb, array_node, parent_scope, LValPtr, nullptr); |
| 5795 | if (array_val_ptr == irb->codegen->invalid_instruction) | 6455 | if (array_val_ptr == irb->codegen->invalid_instruction) |
| 5796 | return array_val_ptr; | 6456 | return array_val_ptr; |
| 5797 | | 6457 | |
| 5798 | IrInstruction *pointer_type = ir_build_to_ptr_type(irb, parent_scope, array_node, array_val_ptr); | | |
| 5799 | IrInstruction *elem_var_type; | | |
| 5800 | if (node->data.for_expr.elem_is_ptr) { | | |
| 5801 | elem_var_type = pointer_type; | | |
| 5802 | } else { | | |
| 5803 | elem_var_type = ir_build_ptr_type_child(irb, parent_scope, elem_node, pointer_type); | | |
| 5804 | } | | |
| 5805 | | | |
| 5806 | IrInstruction *is_comptime = ir_build_const_bool(irb, parent_scope, node, | 6458 | IrInstruction *is_comptime = ir_build_const_bool(irb, parent_scope, node, |
| 5807 | ir_should_inline(irb->exec, parent_scope) || node->data.for_expr.is_inline); | 6459 | ir_should_inline(irb->exec, parent_scope) || node->data.for_expr.is_inline); |
| 5808 | | 6460 | |
| 5809 | // TODO make it an error to write to element variable or i variable. | | |
| 5810 | Buf *elem_var_name = elem_node->data.symbol_expr.symbol; | | |
| 5811 | ZigVar *elem_var = ir_create_var(irb, elem_node, parent_scope, elem_var_name, true, false, false, is_comptime); | | |
| 5812 | Scope *child_scope = elem_var->child_scope; | | |
| 5813 | | | |
| 5814 | IrInstruction *undefined_value = ir_build_const_undefined(irb, child_scope, elem_node); | | |
| 5815 | ir_build_var_decl_src(irb, child_scope, elem_node, elem_var, elem_var_type, nullptr, undefined_value); | | |
| 5816 | IrInstruction *elem_var_ptr = ir_build_var_ptr(irb, child_scope, node, elem_var); | | |
| 5817 | | | |
| 5818 | AstNode *index_var_source_node; | 6461 | AstNode *index_var_source_node; |
| 5819 | ZigVar *index_var; | 6462 | ZigVar *index_var; |
| | 6463 | const char *index_var_name; |
| 5820 | if (index_node) { | 6464 | if (index_node) { |
| 5821 | index_var_source_node = index_node; | 6465 | index_var_source_node = index_node; |
| 5822 | Buf *index_var_name = index_node->data.symbol_expr.symbol; | 6466 | Buf *index_var_name_buf = index_node->data.symbol_expr.symbol; |
| 5823 | index_var = ir_create_var(irb, index_node, child_scope, index_var_name, true, false, false, is_comptime); | 6467 | index_var = ir_create_var(irb, index_node, parent_scope, index_var_name_buf, true, false, false, is_comptime); |
| | 6468 | index_var_name = buf_ptr(index_var_name_buf); |
| 5824 | } else { | 6469 | } else { |
| 5825 | index_var_source_node = node; | 6470 | index_var_source_node = node; |
| 5826 | index_var = ir_create_var(irb, node, child_scope, nullptr, true, false, true, is_comptime); | 6471 | index_var = ir_create_var(irb, node, parent_scope, nullptr, true, false, true, is_comptime); |
| | 6472 | index_var_name = "i"; |
| 5827 | } | 6473 | } |
| 5828 | child_scope = index_var->child_scope; | | |
| 5829 | | 6474 | |
| 5830 | IrInstruction *usize = ir_build_const_type(irb, child_scope, node, irb->codegen->builtin_types.entry_usize); | 6475 | IrInstruction *zero = ir_build_const_usize(irb, parent_scope, node, 0); |
| 5831 | IrInstruction *zero = ir_build_const_usize(irb, child_scope, node, 0); | 6476 | build_decl_var_and_init(irb, parent_scope, index_var_source_node, index_var, zero, index_var_name, is_comptime); |
| 5832 | IrInstruction *one = ir_build_const_usize(irb, child_scope, node, 1); | 6477 | parent_scope = index_var->child_scope; |
| 5833 | ir_build_var_decl_src(irb, child_scope, index_var_source_node, index_var, usize, nullptr, zero); | 6478 | |
| 5834 | IrInstruction *index_ptr = ir_build_var_ptr(irb, child_scope, node, index_var); | 6479 | IrInstruction *one = ir_build_const_usize(irb, parent_scope, node, 1); |
| | 6480 | IrInstruction *index_ptr = ir_build_var_ptr(irb, parent_scope, node, index_var); |
| 5835 | | 6481 | |
| 5836 | | 6482 | |
| 5837 | IrBasicBlock *cond_block = ir_create_basic_block(irb, child_scope, "ForCond"); | 6483 | IrBasicBlock *cond_block = ir_create_basic_block(irb, parent_scope, "ForCond"); |
| 5838 | IrBasicBlock *body_block = ir_create_basic_block(irb, child_scope, "ForBody"); | 6484 | IrBasicBlock *body_block = ir_create_basic_block(irb, parent_scope, "ForBody"); |
| 5839 | IrBasicBlock *end_block = ir_create_basic_block(irb, child_scope, "ForEnd"); | 6485 | IrBasicBlock *end_block = ir_create_basic_block(irb, parent_scope, "ForEnd"); |
| 5840 | IrBasicBlock *else_block = else_node ? ir_create_basic_block(irb, child_scope, "ForElse") : end_block; | 6486 | IrBasicBlock *else_block = else_node ? ir_create_basic_block(irb, parent_scope, "ForElse") : end_block; |
| 5841 | IrBasicBlock *continue_block = ir_create_basic_block(irb, child_scope, "ForContinue"); | 6487 | IrBasicBlock *continue_block = ir_create_basic_block(irb, parent_scope, "ForContinue"); |
| 5842 | | 6488 | |
| 5843 | Buf *len_field_name = buf_create_from_str("len"); | 6489 | Buf *len_field_name = buf_create_from_str("len"); |
| 5844 | IrInstruction *len_ref = ir_build_field_ptr(irb, child_scope, node, array_val_ptr, len_field_name); | 6490 | IrInstruction *len_ref = ir_build_field_ptr(irb, parent_scope, node, array_val_ptr, len_field_name, false); |
| 5845 | IrInstruction *len_val = ir_build_load_ptr(irb, child_scope, node, len_ref); | 6491 | IrInstruction *len_val = ir_build_load_ptr(irb, parent_scope, node, len_ref); |
| 5846 | ir_build_br(irb, child_scope, node, cond_block, is_comptime); | 6492 | ir_build_br(irb, parent_scope, node, cond_block, is_comptime); |
| 5847 | | 6493 | |
| 5848 | ir_set_cursor_at_end_and_append_block(irb, cond_block); | 6494 | ir_set_cursor_at_end_and_append_block(irb, cond_block); |
| 5849 | IrInstruction *index_val = ir_build_load_ptr(irb, child_scope, node, index_ptr); | 6495 | IrInstruction *index_val = ir_build_load_ptr(irb, parent_scope, node, index_ptr); |
| 5850 | IrInstruction *cond = ir_build_bin_op(irb, child_scope, node, IrBinOpCmpLessThan, index_val, len_val, false); | 6496 | IrInstruction *cond = ir_build_bin_op(irb, parent_scope, node, IrBinOpCmpLessThan, index_val, len_val, false); |
| 5851 | IrBasicBlock *after_cond_block = irb->current_basic_block; | 6497 | IrBasicBlock *after_cond_block = irb->current_basic_block; |
| 5852 | IrInstruction *void_else_value = else_node ? nullptr : ir_mark_gen(ir_build_const_void(irb, parent_scope, node)); | 6498 | IrInstruction *void_else_value = else_node ? nullptr : ir_mark_gen(ir_build_const_void(irb, parent_scope, node)); |
| 5853 | ir_mark_gen(ir_build_cond_br(irb, child_scope, node, cond, body_block, else_block, is_comptime)); | 6499 | IrInstruction *cond_br_inst = ir_mark_gen(ir_build_cond_br(irb, parent_scope, node, cond, |
| | 6500 | body_block, else_block, is_comptime)); |
| | 6501 | |
| | 6502 | ResultLocPeerParent *peer_parent = ir_build_result_peers(irb, cond_br_inst, end_block, result_loc, is_comptime); |
| 5854 | | 6503 | |
| 5855 | ir_set_cursor_at_end_and_append_block(irb, body_block); | 6504 | ir_set_cursor_at_end_and_append_block(irb, body_block); |
| 5856 | IrInstruction *elem_ptr = ir_build_elem_ptr(irb, child_scope, node, array_val_ptr, index_val, false, PtrLenSingle); | 6505 | IrInstruction *elem_ptr = ir_build_elem_ptr(irb, parent_scope, node, array_val_ptr, index_val, false, |
| 5857 | IrInstruction *elem_val; | 6506 | PtrLenSingle, nullptr); |
| 5858 | if (node->data.for_expr.elem_is_ptr) { | 6507 | // TODO make it an error to write to element variable or i variable. |
| 5859 | elem_val = elem_ptr; | 6508 | Buf *elem_var_name = elem_node->data.symbol_expr.symbol; |
| 5860 | } else { | 6509 | ZigVar *elem_var = ir_create_var(irb, elem_node, parent_scope, elem_var_name, true, false, false, is_comptime); |
| 5861 | elem_val = ir_build_load_ptr(irb, child_scope, node, elem_ptr); | 6510 | Scope *child_scope = elem_var->child_scope; |
| 5862 | } | 6511 | |
| 5863 | ir_mark_gen(ir_build_store_ptr(irb, child_scope, node, elem_var_ptr, elem_val)); | 6512 | IrInstruction *var_ptr = node->data.for_expr.elem_is_ptr ? |
| | 6513 | ir_build_ref(irb, parent_scope, elem_node, elem_ptr, true, false) : elem_ptr; |
| | 6514 | ir_build_var_decl_src(irb, parent_scope, elem_node, elem_var, nullptr, var_ptr); |
| 5864 | | 6515 | |
| 5865 | ZigList<IrInstruction *> incoming_values = {0}; | 6516 | ZigList<IrInstruction *> incoming_values = {0}; |
| 5866 | ZigList<IrBasicBlock *> incoming_blocks = {0}; | 6517 | ZigList<IrBasicBlock *> incoming_blocks = {0}; |
| ... | @@ -5870,7 +6521,12 @@ static IrInstruction *ir_gen_for_expr(IrBuilder *irb, Scope *parent_scope, AstNo | ... | @@ -5870,7 +6521,12 @@ static IrInstruction *ir_gen_for_expr(IrBuilder *irb, Scope *parent_scope, AstNo |
| 5870 | loop_scope->is_comptime = is_comptime; | 6521 | loop_scope->is_comptime = is_comptime; |
| 5871 | loop_scope->incoming_blocks = &incoming_blocks; | 6522 | loop_scope->incoming_blocks = &incoming_blocks; |
| 5872 | loop_scope->incoming_values = &incoming_values; | 6523 | loop_scope->incoming_values = &incoming_values; |
| | 6524 | loop_scope->lval = LValNone; |
| | 6525 | loop_scope->peer_parent = peer_parent; |
| 5873 | | 6526 | |
| | 6527 | // Note the body block of the loop is not the place that lval and result_loc are used - |
| | 6528 | // it's actually in break statements, handled similarly to return statements. |
| | 6529 | // That is why we set those values in loop_scope above and not in this ir_gen_node call. |
| 5874 | IrInstruction *body_result = ir_gen_node(irb, body_node, &loop_scope->base); | 6530 | IrInstruction *body_result = ir_gen_node(irb, body_node, &loop_scope->base); |
| 5875 | | 6531 | |
| 5876 | if (!instr_is_unreachable(body_result)) { | 6532 | if (!instr_is_unreachable(body_result)) { |
| ... | @@ -5887,7 +6543,12 @@ static IrInstruction *ir_gen_for_expr(IrBuilder *irb, Scope *parent_scope, AstNo | ... | @@ -5887,7 +6543,12 @@ static IrInstruction *ir_gen_for_expr(IrBuilder *irb, Scope *parent_scope, AstNo |
| 5887 | if (else_node) { | 6543 | if (else_node) { |
| 5888 | ir_set_cursor_at_end_and_append_block(irb, else_block); | 6544 | ir_set_cursor_at_end_and_append_block(irb, else_block); |
| 5889 | | 6545 | |
| 5890 | else_result = ir_gen_node(irb, else_node, parent_scope); | 6546 | if (peer_parent->peers.length != 0) { |
| | 6547 | peer_parent->peers.last()->next_bb = else_block; |
| | 6548 | } |
| | 6549 | ResultLocPeer *peer_result = create_peer_result(peer_parent); |
| | 6550 | peer_parent->peers.append(peer_result); |
| | 6551 | else_result = ir_gen_node_extra(irb, else_node, parent_scope, LValNone, &peer_result->base); |
| 5891 | if (else_result == irb->codegen->invalid_instruction) | 6552 | if (else_result == irb->codegen->invalid_instruction) |
| 5892 | return else_result; | 6553 | return else_result; |
| 5893 | if (!instr_is_unreachable(else_result)) | 6554 | if (!instr_is_unreachable(else_result)) |
| ... | @@ -5903,8 +6564,13 @@ static IrInstruction *ir_gen_for_expr(IrBuilder *irb, Scope *parent_scope, AstNo | ... | @@ -5903,8 +6564,13 @@ static IrInstruction *ir_gen_for_expr(IrBuilder *irb, Scope *parent_scope, AstNo |
| 5903 | incoming_blocks.append(after_cond_block); | 6564 | incoming_blocks.append(after_cond_block); |
| 5904 | incoming_values.append(void_else_value); | 6565 | incoming_values.append(void_else_value); |
| 5905 | } | 6566 | } |
| | 6567 | if (peer_parent->peers.length != 0) { |
| | 6568 | peer_parent->peers.last()->next_bb = end_block; |
| | 6569 | } |
| 5906 | | 6570 | |
| 5907 | return ir_build_phi(irb, parent_scope, node, incoming_blocks.length, incoming_blocks.items, incoming_values.items); | 6571 | IrInstruction *phi = ir_build_phi(irb, parent_scope, node, incoming_blocks.length, |
| | 6572 | incoming_blocks.items, incoming_values.items, peer_parent); |
| | 6573 | return ir_lval_wrap(irb, parent_scope, phi, lval, result_loc); |
| 5908 | } | 6574 | } |
| 5909 | | 6575 | |
| 5910 | static IrInstruction *ir_gen_bool_literal(IrBuilder *irb, Scope *scope, AstNode *node) { | 6576 | static IrInstruction *ir_gen_bool_literal(IrBuilder *irb, Scope *scope, AstNode *node) { |
| ... | @@ -6189,7 +6855,9 @@ static IrInstruction *ir_gen_asm_expr(IrBuilder *irb, Scope *scope, AstNode *nod | ... | @@ -6189,7 +6855,9 @@ static IrInstruction *ir_gen_asm_expr(IrBuilder *irb, Scope *scope, AstNode *nod |
| 6189 | input_list, output_types, output_vars, return_count, is_volatile); | 6855 | input_list, output_types, output_vars, return_count, is_volatile); |
| 6190 | } | 6856 | } |
| 6191 | | 6857 | |
| 6192 | static IrInstruction *ir_gen_if_optional_expr(IrBuilder *irb, Scope *scope, AstNode *node) { | 6858 | static IrInstruction *ir_gen_if_optional_expr(IrBuilder *irb, Scope *scope, AstNode *node, LVal lval, |
| | 6859 | ResultLoc *result_loc) |
| | 6860 | { |
| 6193 | assert(node->type == NodeTypeIfOptional); | 6861 | assert(node->type == NodeTypeIfOptional); |
| 6194 | | 6862 | |
| 6195 | Buf *var_symbol = node->data.test_expr.var_symbol; | 6863 | Buf *var_symbol = node->data.test_expr.var_symbol; |
| ... | @@ -6198,7 +6866,7 @@ static IrInstruction *ir_gen_if_optional_expr(IrBuilder *irb, Scope *scope, AstN | ... | @@ -6198,7 +6866,7 @@ static IrInstruction *ir_gen_if_optional_expr(IrBuilder *irb, Scope *scope, AstN |
| 6198 | AstNode *else_node = node->data.test_expr.else_node; | 6866 | AstNode *else_node = node->data.test_expr.else_node; |
| 6199 | bool var_is_ptr = node->data.test_expr.var_is_ptr; | 6867 | bool var_is_ptr = node->data.test_expr.var_is_ptr; |
| 6200 | | 6868 | |
| 6201 | IrInstruction *maybe_val_ptr = ir_gen_node_extra(irb, expr_node, scope, LValPtr); | 6869 | IrInstruction *maybe_val_ptr = ir_gen_node_extra(irb, expr_node, scope, LValPtr, nullptr); |
| 6202 | if (maybe_val_ptr == irb->codegen->invalid_instruction) | 6870 | if (maybe_val_ptr == irb->codegen->invalid_instruction) |
| 6203 | return maybe_val_ptr; | 6871 | return maybe_val_ptr; |
| 6204 | | 6872 | |
| ... | @@ -6215,27 +6883,31 @@ static IrInstruction *ir_gen_if_optional_expr(IrBuilder *irb, Scope *scope, AstN | ... | @@ -6215,27 +6883,31 @@ static IrInstruction *ir_gen_if_optional_expr(IrBuilder *irb, Scope *scope, AstN |
| 6215 | } else { | 6883 | } else { |
| 6216 | is_comptime = ir_build_test_comptime(irb, scope, node, is_non_null); | 6884 | is_comptime = ir_build_test_comptime(irb, scope, node, is_non_null); |
| 6217 | } | 6885 | } |
| 6218 | ir_build_cond_br(irb, scope, node, is_non_null, then_block, else_block, is_comptime); | 6886 | IrInstruction *cond_br_inst = ir_build_cond_br(irb, scope, node, is_non_null, |
| | 6887 | then_block, else_block, is_comptime); |
| | 6888 | |
| | 6889 | ResultLocPeerParent *peer_parent = ir_build_binary_result_peers(irb, cond_br_inst, else_block, endif_block, |
| | 6890 | result_loc, is_comptime); |
| 6219 | | 6891 | |
| 6220 | ir_set_cursor_at_end_and_append_block(irb, then_block); | 6892 | ir_set_cursor_at_end_and_append_block(irb, then_block); |
| 6221 | | 6893 | |
| 6222 | Scope *subexpr_scope = create_runtime_scope(irb->codegen, node, scope, is_comptime); | 6894 | Scope *subexpr_scope = create_runtime_scope(irb->codegen, node, scope, is_comptime); |
| 6223 | Scope *var_scope; | 6895 | Scope *var_scope; |
| 6224 | if (var_symbol) { | 6896 | if (var_symbol) { |
| 6225 | IrInstruction *var_type = nullptr; | | |
| 6226 | bool is_shadowable = false; | 6897 | bool is_shadowable = false; |
| 6227 | bool is_const = true; | 6898 | bool is_const = true; |
| 6228 | ZigVar *var = ir_create_var(irb, node, subexpr_scope, | 6899 | ZigVar *var = ir_create_var(irb, node, subexpr_scope, |
| 6229 | var_symbol, is_const, is_const, is_shadowable, is_comptime); | 6900 | var_symbol, is_const, is_const, is_shadowable, is_comptime); |
| 6230 | | 6901 | |
| 6231 | IrInstruction *var_ptr_value = ir_build_optional_unwrap_ptr(irb, subexpr_scope, node, maybe_val_ptr, false); | 6902 | IrInstruction *payload_ptr = ir_build_optional_unwrap_ptr(irb, subexpr_scope, node, maybe_val_ptr, false, false); |
| 6232 | IrInstruction *var_value = var_is_ptr ? var_ptr_value : ir_build_load_ptr(irb, subexpr_scope, node, var_ptr_value); | 6903 | IrInstruction *var_ptr = var_is_ptr ? ir_build_ref(irb, subexpr_scope, node, payload_ptr, true, false) : payload_ptr; |
| 6233 | ir_build_var_decl_src(irb, subexpr_scope, node, var, var_type, nullptr, var_value); | 6904 | ir_build_var_decl_src(irb, subexpr_scope, node, var, nullptr, var_ptr); |
| 6234 | var_scope = var->child_scope; | 6905 | var_scope = var->child_scope; |
| 6235 | } else { | 6906 | } else { |
| 6236 | var_scope = subexpr_scope; | 6907 | var_scope = subexpr_scope; |
| 6237 | } | 6908 | } |
| 6238 | IrInstruction *then_expr_result = ir_gen_node(irb, then_node, var_scope); | 6909 | IrInstruction *then_expr_result = ir_gen_node_extra(irb, then_node, var_scope, lval, |
| | 6910 | &peer_parent->peers.at(0)->base); |
| 6239 | if (then_expr_result == irb->codegen->invalid_instruction) | 6911 | if (then_expr_result == irb->codegen->invalid_instruction) |
| 6240 | return then_expr_result; | 6912 | return then_expr_result; |
| 6241 | IrBasicBlock *after_then_block = irb->current_basic_block; | 6913 | IrBasicBlock *after_then_block = irb->current_basic_block; |
| ... | @@ -6245,11 +6917,12 @@ static IrInstruction *ir_gen_if_optional_expr(IrBuilder *irb, Scope *scope, AstN | ... | @@ -6245,11 +6917,12 @@ static IrInstruction *ir_gen_if_optional_expr(IrBuilder *irb, Scope *scope, AstN |
| 6245 | ir_set_cursor_at_end_and_append_block(irb, else_block); | 6917 | ir_set_cursor_at_end_and_append_block(irb, else_block); |
| 6246 | IrInstruction *else_expr_result; | 6918 | IrInstruction *else_expr_result; |
| 6247 | if (else_node) { | 6919 | if (else_node) { |
| 6248 | else_expr_result = ir_gen_node(irb, else_node, subexpr_scope); | 6920 | else_expr_result = ir_gen_node_extra(irb, else_node, subexpr_scope, lval, &peer_parent->peers.at(1)->base); |
| 6249 | if (else_expr_result == irb->codegen->invalid_instruction) | 6921 | if (else_expr_result == irb->codegen->invalid_instruction) |
| 6250 | return else_expr_result; | 6922 | return else_expr_result; |
| 6251 | } else { | 6923 | } else { |
| 6252 | else_expr_result = ir_build_const_void(irb, scope, node); | 6924 | else_expr_result = ir_build_const_void(irb, scope, node); |
| | 6925 | ir_build_end_expr(irb, scope, node, else_expr_result, &peer_parent->peers.at(1)->base); |
| 6253 | } | 6926 | } |
| 6254 | IrBasicBlock *after_else_block = irb->current_basic_block; | 6927 | IrBasicBlock *after_else_block = irb->current_basic_block; |
| 6255 | if (!instr_is_unreachable(else_expr_result)) | 6928 | if (!instr_is_unreachable(else_expr_result)) |
| ... | @@ -6263,10 +6936,13 @@ static IrInstruction *ir_gen_if_optional_expr(IrBuilder *irb, Scope *scope, AstN | ... | @@ -6263,10 +6936,13 @@ static IrInstruction *ir_gen_if_optional_expr(IrBuilder *irb, Scope *scope, AstN |
| 6263 | incoming_blocks[0] = after_then_block; | 6936 | incoming_blocks[0] = after_then_block; |
| 6264 | incoming_blocks[1] = after_else_block; | 6937 | incoming_blocks[1] = after_else_block; |
| 6265 | | 6938 | |
| 6266 | return ir_build_phi(irb, scope, node, 2, incoming_blocks, incoming_values); | 6939 | IrInstruction *phi = ir_build_phi(irb, scope, node, 2, incoming_blocks, incoming_values, peer_parent); |
| | 6940 | return ir_expr_wrap(irb, scope, phi, result_loc); |
| 6267 | } | 6941 | } |
| 6268 | | 6942 | |
| 6269 | static IrInstruction *ir_gen_if_err_expr(IrBuilder *irb, Scope *scope, AstNode *node) { | 6943 | static IrInstruction *ir_gen_if_err_expr(IrBuilder *irb, Scope *scope, AstNode *node, LVal lval, |
| | 6944 | ResultLoc *result_loc) |
| | 6945 | { |
| 6270 | assert(node->type == NodeTypeIfErrorExpr); | 6946 | assert(node->type == NodeTypeIfErrorExpr); |
| 6271 | | 6947 | |
| 6272 | AstNode *target_node = node->data.if_err_expr.target_node; | 6948 | AstNode *target_node = node->data.if_err_expr.target_node; |
| ... | @@ -6277,12 +6953,12 @@ static IrInstruction *ir_gen_if_err_expr(IrBuilder *irb, Scope *scope, AstNode * | ... | @@ -6277,12 +6953,12 @@ static IrInstruction *ir_gen_if_err_expr(IrBuilder *irb, Scope *scope, AstNode * |
| 6277 | Buf *var_symbol = node->data.if_err_expr.var_symbol; | 6953 | Buf *var_symbol = node->data.if_err_expr.var_symbol; |
| 6278 | Buf *err_symbol = node->data.if_err_expr.err_symbol; | 6954 | Buf *err_symbol = node->data.if_err_expr.err_symbol; |
| 6279 | | 6955 | |
| 6280 | IrInstruction *err_val_ptr = ir_gen_node_extra(irb, target_node, scope, LValPtr); | 6956 | IrInstruction *err_val_ptr = ir_gen_node_extra(irb, target_node, scope, LValPtr, nullptr); |
| 6281 | if (err_val_ptr == irb->codegen->invalid_instruction) | 6957 | if (err_val_ptr == irb->codegen->invalid_instruction) |
| 6282 | return err_val_ptr; | 6958 | return err_val_ptr; |
| 6283 | | 6959 | |
| 6284 | IrInstruction *err_val = ir_build_load_ptr(irb, scope, node, err_val_ptr); | 6960 | IrInstruction *err_val = ir_build_load_ptr(irb, scope, node, err_val_ptr); |
| 6285 | IrInstruction *is_err = ir_build_test_err(irb, scope, node, err_val); | 6961 | IrInstruction *is_err = ir_build_test_err_src(irb, scope, node, err_val_ptr, true); |
| 6286 | | 6962 | |
| 6287 | IrBasicBlock *ok_block = ir_create_basic_block(irb, scope, "TryOk"); | 6963 | IrBasicBlock *ok_block = ir_create_basic_block(irb, scope, "TryOk"); |
| 6288 | IrBasicBlock *else_block = ir_create_basic_block(irb, scope, "TryElse"); | 6964 | IrBasicBlock *else_block = ir_create_basic_block(irb, scope, "TryElse"); |
| ... | @@ -6290,27 +6966,31 @@ static IrInstruction *ir_gen_if_err_expr(IrBuilder *irb, Scope *scope, AstNode * | ... | @@ -6290,27 +6966,31 @@ static IrInstruction *ir_gen_if_err_expr(IrBuilder *irb, Scope *scope, AstNode * |
| 6290 | | 6966 | |
| 6291 | bool force_comptime = ir_should_inline(irb->exec, scope); | 6967 | bool force_comptime = ir_should_inline(irb->exec, scope); |
| 6292 | IrInstruction *is_comptime = force_comptime ? ir_build_const_bool(irb, scope, node, true) : ir_build_test_comptime(irb, scope, node, is_err); | 6968 | IrInstruction *is_comptime = force_comptime ? ir_build_const_bool(irb, scope, node, true) : ir_build_test_comptime(irb, scope, node, is_err); |
| 6293 | ir_build_cond_br(irb, scope, node, is_err, else_block, ok_block, is_comptime); | 6969 | IrInstruction *cond_br_inst = ir_build_cond_br(irb, scope, node, is_err, else_block, ok_block, is_comptime); |
| | 6970 | |
| | 6971 | ResultLocPeerParent *peer_parent = ir_build_binary_result_peers(irb, cond_br_inst, else_block, endif_block, |
| | 6972 | result_loc, is_comptime); |
| 6294 | | 6973 | |
| 6295 | ir_set_cursor_at_end_and_append_block(irb, ok_block); | 6974 | ir_set_cursor_at_end_and_append_block(irb, ok_block); |
| 6296 | | 6975 | |
| 6297 | Scope *subexpr_scope = create_runtime_scope(irb->codegen, node, scope, is_comptime); | 6976 | Scope *subexpr_scope = create_runtime_scope(irb->codegen, node, scope, is_comptime); |
| 6298 | Scope *var_scope; | 6977 | Scope *var_scope; |
| 6299 | if (var_symbol) { | 6978 | if (var_symbol) { |
| 6300 | IrInstruction *var_type = nullptr; | | |
| 6301 | bool is_shadowable = false; | 6979 | bool is_shadowable = false; |
| 6302 | IrInstruction *var_is_comptime = force_comptime ? ir_build_const_bool(irb, subexpr_scope, node, true) : ir_build_test_comptime(irb, subexpr_scope, node, err_val); | 6980 | IrInstruction *var_is_comptime = force_comptime ? ir_build_const_bool(irb, subexpr_scope, node, true) : ir_build_test_comptime(irb, subexpr_scope, node, err_val); |
| 6303 | ZigVar *var = ir_create_var(irb, node, subexpr_scope, | 6981 | ZigVar *var = ir_create_var(irb, node, subexpr_scope, |
| 6304 | var_symbol, var_is_const, var_is_const, is_shadowable, var_is_comptime); | 6982 | var_symbol, var_is_const, var_is_const, is_shadowable, var_is_comptime); |
| 6305 | | 6983 | |
| 6306 | IrInstruction *var_ptr_value = ir_build_unwrap_err_payload(irb, subexpr_scope, node, err_val_ptr, false); | 6984 | IrInstruction *payload_ptr = ir_build_unwrap_err_payload(irb, subexpr_scope, node, err_val_ptr, false, false); |
| 6307 | IrInstruction *var_value = var_is_ptr ? var_ptr_value : ir_build_load_ptr(irb, subexpr_scope, node, var_ptr_value); | 6985 | IrInstruction *var_ptr = var_is_ptr ? |
| 6308 | ir_build_var_decl_src(irb, subexpr_scope, node, var, var_type, nullptr, var_value); | 6986 | ir_build_ref(irb, subexpr_scope, node, payload_ptr, true, false) : payload_ptr; |
| | 6987 | ir_build_var_decl_src(irb, subexpr_scope, node, var, nullptr, var_ptr); |
| 6309 | var_scope = var->child_scope; | 6988 | var_scope = var->child_scope; |
| 6310 | } else { | 6989 | } else { |
| 6311 | var_scope = subexpr_scope; | 6990 | var_scope = subexpr_scope; |
| 6312 | } | 6991 | } |
| 6313 | IrInstruction *then_expr_result = ir_gen_node(irb, then_node, var_scope); | 6992 | IrInstruction *then_expr_result = ir_gen_node_extra(irb, then_node, var_scope, lval, |
| | 6993 | &peer_parent->peers.at(0)->base); |
| 6314 | if (then_expr_result == irb->codegen->invalid_instruction) | 6994 | if (then_expr_result == irb->codegen->invalid_instruction) |
| 6315 | return then_expr_result; | 6995 | return then_expr_result; |
| 6316 | IrBasicBlock *after_then_block = irb->current_basic_block; | 6996 | IrBasicBlock *after_then_block = irb->current_basic_block; |
| ... | @@ -6323,23 +7003,23 @@ static IrInstruction *ir_gen_if_err_expr(IrBuilder *irb, Scope *scope, AstNode * | ... | @@ -6323,23 +7003,23 @@ static IrInstruction *ir_gen_if_err_expr(IrBuilder *irb, Scope *scope, AstNode * |
| 6323 | if (else_node) { | 7003 | if (else_node) { |
| 6324 | Scope *err_var_scope; | 7004 | Scope *err_var_scope; |
| 6325 | if (err_symbol) { | 7005 | if (err_symbol) { |
| 6326 | IrInstruction *var_type = nullptr; | | |
| 6327 | bool is_shadowable = false; | 7006 | bool is_shadowable = false; |
| 6328 | bool is_const = true; | 7007 | bool is_const = true; |
| 6329 | ZigVar *var = ir_create_var(irb, node, subexpr_scope, | 7008 | ZigVar *var = ir_create_var(irb, node, subexpr_scope, |
| 6330 | err_symbol, is_const, is_const, is_shadowable, is_comptime); | 7009 | err_symbol, is_const, is_const, is_shadowable, is_comptime); |
| 6331 | | 7010 | |
| 6332 | IrInstruction *var_value = ir_build_unwrap_err_code(irb, subexpr_scope, node, err_val_ptr); | 7011 | IrInstruction *err_ptr = ir_build_unwrap_err_code(irb, subexpr_scope, node, err_val_ptr); |
| 6333 | ir_build_var_decl_src(irb, subexpr_scope, node, var, var_type, nullptr, var_value); | 7012 | ir_build_var_decl_src(irb, subexpr_scope, node, var, nullptr, err_ptr); |
| 6334 | err_var_scope = var->child_scope; | 7013 | err_var_scope = var->child_scope; |
| 6335 | } else { | 7014 | } else { |
| 6336 | err_var_scope = subexpr_scope; | 7015 | err_var_scope = subexpr_scope; |
| 6337 | } | 7016 | } |
| 6338 | else_expr_result = ir_gen_node(irb, else_node, err_var_scope); | 7017 | else_expr_result = ir_gen_node_extra(irb, else_node, err_var_scope, lval, &peer_parent->peers.at(1)->base); |
| 6339 | if (else_expr_result == irb->codegen->invalid_instruction) | 7018 | if (else_expr_result == irb->codegen->invalid_instruction) |
| 6340 | return else_expr_result; | 7019 | return else_expr_result; |
| 6341 | } else { | 7020 | } else { |
| 6342 | else_expr_result = ir_build_const_void(irb, scope, node); | 7021 | else_expr_result = ir_build_const_void(irb, scope, node); |
| | 7022 | ir_build_end_expr(irb, scope, node, else_expr_result, &peer_parent->peers.at(1)->base); |
| 6343 | } | 7023 | } |
| 6344 | IrBasicBlock *after_else_block = irb->current_basic_block; | 7024 | IrBasicBlock *after_else_block = irb->current_basic_block; |
| 6345 | if (!instr_is_unreachable(else_expr_result)) | 7025 | if (!instr_is_unreachable(else_expr_result)) |
| ... | @@ -6353,14 +7033,15 @@ static IrInstruction *ir_gen_if_err_expr(IrBuilder *irb, Scope *scope, AstNode * | ... | @@ -6353,14 +7033,15 @@ static IrInstruction *ir_gen_if_err_expr(IrBuilder *irb, Scope *scope, AstNode * |
| 6353 | incoming_blocks[0] = after_then_block; | 7033 | incoming_blocks[0] = after_then_block; |
| 6354 | incoming_blocks[1] = after_else_block; | 7034 | incoming_blocks[1] = after_else_block; |
| 6355 | | 7035 | |
| 6356 | return ir_build_phi(irb, scope, node, 2, incoming_blocks, incoming_values); | 7036 | IrInstruction *phi = ir_build_phi(irb, scope, node, 2, incoming_blocks, incoming_values, peer_parent); |
| | 7037 | return ir_expr_wrap(irb, scope, phi, result_loc); |
| 6357 | } | 7038 | } |
| 6358 | | 7039 | |
| 6359 | static bool ir_gen_switch_prong_expr(IrBuilder *irb, Scope *scope, AstNode *switch_node, AstNode *prong_node, | 7040 | static bool ir_gen_switch_prong_expr(IrBuilder *irb, Scope *scope, AstNode *switch_node, AstNode *prong_node, |
| 6360 | IrBasicBlock *end_block, IrInstruction *is_comptime, IrInstruction *var_is_comptime, | 7041 | IrBasicBlock *end_block, IrInstruction *is_comptime, IrInstruction *var_is_comptime, |
| 6361 | IrInstruction *target_value_ptr, IrInstruction **prong_values, size_t prong_values_len, | 7042 | IrInstruction *target_value_ptr, IrInstruction **prong_values, size_t prong_values_len, |
| 6362 | ZigList<IrBasicBlock *> *incoming_blocks, ZigList<IrInstruction *> *incoming_values, | 7043 | ZigList<IrBasicBlock *> *incoming_blocks, ZigList<IrInstruction *> *incoming_values, |
| 6363 | IrInstructionSwitchElseVar **out_switch_else_var) | 7044 | IrInstructionSwitchElseVar **out_switch_else_var, LVal lval, ResultLoc *result_loc) |
| 6364 | { | 7045 | { |
| 6365 | assert(switch_node->type == NodeTypeSwitchExpr); | 7046 | assert(switch_node->type == NodeTypeSwitchExpr); |
| 6366 | assert(prong_node->type == NodeTypeSwitchProng); | 7047 | assert(prong_node->type == NodeTypeSwitchProng); |
| ... | @@ -6378,28 +7059,27 @@ static bool ir_gen_switch_prong_expr(IrBuilder *irb, Scope *scope, AstNode *swit | ... | @@ -6378,28 +7059,27 @@ static bool ir_gen_switch_prong_expr(IrBuilder *irb, Scope *scope, AstNode *swit |
| 6378 | ZigVar *var = ir_create_var(irb, var_symbol_node, scope, | 7059 | ZigVar *var = ir_create_var(irb, var_symbol_node, scope, |
| 6379 | var_name, is_const, is_const, is_shadowable, var_is_comptime); | 7060 | var_name, is_const, is_const, is_shadowable, var_is_comptime); |
| 6380 | child_scope = var->child_scope; | 7061 | child_scope = var->child_scope; |
| 6381 | IrInstruction *var_value; | 7062 | IrInstruction *var_ptr; |
| 6382 | if (out_switch_else_var != nullptr) { | 7063 | if (out_switch_else_var != nullptr) { |
| 6383 | IrInstructionSwitchElseVar *switch_else_var = ir_build_switch_else_var(irb, scope, var_symbol_node, | 7064 | IrInstructionSwitchElseVar *switch_else_var = ir_build_switch_else_var(irb, scope, var_symbol_node, |
| 6384 | target_value_ptr); | 7065 | target_value_ptr); |
| 6385 | *out_switch_else_var = switch_else_var; | 7066 | *out_switch_else_var = switch_else_var; |
| 6386 | IrInstruction *var_ptr_value = &switch_else_var->base; | 7067 | IrInstruction *payload_ptr = &switch_else_var->base; |
| 6387 | var_value = var_is_ptr ? var_ptr_value : ir_build_load_ptr(irb, scope, var_symbol_node, var_ptr_value); | 7068 | var_ptr = var_is_ptr ? ir_build_ref(irb, scope, var_symbol_node, payload_ptr, true, false) : payload_ptr; |
| 6388 | } else if (prong_values != nullptr) { | 7069 | } else if (prong_values != nullptr) { |
| 6389 | IrInstruction *var_ptr_value = ir_build_switch_var(irb, scope, var_symbol_node, target_value_ptr, | 7070 | IrInstruction *payload_ptr = ir_build_switch_var(irb, scope, var_symbol_node, target_value_ptr, |
| 6390 | prong_values, prong_values_len); | 7071 | prong_values, prong_values_len); |
| 6391 | var_value = var_is_ptr ? var_ptr_value : ir_build_load_ptr(irb, scope, var_symbol_node, var_ptr_value); | 7072 | var_ptr = var_is_ptr ? ir_build_ref(irb, scope, var_symbol_node, payload_ptr, true, false) : payload_ptr; |
| 6392 | } else { | 7073 | } else { |
| 6393 | var_value = var_is_ptr ? target_value_ptr : ir_build_load_ptr(irb, scope, var_symbol_node, | 7074 | var_ptr = var_is_ptr ? |
| 6394 | target_value_ptr); | 7075 | ir_build_ref(irb, scope, var_symbol_node, target_value_ptr, true, false) : target_value_ptr; |
| 6395 | } | 7076 | } |
| 6396 | IrInstruction *var_type = nullptr; // infer the type | 7077 | ir_build_var_decl_src(irb, scope, var_symbol_node, var, nullptr, var_ptr); |
| 6397 | ir_build_var_decl_src(irb, scope, var_symbol_node, var, var_type, nullptr, var_value); | | |
| 6398 | } else { | 7078 | } else { |
| 6399 | child_scope = scope; | 7079 | child_scope = scope; |
| 6400 | } | 7080 | } |
| 6401 | | 7081 | |
| 6402 | IrInstruction *expr_result = ir_gen_node(irb, expr_node, child_scope); | 7082 | IrInstruction *expr_result = ir_gen_node_extra(irb, expr_node, child_scope, lval, result_loc); |
| 6403 | if (expr_result == irb->codegen->invalid_instruction) | 7083 | if (expr_result == irb->codegen->invalid_instruction) |
| 6404 | return false; | 7084 | return false; |
| 6405 | if (!instr_is_unreachable(expr_result)) | 7085 | if (!instr_is_unreachable(expr_result)) |
| ... | @@ -6409,11 +7089,13 @@ target_value_ptr); | ... | @@ -6409,11 +7089,13 @@ target_value_ptr); |
| 6409 | return true; | 7089 | return true; |
| 6410 | } | 7090 | } |
| 6411 | | 7091 | |
| 6412 | static IrInstruction *ir_gen_switch_expr(IrBuilder *irb, Scope *scope, AstNode *node) { | 7092 | static IrInstruction *ir_gen_switch_expr(IrBuilder *irb, Scope *scope, AstNode *node, LVal lval, |
| | 7093 | ResultLoc *result_loc) |
| | 7094 | { |
| 6413 | assert(node->type == NodeTypeSwitchExpr); | 7095 | assert(node->type == NodeTypeSwitchExpr); |
| 6414 | | 7096 | |
| 6415 | AstNode *target_node = node->data.switch_expr.expr; | 7097 | AstNode *target_node = node->data.switch_expr.expr; |
| 6416 | IrInstruction *target_value_ptr = ir_gen_node_extra(irb, target_node, scope, LValPtr); | 7098 | IrInstruction *target_value_ptr = ir_gen_node_extra(irb, target_node, scope, LValPtr, nullptr); |
| 6417 | if (target_value_ptr == irb->codegen->invalid_instruction) | 7099 | if (target_value_ptr == irb->codegen->invalid_instruction) |
| 6418 | return target_value_ptr; | 7100 | return target_value_ptr; |
| 6419 | IrInstruction *target_value = ir_build_switch_target(irb, scope, node, target_value_ptr); | 7101 | IrInstruction *target_value = ir_build_switch_target(irb, scope, node, target_value_ptr); |
| ... | @@ -6440,6 +7122,14 @@ static IrInstruction *ir_gen_switch_expr(IrBuilder *irb, Scope *scope, AstNode * | ... | @@ -6440,6 +7122,14 @@ static IrInstruction *ir_gen_switch_expr(IrBuilder *irb, Scope *scope, AstNode * |
| 6440 | | 7122 | |
| 6441 | IrInstructionSwitchElseVar *switch_else_var = nullptr; | 7123 | IrInstructionSwitchElseVar *switch_else_var = nullptr; |
| 6442 | | 7124 | |
| | 7125 | ResultLocPeerParent *peer_parent = allocate<ResultLocPeerParent>(1); |
| | 7126 | peer_parent->base.id = ResultLocIdPeerParent; |
| | 7127 | peer_parent->end_bb = end_block; |
| | 7128 | peer_parent->is_comptime = is_comptime; |
| | 7129 | peer_parent->parent = result_loc; |
| | 7130 | |
| | 7131 | ir_build_reset_result(irb, scope, node, &peer_parent->base); |
| | 7132 | |
| 6443 | // First do the else and the ranges | 7133 | // First do the else and the ranges |
| 6444 | Scope *subexpr_scope = create_runtime_scope(irb->codegen, node, scope, is_comptime); | 7134 | Scope *subexpr_scope = create_runtime_scope(irb->codegen, node, scope, is_comptime); |
| 6445 | Scope *comptime_scope = create_comptime_scope(irb->codegen, node, scope); | 7135 | Scope *comptime_scope = create_comptime_scope(irb->codegen, node, scope); |
| ... | @@ -6448,6 +7138,7 @@ static IrInstruction *ir_gen_switch_expr(IrBuilder *irb, Scope *scope, AstNode * | ... | @@ -6448,6 +7138,7 @@ static IrInstruction *ir_gen_switch_expr(IrBuilder *irb, Scope *scope, AstNode * |
| 6448 | AstNode *prong_node = node->data.switch_expr.prongs.at(prong_i); | 7138 | AstNode *prong_node = node->data.switch_expr.prongs.at(prong_i); |
| 6449 | size_t prong_item_count = prong_node->data.switch_prong.items.length; | 7139 | size_t prong_item_count = prong_node->data.switch_prong.items.length; |
| 6450 | if (prong_item_count == 0) { | 7140 | if (prong_item_count == 0) { |
| | 7141 | ResultLocPeer *this_peer_result_loc = create_peer_result(peer_parent); |
| 6451 | if (else_prong) { | 7142 | if (else_prong) { |
| 6452 | ErrorMsg *msg = add_node_error(irb->codegen, prong_node, | 7143 | ErrorMsg *msg = add_node_error(irb->codegen, prong_node, |
| 6453 | buf_sprintf("multiple else prongs in switch expression")); | 7144 | buf_sprintf("multiple else prongs in switch expression")); |
| ... | @@ -6458,15 +7149,21 @@ static IrInstruction *ir_gen_switch_expr(IrBuilder *irb, Scope *scope, AstNode * | ... | @@ -6458,15 +7149,21 @@ static IrInstruction *ir_gen_switch_expr(IrBuilder *irb, Scope *scope, AstNode * |
| 6458 | else_prong = prong_node; | 7149 | else_prong = prong_node; |
| 6459 | | 7150 | |
| 6460 | IrBasicBlock *prev_block = irb->current_basic_block; | 7151 | IrBasicBlock *prev_block = irb->current_basic_block; |
| | 7152 | if (peer_parent->peers.length > 0) { |
| | 7153 | peer_parent->peers.last()->next_bb = else_block; |
| | 7154 | } |
| | 7155 | peer_parent->peers.append(this_peer_result_loc); |
| 6461 | ir_set_cursor_at_end_and_append_block(irb, else_block); | 7156 | ir_set_cursor_at_end_and_append_block(irb, else_block); |
| 6462 | if (!ir_gen_switch_prong_expr(irb, subexpr_scope, node, prong_node, end_block, | 7157 | if (!ir_gen_switch_prong_expr(irb, subexpr_scope, node, prong_node, end_block, |
| 6463 | is_comptime, var_is_comptime, target_value_ptr, nullptr, 0, &incoming_blocks, &incoming_values, | 7158 | is_comptime, var_is_comptime, target_value_ptr, nullptr, 0, &incoming_blocks, &incoming_values, |
| 6464 | &switch_else_var)) | 7159 | &switch_else_var, LValNone, &this_peer_result_loc->base)) |
| 6465 | { | 7160 | { |
| 6466 | return irb->codegen->invalid_instruction; | 7161 | return irb->codegen->invalid_instruction; |
| 6467 | } | 7162 | } |
| 6468 | ir_set_cursor_at_end(irb, prev_block); | 7163 | ir_set_cursor_at_end(irb, prev_block); |
| 6469 | } else if (prong_node->data.switch_prong.any_items_are_range) { | 7164 | } else if (prong_node->data.switch_prong.any_items_are_range) { |
| | 7165 | ResultLocPeer *this_peer_result_loc = create_peer_result(peer_parent); |
| | 7166 | |
| 6470 | IrInstruction *ok_bit = nullptr; | 7167 | IrInstruction *ok_bit = nullptr; |
| 6471 | AstNode *last_item_node = nullptr; | 7168 | AstNode *last_item_node = nullptr; |
| 6472 | for (size_t item_i = 0; item_i < prong_item_count; item_i += 1) { | 7169 | for (size_t item_i = 0; item_i < prong_item_count; item_i += 1) { |
| ... | @@ -6523,13 +7220,20 @@ static IrInstruction *ir_gen_switch_expr(IrBuilder *irb, Scope *scope, AstNode * | ... | @@ -6523,13 +7220,20 @@ static IrInstruction *ir_gen_switch_expr(IrBuilder *irb, Scope *scope, AstNode * |
| 6523 | | 7220 | |
| 6524 | assert(ok_bit); | 7221 | assert(ok_bit); |
| 6525 | assert(last_item_node); | 7222 | assert(last_item_node); |
| 6526 | ir_mark_gen(ir_build_cond_br(irb, scope, last_item_node, ok_bit, range_block_yes, | 7223 | IrInstruction *br_inst = ir_mark_gen(ir_build_cond_br(irb, scope, last_item_node, ok_bit, |
| 6527 | range_block_no, is_comptime)); | 7224 | range_block_yes, range_block_no, is_comptime)); |
| | 7225 | if (peer_parent->base.source_instruction == nullptr) { |
| | 7226 | peer_parent->base.source_instruction = br_inst; |
| | 7227 | } |
| 6528 | | 7228 | |
| | 7229 | if (peer_parent->peers.length > 0) { |
| | 7230 | peer_parent->peers.last()->next_bb = range_block_yes; |
| | 7231 | } |
| | 7232 | peer_parent->peers.append(this_peer_result_loc); |
| 6529 | ir_set_cursor_at_end_and_append_block(irb, range_block_yes); | 7233 | ir_set_cursor_at_end_and_append_block(irb, range_block_yes); |
| 6530 | if (!ir_gen_switch_prong_expr(irb, subexpr_scope, node, prong_node, end_block, | 7234 | if (!ir_gen_switch_prong_expr(irb, subexpr_scope, node, prong_node, end_block, |
| 6531 | is_comptime, var_is_comptime, target_value_ptr, nullptr, 0, | 7235 | is_comptime, var_is_comptime, target_value_ptr, nullptr, 0, |
| 6532 | &incoming_blocks, &incoming_values, nullptr)) | 7236 | &incoming_blocks, &incoming_values, nullptr, LValNone, &this_peer_result_loc->base)) |
| 6533 | { | 7237 | { |
| 6534 | return irb->codegen->invalid_instruction; | 7238 | return irb->codegen->invalid_instruction; |
| 6535 | } | 7239 | } |
| ... | @@ -6547,6 +7251,8 @@ static IrInstruction *ir_gen_switch_expr(IrBuilder *irb, Scope *scope, AstNode * | ... | @@ -6547,6 +7251,8 @@ static IrInstruction *ir_gen_switch_expr(IrBuilder *irb, Scope *scope, AstNode * |
| 6547 | if (prong_node->data.switch_prong.any_items_are_range) | 7251 | if (prong_node->data.switch_prong.any_items_are_range) |
| 6548 | continue; | 7252 | continue; |
| 6549 | | 7253 | |
| | 7254 | ResultLocPeer *this_peer_result_loc = create_peer_result(peer_parent); |
| | 7255 | |
| 6550 | IrBasicBlock *prong_block = ir_create_basic_block(irb, scope, "SwitchProng"); | 7256 | IrBasicBlock *prong_block = ir_create_basic_block(irb, scope, "SwitchProng"); |
| 6551 | IrInstruction **items = allocate<IrInstruction *>(prong_item_count); | 7257 | IrInstruction **items = allocate<IrInstruction *>(prong_item_count); |
| 6552 | | 7258 | |
| ... | @@ -6570,10 +7276,14 @@ static IrInstruction *ir_gen_switch_expr(IrBuilder *irb, Scope *scope, AstNode * | ... | @@ -6570,10 +7276,14 @@ static IrInstruction *ir_gen_switch_expr(IrBuilder *irb, Scope *scope, AstNode * |
| 6570 | } | 7276 | } |
| 6571 | | 7277 | |
| 6572 | IrBasicBlock *prev_block = irb->current_basic_block; | 7278 | IrBasicBlock *prev_block = irb->current_basic_block; |
| | 7279 | if (peer_parent->peers.length > 0) { |
| | 7280 | peer_parent->peers.last()->next_bb = prong_block; |
| | 7281 | } |
| | 7282 | peer_parent->peers.append(this_peer_result_loc); |
| 6573 | ir_set_cursor_at_end_and_append_block(irb, prong_block); | 7283 | ir_set_cursor_at_end_and_append_block(irb, prong_block); |
| 6574 | if (!ir_gen_switch_prong_expr(irb, subexpr_scope, node, prong_node, end_block, | 7284 | if (!ir_gen_switch_prong_expr(irb, subexpr_scope, node, prong_node, end_block, |
| 6575 | is_comptime, var_is_comptime, target_value_ptr, items, prong_item_count, | 7285 | is_comptime, var_is_comptime, target_value_ptr, items, prong_item_count, |
| 6576 | &incoming_blocks, &incoming_values, nullptr)) | 7286 | &incoming_blocks, &incoming_values, nullptr, LValNone, &this_peer_result_loc->base)) |
| 6577 | { | 7287 | { |
| 6578 | return irb->codegen->invalid_instruction; | 7288 | return irb->codegen->invalid_instruction; |
| 6579 | } | 7289 | } |
| ... | @@ -6582,38 +7292,57 @@ static IrInstruction *ir_gen_switch_expr(IrBuilder *irb, Scope *scope, AstNode * | ... | @@ -6582,38 +7292,57 @@ static IrInstruction *ir_gen_switch_expr(IrBuilder *irb, Scope *scope, AstNode * |
| 6582 | | 7292 | |
| 6583 | } | 7293 | } |
| 6584 | | 7294 | |
| 6585 | IrInstruction *switch_prongs_void = ir_build_check_switch_prongs(irb, scope, node, target_value, check_ranges.items, check_ranges.length, | 7295 | IrInstruction *switch_prongs_void = ir_build_check_switch_prongs(irb, scope, node, target_value, |
| 6586 | else_prong != nullptr); | 7296 | check_ranges.items, check_ranges.length, else_prong != nullptr); |
| 6587 | | 7297 | |
| | 7298 | IrInstruction *br_instruction; |
| 6588 | if (cases.length == 0) { | 7299 | if (cases.length == 0) { |
| 6589 | ir_build_br(irb, scope, node, else_block, is_comptime); | 7300 | br_instruction = ir_build_br(irb, scope, node, else_block, is_comptime); |
| 6590 | } else { | 7301 | } else { |
| 6591 | IrInstructionSwitchBr *switch_br = ir_build_switch_br(irb, scope, node, target_value, else_block, | 7302 | IrInstructionSwitchBr *switch_br = ir_build_switch_br(irb, scope, node, target_value, else_block, |
| 6592 | cases.length, cases.items, is_comptime, switch_prongs_void); | 7303 | cases.length, cases.items, is_comptime, switch_prongs_void); |
| 6593 | if (switch_else_var != nullptr) { | 7304 | if (switch_else_var != nullptr) { |
| 6594 | switch_else_var->switch_br = switch_br; | 7305 | switch_else_var->switch_br = switch_br; |
| 6595 | } | 7306 | } |
| | 7307 | br_instruction = &switch_br->base; |
| | 7308 | } |
| | 7309 | if (peer_parent->base.source_instruction == nullptr) { |
| | 7310 | peer_parent->base.source_instruction = br_instruction; |
| | 7311 | } |
| | 7312 | for (size_t i = 0; i < peer_parent->peers.length; i += 1) { |
| | 7313 | peer_parent->peers.at(i)->base.source_instruction = peer_parent->base.source_instruction; |
| 6596 | } | 7314 | } |
| 6597 | | 7315 | |
| 6598 | if (!else_prong) { | 7316 | if (!else_prong) { |
| | 7317 | if (peer_parent->peers.length != 0) { |
| | 7318 | peer_parent->peers.last()->next_bb = else_block; |
| | 7319 | } |
| 6599 | ir_set_cursor_at_end_and_append_block(irb, else_block); | 7320 | ir_set_cursor_at_end_and_append_block(irb, else_block); |
| 6600 | ir_build_unreachable(irb, scope, node); | 7321 | ir_build_unreachable(irb, scope, node); |
| | 7322 | } else { |
| | 7323 | if (peer_parent->peers.length != 0) { |
| | 7324 | peer_parent->peers.last()->next_bb = end_block; |
| | 7325 | } |
| 6601 | } | 7326 | } |
| 6602 | | 7327 | |
| 6603 | ir_set_cursor_at_end_and_append_block(irb, end_block); | 7328 | ir_set_cursor_at_end_and_append_block(irb, end_block); |
| 6604 | assert(incoming_blocks.length == incoming_values.length); | 7329 | assert(incoming_blocks.length == incoming_values.length); |
| | 7330 | IrInstruction *result_instruction; |
| 6605 | if (incoming_blocks.length == 0) { | 7331 | if (incoming_blocks.length == 0) { |
| 6606 | return ir_build_const_void(irb, scope, node); | 7332 | result_instruction = ir_build_const_void(irb, scope, node); |
| 6607 | } else { | 7333 | } else { |
| 6608 | return ir_build_phi(irb, scope, node, incoming_blocks.length, incoming_blocks.items, incoming_values.items); | 7334 | result_instruction = ir_build_phi(irb, scope, node, incoming_blocks.length, |
| | 7335 | incoming_blocks.items, incoming_values.items, peer_parent); |
| 6609 | } | 7336 | } |
| | 7337 | return ir_lval_wrap(irb, scope, result_instruction, lval, result_loc); |
| 6610 | } | 7338 | } |
| 6611 | | 7339 | |
| 6612 | static IrInstruction *ir_gen_comptime(IrBuilder *irb, Scope *parent_scope, AstNode *node, LVal lval) { | 7340 | static IrInstruction *ir_gen_comptime(IrBuilder *irb, Scope *parent_scope, AstNode *node, LVal lval) { |
| 6613 | assert(node->type == NodeTypeCompTime); | 7341 | assert(node->type == NodeTypeCompTime); |
| 6614 | | 7342 | |
| 6615 | Scope *child_scope = create_comptime_scope(irb->codegen, node, parent_scope); | 7343 | Scope *child_scope = create_comptime_scope(irb->codegen, node, parent_scope); |
| 6616 | return ir_gen_node_extra(irb, node->data.comptime_expr.expr, child_scope, lval); | 7344 | // purposefully pass null for result_loc and let EndExpr handle it |
| | 7345 | return ir_gen_node_extra(irb, node->data.comptime_expr.expr, child_scope, lval, nullptr); |
| 6617 | } | 7346 | } |
| 6618 | | 7347 | |
| 6619 | static IrInstruction *ir_gen_return_from_block(IrBuilder *irb, Scope *break_scope, AstNode *node, ScopeBlock *block_scope) { | 7348 | static IrInstruction *ir_gen_return_from_block(IrBuilder *irb, Scope *break_scope, AstNode *node, ScopeBlock *block_scope) { |
| ... | @@ -6626,7 +7355,11 @@ static IrInstruction *ir_gen_return_from_block(IrBuilder *irb, Scope *break_scop | ... | @@ -6626,7 +7355,11 @@ static IrInstruction *ir_gen_return_from_block(IrBuilder *irb, Scope *break_scop |
| 6626 | | 7355 | |
| 6627 | IrInstruction *result_value; | 7356 | IrInstruction *result_value; |
| 6628 | if (node->data.break_expr.expr) { | 7357 | if (node->data.break_expr.expr) { |
| 6629 | result_value = ir_gen_node(irb, node->data.break_expr.expr, break_scope); | 7358 | ResultLocPeer *peer_result = create_peer_result(block_scope->peer_parent); |
| | 7359 | block_scope->peer_parent->peers.append(peer_result); |
| | 7360 | |
| | 7361 | result_value = ir_gen_node_extra(irb, node->data.break_expr.expr, break_scope, block_scope->lval, |
| | 7362 | &peer_result->base); |
| 6630 | if (result_value == irb->codegen->invalid_instruction) | 7363 | if (result_value == irb->codegen->invalid_instruction) |
| 6631 | return irb->codegen->invalid_instruction; | 7364 | return irb->codegen->invalid_instruction; |
| 6632 | } else { | 7365 | } else { |
| ... | @@ -6696,7 +7429,11 @@ static IrInstruction *ir_gen_break(IrBuilder *irb, Scope *break_scope, AstNode * | ... | @@ -6696,7 +7429,11 @@ static IrInstruction *ir_gen_break(IrBuilder *irb, Scope *break_scope, AstNode * |
| 6696 | | 7429 | |
| 6697 | IrInstruction *result_value; | 7430 | IrInstruction *result_value; |
| 6698 | if (node->data.break_expr.expr) { | 7431 | if (node->data.break_expr.expr) { |
| 6699 | result_value = ir_gen_node(irb, node->data.break_expr.expr, break_scope); | 7432 | ResultLocPeer *peer_result = create_peer_result(loop_scope->peer_parent); |
| | 7433 | loop_scope->peer_parent->peers.append(peer_result); |
| | 7434 | |
| | 7435 | result_value = ir_gen_node_extra(irb, node->data.break_expr.expr, break_scope, |
| | 7436 | loop_scope->lval, &peer_result->base); |
| 6700 | if (result_value == irb->codegen->invalid_instruction) | 7437 | if (result_value == irb->codegen->invalid_instruction) |
| 6701 | return irb->codegen->invalid_instruction; | 7438 | return irb->codegen->invalid_instruction; |
| 6702 | } else { | 7439 | } else { |
| ... | @@ -6784,7 +7521,7 @@ static IrInstruction *ir_gen_defer(IrBuilder *irb, Scope *parent_scope, AstNode | ... | @@ -6784,7 +7521,7 @@ static IrInstruction *ir_gen_defer(IrBuilder *irb, Scope *parent_scope, AstNode |
| 6784 | return ir_build_const_void(irb, parent_scope, node); | 7521 | return ir_build_const_void(irb, parent_scope, node); |
| 6785 | } | 7522 | } |
| 6786 | | 7523 | |
| 6787 | static IrInstruction *ir_gen_slice(IrBuilder *irb, Scope *scope, AstNode *node) { | 7524 | static IrInstruction *ir_gen_slice(IrBuilder *irb, Scope *scope, AstNode *node, LVal lval, ResultLoc *result_loc) { |
| 6788 | assert(node->type == NodeTypeSliceExpr); | 7525 | assert(node->type == NodeTypeSliceExpr); |
| 6789 | | 7526 | |
| 6790 | AstNodeSliceExpr *slice_expr = &node->data.slice_expr; | 7527 | AstNodeSliceExpr *slice_expr = &node->data.slice_expr; |
| ... | @@ -6792,7 +7529,7 @@ static IrInstruction *ir_gen_slice(IrBuilder *irb, Scope *scope, AstNode *node) | ... | @@ -6792,7 +7529,7 @@ static IrInstruction *ir_gen_slice(IrBuilder *irb, Scope *scope, AstNode *node) |
| 6792 | AstNode *start_node = slice_expr->start; | 7529 | AstNode *start_node = slice_expr->start; |
| 6793 | AstNode *end_node = slice_expr->end; | 7530 | AstNode *end_node = slice_expr->end; |
| 6794 | | 7531 | |
| 6795 | IrInstruction *ptr_value = ir_gen_node_extra(irb, array_node, scope, LValPtr); | 7532 | IrInstruction *ptr_value = ir_gen_node_extra(irb, array_node, scope, LValPtr, nullptr); |
| 6796 | if (ptr_value == irb->codegen->invalid_instruction) | 7533 | if (ptr_value == irb->codegen->invalid_instruction) |
| 6797 | return irb->codegen->invalid_instruction; | 7534 | return irb->codegen->invalid_instruction; |
| 6798 | | 7535 | |
| ... | @@ -6809,11 +7546,14 @@ static IrInstruction *ir_gen_slice(IrBuilder *irb, Scope *scope, AstNode *node) | ... | @@ -6809,11 +7546,14 @@ static IrInstruction *ir_gen_slice(IrBuilder *irb, Scope *scope, AstNode *node) |
| 6809 | end_value = nullptr; | 7546 | end_value = nullptr; |
| 6810 | } | 7547 | } |
| 6811 | | 7548 | |
| 6812 | return ir_build_slice(irb, scope, node, ptr_value, start_value, end_value, true); | 7549 | IrInstruction *slice = ir_build_slice_src(irb, scope, node, ptr_value, start_value, end_value, true, result_loc); |
| | 7550 | return ir_lval_wrap(irb, scope, slice, lval, result_loc); |
| 6813 | } | 7551 | } |
| 6814 | | 7552 | |
| 6815 | static IrInstruction *ir_gen_catch(IrBuilder *irb, Scope *parent_scope, AstNode *node) { | 7553 | static IrInstruction *ir_gen_catch(IrBuilder *irb, Scope *parent_scope, AstNode *node, LVal lval, |
| 6816 | assert(node->type == NodeTypeUnwrapErrorExpr); | 7554 | ResultLoc *result_loc) |
| | 7555 | { |
| | 7556 | assert(node->type == NodeTypeCatchExpr); |
| 6817 | | 7557 | |
| 6818 | AstNode *op1_node = node->data.unwrap_err_expr.op1; | 7558 | AstNode *op1_node = node->data.unwrap_err_expr.op1; |
| 6819 | AstNode *op2_node = node->data.unwrap_err_expr.op2; | 7559 | AstNode *op2_node = node->data.unwrap_err_expr.op2; |
| ... | @@ -6826,16 +7566,15 @@ static IrInstruction *ir_gen_catch(IrBuilder *irb, Scope *parent_scope, AstNode | ... | @@ -6826,16 +7566,15 @@ static IrInstruction *ir_gen_catch(IrBuilder *irb, Scope *parent_scope, AstNode |
| 6826 | add_node_error(irb->codegen, var_node, buf_sprintf("unused variable: '%s'", buf_ptr(var_name))); | 7566 | add_node_error(irb->codegen, var_node, buf_sprintf("unused variable: '%s'", buf_ptr(var_name))); |
| 6827 | return irb->codegen->invalid_instruction; | 7567 | return irb->codegen->invalid_instruction; |
| 6828 | } | 7568 | } |
| 6829 | return ir_gen_catch_unreachable(irb, parent_scope, node, op1_node, LValNone); | 7569 | return ir_gen_catch_unreachable(irb, parent_scope, node, op1_node, lval, result_loc); |
| 6830 | } | 7570 | } |
| 6831 | | 7571 | |
| 6832 | | 7572 | |
| 6833 | IrInstruction *err_union_ptr = ir_gen_node_extra(irb, op1_node, parent_scope, LValPtr); | 7573 | IrInstruction *err_union_ptr = ir_gen_node_extra(irb, op1_node, parent_scope, LValPtr, nullptr); |
| 6834 | if (err_union_ptr == irb->codegen->invalid_instruction) | 7574 | if (err_union_ptr == irb->codegen->invalid_instruction) |
| 6835 | return irb->codegen->invalid_instruction; | 7575 | return irb->codegen->invalid_instruction; |
| 6836 | | 7576 | |
| 6837 | IrInstruction *err_union_val = ir_build_load_ptr(irb, parent_scope, node, err_union_ptr); | 7577 | IrInstruction *is_err = ir_build_test_err_src(irb, parent_scope, node, err_union_ptr, true); |
| 6838 | IrInstruction *is_err = ir_build_test_err(irb, parent_scope, node, err_union_val); | | |
| 6839 | | 7578 | |
| 6840 | IrInstruction *is_comptime; | 7579 | IrInstruction *is_comptime; |
| 6841 | if (ir_should_inline(irb->exec, parent_scope)) { | 7580 | if (ir_should_inline(irb->exec, parent_scope)) { |
| ... | @@ -6847,7 +7586,10 @@ static IrInstruction *ir_gen_catch(IrBuilder *irb, Scope *parent_scope, AstNode | ... | @@ -6847,7 +7586,10 @@ static IrInstruction *ir_gen_catch(IrBuilder *irb, Scope *parent_scope, AstNode |
| 6847 | IrBasicBlock *ok_block = ir_create_basic_block(irb, parent_scope, "UnwrapErrOk"); | 7586 | IrBasicBlock *ok_block = ir_create_basic_block(irb, parent_scope, "UnwrapErrOk"); |
| 6848 | IrBasicBlock *err_block = ir_create_basic_block(irb, parent_scope, "UnwrapErrError"); | 7587 | IrBasicBlock *err_block = ir_create_basic_block(irb, parent_scope, "UnwrapErrError"); |
| 6849 | IrBasicBlock *end_block = ir_create_basic_block(irb, parent_scope, "UnwrapErrEnd"); | 7588 | IrBasicBlock *end_block = ir_create_basic_block(irb, parent_scope, "UnwrapErrEnd"); |
| 6850 | ir_build_cond_br(irb, parent_scope, node, is_err, err_block, ok_block, is_comptime); | 7589 | IrInstruction *cond_br_inst = ir_build_cond_br(irb, parent_scope, node, is_err, err_block, ok_block, is_comptime); |
| | 7590 | |
| | 7591 | ResultLocPeerParent *peer_parent = ir_build_binary_result_peers(irb, cond_br_inst, ok_block, end_block, result_loc, |
| | 7592 | is_comptime); |
| 6851 | | 7593 | |
| 6852 | ir_set_cursor_at_end_and_append_block(irb, err_block); | 7594 | ir_set_cursor_at_end_and_append_block(irb, err_block); |
| 6853 | Scope *err_scope; | 7595 | Scope *err_scope; |
| ... | @@ -6859,12 +7601,12 @@ static IrInstruction *ir_gen_catch(IrBuilder *irb, Scope *parent_scope, AstNode | ... | @@ -6859,12 +7601,12 @@ static IrInstruction *ir_gen_catch(IrBuilder *irb, Scope *parent_scope, AstNode |
| 6859 | ZigVar *var = ir_create_var(irb, node, parent_scope, var_name, | 7601 | ZigVar *var = ir_create_var(irb, node, parent_scope, var_name, |
| 6860 | is_const, is_const, is_shadowable, is_comptime); | 7602 | is_const, is_const, is_shadowable, is_comptime); |
| 6861 | err_scope = var->child_scope; | 7603 | err_scope = var->child_scope; |
| 6862 | IrInstruction *err_val = ir_build_unwrap_err_code(irb, err_scope, node, err_union_ptr); | 7604 | IrInstruction *err_ptr = ir_build_unwrap_err_code(irb, err_scope, node, err_union_ptr); |
| 6863 | ir_build_var_decl_src(irb, err_scope, var_node, var, nullptr, nullptr, err_val); | 7605 | ir_build_var_decl_src(irb, err_scope, var_node, var, nullptr, err_ptr); |
| 6864 | } else { | 7606 | } else { |
| 6865 | err_scope = parent_scope; | 7607 | err_scope = parent_scope; |
| 6866 | } | 7608 | } |
| 6867 | IrInstruction *err_result = ir_gen_node(irb, op2_node, err_scope); | 7609 | IrInstruction *err_result = ir_gen_node_extra(irb, op2_node, err_scope, LValNone, &peer_parent->peers.at(0)->base); |
| 6868 | if (err_result == irb->codegen->invalid_instruction) | 7610 | if (err_result == irb->codegen->invalid_instruction) |
| 6869 | return irb->codegen->invalid_instruction; | 7611 | return irb->codegen->invalid_instruction; |
| 6870 | IrBasicBlock *after_err_block = irb->current_basic_block; | 7612 | IrBasicBlock *after_err_block = irb->current_basic_block; |
| ... | @@ -6872,8 +7614,9 @@ static IrInstruction *ir_gen_catch(IrBuilder *irb, Scope *parent_scope, AstNode | ... | @@ -6872,8 +7614,9 @@ static IrInstruction *ir_gen_catch(IrBuilder *irb, Scope *parent_scope, AstNode |
| 6872 | ir_mark_gen(ir_build_br(irb, err_scope, node, end_block, is_comptime)); | 7614 | ir_mark_gen(ir_build_br(irb, err_scope, node, end_block, is_comptime)); |
| 6873 | | 7615 | |
| 6874 | ir_set_cursor_at_end_and_append_block(irb, ok_block); | 7616 | ir_set_cursor_at_end_and_append_block(irb, ok_block); |
| 6875 | IrInstruction *unwrapped_ptr = ir_build_unwrap_err_payload(irb, parent_scope, node, err_union_ptr, false); | 7617 | IrInstruction *unwrapped_ptr = ir_build_unwrap_err_payload(irb, parent_scope, node, err_union_ptr, false, false); |
| 6876 | IrInstruction *unwrapped_payload = ir_build_load_ptr(irb, parent_scope, node, unwrapped_ptr); | 7618 | IrInstruction *unwrapped_payload = ir_build_load_ptr(irb, parent_scope, node, unwrapped_ptr); |
| | 7619 | ir_build_end_expr(irb, parent_scope, node, unwrapped_payload, &peer_parent->peers.at(1)->base); |
| 6877 | IrBasicBlock *after_ok_block = irb->current_basic_block; | 7620 | IrBasicBlock *after_ok_block = irb->current_basic_block; |
| 6878 | ir_build_br(irb, parent_scope, node, end_block, is_comptime); | 7621 | ir_build_br(irb, parent_scope, node, end_block, is_comptime); |
| 6879 | | 7622 | |
| ... | @@ -6884,7 +7627,8 @@ static IrInstruction *ir_gen_catch(IrBuilder *irb, Scope *parent_scope, AstNode | ... | @@ -6884,7 +7627,8 @@ static IrInstruction *ir_gen_catch(IrBuilder *irb, Scope *parent_scope, AstNode |
| 6884 | IrBasicBlock **incoming_blocks = allocate<IrBasicBlock *>(2); | 7627 | IrBasicBlock **incoming_blocks = allocate<IrBasicBlock *>(2); |
| 6885 | incoming_blocks[0] = after_err_block; | 7628 | incoming_blocks[0] = after_err_block; |
| 6886 | incoming_blocks[1] = after_ok_block; | 7629 | incoming_blocks[1] = after_ok_block; |
| 6887 | return ir_build_phi(irb, parent_scope, node, 2, incoming_blocks, incoming_values); | 7630 | IrInstruction *phi = ir_build_phi(irb, parent_scope, node, 2, incoming_blocks, incoming_values, peer_parent); |
| | 7631 | return ir_lval_wrap(irb, parent_scope, phi, lval, result_loc); |
| 6888 | } | 7632 | } |
| 6889 | | 7633 | |
| 6890 | static bool render_instance_name_recursive(CodeGen *codegen, Buf *name, Scope *outer_scope, Scope *inner_scope) { | 7634 | static bool render_instance_name_recursive(CodeGen *codegen, Buf *name, Scope *outer_scope, Scope *inner_scope) { |
| ... | @@ -7160,7 +7904,7 @@ static IrInstruction *ir_gen_cancel_target(IrBuilder *irb, Scope *scope, AstNode | ... | @@ -7160,7 +7904,7 @@ static IrInstruction *ir_gen_cancel_target(IrBuilder *irb, Scope *scope, AstNode |
| 7160 | IrInstruction *coro_promise_ptr = ir_build_coro_promise(irb, scope, node, casted_target_inst); | 7904 | IrInstruction *coro_promise_ptr = ir_build_coro_promise(irb, scope, node, casted_target_inst); |
| 7161 | Buf *atomic_state_field_name = buf_create_from_str(ATOMIC_STATE_FIELD_NAME); | 7905 | Buf *atomic_state_field_name = buf_create_from_str(ATOMIC_STATE_FIELD_NAME); |
| 7162 | IrInstruction *atomic_state_ptr = ir_build_field_ptr(irb, scope, node, coro_promise_ptr, | 7906 | IrInstruction *atomic_state_ptr = ir_build_field_ptr(irb, scope, node, coro_promise_ptr, |
| 7163 | atomic_state_field_name); | 7907 | atomic_state_field_name, false); |
| 7164 | | 7908 | |
| 7165 | // set the is_canceled bit | 7909 | // set the is_canceled bit |
| 7166 | IrInstruction *prev_atomic_value = ir_build_atomic_rmw(irb, scope, node, | 7910 | IrInstruction *prev_atomic_value = ir_build_atomic_rmw(irb, scope, node, |
| ... | @@ -7239,7 +7983,7 @@ static IrInstruction *ir_gen_resume_target(IrBuilder *irb, Scope *scope, AstNode | ... | @@ -7239,7 +7983,7 @@ static IrInstruction *ir_gen_resume_target(IrBuilder *irb, Scope *scope, AstNode |
| 7239 | IrInstruction *coro_promise_ptr = ir_build_coro_promise(irb, scope, node, casted_target_inst); | 7983 | IrInstruction *coro_promise_ptr = ir_build_coro_promise(irb, scope, node, casted_target_inst); |
| 7240 | Buf *atomic_state_field_name = buf_create_from_str(ATOMIC_STATE_FIELD_NAME); | 7984 | Buf *atomic_state_field_name = buf_create_from_str(ATOMIC_STATE_FIELD_NAME); |
| 7241 | IrInstruction *atomic_state_ptr = ir_build_field_ptr(irb, scope, node, coro_promise_ptr, | 7985 | IrInstruction *atomic_state_ptr = ir_build_field_ptr(irb, scope, node, coro_promise_ptr, |
| 7242 | atomic_state_field_name); | 7986 | atomic_state_field_name, false); |
| 7243 | | 7987 | |
| 7244 | // clear the is_suspended bit | 7988 | // clear the is_suspended bit |
| 7245 | IrInstruction *prev_atomic_value = ir_build_atomic_rmw(irb, scope, node, | 7989 | IrInstruction *prev_atomic_value = ir_build_atomic_rmw(irb, scope, node, |
| ... | @@ -7306,12 +8050,12 @@ static IrInstruction *ir_gen_await_expr(IrBuilder *irb, Scope *scope, AstNode *n | ... | @@ -7306,12 +8050,12 @@ static IrInstruction *ir_gen_await_expr(IrBuilder *irb, Scope *scope, AstNode *n |
| 7306 | | 8050 | |
| 7307 | IrInstruction *coro_promise_ptr = ir_build_coro_promise(irb, scope, node, target_inst); | 8051 | IrInstruction *coro_promise_ptr = ir_build_coro_promise(irb, scope, node, target_inst); |
| 7308 | Buf *result_ptr_field_name = buf_create_from_str(RESULT_PTR_FIELD_NAME); | 8052 | Buf *result_ptr_field_name = buf_create_from_str(RESULT_PTR_FIELD_NAME); |
| 7309 | IrInstruction *result_ptr_field_ptr = ir_build_field_ptr(irb, scope, node, coro_promise_ptr, result_ptr_field_name); | 8053 | IrInstruction *result_ptr_field_ptr = ir_build_field_ptr(irb, scope, node, coro_promise_ptr, result_ptr_field_name, false); |
| 7310 | | 8054 | |
| 7311 | if (irb->codegen->have_err_ret_tracing) { | 8055 | if (irb->codegen->have_err_ret_tracing) { |
| 7312 | IrInstruction *err_ret_trace_ptr = ir_build_error_return_trace(irb, scope, node, IrInstructionErrorReturnTrace::NonNull); | 8056 | IrInstruction *err_ret_trace_ptr = ir_build_error_return_trace(irb, scope, node, IrInstructionErrorReturnTrace::NonNull); |
| 7313 | Buf *err_ret_trace_ptr_field_name = buf_create_from_str(ERR_RET_TRACE_PTR_FIELD_NAME); | 8057 | Buf *err_ret_trace_ptr_field_name = buf_create_from_str(ERR_RET_TRACE_PTR_FIELD_NAME); |
| 7314 | IrInstruction *err_ret_trace_ptr_field_ptr = ir_build_field_ptr(irb, scope, node, coro_promise_ptr, err_ret_trace_ptr_field_name); | 8058 | IrInstruction *err_ret_trace_ptr_field_ptr = ir_build_field_ptr(irb, scope, node, coro_promise_ptr, err_ret_trace_ptr_field_name, false); |
| 7315 | ir_build_store_ptr(irb, scope, node, err_ret_trace_ptr_field_ptr, err_ret_trace_ptr); | 8059 | ir_build_store_ptr(irb, scope, node, err_ret_trace_ptr_field_ptr, err_ret_trace_ptr); |
| 7316 | } | 8060 | } |
| 7317 | | 8061 | |
| ... | @@ -7333,11 +8077,11 @@ static IrInstruction *ir_gen_await_expr(IrBuilder *irb, Scope *scope, AstNode *n | ... | @@ -7333,11 +8077,11 @@ static IrInstruction *ir_gen_await_expr(IrBuilder *irb, Scope *scope, AstNode *n |
| 7333 | | 8077 | |
| 7334 | Buf *atomic_state_field_name = buf_create_from_str(ATOMIC_STATE_FIELD_NAME); | 8078 | Buf *atomic_state_field_name = buf_create_from_str(ATOMIC_STATE_FIELD_NAME); |
| 7335 | IrInstruction *atomic_state_ptr = ir_build_field_ptr(irb, scope, node, coro_promise_ptr, | 8079 | IrInstruction *atomic_state_ptr = ir_build_field_ptr(irb, scope, node, coro_promise_ptr, |
| 7336 | atomic_state_field_name); | 8080 | atomic_state_field_name, false); |
| 7337 | | 8081 | |
| 7338 | IrInstruction *promise_type_val = ir_build_const_type(irb, scope, node, irb->codegen->builtin_types.entry_promise); | 8082 | IrInstruction *promise_type_val = ir_build_const_type(irb, scope, node, irb->codegen->builtin_types.entry_promise); |
| 7339 | IrInstruction *const_bool_false = ir_build_const_bool(irb, scope, node, false); | 8083 | IrInstruction *const_bool_false = ir_build_const_bool(irb, scope, node, false); |
| 7340 | IrInstruction *undefined_value = ir_build_const_undefined(irb, scope, node); | 8084 | IrInstruction *undef = ir_build_const_undefined(irb, scope, node); |
| 7341 | IrInstruction *usize_type_val = ir_build_const_type(irb, scope, node, irb->codegen->builtin_types.entry_usize); | 8085 | IrInstruction *usize_type_val = ir_build_const_type(irb, scope, node, irb->codegen->builtin_types.entry_usize); |
| 7342 | IrInstruction *zero = ir_build_const_usize(irb, scope, node, 0); | 8086 | IrInstruction *zero = ir_build_const_usize(irb, scope, node, 0); |
| 7343 | IrInstruction *inverted_ptr_mask = ir_build_const_usize(irb, scope, node, 0x7); // 0b111 | 8087 | IrInstruction *inverted_ptr_mask = ir_build_const_usize(irb, scope, node, 0x7); // 0b111 |
| ... | @@ -7351,7 +8095,8 @@ static IrInstruction *ir_gen_await_expr(IrBuilder *irb, Scope *scope, AstNode *n | ... | @@ -7351,7 +8095,8 @@ static IrInstruction *ir_gen_await_expr(IrBuilder *irb, Scope *scope, AstNode *n |
| 7351 | IrInstruction *target_promise_type = ir_build_typeof(irb, scope, node, target_inst); | 8095 | IrInstruction *target_promise_type = ir_build_typeof(irb, scope, node, target_inst); |
| 7352 | IrInstruction *promise_result_type = ir_build_promise_result_type(irb, scope, node, target_promise_type); | 8096 | IrInstruction *promise_result_type = ir_build_promise_result_type(irb, scope, node, target_promise_type); |
| 7353 | ir_build_await_bookkeeping(irb, scope, node, promise_result_type); | 8097 | ir_build_await_bookkeeping(irb, scope, node, promise_result_type); |
| 7354 | ir_build_var_decl_src(irb, scope, node, result_var, promise_result_type, nullptr, undefined_value); | 8098 | IrInstruction *undef_promise_result = ir_build_implicit_cast(irb, scope, node, promise_result_type, undef, nullptr); |
| | 8099 | build_decl_var_and_init(irb, scope, node, result_var, undef_promise_result, "result", const_bool_false); |
| 7355 | IrInstruction *my_result_var_ptr = ir_build_var_ptr(irb, scope, node, result_var); | 8100 | IrInstruction *my_result_var_ptr = ir_build_var_ptr(irb, scope, node, result_var); |
| 7356 | ir_build_store_ptr(irb, scope, node, result_ptr_field_ptr, my_result_var_ptr); | 8101 | ir_build_store_ptr(irb, scope, node, result_ptr_field_ptr, my_result_var_ptr); |
| 7357 | IrInstruction *save_token = ir_build_coro_save(irb, scope, node, irb->exec->coro_handle); | 8102 | IrInstruction *save_token = ir_build_coro_save(irb, scope, node, irb->exec->coro_handle); |
| ... | @@ -7386,12 +8131,12 @@ static IrInstruction *ir_gen_await_expr(IrBuilder *irb, Scope *scope, AstNode *n | ... | @@ -7386,12 +8131,12 @@ static IrInstruction *ir_gen_await_expr(IrBuilder *irb, Scope *scope, AstNode *n |
| 7386 | ir_set_cursor_at_end_and_append_block(irb, no_suspend_block); | 8131 | ir_set_cursor_at_end_and_append_block(irb, no_suspend_block); |
| 7387 | if (irb->codegen->have_err_ret_tracing) { | 8132 | if (irb->codegen->have_err_ret_tracing) { |
| 7388 | Buf *err_ret_trace_field_name = buf_create_from_str(ERR_RET_TRACE_FIELD_NAME); | 8133 | Buf *err_ret_trace_field_name = buf_create_from_str(ERR_RET_TRACE_FIELD_NAME); |
| 7389 | IrInstruction *src_err_ret_trace_ptr = ir_build_field_ptr(irb, scope, node, coro_promise_ptr, err_ret_trace_field_name); | 8134 | IrInstruction *src_err_ret_trace_ptr = ir_build_field_ptr(irb, scope, node, coro_promise_ptr, err_ret_trace_field_name, false); |
| 7390 | IrInstruction *dest_err_ret_trace_ptr = ir_build_error_return_trace(irb, scope, node, IrInstructionErrorReturnTrace::NonNull); | 8135 | IrInstruction *dest_err_ret_trace_ptr = ir_build_error_return_trace(irb, scope, node, IrInstructionErrorReturnTrace::NonNull); |
| 7391 | ir_build_merge_err_ret_traces(irb, scope, node, coro_promise_ptr, src_err_ret_trace_ptr, dest_err_ret_trace_ptr); | 8136 | ir_build_merge_err_ret_traces(irb, scope, node, coro_promise_ptr, src_err_ret_trace_ptr, dest_err_ret_trace_ptr); |
| 7392 | } | 8137 | } |
| 7393 | Buf *result_field_name = buf_create_from_str(RESULT_FIELD_NAME); | 8138 | Buf *result_field_name = buf_create_from_str(RESULT_FIELD_NAME); |
| 7394 | IrInstruction *promise_result_ptr = ir_build_field_ptr(irb, scope, node, coro_promise_ptr, result_field_name); | 8139 | IrInstruction *promise_result_ptr = ir_build_field_ptr(irb, scope, node, coro_promise_ptr, result_field_name, false); |
| 7395 | // If the type of the result handle_is_ptr then this does not actually perform a load. But we need it to, | 8140 | // If the type of the result handle_is_ptr then this does not actually perform a load. But we need it to, |
| 7396 | // because we're about to destroy the memory. So we store it into our result variable. | 8141 | // because we're about to destroy the memory. So we store it into our result variable. |
| 7397 | IrInstruction *no_suspend_result = ir_build_load_ptr(irb, scope, node, promise_result_ptr); | 8142 | IrInstruction *no_suspend_result = ir_build_load_ptr(irb, scope, node, promise_result_ptr); |
| ... | @@ -7567,7 +8312,8 @@ static IrInstruction *ir_gen_suspend(IrBuilder *irb, Scope *parent_scope, AstNod | ... | @@ -7567,7 +8312,8 @@ static IrInstruction *ir_gen_suspend(IrBuilder *irb, Scope *parent_scope, AstNod |
| 7567 | incoming_values[0] = const_bool_true; | 8312 | incoming_values[0] = const_bool_true; |
| 7568 | incoming_blocks[1] = post_cancel_awaiter_block; | 8313 | incoming_blocks[1] = post_cancel_awaiter_block; |
| 7569 | incoming_values[1] = const_bool_false; | 8314 | incoming_values[1] = const_bool_false; |
| 7570 | IrInstruction *destroy_ourselves = ir_build_phi(irb, parent_scope, node, 2, incoming_blocks, incoming_values); | 8315 | IrInstruction *destroy_ourselves = ir_build_phi(irb, parent_scope, node, 2, incoming_blocks, incoming_values, |
| | 8316 | nullptr); |
| 7571 | ir_gen_defers_for_block(irb, parent_scope, outer_scope, true); | 8317 | ir_gen_defers_for_block(irb, parent_scope, outer_scope, true); |
| 7572 | ir_mark_gen(ir_build_cond_br(irb, parent_scope, node, destroy_ourselves, irb->exec->coro_final_cleanup_block, irb->exec->coro_early_final, const_bool_false)); | 8318 | ir_mark_gen(ir_build_cond_br(irb, parent_scope, node, destroy_ourselves, irb->exec->coro_final_cleanup_block, irb->exec->coro_early_final, const_bool_false)); |
| 7573 | | 8319 | |
| ... | @@ -7576,7 +8322,7 @@ static IrInstruction *ir_gen_suspend(IrBuilder *irb, Scope *parent_scope, AstNod | ... | @@ -7576,7 +8322,7 @@ static IrInstruction *ir_gen_suspend(IrBuilder *irb, Scope *parent_scope, AstNod |
| 7576 | } | 8322 | } |
| 7577 | | 8323 | |
| 7578 | static IrInstruction *ir_gen_node_raw(IrBuilder *irb, AstNode *node, Scope *scope, | 8324 | static IrInstruction *ir_gen_node_raw(IrBuilder *irb, AstNode *node, Scope *scope, |
| 7579 | LVal lval) | 8325 | LVal lval, ResultLoc *result_loc) |
| 7580 | { | 8326 | { |
| 7581 | assert(scope); | 8327 | assert(scope); |
| 7582 | switch (node->type) { | 8328 | switch (node->type) { |
| ... | @@ -7590,37 +8336,37 @@ static IrInstruction *ir_gen_node_raw(IrBuilder *irb, AstNode *node, Scope *scop | ... | @@ -7590,37 +8336,37 @@ static IrInstruction *ir_gen_node_raw(IrBuilder *irb, AstNode *node, Scope *scop |
| 7590 | case NodeTypeTestDecl: | 8336 | case NodeTypeTestDecl: |
| 7591 | zig_unreachable(); | 8337 | zig_unreachable(); |
| 7592 | case NodeTypeBlock: | 8338 | case NodeTypeBlock: |
| 7593 | return ir_lval_wrap(irb, scope, ir_gen_block(irb, scope, node), lval); | 8339 | return ir_gen_block(irb, scope, node, lval, result_loc); |
| 7594 | case NodeTypeGroupedExpr: | 8340 | case NodeTypeGroupedExpr: |
| 7595 | return ir_gen_node_raw(irb, node->data.grouped_expr, scope, lval); | 8341 | return ir_gen_node_raw(irb, node->data.grouped_expr, scope, lval, result_loc); |
| 7596 | case NodeTypeBinOpExpr: | 8342 | case NodeTypeBinOpExpr: |
| 7597 | return ir_lval_wrap(irb, scope, ir_gen_bin_op(irb, scope, node), lval); | 8343 | return ir_gen_bin_op(irb, scope, node, lval, result_loc); |
| 7598 | case NodeTypeIntLiteral: | 8344 | case NodeTypeIntLiteral: |
| 7599 | return ir_lval_wrap(irb, scope, ir_gen_int_lit(irb, scope, node), lval); | 8345 | return ir_lval_wrap(irb, scope, ir_gen_int_lit(irb, scope, node), lval, result_loc); |
| 7600 | case NodeTypeFloatLiteral: | 8346 | case NodeTypeFloatLiteral: |
| 7601 | return ir_lval_wrap(irb, scope, ir_gen_float_lit(irb, scope, node), lval); | 8347 | return ir_lval_wrap(irb, scope, ir_gen_float_lit(irb, scope, node), lval, result_loc); |
| 7602 | case NodeTypeCharLiteral: | 8348 | case NodeTypeCharLiteral: |
| 7603 | return ir_lval_wrap(irb, scope, ir_gen_char_lit(irb, scope, node), lval); | 8349 | return ir_lval_wrap(irb, scope, ir_gen_char_lit(irb, scope, node), lval, result_loc); |
| 7604 | case NodeTypeSymbol: | 8350 | case NodeTypeSymbol: |
| 7605 | return ir_gen_symbol(irb, scope, node, lval); | 8351 | return ir_gen_symbol(irb, scope, node, lval, result_loc); |
| 7606 | case NodeTypeFnCallExpr: | 8352 | case NodeTypeFnCallExpr: |
| 7607 | return ir_gen_fn_call(irb, scope, node, lval); | 8353 | return ir_gen_fn_call(irb, scope, node, lval, result_loc); |
| 7608 | case NodeTypeIfBoolExpr: | 8354 | case NodeTypeIfBoolExpr: |
| 7609 | return ir_lval_wrap(irb, scope, ir_gen_if_bool_expr(irb, scope, node), lval); | 8355 | return ir_gen_if_bool_expr(irb, scope, node, lval, result_loc); |
| 7610 | case NodeTypePrefixOpExpr: | 8356 | case NodeTypePrefixOpExpr: |
| 7611 | return ir_gen_prefix_op_expr(irb, scope, node, lval); | 8357 | return ir_gen_prefix_op_expr(irb, scope, node, lval, result_loc); |
| 7612 | case NodeTypeContainerInitExpr: | 8358 | case NodeTypeContainerInitExpr: |
| 7613 | return ir_lval_wrap(irb, scope, ir_gen_container_init_expr(irb, scope, node), lval); | 8359 | return ir_gen_container_init_expr(irb, scope, node, lval, result_loc); |
| 7614 | case NodeTypeVariableDeclaration: | 8360 | case NodeTypeVariableDeclaration: |
| 7615 | return ir_lval_wrap(irb, scope, ir_gen_var_decl(irb, scope, node), lval); | 8361 | return ir_gen_var_decl(irb, scope, node); |
| 7616 | case NodeTypeWhileExpr: | 8362 | case NodeTypeWhileExpr: |
| 7617 | return ir_lval_wrap(irb, scope, ir_gen_while_expr(irb, scope, node), lval); | 8363 | return ir_gen_while_expr(irb, scope, node, lval, result_loc); |
| 7618 | case NodeTypeForExpr: | 8364 | case NodeTypeForExpr: |
| 7619 | return ir_lval_wrap(irb, scope, ir_gen_for_expr(irb, scope, node), lval); | 8365 | return ir_gen_for_expr(irb, scope, node, lval, result_loc); |
| 7620 | case NodeTypeArrayAccessExpr: | 8366 | case NodeTypeArrayAccessExpr: |
| 7621 | return ir_gen_array_access(irb, scope, node, lval); | 8367 | return ir_gen_array_access(irb, scope, node, lval, result_loc); |
| 7622 | case NodeTypeReturnExpr: | 8368 | case NodeTypeReturnExpr: |
| 7623 | return ir_gen_return(irb, scope, node, lval); | 8369 | return ir_gen_return(irb, scope, node, lval, result_loc); |
| 7624 | case NodeTypeFieldAccessExpr: | 8370 | case NodeTypeFieldAccessExpr: |
| 7625 | { | 8371 | { |
| 7626 | IrInstruction *ptr_instruction = ir_gen_field_access(irb, scope, node); | 8372 | IrInstruction *ptr_instruction = ir_gen_field_access(irb, scope, node); |
| ... | @@ -7629,86 +8375,89 @@ static IrInstruction *ir_gen_node_raw(IrBuilder *irb, AstNode *node, Scope *scop | ... | @@ -7629,86 +8375,89 @@ static IrInstruction *ir_gen_node_raw(IrBuilder *irb, AstNode *node, Scope *scop |
| 7629 | if (lval == LValPtr) | 8375 | if (lval == LValPtr) |
| 7630 | return ptr_instruction; | 8376 | return ptr_instruction; |
| 7631 | | 8377 | |
| 7632 | return ir_build_load_ptr(irb, scope, node, ptr_instruction); | 8378 | IrInstruction *load_ptr = ir_build_load_ptr(irb, scope, node, ptr_instruction); |
| | 8379 | return ir_expr_wrap(irb, scope, load_ptr, result_loc); |
| 7633 | } | 8380 | } |
| 7634 | case NodeTypePtrDeref: { | 8381 | case NodeTypePtrDeref: { |
| 7635 | AstNode *expr_node = node->data.ptr_deref_expr.target; | 8382 | AstNode *expr_node = node->data.ptr_deref_expr.target; |
| 7636 | IrInstruction *value = ir_gen_node_extra(irb, expr_node, scope, lval); | 8383 | IrInstruction *value = ir_gen_node_extra(irb, expr_node, scope, lval, nullptr); |
| 7637 | if (value == irb->codegen->invalid_instruction) | 8384 | if (value == irb->codegen->invalid_instruction) |
| 7638 | return value; | 8385 | return value; |
| 7639 | | 8386 | |
| 7640 | // We essentially just converted any lvalue from &(x.*) to (&x).*; | 8387 | // We essentially just converted any lvalue from &(x.*) to (&x).*; |
| 7641 | // this inhibits checking that x is a pointer later, so we directly | 8388 | // this inhibits checking that x is a pointer later, so we directly |
| 7642 | // record whether the pointer check is needed | 8389 | // record whether the pointer check is needed |
| 7643 | return ir_build_un_op_lval(irb, scope, node, IrUnOpDereference, value, lval); | 8390 | IrInstruction *un_op = ir_build_un_op_lval(irb, scope, node, IrUnOpDereference, value, lval, result_loc); |
| | 8391 | return ir_expr_wrap(irb, scope, un_op, result_loc); |
| 7644 | } | 8392 | } |
| 7645 | case NodeTypeUnwrapOptional: { | 8393 | case NodeTypeUnwrapOptional: { |
| 7646 | AstNode *expr_node = node->data.unwrap_optional.expr; | 8394 | AstNode *expr_node = node->data.unwrap_optional.expr; |
| 7647 | | 8395 | |
| 7648 | IrInstruction *maybe_ptr = ir_gen_node_extra(irb, expr_node, scope, LValPtr); | 8396 | IrInstruction *maybe_ptr = ir_gen_node_extra(irb, expr_node, scope, LValPtr, nullptr); |
| 7649 | if (maybe_ptr == irb->codegen->invalid_instruction) | 8397 | if (maybe_ptr == irb->codegen->invalid_instruction) |
| 7650 | return irb->codegen->invalid_instruction; | 8398 | return irb->codegen->invalid_instruction; |
| 7651 | | 8399 | |
| 7652 | IrInstruction *unwrapped_ptr = ir_build_optional_unwrap_ptr(irb, scope, node, maybe_ptr, true); | 8400 | IrInstruction *unwrapped_ptr = ir_build_optional_unwrap_ptr(irb, scope, node, maybe_ptr, true, false); |
| 7653 | if (lval == LValPtr) | 8401 | if (lval == LValPtr) |
| 7654 | return unwrapped_ptr; | 8402 | return unwrapped_ptr; |
| 7655 | | 8403 | |
| 7656 | return ir_build_load_ptr(irb, scope, node, unwrapped_ptr); | 8404 | IrInstruction *load_ptr = ir_build_load_ptr(irb, scope, node, unwrapped_ptr); |
| | 8405 | return ir_expr_wrap(irb, scope, load_ptr, result_loc); |
| 7657 | } | 8406 | } |
| 7658 | case NodeTypeBoolLiteral: | 8407 | case NodeTypeBoolLiteral: |
| 7659 | return ir_lval_wrap(irb, scope, ir_gen_bool_literal(irb, scope, node), lval); | 8408 | return ir_lval_wrap(irb, scope, ir_gen_bool_literal(irb, scope, node), lval, result_loc); |
| 7660 | case NodeTypeArrayType: | 8409 | case NodeTypeArrayType: |
| 7661 | return ir_lval_wrap(irb, scope, ir_gen_array_type(irb, scope, node), lval); | 8410 | return ir_lval_wrap(irb, scope, ir_gen_array_type(irb, scope, node), lval, result_loc); |
| 7662 | case NodeTypePointerType: | 8411 | case NodeTypePointerType: |
| 7663 | return ir_lval_wrap(irb, scope, ir_gen_pointer_type(irb, scope, node), lval); | 8412 | return ir_lval_wrap(irb, scope, ir_gen_pointer_type(irb, scope, node), lval, result_loc); |
| 7664 | case NodeTypePromiseType: | 8413 | case NodeTypePromiseType: |
| 7665 | return ir_lval_wrap(irb, scope, ir_gen_promise_type(irb, scope, node), lval); | 8414 | return ir_lval_wrap(irb, scope, ir_gen_promise_type(irb, scope, node), lval, result_loc); |
| 7666 | case NodeTypeStringLiteral: | 8415 | case NodeTypeStringLiteral: |
| 7667 | return ir_lval_wrap(irb, scope, ir_gen_string_literal(irb, scope, node), lval); | 8416 | return ir_lval_wrap(irb, scope, ir_gen_string_literal(irb, scope, node), lval, result_loc); |
| 7668 | case NodeTypeUndefinedLiteral: | 8417 | case NodeTypeUndefinedLiteral: |
| 7669 | return ir_lval_wrap(irb, scope, ir_gen_undefined_literal(irb, scope, node), lval); | 8418 | return ir_lval_wrap(irb, scope, ir_gen_undefined_literal(irb, scope, node), lval, result_loc); |
| 7670 | case NodeTypeAsmExpr: | 8419 | case NodeTypeAsmExpr: |
| 7671 | return ir_lval_wrap(irb, scope, ir_gen_asm_expr(irb, scope, node), lval); | 8420 | return ir_lval_wrap(irb, scope, ir_gen_asm_expr(irb, scope, node), lval, result_loc); |
| 7672 | case NodeTypeNullLiteral: | 8421 | case NodeTypeNullLiteral: |
| 7673 | return ir_lval_wrap(irb, scope, ir_gen_null_literal(irb, scope, node), lval); | 8422 | return ir_lval_wrap(irb, scope, ir_gen_null_literal(irb, scope, node), lval, result_loc); |
| 7674 | case NodeTypeIfErrorExpr: | 8423 | case NodeTypeIfErrorExpr: |
| 7675 | return ir_lval_wrap(irb, scope, ir_gen_if_err_expr(irb, scope, node), lval); | 8424 | return ir_gen_if_err_expr(irb, scope, node, lval, result_loc); |
| 7676 | case NodeTypeIfOptional: | 8425 | case NodeTypeIfOptional: |
| 7677 | return ir_lval_wrap(irb, scope, ir_gen_if_optional_expr(irb, scope, node), lval); | 8426 | return ir_gen_if_optional_expr(irb, scope, node, lval, result_loc); |
| 7678 | case NodeTypeSwitchExpr: | 8427 | case NodeTypeSwitchExpr: |
| 7679 | return ir_lval_wrap(irb, scope, ir_gen_switch_expr(irb, scope, node), lval); | 8428 | return ir_gen_switch_expr(irb, scope, node, lval, result_loc); |
| 7680 | case NodeTypeCompTime: | 8429 | case NodeTypeCompTime: |
| 7681 | return ir_gen_comptime(irb, scope, node, lval); | 8430 | return ir_expr_wrap(irb, scope, ir_gen_comptime(irb, scope, node, lval), result_loc); |
| 7682 | case NodeTypeErrorType: | 8431 | case NodeTypeErrorType: |
| 7683 | return ir_lval_wrap(irb, scope, ir_gen_error_type(irb, scope, node), lval); | 8432 | return ir_lval_wrap(irb, scope, ir_gen_error_type(irb, scope, node), lval, result_loc); |
| 7684 | case NodeTypeBreak: | 8433 | case NodeTypeBreak: |
| 7685 | return ir_lval_wrap(irb, scope, ir_gen_break(irb, scope, node), lval); | 8434 | return ir_lval_wrap(irb, scope, ir_gen_break(irb, scope, node), lval, result_loc); |
| 7686 | case NodeTypeContinue: | 8435 | case NodeTypeContinue: |
| 7687 | return ir_lval_wrap(irb, scope, ir_gen_continue(irb, scope, node), lval); | 8436 | return ir_lval_wrap(irb, scope, ir_gen_continue(irb, scope, node), lval, result_loc); |
| 7688 | case NodeTypeUnreachable: | 8437 | case NodeTypeUnreachable: |
| 7689 | return ir_lval_wrap(irb, scope, ir_build_unreachable(irb, scope, node), lval); | 8438 | return ir_build_unreachable(irb, scope, node); |
| 7690 | case NodeTypeDefer: | 8439 | case NodeTypeDefer: |
| 7691 | return ir_lval_wrap(irb, scope, ir_gen_defer(irb, scope, node), lval); | 8440 | return ir_lval_wrap(irb, scope, ir_gen_defer(irb, scope, node), lval, result_loc); |
| 7692 | case NodeTypeSliceExpr: | 8441 | case NodeTypeSliceExpr: |
| 7693 | return ir_lval_wrap(irb, scope, ir_gen_slice(irb, scope, node), lval); | 8442 | return ir_gen_slice(irb, scope, node, lval, result_loc); |
| 7694 | case NodeTypeUnwrapErrorExpr: | 8443 | case NodeTypeCatchExpr: |
| 7695 | return ir_lval_wrap(irb, scope, ir_gen_catch(irb, scope, node), lval); | 8444 | return ir_gen_catch(irb, scope, node, lval, result_loc); |
| 7696 | case NodeTypeContainerDecl: | 8445 | case NodeTypeContainerDecl: |
| 7697 | return ir_lval_wrap(irb, scope, ir_gen_container_decl(irb, scope, node), lval); | 8446 | return ir_lval_wrap(irb, scope, ir_gen_container_decl(irb, scope, node), lval, result_loc); |
| 7698 | case NodeTypeFnProto: | 8447 | case NodeTypeFnProto: |
| 7699 | return ir_lval_wrap(irb, scope, ir_gen_fn_proto(irb, scope, node), lval); | 8448 | return ir_lval_wrap(irb, scope, ir_gen_fn_proto(irb, scope, node), lval, result_loc); |
| 7700 | case NodeTypeErrorSetDecl: | 8449 | case NodeTypeErrorSetDecl: |
| 7701 | return ir_lval_wrap(irb, scope, ir_gen_err_set_decl(irb, scope, node), lval); | 8450 | return ir_lval_wrap(irb, scope, ir_gen_err_set_decl(irb, scope, node), lval, result_loc); |
| 7702 | case NodeTypeCancel: | 8451 | case NodeTypeCancel: |
| 7703 | return ir_lval_wrap(irb, scope, ir_gen_cancel(irb, scope, node), lval); | 8452 | return ir_lval_wrap(irb, scope, ir_gen_cancel(irb, scope, node), lval, result_loc); |
| 7704 | case NodeTypeResume: | 8453 | case NodeTypeResume: |
| 7705 | return ir_lval_wrap(irb, scope, ir_gen_resume(irb, scope, node), lval); | 8454 | return ir_lval_wrap(irb, scope, ir_gen_resume(irb, scope, node), lval, result_loc); |
| 7706 | case NodeTypeAwaitExpr: | 8455 | case NodeTypeAwaitExpr: |
| 7707 | return ir_lval_wrap(irb, scope, ir_gen_await_expr(irb, scope, node), lval); | 8456 | return ir_lval_wrap(irb, scope, ir_gen_await_expr(irb, scope, node), lval, result_loc); |
| 7708 | case NodeTypeSuspend: | 8457 | case NodeTypeSuspend: |
| 7709 | return ir_lval_wrap(irb, scope, ir_gen_suspend(irb, scope, node), lval); | 8458 | return ir_lval_wrap(irb, scope, ir_gen_suspend(irb, scope, node), lval, result_loc); |
| 7710 | case NodeTypeEnumLiteral: | 8459 | case NodeTypeEnumLiteral: |
| 7711 | return ir_lval_wrap(irb, scope, ir_gen_enum_literal(irb, scope, node), lval); | 8460 | return ir_lval_wrap(irb, scope, ir_gen_enum_literal(irb, scope, node), lval, result_loc); |
| 7712 | case NodeTypeInferredArrayType: | 8461 | case NodeTypeInferredArrayType: |
| 7713 | add_node_error(irb->codegen, node, | 8462 | add_node_error(irb->codegen, node, |
| 7714 | buf_sprintf("inferred array size invalid here")); | 8463 | buf_sprintf("inferred array size invalid here")); |
| ... | @@ -7717,14 +8466,28 @@ static IrInstruction *ir_gen_node_raw(IrBuilder *irb, AstNode *node, Scope *scop | ... | @@ -7717,14 +8466,28 @@ static IrInstruction *ir_gen_node_raw(IrBuilder *irb, AstNode *node, Scope *scop |
| 7717 | zig_unreachable(); | 8466 | zig_unreachable(); |
| 7718 | } | 8467 | } |
| 7719 | | 8468 | |
| 7720 | static IrInstruction *ir_gen_node_extra(IrBuilder *irb, AstNode *node, Scope *scope, LVal lval) { | 8469 | static ResultLoc *no_result_loc(void) { |
| 7721 | IrInstruction *result = ir_gen_node_raw(irb, node, scope, lval); | 8470 | ResultLocNone *result_loc_none = allocate<ResultLocNone>(1); |
| | 8471 | result_loc_none->base.id = ResultLocIdNone; |
| | 8472 | return &result_loc_none->base; |
| | 8473 | } |
| | 8474 | |
| | 8475 | static IrInstruction *ir_gen_node_extra(IrBuilder *irb, AstNode *node, Scope *scope, LVal lval, |
| | 8476 | ResultLoc *result_loc) |
| | 8477 | { |
| | 8478 | if (result_loc == nullptr) { |
| | 8479 | // Create a result location indicating there is none - but if one gets created |
| | 8480 | // it will be properly distributed. |
| | 8481 | result_loc = no_result_loc(); |
| | 8482 | ir_build_reset_result(irb, scope, node, result_loc); |
| | 8483 | } |
| | 8484 | IrInstruction *result = ir_gen_node_raw(irb, node, scope, lval, result_loc); |
| 7722 | irb->exec->invalid = irb->exec->invalid || (result == irb->codegen->invalid_instruction); | 8485 | irb->exec->invalid = irb->exec->invalid || (result == irb->codegen->invalid_instruction); |
| 7723 | return result; | 8486 | return result; |
| 7724 | } | 8487 | } |
| 7725 | | 8488 | |
| 7726 | static IrInstruction *ir_gen_node(IrBuilder *irb, AstNode *node, Scope *scope) { | 8489 | static IrInstruction *ir_gen_node(IrBuilder *irb, AstNode *node, Scope *scope) { |
| 7727 | return ir_gen_node_extra(irb, node, scope, LValNone); | 8490 | return ir_gen_node_extra(irb, node, scope, LValNone, nullptr); |
| 7728 | } | 8491 | } |
| 7729 | | 8492 | |
| 7730 | static void invalidate_exec(IrExecutable *exec) { | 8493 | static void invalidate_exec(IrExecutable *exec) { |
| ... | @@ -7775,17 +8538,19 @@ bool ir_gen(CodeGen *codegen, AstNode *node, Scope *scope, IrExecutable *ir_exec | ... | @@ -7775,17 +8538,19 @@ bool ir_gen(CodeGen *codegen, AstNode *node, Scope *scope, IrExecutable *ir_exec |
| 7775 | | 8538 | |
| 7776 | return_type = fn_entry->type_entry->data.fn.fn_type_id.return_type; | 8539 | return_type = fn_entry->type_entry->data.fn.fn_type_id.return_type; |
| 7777 | IrInstruction *undef = ir_build_const_undefined(irb, coro_scope, node); | 8540 | IrInstruction *undef = ir_build_const_undefined(irb, coro_scope, node); |
| | 8541 | // TODO mark this var decl as "no safety" e.g. disable initializing the undef value to 0xaa |
| 7778 | ZigType *coro_frame_type = get_promise_frame_type(irb->codegen, return_type); | 8542 | ZigType *coro_frame_type = get_promise_frame_type(irb->codegen, return_type); |
| 7779 | IrInstruction *coro_frame_type_value = ir_build_const_type(irb, coro_scope, node, coro_frame_type); | 8543 | IrInstruction *coro_frame_type_value = ir_build_const_type(irb, coro_scope, node, coro_frame_type); |
| 7780 | // TODO mark this var decl as "no safety" e.g. disable initializing the undef value to 0xaa | 8544 | IrInstruction *undef_coro_frame = ir_build_implicit_cast(irb, coro_scope, node, coro_frame_type_value, undef, nullptr); |
| 7781 | ir_build_var_decl_src(irb, coro_scope, node, promise_var, coro_frame_type_value, nullptr, undef); | 8545 | build_decl_var_and_init(irb, coro_scope, node, promise_var, undef_coro_frame, "promise", const_bool_false); |
| 7782 | coro_promise_ptr = ir_build_var_ptr(irb, coro_scope, node, promise_var); | 8546 | coro_promise_ptr = ir_build_var_ptr(irb, coro_scope, node, promise_var); |
| 7783 | | 8547 | |
| 7784 | ZigVar *await_handle_var = ir_create_var(irb, node, coro_scope, nullptr, false, false, true, const_bool_false); | 8548 | ZigVar *await_handle_var = ir_create_var(irb, node, coro_scope, nullptr, false, false, true, const_bool_false); |
| 7785 | IrInstruction *null_value = ir_build_const_null(irb, coro_scope, node); | 8549 | IrInstruction *null_value = ir_build_const_null(irb, coro_scope, node); |
| 7786 | IrInstruction *await_handle_type_val = ir_build_const_type(irb, coro_scope, node, | 8550 | IrInstruction *await_handle_type_val = ir_build_const_type(irb, coro_scope, node, |
| 7787 | get_optional_type(irb->codegen, irb->codegen->builtin_types.entry_promise)); | 8551 | get_optional_type(irb->codegen, irb->codegen->builtin_types.entry_promise)); |
| 7788 | ir_build_var_decl_src(irb, coro_scope, node, await_handle_var, await_handle_type_val, nullptr, null_value); | 8552 | IrInstruction *null_await_handle = ir_build_implicit_cast(irb, coro_scope, node, await_handle_type_val, null_value, nullptr); |
| | 8553 | build_decl_var_and_init(irb, coro_scope, node, await_handle_var, null_await_handle, "await_handle", const_bool_false); |
| 7789 | irb->exec->await_handle_var_ptr = ir_build_var_ptr(irb, coro_scope, node, await_handle_var); | 8554 | irb->exec->await_handle_var_ptr = ir_build_var_ptr(irb, coro_scope, node, await_handle_var); |
| 7790 | | 8555 | |
| 7791 | u8_ptr_type = ir_build_const_type(irb, coro_scope, node, | 8556 | u8_ptr_type = ir_build_const_type(irb, coro_scope, node, |
| ... | @@ -7795,13 +8560,14 @@ bool ir_gen(CodeGen *codegen, AstNode *node, Scope *scope, IrExecutable *ir_exec | ... | @@ -7795,13 +8560,14 @@ bool ir_gen(CodeGen *codegen, AstNode *node, Scope *scope, IrExecutable *ir_exec |
| 7795 | coro_id = ir_build_coro_id(irb, coro_scope, node, promise_as_u8_ptr); | 8560 | coro_id = ir_build_coro_id(irb, coro_scope, node, promise_as_u8_ptr); |
| 7796 | coro_size_var = ir_create_var(irb, node, coro_scope, nullptr, false, false, true, const_bool_false); | 8561 | coro_size_var = ir_create_var(irb, node, coro_scope, nullptr, false, false, true, const_bool_false); |
| 7797 | IrInstruction *coro_size = ir_build_coro_size(irb, coro_scope, node); | 8562 | IrInstruction *coro_size = ir_build_coro_size(irb, coro_scope, node); |
| 7798 | ir_build_var_decl_src(irb, coro_scope, node, coro_size_var, nullptr, nullptr, coro_size); | 8563 | build_decl_var_and_init(irb, coro_scope, node, coro_size_var, coro_size, "coro_size", const_bool_false); |
| 7799 | IrInstruction *implicit_allocator_ptr = ir_build_get_implicit_allocator(irb, coro_scope, node, | 8564 | IrInstruction *implicit_allocator_ptr = ir_build_get_implicit_allocator(irb, coro_scope, node, |
| 7800 | ImplicitAllocatorIdArg); | 8565 | ImplicitAllocatorIdArg); |
| 7801 | irb->exec->coro_allocator_var = ir_create_var(irb, node, coro_scope, nullptr, true, true, true, const_bool_false); | 8566 | irb->exec->coro_allocator_var = ir_create_var(irb, node, coro_scope, nullptr, true, true, true, const_bool_false); |
| 7802 | ir_build_var_decl_src(irb, coro_scope, node, irb->exec->coro_allocator_var, nullptr, nullptr, implicit_allocator_ptr); | 8567 | build_decl_var_and_init(irb, coro_scope, node, irb->exec->coro_allocator_var, implicit_allocator_ptr, |
| | 8568 | "allocator", const_bool_false); |
| 7803 | Buf *realloc_field_name = buf_create_from_str(ASYNC_REALLOC_FIELD_NAME); | 8569 | Buf *realloc_field_name = buf_create_from_str(ASYNC_REALLOC_FIELD_NAME); |
| 7804 | IrInstruction *realloc_fn_ptr = ir_build_field_ptr(irb, coro_scope, node, implicit_allocator_ptr, realloc_field_name); | 8570 | IrInstruction *realloc_fn_ptr = ir_build_field_ptr(irb, coro_scope, node, implicit_allocator_ptr, realloc_field_name, false); |
| 7805 | IrInstruction *realloc_fn = ir_build_load_ptr(irb, coro_scope, node, realloc_fn_ptr); | 8571 | IrInstruction *realloc_fn = ir_build_load_ptr(irb, coro_scope, node, realloc_fn_ptr); |
| 7806 | IrInstruction *maybe_coro_mem_ptr = ir_build_coro_alloc_helper(irb, coro_scope, node, realloc_fn, coro_size); | 8572 | IrInstruction *maybe_coro_mem_ptr = ir_build_coro_alloc_helper(irb, coro_scope, node, realloc_fn, coro_size); |
| 7807 | IrInstruction *alloc_result_is_ok = ir_build_test_nonnull(irb, coro_scope, node, maybe_coro_mem_ptr); | 8573 | IrInstruction *alloc_result_is_ok = ir_build_test_nonnull(irb, coro_scope, node, maybe_coro_mem_ptr); |
| ... | @@ -7821,32 +8587,32 @@ bool ir_gen(CodeGen *codegen, AstNode *node, Scope *scope, IrExecutable *ir_exec | ... | @@ -7821,32 +8587,32 @@ bool ir_gen(CodeGen *codegen, AstNode *node, Scope *scope, IrExecutable *ir_exec |
| 7821 | | 8587 | |
| 7822 | Buf *atomic_state_field_name = buf_create_from_str(ATOMIC_STATE_FIELD_NAME); | 8588 | Buf *atomic_state_field_name = buf_create_from_str(ATOMIC_STATE_FIELD_NAME); |
| 7823 | irb->exec->atomic_state_field_ptr = ir_build_field_ptr(irb, scope, node, coro_promise_ptr, | 8589 | irb->exec->atomic_state_field_ptr = ir_build_field_ptr(irb, scope, node, coro_promise_ptr, |
| 7824 | atomic_state_field_name); | 8590 | atomic_state_field_name, false); |
| 7825 | IrInstruction *zero = ir_build_const_usize(irb, scope, node, 0); | 8591 | IrInstruction *zero = ir_build_const_usize(irb, scope, node, 0); |
| 7826 | ir_build_store_ptr(irb, scope, node, irb->exec->atomic_state_field_ptr, zero); | 8592 | ir_build_store_ptr(irb, scope, node, irb->exec->atomic_state_field_ptr, zero); |
| 7827 | Buf *result_field_name = buf_create_from_str(RESULT_FIELD_NAME); | 8593 | Buf *result_field_name = buf_create_from_str(RESULT_FIELD_NAME); |
| 7828 | irb->exec->coro_result_field_ptr = ir_build_field_ptr(irb, scope, node, coro_promise_ptr, result_field_name); | 8594 | irb->exec->coro_result_field_ptr = ir_build_field_ptr(irb, scope, node, coro_promise_ptr, result_field_name, false); |
| 7829 | result_ptr_field_name = buf_create_from_str(RESULT_PTR_FIELD_NAME); | 8595 | result_ptr_field_name = buf_create_from_str(RESULT_PTR_FIELD_NAME); |
| 7830 | irb->exec->coro_result_ptr_field_ptr = ir_build_field_ptr(irb, scope, node, coro_promise_ptr, result_ptr_field_name); | 8596 | irb->exec->coro_result_ptr_field_ptr = ir_build_field_ptr(irb, scope, node, coro_promise_ptr, result_ptr_field_name, false); |
| 7831 | ir_build_store_ptr(irb, scope, node, irb->exec->coro_result_ptr_field_ptr, irb->exec->coro_result_field_ptr); | 8597 | ir_build_store_ptr(irb, scope, node, irb->exec->coro_result_ptr_field_ptr, irb->exec->coro_result_field_ptr); |
| 7832 | if (irb->codegen->have_err_ret_tracing) { | 8598 | if (irb->codegen->have_err_ret_tracing) { |
| 7833 | // initialize the error return trace | 8599 | // initialize the error return trace |
| 7834 | Buf *return_addresses_field_name = buf_create_from_str(RETURN_ADDRESSES_FIELD_NAME); | 8600 | Buf *return_addresses_field_name = buf_create_from_str(RETURN_ADDRESSES_FIELD_NAME); |
| 7835 | IrInstruction *return_addresses_ptr = ir_build_field_ptr(irb, scope, node, coro_promise_ptr, return_addresses_field_name); | 8601 | IrInstruction *return_addresses_ptr = ir_build_field_ptr(irb, scope, node, coro_promise_ptr, return_addresses_field_name, false); |
| 7836 | | 8602 | |
| 7837 | Buf *err_ret_trace_field_name = buf_create_from_str(ERR_RET_TRACE_FIELD_NAME); | 8603 | Buf *err_ret_trace_field_name = buf_create_from_str(ERR_RET_TRACE_FIELD_NAME); |
| 7838 | err_ret_trace_ptr = ir_build_field_ptr(irb, scope, node, coro_promise_ptr, err_ret_trace_field_name); | 8604 | err_ret_trace_ptr = ir_build_field_ptr(irb, scope, node, coro_promise_ptr, err_ret_trace_field_name, false); |
| 7839 | ir_build_mark_err_ret_trace_ptr(irb, scope, node, err_ret_trace_ptr); | 8605 | ir_build_mark_err_ret_trace_ptr(irb, scope, node, err_ret_trace_ptr); |
| 7840 | | 8606 | |
| 7841 | // coordinate with builtin.zig | 8607 | // coordinate with builtin.zig |
| 7842 | Buf *index_name = buf_create_from_str("index"); | 8608 | Buf *index_name = buf_create_from_str("index"); |
| 7843 | IrInstruction *index_ptr = ir_build_field_ptr(irb, scope, node, err_ret_trace_ptr, index_name); | 8609 | IrInstruction *index_ptr = ir_build_field_ptr(irb, scope, node, err_ret_trace_ptr, index_name, false); |
| 7844 | ir_build_store_ptr(irb, scope, node, index_ptr, zero); | 8610 | ir_build_store_ptr(irb, scope, node, index_ptr, zero); |
| 7845 | | 8611 | |
| 7846 | Buf *instruction_addresses_name = buf_create_from_str("instruction_addresses"); | 8612 | Buf *instruction_addresses_name = buf_create_from_str("instruction_addresses"); |
| 7847 | IrInstruction *addrs_slice_ptr = ir_build_field_ptr(irb, scope, node, err_ret_trace_ptr, instruction_addresses_name); | 8613 | IrInstruction *addrs_slice_ptr = ir_build_field_ptr(irb, scope, node, err_ret_trace_ptr, instruction_addresses_name, false); |
| 7848 | | 8614 | |
| 7849 | IrInstruction *slice_value = ir_build_slice(irb, scope, node, return_addresses_ptr, zero, nullptr, false); | 8615 | IrInstruction *slice_value = ir_build_slice_src(irb, scope, node, return_addresses_ptr, zero, nullptr, false, no_result_loc()); |
| 7850 | ir_build_store_ptr(irb, scope, node, addrs_slice_ptr, slice_value); | 8616 | ir_build_store_ptr(irb, scope, node, addrs_slice_ptr, slice_value); |
| 7851 | } | 8617 | } |
| 7852 | | 8618 | |
| ... | @@ -7857,7 +8623,7 @@ bool ir_gen(CodeGen *codegen, AstNode *node, Scope *scope, IrExecutable *ir_exec | ... | @@ -7857,7 +8623,7 @@ bool ir_gen(CodeGen *codegen, AstNode *node, Scope *scope, IrExecutable *ir_exec |
| 7857 | irb->exec->coro_final_cleanup_block = ir_create_basic_block(irb, scope, "FinalCleanup"); | 8623 | irb->exec->coro_final_cleanup_block = ir_create_basic_block(irb, scope, "FinalCleanup"); |
| 7858 | } | 8624 | } |
| 7859 | | 8625 | |
| 7860 | IrInstruction *result = ir_gen_node_extra(irb, node, scope, LValNone); | 8626 | IrInstruction *result = ir_gen_node_extra(irb, node, scope, LValNone, nullptr); |
| 7861 | assert(result); | 8627 | assert(result); |
| 7862 | if (irb->exec->invalid) | 8628 | if (irb->exec->invalid) |
| 7863 | return false; | 8629 | return false; |
| ... | @@ -7905,7 +8671,7 @@ bool ir_gen(CodeGen *codegen, AstNode *node, Scope *scope, IrExecutable *ir_exec | ... | @@ -7905,7 +8671,7 @@ bool ir_gen(CodeGen *codegen, AstNode *node, Scope *scope, IrExecutable *ir_exec |
| 7905 | } | 8671 | } |
| 7906 | if (irb->codegen->have_err_ret_tracing) { | 8672 | if (irb->codegen->have_err_ret_tracing) { |
| 7907 | Buf *err_ret_trace_ptr_field_name = buf_create_from_str(ERR_RET_TRACE_PTR_FIELD_NAME); | 8673 | Buf *err_ret_trace_ptr_field_name = buf_create_from_str(ERR_RET_TRACE_PTR_FIELD_NAME); |
| 7908 | IrInstruction *err_ret_trace_ptr_field_ptr = ir_build_field_ptr(irb, scope, node, coro_promise_ptr, err_ret_trace_ptr_field_name); | 8674 | IrInstruction *err_ret_trace_ptr_field_ptr = ir_build_field_ptr(irb, scope, node, coro_promise_ptr, err_ret_trace_ptr_field_name, false); |
| 7909 | IrInstruction *dest_err_ret_trace_ptr = ir_build_load_ptr(irb, scope, node, err_ret_trace_ptr_field_ptr); | 8675 | IrInstruction *dest_err_ret_trace_ptr = ir_build_load_ptr(irb, scope, node, err_ret_trace_ptr_field_ptr); |
| 7910 | ir_build_merge_err_ret_traces(irb, scope, node, coro_promise_ptr, err_ret_trace_ptr, dest_err_ret_trace_ptr); | 8676 | ir_build_merge_err_ret_traces(irb, scope, node, coro_promise_ptr, err_ret_trace_ptr, dest_err_ret_trace_ptr); |
| 7911 | } | 8677 | } |
| ... | @@ -7913,7 +8679,7 @@ bool ir_gen(CodeGen *codegen, AstNode *node, Scope *scope, IrExecutable *ir_exec | ... | @@ -7913,7 +8679,7 @@ bool ir_gen(CodeGen *codegen, AstNode *node, Scope *scope, IrExecutable *ir_exec |
| 7913 | // a register or local variable which does not get spilled into the frame, | 8679 | // a register or local variable which does not get spilled into the frame, |
| 7914 | // otherwise llvm tries to access memory inside the destroyed frame. | 8680 | // otherwise llvm tries to access memory inside the destroyed frame. |
| 7915 | IrInstruction *unwrapped_await_handle_ptr = ir_build_optional_unwrap_ptr(irb, scope, node, | 8681 | IrInstruction *unwrapped_await_handle_ptr = ir_build_optional_unwrap_ptr(irb, scope, node, |
| 7916 | irb->exec->await_handle_var_ptr, false); | 8682 | irb->exec->await_handle_var_ptr, false, false); |
| 7917 | IrInstruction *await_handle_in_block = ir_build_load_ptr(irb, scope, node, unwrapped_await_handle_ptr); | 8683 | IrInstruction *await_handle_in_block = ir_build_load_ptr(irb, scope, node, unwrapped_await_handle_ptr); |
| 7918 | ir_build_br(irb, scope, node, check_free_block, const_bool_false); | 8684 | ir_build_br(irb, scope, node, check_free_block, const_bool_false); |
| 7919 | | 8685 | |
| ... | @@ -7927,7 +8693,7 @@ bool ir_gen(CodeGen *codegen, AstNode *node, Scope *scope, IrExecutable *ir_exec | ... | @@ -7927,7 +8693,7 @@ bool ir_gen(CodeGen *codegen, AstNode *node, Scope *scope, IrExecutable *ir_exec |
| 7927 | incoming_values[0] = const_bool_false; | 8693 | incoming_values[0] = const_bool_false; |
| 7928 | incoming_blocks[1] = irb->exec->coro_normal_final; | 8694 | incoming_blocks[1] = irb->exec->coro_normal_final; |
| 7929 | incoming_values[1] = const_bool_true; | 8695 | incoming_values[1] = const_bool_true; |
| 7930 | IrInstruction *resume_awaiter = ir_build_phi(irb, scope, node, 2, incoming_blocks, incoming_values); | 8696 | IrInstruction *resume_awaiter = ir_build_phi(irb, scope, node, 2, incoming_blocks, incoming_values, nullptr); |
| 7931 | | 8697 | |
| 7932 | IrBasicBlock **merge_incoming_blocks = allocate<IrBasicBlock *>(2); | 8698 | IrBasicBlock **merge_incoming_blocks = allocate<IrBasicBlock *>(2); |
| 7933 | IrInstruction **merge_incoming_values = allocate<IrInstruction *>(2); | 8699 | IrInstruction **merge_incoming_values = allocate<IrInstruction *>(2); |
| ... | @@ -7935,12 +8701,12 @@ bool ir_gen(CodeGen *codegen, AstNode *node, Scope *scope, IrExecutable *ir_exec | ... | @@ -7935,12 +8701,12 @@ bool ir_gen(CodeGen *codegen, AstNode *node, Scope *scope, IrExecutable *ir_exec |
| 7935 | merge_incoming_values[0] = ir_build_const_undefined(irb, scope, node); | 8701 | merge_incoming_values[0] = ir_build_const_undefined(irb, scope, node); |
| 7936 | merge_incoming_blocks[1] = irb->exec->coro_normal_final; | 8702 | merge_incoming_blocks[1] = irb->exec->coro_normal_final; |
| 7937 | merge_incoming_values[1] = await_handle_in_block; | 8703 | merge_incoming_values[1] = await_handle_in_block; |
| 7938 | IrInstruction *awaiter_handle = ir_build_phi(irb, scope, node, 2, merge_incoming_blocks, merge_incoming_values); | 8704 | IrInstruction *awaiter_handle = ir_build_phi(irb, scope, node, 2, merge_incoming_blocks, merge_incoming_values, nullptr); |
| 7939 | | 8705 | |
| 7940 | Buf *shrink_field_name = buf_create_from_str(ASYNC_SHRINK_FIELD_NAME); | 8706 | Buf *shrink_field_name = buf_create_from_str(ASYNC_SHRINK_FIELD_NAME); |
| 7941 | IrInstruction *implicit_allocator_ptr = ir_build_get_implicit_allocator(irb, scope, node, | 8707 | IrInstruction *implicit_allocator_ptr = ir_build_get_implicit_allocator(irb, scope, node, |
| 7942 | ImplicitAllocatorIdLocalVar); | 8708 | ImplicitAllocatorIdLocalVar); |
| 7943 | IrInstruction *shrink_fn_ptr = ir_build_field_ptr(irb, scope, node, implicit_allocator_ptr, shrink_field_name); | 8709 | IrInstruction *shrink_fn_ptr = ir_build_field_ptr(irb, scope, node, implicit_allocator_ptr, shrink_field_name, false); |
| 7944 | IrInstruction *shrink_fn = ir_build_load_ptr(irb, scope, node, shrink_fn_ptr); | 8710 | IrInstruction *shrink_fn = ir_build_load_ptr(irb, scope, node, shrink_fn_ptr); |
| 7945 | IrInstruction *zero = ir_build_const_usize(irb, scope, node, 0); | 8711 | IrInstruction *zero = ir_build_const_usize(irb, scope, node, 0); |
| 7946 | IrInstruction *coro_mem_ptr_maybe = ir_build_coro_free(irb, scope, node, coro_id, irb->exec->coro_handle); | 8712 | IrInstruction *coro_mem_ptr_maybe = ir_build_coro_free(irb, scope, node, coro_id, irb->exec->coro_handle); |
| ... | @@ -7952,7 +8718,8 @@ bool ir_gen(CodeGen *codegen, AstNode *node, Scope *scope, IrExecutable *ir_exec | ... | @@ -7952,7 +8718,8 @@ bool ir_gen(CodeGen *codegen, AstNode *node, Scope *scope, IrExecutable *ir_exec |
| 7952 | IrInstruction *coro_mem_ptr_ref = ir_build_ref(irb, scope, node, coro_mem_ptr, true, false); | 8718 | IrInstruction *coro_mem_ptr_ref = ir_build_ref(irb, scope, node, coro_mem_ptr, true, false); |
| 7953 | IrInstruction *coro_size_ptr = ir_build_var_ptr(irb, scope, node, coro_size_var); | 8719 | IrInstruction *coro_size_ptr = ir_build_var_ptr(irb, scope, node, coro_size_var); |
| 7954 | IrInstruction *coro_size = ir_build_load_ptr(irb, scope, node, coro_size_ptr); | 8720 | IrInstruction *coro_size = ir_build_load_ptr(irb, scope, node, coro_size_ptr); |
| 7955 | IrInstruction *mem_slice = ir_build_slice(irb, scope, node, coro_mem_ptr_ref, zero, coro_size, false); | 8721 | IrInstruction *mem_slice = ir_build_slice_src(irb, scope, node, coro_mem_ptr_ref, zero, coro_size, false, |
| | 8722 | no_result_loc()); |
| 7956 | size_t arg_count = 5; | 8723 | size_t arg_count = 5; |
| 7957 | IrInstruction **args = allocate<IrInstruction *>(arg_count); | 8724 | IrInstruction **args = allocate<IrInstruction *>(arg_count); |
| 7958 | args[0] = implicit_allocator_ptr; // self | 8725 | args[0] = implicit_allocator_ptr; // self |
| ... | @@ -7966,7 +8733,8 @@ bool ir_gen(CodeGen *codegen, AstNode *node, Scope *scope, IrExecutable *ir_exec | ... | @@ -7966,7 +8733,8 @@ bool ir_gen(CodeGen *codegen, AstNode *node, Scope *scope, IrExecutable *ir_exec |
| 7966 | // non-allocating. Basically coroutines are not supported right now until they are reworked. | 8733 | // non-allocating. Basically coroutines are not supported right now until they are reworked. |
| 7967 | args[3] = ir_build_const_usize(irb, scope, node, 1); // new_size | 8734 | args[3] = ir_build_const_usize(irb, scope, node, 1); // new_size |
| 7968 | args[4] = ir_build_const_usize(irb, scope, node, 1); // new_align | 8735 | args[4] = ir_build_const_usize(irb, scope, node, 1); // new_align |
| 7969 | ir_build_call(irb, scope, node, nullptr, shrink_fn, arg_count, args, false, FnInlineAuto, false, nullptr, nullptr); | 8736 | ir_build_call_src(irb, scope, node, nullptr, shrink_fn, arg_count, args, false, FnInlineAuto, false, nullptr, |
| | 8737 | nullptr, no_result_loc()); |
| 7970 | | 8738 | |
| 7971 | IrBasicBlock *resume_block = ir_create_basic_block(irb, scope, "Resume"); | 8739 | IrBasicBlock *resume_block = ir_create_basic_block(irb, scope, "Resume"); |
| 7972 | ir_build_cond_br(irb, scope, node, resume_awaiter, resume_block, irb->exec->coro_suspend_block, const_bool_false); | 8740 | ir_build_cond_br(irb, scope, node, resume_awaiter, resume_block, irb->exec->coro_suspend_block, const_bool_false); |
| ... | @@ -8073,6 +8841,15 @@ static ConstExprValue *ir_exec_const_result(CodeGen *codegen, IrExecutable *exec | ... | @@ -8073,6 +8841,15 @@ static ConstExprValue *ir_exec_const_result(CodeGen *codegen, IrExecutable *exec |
| 8073 | } | 8841 | } |
| 8074 | return &value->value; | 8842 | return &value->value; |
| 8075 | } else if (ir_has_side_effects(instruction)) { | 8843 | } else if (ir_has_side_effects(instruction)) { |
| | 8844 | if (instr_is_comptime(instruction)) { |
| | 8845 | switch (instruction->id) { |
| | 8846 | case IrInstructionIdUnwrapErrPayload: |
| | 8847 | case IrInstructionIdUnionFieldPtr: |
| | 8848 | continue; |
| | 8849 | default: |
| | 8850 | break; |
| | 8851 | } |
| | 8852 | } |
| 8076 | exec_add_error_node(codegen, exec, instruction->source_node, | 8853 | exec_add_error_node(codegen, exec, instruction->source_node, |
| 8077 | buf_sprintf("unable to evaluate constant expression")); | 8854 | buf_sprintf("unable to evaluate constant expression")); |
| 8078 | return &codegen->invalid_instruction->value; | 8855 | return &codegen->invalid_instruction->value; |
| ... | @@ -9050,15 +9827,6 @@ static bool ir_num_lit_fits_in_other_type(IrAnalyze *ira, IrInstruction *instruc | ... | @@ -9050,15 +9827,6 @@ static bool ir_num_lit_fits_in_other_type(IrAnalyze *ira, IrInstruction *instruc |
| 9050 | return false; | 9827 | return false; |
| 9051 | } | 9828 | } |
| 9052 | | 9829 | |
| 9053 | static bool is_slice(ZigType *type) { | | |
| 9054 | return type->id == ZigTypeIdStruct && type->data.structure.is_slice; | | |
| 9055 | } | | |
| 9056 | | | |
| 9057 | static bool slice_is_const(ZigType *type) { | | |
| 9058 | assert(is_slice(type)); | | |
| 9059 | return type->data.structure.fields[slice_ptr_index].type_entry->data.pointer.is_const; | | |
| 9060 | } | | |
| 9061 | | | |
| 9062 | static bool is_tagged_union(ZigType *type) { | 9830 | static bool is_tagged_union(ZigType *type) { |
| 9063 | if (type->id != ZigTypeIdUnion) | 9831 | if (type->id != ZigTypeIdUnion) |
| 9064 | return false; | 9832 | return false; |
| ... | @@ -9429,9 +10197,21 @@ static ZigType *ir_resolve_peer_types(IrAnalyze *ira, AstNode *source_node, ZigT | ... | @@ -9429,9 +10197,21 @@ static ZigType *ir_resolve_peer_types(IrAnalyze *ira, AstNode *source_node, ZigT |
| 9429 | { | 10197 | { |
| 9430 | Error err; | 10198 | Error err; |
| 9431 | assert(instruction_count >= 1); | 10199 | assert(instruction_count >= 1); |
| 9432 | IrInstruction *prev_inst = instructions[0]; | 10200 | IrInstruction *prev_inst; |
| 9433 | if (type_is_invalid(prev_inst->value.type)) { | 10201 | size_t i = 0; |
| 9434 | return ira->codegen->builtin_types.entry_invalid; | 10202 | for (;;) { |
| | 10203 | prev_inst = instructions[i]; |
| | 10204 | if (type_is_invalid(prev_inst->value.type)) { |
| | 10205 | return ira->codegen->builtin_types.entry_invalid; |
| | 10206 | } |
| | 10207 | if (prev_inst->value.type->id == ZigTypeIdUnreachable) { |
| | 10208 | i += 1; |
| | 10209 | if (i == instruction_count) { |
| | 10210 | return prev_inst->value.type; |
| | 10211 | } |
| | 10212 | continue; |
| | 10213 | } |
| | 10214 | break; |
| 9435 | } | 10215 | } |
| 9436 | ErrorTableEntry **errors = nullptr; | 10216 | ErrorTableEntry **errors = nullptr; |
| 9437 | size_t errors_count = 0; | 10217 | size_t errors_count = 0; |
| ... | @@ -9456,7 +10236,7 @@ static ZigType *ir_resolve_peer_types(IrAnalyze *ira, AstNode *source_node, ZigT | ... | @@ -9456,7 +10236,7 @@ static ZigType *ir_resolve_peer_types(IrAnalyze *ira, AstNode *source_node, ZigT |
| 9456 | | 10236 | |
| 9457 | bool any_are_null = (prev_inst->value.type->id == ZigTypeIdNull); | 10237 | bool any_are_null = (prev_inst->value.type->id == ZigTypeIdNull); |
| 9458 | bool convert_to_const_slice = false; | 10238 | bool convert_to_const_slice = false; |
| 9459 | for (size_t i = 1; i < instruction_count; i += 1) { | 10239 | for (; i < instruction_count; i += 1) { |
| 9460 | IrInstruction *cur_inst = instructions[i]; | 10240 | IrInstruction *cur_inst = instructions[i]; |
| 9461 | ZigType *cur_type = cur_inst->value.type; | 10241 | ZigType *cur_type = cur_inst->value.type; |
| 9462 | ZigType *prev_type = prev_inst->value.type; | 10242 | ZigType *prev_type = prev_inst->value.type; |
| ... | @@ -9475,7 +10255,7 @@ static ZigType *ir_resolve_peer_types(IrAnalyze *ira, AstNode *source_node, ZigT | ... | @@ -9475,7 +10255,7 @@ static ZigType *ir_resolve_peer_types(IrAnalyze *ira, AstNode *source_node, ZigT |
| 9475 | } | 10255 | } |
| 9476 | | 10256 | |
| 9477 | if (prev_type->id == ZigTypeIdErrorSet) { | 10257 | if (prev_type->id == ZigTypeIdErrorSet) { |
| 9478 | assert(err_set_type != nullptr); | 10258 | ir_assert(err_set_type != nullptr, prev_inst); |
| 9479 | if (cur_type->id == ZigTypeIdErrorSet) { | 10259 | if (cur_type->id == ZigTypeIdErrorSet) { |
| 9480 | if (type_is_global_error_set(err_set_type)) { | 10260 | if (type_is_global_error_set(err_set_type)) { |
| 9481 | continue; | 10261 | continue; |
| ... | @@ -9735,6 +10515,7 @@ static ZigType *ir_resolve_peer_types(IrAnalyze *ira, AstNode *source_node, ZigT | ... | @@ -9735,6 +10515,7 @@ static ZigType *ir_resolve_peer_types(IrAnalyze *ira, AstNode *source_node, ZigT |
| 9735 | | 10515 | |
| 9736 | if (prev_type->id == ZigTypeIdNull) { | 10516 | if (prev_type->id == ZigTypeIdNull) { |
| 9737 | prev_inst = cur_inst; | 10517 | prev_inst = cur_inst; |
| | 10518 | any_are_null = true; |
| 9738 | continue; | 10519 | continue; |
| 9739 | } | 10520 | } |
| 9740 | | 10521 | |
| ... | @@ -10049,6 +10830,8 @@ static ZigType *ir_resolve_peer_types(IrAnalyze *ira, AstNode *source_node, ZigT | ... | @@ -10049,6 +10830,8 @@ static ZigType *ir_resolve_peer_types(IrAnalyze *ira, AstNode *source_node, ZigT |
| 10049 | } else if (prev_inst->value.type->id == ZigTypeIdOptional) { | 10830 | } else if (prev_inst->value.type->id == ZigTypeIdOptional) { |
| 10050 | return prev_inst->value.type; | 10831 | return prev_inst->value.type; |
| 10051 | } else { | 10832 | } else { |
| | 10833 | if ((err = type_resolve(ira->codegen, prev_inst->value.type, ResolveStatusSizeKnown))) |
| | 10834 | return ira->codegen->builtin_types.entry_invalid; |
| 10052 | return get_optional_type(ira->codegen, prev_inst->value.type); | 10835 | return get_optional_type(ira->codegen, prev_inst->value.type); |
| 10053 | } | 10836 | } |
| 10054 | } else { | 10837 | } else { |
| ... | @@ -10056,24 +10839,18 @@ static ZigType *ir_resolve_peer_types(IrAnalyze *ira, AstNode *source_node, ZigT | ... | @@ -10056,24 +10839,18 @@ static ZigType *ir_resolve_peer_types(IrAnalyze *ira, AstNode *source_node, ZigT |
| 10056 | } | 10839 | } |
| 10057 | } | 10840 | } |
| 10058 | | 10841 | |
| 10059 | static void ir_add_alloca(IrAnalyze *ira, IrInstruction *instruction, ZigType *type_entry) { | | |
| 10060 | if (type_has_bits(type_entry) && handle_is_ptr(type_entry)) { | | |
| 10061 | ZigFn *fn_entry = exec_fn_entry(ira->new_irb.exec); | | |
| 10062 | if (fn_entry != nullptr) { | | |
| 10063 | fn_entry->alloca_list.append(instruction); | | |
| 10064 | } | | |
| 10065 | } | | |
| 10066 | } | | |
| 10067 | | | |
| 10068 | static void copy_const_val(ConstExprValue *dest, ConstExprValue *src, bool same_global_refs) { | 10842 | static void copy_const_val(ConstExprValue *dest, ConstExprValue *src, bool same_global_refs) { |
| 10069 | ConstGlobalRefs *global_refs = dest->global_refs; | 10843 | ConstGlobalRefs *global_refs = dest->global_refs; |
| 10070 | assert(!same_global_refs || src->global_refs != nullptr); | 10844 | memcpy(dest, src, sizeof(ConstExprValue)); |
| 10071 | *dest = *src; | | |
| 10072 | if (!same_global_refs) { | 10845 | if (!same_global_refs) { |
| 10073 | dest->global_refs = global_refs; | 10846 | dest->global_refs = global_refs; |
| | 10847 | if (src->special == ConstValSpecialUndef) |
| | 10848 | return; |
| 10074 | if (dest->type->id == ZigTypeIdStruct) { | 10849 | if (dest->type->id == ZigTypeIdStruct) { |
| 10075 | dest->data.x_struct.fields = allocate_nonzero<ConstExprValue>(dest->type->data.structure.src_field_count); | 10850 | dest->data.x_struct.fields = create_const_vals(dest->type->data.structure.src_field_count); |
| 10076 | memcpy(dest->data.x_struct.fields, src->data.x_struct.fields, sizeof(ConstExprValue) * dest->type->data.structure.src_field_count); | 10851 | for (size_t i = 0; i < dest->type->data.structure.src_field_count; i += 1) { |
| | 10852 | copy_const_val(&dest->data.x_struct.fields[i], &src->data.x_struct.fields[i], false); |
| | 10853 | } |
| 10077 | } | 10854 | } |
| 10078 | } | 10855 | } |
| 10079 | } | 10856 | } |
| ... | @@ -10091,7 +10868,6 @@ static bool eval_const_expr_implicit_cast(IrAnalyze *ira, IrInstruction *source_ | ... | @@ -10091,7 +10868,6 @@ static bool eval_const_expr_implicit_cast(IrAnalyze *ira, IrInstruction *source_ |
| 10091 | zig_unreachable(); | 10868 | zig_unreachable(); |
| 10092 | case CastOpErrSet: | 10869 | case CastOpErrSet: |
| 10093 | case CastOpBitCast: | 10870 | case CastOpBitCast: |
| 10094 | case CastOpPtrOfArrayToSlice: | | |
| 10095 | zig_panic("TODO"); | 10871 | zig_panic("TODO"); |
| 10096 | case CastOpNoop: | 10872 | case CastOpNoop: |
| 10097 | { | 10873 | { |
| ... | @@ -10191,7 +10967,7 @@ static IrInstruction *ir_const(IrAnalyze *ira, IrInstruction *old_instruction, Z | ... | @@ -10191,7 +10967,7 @@ static IrInstruction *ir_const(IrAnalyze *ira, IrInstruction *old_instruction, Z |
| 10191 | } | 10967 | } |
| 10192 | | 10968 | |
| 10193 | static IrInstruction *ir_resolve_cast(IrAnalyze *ira, IrInstruction *source_instr, IrInstruction *value, | 10969 | static IrInstruction *ir_resolve_cast(IrAnalyze *ira, IrInstruction *source_instr, IrInstruction *value, |
| 10194 | ZigType *wanted_type, CastOp cast_op, bool need_alloca) | 10970 | ZigType *wanted_type, CastOp cast_op) |
| 10195 | { | 10971 | { |
| 10196 | if (instr_is_comptime(value) || !type_has_bits(wanted_type)) { | 10972 | if (instr_is_comptime(value) || !type_has_bits(wanted_type)) { |
| 10197 | IrInstruction *result = ir_const(ira, source_instr, wanted_type); | 10973 | IrInstruction *result = ir_const(ira, source_instr, wanted_type); |
| ... | @@ -10204,9 +10980,6 @@ static IrInstruction *ir_resolve_cast(IrAnalyze *ira, IrInstruction *source_inst | ... | @@ -10204,9 +10980,6 @@ static IrInstruction *ir_resolve_cast(IrAnalyze *ira, IrInstruction *source_inst |
| 10204 | } else { | 10980 | } else { |
| 10205 | IrInstruction *result = ir_build_cast(&ira->new_irb, source_instr->scope, source_instr->source_node, wanted_type, value, cast_op); | 10981 | IrInstruction *result = ir_build_cast(&ira->new_irb, source_instr->scope, source_instr->source_node, wanted_type, value, cast_op); |
| 10206 | result->value.type = wanted_type; | 10982 | result->value.type = wanted_type; |
| 10207 | if (need_alloca) { | | |
| 10208 | ir_add_alloca(ira, result, wanted_type); | | |
| 10209 | } | | |
| 10210 | return result; | 10983 | return result; |
| 10211 | } | 10984 | } |
| 10212 | } | 10985 | } |
| ... | @@ -10248,7 +11021,7 @@ static IrInstruction *ir_resolve_ptr_of_array_to_unknown_len_ptr(IrAnalyze *ira, | ... | @@ -10248,7 +11021,7 @@ static IrInstruction *ir_resolve_ptr_of_array_to_unknown_len_ptr(IrAnalyze *ira, |
| 10248 | } | 11021 | } |
| 10249 | | 11022 | |
| 10250 | static IrInstruction *ir_resolve_ptr_of_array_to_slice(IrAnalyze *ira, IrInstruction *source_instr, | 11023 | static IrInstruction *ir_resolve_ptr_of_array_to_slice(IrAnalyze *ira, IrInstruction *source_instr, |
| 10251 | IrInstruction *value, ZigType *wanted_type) | 11024 | IrInstruction *value, ZigType *wanted_type, ResultLoc *result_loc) |
| 10252 | { | 11025 | { |
| 10253 | Error err; | 11026 | Error err; |
| 10254 | | 11027 | |
| ... | @@ -10279,11 +11052,12 @@ static IrInstruction *ir_resolve_ptr_of_array_to_slice(IrAnalyze *ira, IrInstruc | ... | @@ -10279,11 +11052,12 @@ static IrInstruction *ir_resolve_ptr_of_array_to_slice(IrAnalyze *ira, IrInstruc |
| 10279 | } | 11052 | } |
| 10280 | } | 11053 | } |
| 10281 | | 11054 | |
| 10282 | IrInstruction *result = ir_build_cast(&ira->new_irb, source_instr->scope, source_instr->source_node, | 11055 | if (result_loc == nullptr) result_loc = no_result_loc(); |
| 10283 | wanted_type, value, CastOpPtrOfArrayToSlice); | 11056 | IrInstruction *result_loc_inst = ir_resolve_result(ira, source_instr, result_loc, wanted_type, nullptr, true, false); |
| 10284 | result->value.type = wanted_type; | 11057 | if (type_is_invalid(result_loc_inst->value.type) || instr_is_unreachable(result_loc_inst)) { |
| 10285 | ir_add_alloca(ira, result, wanted_type); | 11058 | return result_loc_inst; |
| 10286 | return result; | 11059 | } |
| | 11060 | return ir_build_ptr_of_array_to_slice(ira, source_instr, wanted_type, value, result_loc_inst); |
| 10287 | } | 11061 | } |
| 10288 | | 11062 | |
| 10289 | static IrBasicBlock *ir_get_new_bb(IrAnalyze *ira, IrBasicBlock *old_bb, IrInstruction *ref_old_instruction) { | 11063 | static IrBasicBlock *ir_get_new_bb(IrAnalyze *ira, IrBasicBlock *old_bb, IrInstruction *ref_old_instruction) { |
| ... | @@ -10315,51 +11089,136 @@ static IrBasicBlock *ir_get_new_bb_runtime(IrAnalyze *ira, IrBasicBlock *old_bb, | ... | @@ -10315,51 +11089,136 @@ static IrBasicBlock *ir_get_new_bb_runtime(IrAnalyze *ira, IrBasicBlock *old_bb, |
| 10315 | } | 11089 | } |
| 10316 | | 11090 | |
| 10317 | static void ir_start_bb(IrAnalyze *ira, IrBasicBlock *old_bb, IrBasicBlock *const_predecessor_bb) { | 11091 | static void ir_start_bb(IrAnalyze *ira, IrBasicBlock *old_bb, IrBasicBlock *const_predecessor_bb) { |
| | 11092 | assert(!old_bb->suspended); |
| 10318 | ira->instruction_index = 0; | 11093 | ira->instruction_index = 0; |
| 10319 | ira->old_irb.current_basic_block = old_bb; | 11094 | ira->old_irb.current_basic_block = old_bb; |
| 10320 | ira->const_predecessor_bb = const_predecessor_bb; | 11095 | ira->const_predecessor_bb = const_predecessor_bb; |
| | 11096 | ira->old_bb_index = old_bb->index; |
| 10321 | } | 11097 | } |
| 10322 | | 11098 | |
| 10323 | static void ir_finish_bb(IrAnalyze *ira) { | 11099 | static IrInstruction *ira_suspend(IrAnalyze *ira, IrInstruction *old_instruction, IrBasicBlock *next_bb, |
| 10324 | ira->new_irb.exec->basic_block_list.append(ira->new_irb.current_basic_block); | 11100 | IrSuspendPosition *suspend_pos) |
| 10325 | ira->instruction_index += 1; | 11101 | { |
| 10326 | while (ira->instruction_index < ira->old_irb.current_basic_block->instruction_list.length) { | 11102 | if (ira->codegen->verbose_ir) { |
| 10327 | IrInstruction *next_instruction = ira->old_irb.current_basic_block->instruction_list.at(ira->instruction_index); | 11103 | fprintf(stderr, "suspend %s_%zu %s_%zu #%zu (%zu,%zu)\n", ira->old_irb.current_basic_block->name_hint, |
| 10328 | if (!next_instruction->is_gen) { | 11104 | ira->old_irb.current_basic_block->debug_id, |
| 10329 | ir_add_error(ira, next_instruction, buf_sprintf("unreachable code")); | 11105 | ira->old_irb.exec->basic_block_list.at(ira->old_bb_index)->name_hint, |
| 10330 | break; | 11106 | ira->old_irb.exec->basic_block_list.at(ira->old_bb_index)->debug_id, |
| 10331 | } | 11107 | ira->old_irb.current_basic_block->instruction_list.at(ira->instruction_index)->debug_id, |
| 10332 | ira->instruction_index += 1; | 11108 | ira->old_bb_index, ira->instruction_index); |
| | 11109 | } |
| | 11110 | suspend_pos->basic_block_index = ira->old_bb_index; |
| | 11111 | suspend_pos->instruction_index = ira->instruction_index; |
| | 11112 | |
| | 11113 | ira->old_irb.current_basic_block->suspended = true; |
| | 11114 | |
| | 11115 | // null next_bb means that the caller plans to call ira_resume before returning |
| | 11116 | if (next_bb != nullptr) { |
| | 11117 | ira->old_bb_index = next_bb->index; |
| | 11118 | ira->old_irb.current_basic_block = ira->old_irb.exec->basic_block_list.at(ira->old_bb_index); |
| | 11119 | assert(ira->old_irb.current_basic_block == next_bb); |
| | 11120 | ira->instruction_index = 0; |
| | 11121 | ira->const_predecessor_bb = nullptr; |
| | 11122 | next_bb->other = ir_get_new_bb_runtime(ira, next_bb, old_instruction); |
| | 11123 | ira->new_irb.current_basic_block = next_bb->other; |
| 10333 | } | 11124 | } |
| | 11125 | return ira->codegen->unreach_instruction; |
| | 11126 | } |
| | 11127 | |
| | 11128 | static IrInstruction *ira_resume(IrAnalyze *ira) { |
| | 11129 | IrSuspendPosition pos = ira->resume_stack.pop(); |
| | 11130 | if (ira->codegen->verbose_ir) { |
| | 11131 | fprintf(stderr, "resume (%zu,%zu) ", pos.basic_block_index, pos.instruction_index); |
| | 11132 | } |
| | 11133 | ira->old_bb_index = pos.basic_block_index; |
| | 11134 | ira->old_irb.current_basic_block = ira->old_irb.exec->basic_block_list.at(ira->old_bb_index); |
| | 11135 | assert(ira->old_irb.current_basic_block->in_resume_stack); |
| | 11136 | ira->old_irb.current_basic_block->in_resume_stack = false; |
| | 11137 | ira->old_irb.current_basic_block->suspended = false; |
| | 11138 | ira->instruction_index = pos.instruction_index; |
| | 11139 | assert(pos.instruction_index < ira->old_irb.current_basic_block->instruction_list.length); |
| | 11140 | if (ira->codegen->verbose_ir) { |
| | 11141 | fprintf(stderr, "%s_%zu #%zu\n", ira->old_irb.current_basic_block->name_hint, |
| | 11142 | ira->old_irb.current_basic_block->debug_id, |
| | 11143 | ira->old_irb.current_basic_block->instruction_list.at(pos.instruction_index)->debug_id); |
| | 11144 | } |
| | 11145 | ira->const_predecessor_bb = nullptr; |
| | 11146 | ira->new_irb.current_basic_block = ira->old_irb.current_basic_block->other; |
| | 11147 | assert(ira->new_irb.current_basic_block != nullptr); |
| | 11148 | return ira->codegen->unreach_instruction; |
| | 11149 | } |
| 10334 | | 11150 | |
| 10335 | size_t my_old_bb_index = ira->old_bb_index; | 11151 | static void ir_start_next_bb(IrAnalyze *ira) { |
| 10336 | ira->old_bb_index += 1; | 11152 | ira->old_bb_index += 1; |
| 10337 | | 11153 | |
| 10338 | bool need_repeat = true; | 11154 | bool need_repeat = true; |
| 10339 | for (;;) { | 11155 | for (;;) { |
| 10340 | while (ira->old_bb_index < ira->old_irb.exec->basic_block_list.length) { | 11156 | while (ira->old_bb_index < ira->old_irb.exec->basic_block_list.length) { |
| 10341 | IrBasicBlock *old_bb = ira->old_irb.exec->basic_block_list.at(ira->old_bb_index); | 11157 | IrBasicBlock *old_bb = ira->old_irb.exec->basic_block_list.at(ira->old_bb_index); |
| 10342 | if (old_bb->other == nullptr) { | 11158 | if (old_bb->other == nullptr && old_bb->suspend_instruction_ref == nullptr) { |
| 10343 | ira->old_bb_index += 1; | 11159 | ira->old_bb_index += 1; |
| 10344 | continue; | 11160 | continue; |
| 10345 | } | 11161 | } |
| 10346 | if (old_bb->other->instruction_list.length != 0 || ira->old_bb_index == my_old_bb_index) { | 11162 | // if it's already started, or |
| | 11163 | // if it's a suspended block, |
| | 11164 | // then skip it |
| | 11165 | if (old_bb->suspended || |
| | 11166 | (old_bb->other != nullptr && old_bb->other->instruction_list.length != 0) || |
| | 11167 | (old_bb->other != nullptr && old_bb->other->already_appended)) |
| | 11168 | { |
| 10347 | ira->old_bb_index += 1; | 11169 | ira->old_bb_index += 1; |
| 10348 | continue; | 11170 | continue; |
| 10349 | } | 11171 | } |
| 10350 | ira->new_irb.current_basic_block = old_bb->other; | | |
| 10351 | | 11172 | |
| | 11173 | // if there is a resume_stack, pop one from there rather than moving on. |
| | 11174 | // the last item of the resume stack will be a basic block that will |
| | 11175 | // move on to the next one below |
| | 11176 | if (ira->resume_stack.length != 0) { |
| | 11177 | ira_resume(ira); |
| | 11178 | return; |
| | 11179 | } |
| | 11180 | |
| | 11181 | if (old_bb->other == nullptr) { |
| | 11182 | old_bb->other = ir_get_new_bb_runtime(ira, old_bb, old_bb->suspend_instruction_ref); |
| | 11183 | } |
| | 11184 | ira->new_irb.current_basic_block = old_bb->other; |
| 10352 | ir_start_bb(ira, old_bb, nullptr); | 11185 | ir_start_bb(ira, old_bb, nullptr); |
| 10353 | return; | 11186 | return; |
| 10354 | } | 11187 | } |
| 10355 | if (!need_repeat) | 11188 | if (!need_repeat) { |
| | 11189 | if (ira->resume_stack.length != 0) { |
| | 11190 | ira_resume(ira); |
| | 11191 | } |
| 10356 | return; | 11192 | return; |
| | 11193 | } |
| 10357 | need_repeat = false; | 11194 | need_repeat = false; |
| 10358 | ira->old_bb_index = 0; | 11195 | ira->old_bb_index = 0; |
| 10359 | continue; | 11196 | continue; |
| 10360 | } | 11197 | } |
| 10361 | } | 11198 | } |
| 10362 | | 11199 | |
| | 11200 | static void ir_finish_bb(IrAnalyze *ira) { |
| | 11201 | if (!ira->new_irb.current_basic_block->already_appended) { |
| | 11202 | ira->new_irb.current_basic_block->already_appended = true; |
| | 11203 | if (ira->codegen->verbose_ir) { |
| | 11204 | fprintf(stderr, "append new bb %s_%zu\n", ira->new_irb.current_basic_block->name_hint, |
| | 11205 | ira->new_irb.current_basic_block->debug_id); |
| | 11206 | } |
| | 11207 | ira->new_irb.exec->basic_block_list.append(ira->new_irb.current_basic_block); |
| | 11208 | } |
| | 11209 | ira->instruction_index += 1; |
| | 11210 | while (ira->instruction_index < ira->old_irb.current_basic_block->instruction_list.length) { |
| | 11211 | IrInstruction *next_instruction = ira->old_irb.current_basic_block->instruction_list.at(ira->instruction_index); |
| | 11212 | if (!next_instruction->is_gen) { |
| | 11213 | ir_add_error(ira, next_instruction, buf_sprintf("unreachable code")); |
| | 11214 | break; |
| | 11215 | } |
| | 11216 | ira->instruction_index += 1; |
| | 11217 | } |
| | 11218 | |
| | 11219 | ir_start_next_bb(ira); |
| | 11220 | } |
| | 11221 | |
| 10363 | static IrInstruction *ir_unreach_error(IrAnalyze *ira) { | 11222 | static IrInstruction *ir_unreach_error(IrAnalyze *ira) { |
| 10364 | ira->old_bb_index = SIZE_MAX; | 11223 | ira->old_bb_index = SIZE_MAX; |
| 10365 | ira->new_irb.exec->invalid = true; | 11224 | ira->new_irb.exec->invalid = true; |
| ... | @@ -10420,6 +11279,12 @@ static IrInstruction *ir_const_undef(IrAnalyze *ira, IrInstruction *source_instr | ... | @@ -10420,6 +11279,12 @@ static IrInstruction *ir_const_undef(IrAnalyze *ira, IrInstruction *source_instr |
| 10420 | return result; | 11279 | return result; |
| 10421 | } | 11280 | } |
| 10422 | | 11281 | |
| | 11282 | static IrInstruction *ir_const_unreachable(IrAnalyze *ira, IrInstruction *source_instruction) { |
| | 11283 | IrInstruction *result = ir_const(ira, source_instruction, ira->codegen->builtin_types.entry_unreachable); |
| | 11284 | result->value.special = ConstValSpecialStatic; |
| | 11285 | return result; |
| | 11286 | } |
| | 11287 | |
| 10423 | static IrInstruction *ir_const_void(IrAnalyze *ira, IrInstruction *source_instruction) { | 11288 | static IrInstruction *ir_const_void(IrAnalyze *ira, IrInstruction *source_instruction) { |
| 10424 | return ir_const(ira, source_instruction, ira->codegen->builtin_types.entry_void); | 11289 | return ir_const(ira, source_instruction, ira->codegen->builtin_types.entry_void); |
| 10425 | } | 11290 | } |
| ... | @@ -10617,7 +11482,7 @@ static ZigFn *ir_resolve_fn(IrAnalyze *ira, IrInstruction *fn_value) { | ... | @@ -10617,7 +11482,7 @@ static ZigFn *ir_resolve_fn(IrAnalyze *ira, IrInstruction *fn_value) { |
| 10617 | } | 11482 | } |
| 10618 | | 11483 | |
| 10619 | static IrInstruction *ir_analyze_optional_wrap(IrAnalyze *ira, IrInstruction *source_instr, IrInstruction *value, | 11484 | static IrInstruction *ir_analyze_optional_wrap(IrAnalyze *ira, IrInstruction *source_instr, IrInstruction *value, |
| 10620 | ZigType *wanted_type) | 11485 | ZigType *wanted_type, ResultLoc *result_loc) |
| 10621 | { | 11486 | { |
| 10622 | assert(wanted_type->id == ZigTypeIdOptional); | 11487 | assert(wanted_type->id == ZigTypeIdOptional); |
| 10623 | | 11488 | |
| ... | @@ -10643,20 +11508,29 @@ static IrInstruction *ir_analyze_optional_wrap(IrAnalyze *ira, IrInstruction *so | ... | @@ -10643,20 +11508,29 @@ static IrInstruction *ir_analyze_optional_wrap(IrAnalyze *ira, IrInstruction *so |
| 10643 | return &const_instruction->base; | 11508 | return &const_instruction->base; |
| 10644 | } | 11509 | } |
| 10645 | | 11510 | |
| 10646 | IrInstruction *result = ir_build_maybe_wrap(&ira->new_irb, source_instr->scope, source_instr->source_node, value); | 11511 | if (result_loc == nullptr && handle_is_ptr(wanted_type)) { |
| 10647 | result->value.type = wanted_type; | 11512 | result_loc = no_result_loc(); |
| | 11513 | } |
| | 11514 | IrInstruction *result_loc_inst = nullptr; |
| | 11515 | if (result_loc != nullptr) { |
| | 11516 | result_loc_inst = ir_resolve_result(ira, source_instr, result_loc, wanted_type, nullptr, true, false); |
| | 11517 | if (type_is_invalid(result_loc_inst->value.type) || instr_is_unreachable(result_loc_inst)) { |
| | 11518 | return result_loc_inst; |
| | 11519 | } |
| | 11520 | } |
| | 11521 | IrInstruction *result = ir_build_optional_wrap(ira, source_instr, wanted_type, value, result_loc_inst); |
| 10648 | result->value.data.rh_maybe = RuntimeHintOptionalNonNull; | 11522 | result->value.data.rh_maybe = RuntimeHintOptionalNonNull; |
| 10649 | ir_add_alloca(ira, result, wanted_type); | | |
| 10650 | return result; | 11523 | return result; |
| 10651 | } | 11524 | } |
| 10652 | | 11525 | |
| 10653 | static IrInstruction *ir_analyze_err_wrap_payload(IrAnalyze *ira, IrInstruction *source_instr, | 11526 | static IrInstruction *ir_analyze_err_wrap_payload(IrAnalyze *ira, IrInstruction *source_instr, |
| 10654 | IrInstruction *value, ZigType *wanted_type) | 11527 | IrInstruction *value, ZigType *wanted_type, ResultLoc *result_loc) |
| 10655 | { | 11528 | { |
| 10656 | assert(wanted_type->id == ZigTypeIdErrorUnion); | 11529 | assert(wanted_type->id == ZigTypeIdErrorUnion); |
| 10657 | | 11530 | |
| | 11531 | ZigType *payload_type = wanted_type->data.error_union.payload_type; |
| | 11532 | ZigType *err_set_type = wanted_type->data.error_union.err_set_type; |
| 10658 | if (instr_is_comptime(value)) { | 11533 | if (instr_is_comptime(value)) { |
| 10659 | ZigType *payload_type = wanted_type->data.error_union.payload_type; | | |
| 10660 | IrInstruction *casted_payload = ir_implicit_cast(ira, value, payload_type); | 11534 | IrInstruction *casted_payload = ir_implicit_cast(ira, value, payload_type); |
| 10661 | if (type_is_invalid(casted_payload->value.type)) | 11535 | if (type_is_invalid(casted_payload->value.type)) |
| 10662 | return ira->codegen->invalid_instruction; | 11536 | return ira->codegen->invalid_instruction; |
| ... | @@ -10666,7 +11540,7 @@ static IrInstruction *ir_analyze_err_wrap_payload(IrAnalyze *ira, IrInstruction | ... | @@ -10666,7 +11540,7 @@ static IrInstruction *ir_analyze_err_wrap_payload(IrAnalyze *ira, IrInstruction |
| 10666 | return ira->codegen->invalid_instruction; | 11540 | return ira->codegen->invalid_instruction; |
| 10667 | | 11541 | |
| 10668 | ConstExprValue *err_set_val = create_const_vals(1); | 11542 | ConstExprValue *err_set_val = create_const_vals(1); |
| 10669 | err_set_val->type = wanted_type->data.error_union.err_set_type; | 11543 | err_set_val->type = err_set_type; |
| 10670 | err_set_val->special = ConstValSpecialStatic; | 11544 | err_set_val->special = ConstValSpecialStatic; |
| 10671 | err_set_val->data.x_err_set = nullptr; | 11545 | err_set_val->data.x_err_set = nullptr; |
| 10672 | | 11546 | |
| ... | @@ -10679,10 +11553,19 @@ static IrInstruction *ir_analyze_err_wrap_payload(IrAnalyze *ira, IrInstruction | ... | @@ -10679,10 +11553,19 @@ static IrInstruction *ir_analyze_err_wrap_payload(IrAnalyze *ira, IrInstruction |
| 10679 | return &const_instruction->base; | 11553 | return &const_instruction->base; |
| 10680 | } | 11554 | } |
| 10681 | | 11555 | |
| 10682 | IrInstruction *result = ir_build_err_wrap_payload(&ira->new_irb, source_instr->scope, source_instr->source_node, value); | 11556 | IrInstruction *result_loc_inst; |
| 10683 | result->value.type = wanted_type; | 11557 | if (handle_is_ptr(wanted_type)) { |
| | 11558 | if (result_loc == nullptr) result_loc = no_result_loc(); |
| | 11559 | result_loc_inst = ir_resolve_result(ira, source_instr, result_loc, wanted_type, nullptr, true, false); |
| | 11560 | if (type_is_invalid(result_loc_inst->value.type) || instr_is_unreachable(result_loc_inst)) { |
| | 11561 | return result_loc_inst; |
| | 11562 | } |
| | 11563 | } else { |
| | 11564 | result_loc_inst = nullptr; |
| | 11565 | } |
| | 11566 | |
| | 11567 | IrInstruction *result = ir_build_err_wrap_payload(ira, source_instr, wanted_type, value, result_loc_inst); |
| 10684 | result->value.data.rh_error_union = RuntimeHintErrorUnionNonError; | 11568 | result->value.data.rh_error_union = RuntimeHintErrorUnionNonError; |
| 10685 | ir_add_alloca(ira, result, wanted_type); | | |
| 10686 | return result; | 11569 | return result; |
| 10687 | } | 11570 | } |
| 10688 | | 11571 | |
| ... | @@ -10729,7 +11612,9 @@ static IrInstruction *ir_analyze_err_set_cast(IrAnalyze *ira, IrInstruction *sou | ... | @@ -10729,7 +11612,9 @@ static IrInstruction *ir_analyze_err_set_cast(IrAnalyze *ira, IrInstruction *sou |
| 10729 | return result; | 11612 | return result; |
| 10730 | } | 11613 | } |
| 10731 | | 11614 | |
| 10732 | static IrInstruction *ir_analyze_err_wrap_code(IrAnalyze *ira, IrInstruction *source_instr, IrInstruction *value, ZigType *wanted_type) { | 11615 | static IrInstruction *ir_analyze_err_wrap_code(IrAnalyze *ira, IrInstruction *source_instr, IrInstruction *value, |
| | 11616 | ZigType *wanted_type, ResultLoc *result_loc) |
| | 11617 | { |
| 10733 | assert(wanted_type->id == ZigTypeIdErrorUnion); | 11618 | assert(wanted_type->id == ZigTypeIdErrorUnion); |
| 10734 | | 11619 | |
| 10735 | IrInstruction *casted_value = ir_implicit_cast(ira, value, wanted_type->data.error_union.err_set_type); | 11620 | IrInstruction *casted_value = ir_implicit_cast(ira, value, wanted_type->data.error_union.err_set_type); |
| ... | @@ -10753,10 +11638,20 @@ static IrInstruction *ir_analyze_err_wrap_code(IrAnalyze *ira, IrInstruction *so | ... | @@ -10753,10 +11638,20 @@ static IrInstruction *ir_analyze_err_wrap_code(IrAnalyze *ira, IrInstruction *so |
| 10753 | return &const_instruction->base; | 11638 | return &const_instruction->base; |
| 10754 | } | 11639 | } |
| 10755 | | 11640 | |
| 10756 | IrInstruction *result = ir_build_err_wrap_code(&ira->new_irb, source_instr->scope, source_instr->source_node, value); | 11641 | IrInstruction *result_loc_inst; |
| 10757 | result->value.type = wanted_type; | 11642 | if (handle_is_ptr(wanted_type)) { |
| | 11643 | if (result_loc == nullptr) result_loc = no_result_loc(); |
| | 11644 | result_loc_inst = ir_resolve_result(ira, source_instr, result_loc, wanted_type, nullptr, true, false); |
| | 11645 | if (type_is_invalid(result_loc_inst->value.type) || instr_is_unreachable(result_loc_inst)) { |
| | 11646 | return result_loc_inst; |
| | 11647 | } |
| | 11648 | } else { |
| | 11649 | result_loc_inst = nullptr; |
| | 11650 | } |
| | 11651 | |
| | 11652 | |
| | 11653 | IrInstruction *result = ir_build_err_wrap_code(ira, source_instr, wanted_type, value, result_loc_inst); |
| 10758 | result->value.data.rh_error_union = RuntimeHintErrorUnionError; | 11654 | result->value.data.rh_error_union = RuntimeHintErrorUnionError; |
| 10759 | ir_add_alloca(ira, result, wanted_type); | | |
| 10760 | return result; | 11655 | return result; |
| 10761 | } | 11656 | } |
| 10762 | | 11657 | |
| ... | @@ -10816,20 +11711,21 @@ static IrInstruction *ir_get_ref(IrAnalyze *ira, IrInstruction *source_instructi | ... | @@ -10816,20 +11711,21 @@ static IrInstruction *ir_get_ref(IrAnalyze *ira, IrInstruction *source_instructi |
| 10816 | | 11711 | |
| 10817 | ZigType *ptr_type = get_pointer_to_type_extra(ira->codegen, value->value.type, | 11712 | ZigType *ptr_type = get_pointer_to_type_extra(ira->codegen, value->value.type, |
| 10818 | is_const, is_volatile, PtrLenSingle, 0, 0, 0, false); | 11713 | is_const, is_volatile, PtrLenSingle, 0, 0, 0, false); |
| 10819 | IrInstruction *new_instruction = ir_build_ref(&ira->new_irb, source_instruction->scope, | 11714 | |
| 10820 | source_instruction->source_node, value, is_const, is_volatile); | 11715 | IrInstruction *result_loc; |
| 10821 | new_instruction->value.type = ptr_type; | | |
| 10822 | new_instruction->value.data.rh_ptr = RuntimeHintPtrStack; | | |
| 10823 | if (type_has_bits(ptr_type) && !handle_is_ptr(value->value.type)) { | 11716 | if (type_has_bits(ptr_type) && !handle_is_ptr(value->value.type)) { |
| 10824 | ZigFn *fn_entry = exec_fn_entry(ira->new_irb.exec); | 11717 | result_loc = ir_resolve_result(ira, source_instruction, no_result_loc(), value->value.type, nullptr, true, false); |
| 10825 | assert(fn_entry); | 11718 | } else { |
| 10826 | fn_entry->alloca_list.append(new_instruction); | 11719 | result_loc = nullptr; |
| 10827 | } | 11720 | } |
| | 11721 | |
| | 11722 | IrInstruction *new_instruction = ir_build_ref_gen(ira, source_instruction, ptr_type, value, result_loc); |
| | 11723 | new_instruction->value.data.rh_ptr = RuntimeHintPtrStack; |
| 10828 | return new_instruction; | 11724 | return new_instruction; |
| 10829 | } | 11725 | } |
| 10830 | | 11726 | |
| 10831 | static IrInstruction *ir_analyze_array_to_slice(IrAnalyze *ira, IrInstruction *source_instr, | 11727 | static IrInstruction *ir_analyze_array_to_slice(IrAnalyze *ira, IrInstruction *source_instr, |
| 10832 | IrInstruction *array_arg, ZigType *wanted_type) | 11728 | IrInstruction *array_arg, ZigType *wanted_type, ResultLoc *result_loc) |
| 10833 | { | 11729 | { |
| 10834 | assert(is_slice(wanted_type)); | 11730 | assert(is_slice(wanted_type)); |
| 10835 | // In this function we honor the const-ness of wanted_type, because | 11731 | // In this function we honor the const-ness of wanted_type, because |
| ... | @@ -10838,7 +11734,7 @@ static IrInstruction *ir_analyze_array_to_slice(IrAnalyze *ira, IrInstruction *s | ... | @@ -10838,7 +11734,7 @@ static IrInstruction *ir_analyze_array_to_slice(IrAnalyze *ira, IrInstruction *s |
| 10838 | IrInstruction *array_ptr = nullptr; | 11734 | IrInstruction *array_ptr = nullptr; |
| 10839 | IrInstruction *array; | 11735 | IrInstruction *array; |
| 10840 | if (array_arg->value.type->id == ZigTypeIdPointer) { | 11736 | if (array_arg->value.type->id == ZigTypeIdPointer) { |
| 10841 | array = ir_get_deref(ira, source_instr, array_arg); | 11737 | array = ir_get_deref(ira, source_instr, array_arg, nullptr); |
| 10842 | array_ptr = array_arg; | 11738 | array_ptr = array_arg; |
| 10843 | } else { | 11739 | } else { |
| 10844 | array = array_arg; | 11740 | array = array_arg; |
| ... | @@ -10861,12 +11757,14 @@ static IrInstruction *ir_analyze_array_to_slice(IrAnalyze *ira, IrInstruction *s | ... | @@ -10861,12 +11757,14 @@ static IrInstruction *ir_analyze_array_to_slice(IrAnalyze *ira, IrInstruction *s |
| 10861 | | 11757 | |
| 10862 | if (!array_ptr) array_ptr = ir_get_ref(ira, source_instr, array, true, false); | 11758 | if (!array_ptr) array_ptr = ir_get_ref(ira, source_instr, array, true, false); |
| 10863 | | 11759 | |
| 10864 | IrInstruction *result = ir_build_slice(&ira->new_irb, source_instr->scope, | 11760 | if (result_loc == nullptr) result_loc = no_result_loc(); |
| 10865 | source_instr->source_node, array_ptr, start, end, false); | 11761 | IrInstruction *result_loc_inst = ir_resolve_result(ira, source_instr, result_loc, wanted_type, nullptr, true, false); |
| 10866 | result->value.type = wanted_type; | 11762 | if (type_is_invalid(result_loc_inst->value.type) || instr_is_unreachable(result_loc_inst)) { |
| | 11763 | return result_loc_inst; |
| | 11764 | } |
| | 11765 | IrInstruction *result = ir_build_slice_gen(ira, source_instr, wanted_type, array_ptr, start, end, false, result_loc_inst); |
| 10867 | result->value.data.rh_slice.id = RuntimeHintSliceIdLen; | 11766 | result->value.data.rh_slice.id = RuntimeHintSliceIdLen; |
| 10868 | result->value.data.rh_slice.len = array_type->data.array.len; | 11767 | result->value.data.rh_slice.len = array_type->data.array.len; |
| 10869 | ir_add_alloca(ira, result, result->value.type); | | |
| 10870 | | 11768 | |
| 10871 | return result; | 11769 | return result; |
| 10872 | } | 11770 | } |
| ... | @@ -11504,7 +12402,7 @@ static IrInstruction *ir_analyze_array_to_vector(IrAnalyze *ira, IrInstruction * | ... | @@ -11504,7 +12402,7 @@ static IrInstruction *ir_analyze_array_to_vector(IrAnalyze *ira, IrInstruction * |
| 11504 | } | 12402 | } |
| 11505 | | 12403 | |
| 11506 | static IrInstruction *ir_analyze_vector_to_array(IrAnalyze *ira, IrInstruction *source_instr, | 12404 | static IrInstruction *ir_analyze_vector_to_array(IrAnalyze *ira, IrInstruction *source_instr, |
| 11507 | IrInstruction *vector, ZigType *array_type) | 12405 | IrInstruction *vector, ZigType *array_type, ResultLoc *result_loc) |
| 11508 | { | 12406 | { |
| 11509 | if (instr_is_comptime(vector)) { | 12407 | if (instr_is_comptime(vector)) { |
| 11510 | // arrays and vectors have the same ConstExprValue representation | 12408 | // arrays and vectors have the same ConstExprValue representation |
| ... | @@ -11513,7 +12411,14 @@ static IrInstruction *ir_analyze_vector_to_array(IrAnalyze *ira, IrInstruction * | ... | @@ -11513,7 +12411,14 @@ static IrInstruction *ir_analyze_vector_to_array(IrAnalyze *ira, IrInstruction * |
| 11513 | result->value.type = array_type; | 12411 | result->value.type = array_type; |
| 11514 | return result; | 12412 | return result; |
| 11515 | } | 12413 | } |
| 11516 | return ir_build_vector_to_array(ira, source_instr, vector, array_type); | 12414 | if (result_loc == nullptr) { |
| | 12415 | result_loc = no_result_loc(); |
| | 12416 | } |
| | 12417 | IrInstruction *result_loc_inst = ir_resolve_result(ira, source_instr, result_loc, array_type, nullptr, true, false); |
| | 12418 | if (type_is_invalid(result_loc_inst->value.type) || instr_is_unreachable(result_loc_inst)) { |
| | 12419 | return result_loc_inst; |
| | 12420 | } |
| | 12421 | return ir_build_vector_to_array(ira, source_instr, array_type, vector, result_loc_inst); |
| 11517 | } | 12422 | } |
| 11518 | | 12423 | |
| 11519 | static IrInstruction *ir_analyze_int_to_c_ptr(IrAnalyze *ira, IrInstruction *source_instr, | 12424 | static IrInstruction *ir_analyze_int_to_c_ptr(IrAnalyze *ira, IrInstruction *source_instr, |
| ... | @@ -11563,7 +12468,7 @@ static bool is_pointery_and_elem_is_not_pointery(ZigType *ty) { | ... | @@ -11563,7 +12468,7 @@ static bool is_pointery_and_elem_is_not_pointery(ZigType *ty) { |
| 11563 | } | 12468 | } |
| 11564 | | 12469 | |
| 11565 | static IrInstruction *ir_analyze_cast(IrAnalyze *ira, IrInstruction *source_instr, | 12470 | static IrInstruction *ir_analyze_cast(IrAnalyze *ira, IrInstruction *source_instr, |
| 11566 | ZigType *wanted_type, IrInstruction *value) | 12471 | ZigType *wanted_type, IrInstruction *value, ResultLoc *result_loc) |
| 11567 | { | 12472 | { |
| 11568 | Error err; | 12473 | Error err; |
| 11569 | ZigType *actual_type = value->value.type; | 12474 | ZigType *actual_type = value->value.type; |
| ... | @@ -11579,7 +12484,7 @@ static IrInstruction *ir_analyze_cast(IrAnalyze *ira, IrInstruction *source_inst | ... | @@ -11579,7 +12484,7 @@ static IrInstruction *ir_analyze_cast(IrAnalyze *ira, IrInstruction *source_inst |
| 11579 | if (const_cast_result.id == ConstCastResultIdInvalid) | 12484 | if (const_cast_result.id == ConstCastResultIdInvalid) |
| 11580 | return ira->codegen->invalid_instruction; | 12485 | return ira->codegen->invalid_instruction; |
| 11581 | if (const_cast_result.id == ConstCastResultIdOk) { | 12486 | if (const_cast_result.id == ConstCastResultIdOk) { |
| 11582 | return ir_resolve_cast(ira, source_instr, value, wanted_type, CastOpNoop, false); | 12487 | return ir_resolve_cast(ira, source_instr, value, wanted_type, CastOpNoop); |
| 11583 | } | 12488 | } |
| 11584 | | 12489 | |
| 11585 | // cast from T to ?T | 12490 | // cast from T to ?T |
| ... | @@ -11589,12 +12494,12 @@ static IrInstruction *ir_analyze_cast(IrAnalyze *ira, IrInstruction *source_inst | ... | @@ -11589,12 +12494,12 @@ static IrInstruction *ir_analyze_cast(IrAnalyze *ira, IrInstruction *source_inst |
| 11589 | if (types_match_const_cast_only(ira, wanted_child_type, actual_type, source_node, | 12494 | if (types_match_const_cast_only(ira, wanted_child_type, actual_type, source_node, |
| 11590 | false).id == ConstCastResultIdOk) | 12495 | false).id == ConstCastResultIdOk) |
| 11591 | { | 12496 | { |
| 11592 | return ir_analyze_optional_wrap(ira, source_instr, value, wanted_type); | 12497 | return ir_analyze_optional_wrap(ira, source_instr, value, wanted_type, result_loc); |
| 11593 | } else if (actual_type->id == ZigTypeIdComptimeInt || | 12498 | } else if (actual_type->id == ZigTypeIdComptimeInt || |
| 11594 | actual_type->id == ZigTypeIdComptimeFloat) | 12499 | actual_type->id == ZigTypeIdComptimeFloat) |
| 11595 | { | 12500 | { |
| 11596 | if (ir_num_lit_fits_in_other_type(ira, value, wanted_child_type, true)) { | 12501 | if (ir_num_lit_fits_in_other_type(ira, value, wanted_child_type, true)) { |
| 11597 | return ir_analyze_optional_wrap(ira, source_instr, value, wanted_type); | 12502 | return ir_analyze_optional_wrap(ira, source_instr, value, wanted_type, result_loc); |
| 11598 | } else { | 12503 | } else { |
| 11599 | return ira->codegen->invalid_instruction; | 12504 | return ira->codegen->invalid_instruction; |
| 11600 | } | 12505 | } |
| ... | @@ -11618,7 +12523,7 @@ static IrInstruction *ir_analyze_cast(IrAnalyze *ira, IrInstruction *source_inst | ... | @@ -11618,7 +12523,7 @@ static IrInstruction *ir_analyze_cast(IrAnalyze *ira, IrInstruction *source_inst |
| 11618 | wanted_child_type); | 12523 | wanted_child_type); |
| 11619 | if (type_is_invalid(cast1->value.type)) | 12524 | if (type_is_invalid(cast1->value.type)) |
| 11620 | return ira->codegen->invalid_instruction; | 12525 | return ira->codegen->invalid_instruction; |
| 11621 | return ir_analyze_optional_wrap(ira, source_instr, cast1, wanted_type); | 12526 | return ir_analyze_optional_wrap(ira, source_instr, cast1, wanted_type, result_loc); |
| 11622 | } | 12527 | } |
| 11623 | } | 12528 | } |
| 11624 | } | 12529 | } |
| ... | @@ -11628,12 +12533,12 @@ static IrInstruction *ir_analyze_cast(IrAnalyze *ira, IrInstruction *source_inst | ... | @@ -11628,12 +12533,12 @@ static IrInstruction *ir_analyze_cast(IrAnalyze *ira, IrInstruction *source_inst |
| 11628 | if (types_match_const_cast_only(ira, wanted_type->data.error_union.payload_type, actual_type, | 12533 | if (types_match_const_cast_only(ira, wanted_type->data.error_union.payload_type, actual_type, |
| 11629 | source_node, false).id == ConstCastResultIdOk) | 12534 | source_node, false).id == ConstCastResultIdOk) |
| 11630 | { | 12535 | { |
| 11631 | return ir_analyze_err_wrap_payload(ira, source_instr, value, wanted_type); | 12536 | return ir_analyze_err_wrap_payload(ira, source_instr, value, wanted_type, result_loc); |
| 11632 | } else if (actual_type->id == ZigTypeIdComptimeInt || | 12537 | } else if (actual_type->id == ZigTypeIdComptimeInt || |
| 11633 | actual_type->id == ZigTypeIdComptimeFloat) | 12538 | actual_type->id == ZigTypeIdComptimeFloat) |
| 11634 | { | 12539 | { |
| 11635 | if (ir_num_lit_fits_in_other_type(ira, value, wanted_type->data.error_union.payload_type, true)) { | 12540 | if (ir_num_lit_fits_in_other_type(ira, value, wanted_type->data.error_union.payload_type, true)) { |
| 11636 | return ir_analyze_err_wrap_payload(ira, source_instr, value, wanted_type); | 12541 | return ir_analyze_err_wrap_payload(ira, source_instr, value, wanted_type, result_loc); |
| 11637 | } else { | 12542 | } else { |
| 11638 | return ira->codegen->invalid_instruction; | 12543 | return ira->codegen->invalid_instruction; |
| 11639 | } | 12544 | } |
| ... | @@ -11651,11 +12556,11 @@ static IrInstruction *ir_analyze_cast(IrAnalyze *ira, IrInstruction *source_inst | ... | @@ -11651,11 +12556,11 @@ static IrInstruction *ir_analyze_cast(IrAnalyze *ira, IrInstruction *source_inst |
| 11651 | actual_type->id == ZigTypeIdComptimeInt || | 12556 | actual_type->id == ZigTypeIdComptimeInt || |
| 11652 | actual_type->id == ZigTypeIdComptimeFloat) | 12557 | actual_type->id == ZigTypeIdComptimeFloat) |
| 11653 | { | 12558 | { |
| 11654 | IrInstruction *cast1 = ir_analyze_cast(ira, source_instr, wanted_type->data.error_union.payload_type, value); | 12559 | IrInstruction *cast1 = ir_analyze_cast(ira, source_instr, wanted_type->data.error_union.payload_type, value, nullptr); |
| 11655 | if (type_is_invalid(cast1->value.type)) | 12560 | if (type_is_invalid(cast1->value.type)) |
| 11656 | return ira->codegen->invalid_instruction; | 12561 | return ira->codegen->invalid_instruction; |
| 11657 | | 12562 | |
| 11658 | IrInstruction *cast2 = ir_analyze_cast(ira, source_instr, wanted_type, cast1); | 12563 | IrInstruction *cast2 = ir_analyze_cast(ira, source_instr, wanted_type, cast1, result_loc); |
| 11659 | if (type_is_invalid(cast2->value.type)) | 12564 | if (type_is_invalid(cast2->value.type)) |
| 11660 | return ira->codegen->invalid_instruction; | 12565 | return ira->codegen->invalid_instruction; |
| 11661 | | 12566 | |
| ... | @@ -11737,7 +12642,7 @@ static IrInstruction *ir_analyze_cast(IrAnalyze *ira, IrInstruction *source_inst | ... | @@ -11737,7 +12642,7 @@ static IrInstruction *ir_analyze_cast(IrAnalyze *ira, IrInstruction *source_inst |
| 11737 | types_match_const_cast_only(ira, ptr_type->data.pointer.child_type, actual_type->data.array.child_type, | 12642 | types_match_const_cast_only(ira, ptr_type->data.pointer.child_type, actual_type->data.array.child_type, |
| 11738 | source_node, false).id == ConstCastResultIdOk) | 12643 | source_node, false).id == ConstCastResultIdOk) |
| 11739 | { | 12644 | { |
| 11740 | return ir_analyze_array_to_slice(ira, source_instr, value, wanted_type); | 12645 | return ir_analyze_array_to_slice(ira, source_instr, value, wanted_type, result_loc); |
| 11741 | } | 12646 | } |
| 11742 | } | 12647 | } |
| 11743 | | 12648 | |
| ... | @@ -11754,11 +12659,11 @@ static IrInstruction *ir_analyze_cast(IrAnalyze *ira, IrInstruction *source_inst | ... | @@ -11754,11 +12659,11 @@ static IrInstruction *ir_analyze_cast(IrAnalyze *ira, IrInstruction *source_inst |
| 11754 | types_match_const_cast_only(ira, ptr_type->data.pointer.child_type, actual_type->data.array.child_type, | 12659 | types_match_const_cast_only(ira, ptr_type->data.pointer.child_type, actual_type->data.array.child_type, |
| 11755 | source_node, false).id == ConstCastResultIdOk) | 12660 | source_node, false).id == ConstCastResultIdOk) |
| 11756 | { | 12661 | { |
| 11757 | IrInstruction *cast1 = ir_analyze_cast(ira, source_instr, wanted_type->data.maybe.child_type, value); | 12662 | IrInstruction *cast1 = ir_analyze_cast(ira, source_instr, wanted_type->data.maybe.child_type, value, nullptr); |
| 11758 | if (type_is_invalid(cast1->value.type)) | 12663 | if (type_is_invalid(cast1->value.type)) |
| 11759 | return ira->codegen->invalid_instruction; | 12664 | return ira->codegen->invalid_instruction; |
| 11760 | | 12665 | |
| 11761 | IrInstruction *cast2 = ir_analyze_cast(ira, source_instr, wanted_type, cast1); | 12666 | IrInstruction *cast2 = ir_analyze_cast(ira, source_instr, wanted_type, cast1, result_loc); |
| 11762 | if (type_is_invalid(cast2->value.type)) | 12667 | if (type_is_invalid(cast2->value.type)) |
| 11763 | return ira->codegen->invalid_instruction; | 12668 | return ira->codegen->invalid_instruction; |
| 11764 | | 12669 | |
| ... | @@ -11801,7 +12706,7 @@ static IrInstruction *ir_analyze_cast(IrAnalyze *ira, IrInstruction *source_inst | ... | @@ -11801,7 +12706,7 @@ static IrInstruction *ir_analyze_cast(IrAnalyze *ira, IrInstruction *source_inst |
| 11801 | array_type->data.array.child_type, source_node, | 12706 | array_type->data.array.child_type, source_node, |
| 11802 | !slice_ptr_type->data.pointer.is_const).id == ConstCastResultIdOk) | 12707 | !slice_ptr_type->data.pointer.is_const).id == ConstCastResultIdOk) |
| 11803 | { | 12708 | { |
| 11804 | return ir_resolve_ptr_of_array_to_slice(ira, source_instr, value, wanted_type); | 12709 | return ir_resolve_ptr_of_array_to_slice(ira, source_instr, value, wanted_type, result_loc); |
| 11805 | } | 12710 | } |
| 11806 | } | 12711 | } |
| 11807 | | 12712 | |
| ... | @@ -11832,11 +12737,11 @@ static IrInstruction *ir_analyze_cast(IrAnalyze *ira, IrInstruction *source_inst | ... | @@ -11832,11 +12737,11 @@ static IrInstruction *ir_analyze_cast(IrAnalyze *ira, IrInstruction *source_inst |
| 11832 | types_match_const_cast_only(ira, ptr_type->data.pointer.child_type, actual_type->data.array.child_type, | 12737 | types_match_const_cast_only(ira, ptr_type->data.pointer.child_type, actual_type->data.array.child_type, |
| 11833 | source_node, false).id == ConstCastResultIdOk) | 12738 | source_node, false).id == ConstCastResultIdOk) |
| 11834 | { | 12739 | { |
| 11835 | IrInstruction *cast1 = ir_analyze_cast(ira, source_instr, wanted_type->data.error_union.payload_type, value); | 12740 | IrInstruction *cast1 = ir_analyze_cast(ira, source_instr, wanted_type->data.error_union.payload_type, value, nullptr); |
| 11836 | if (type_is_invalid(cast1->value.type)) | 12741 | if (type_is_invalid(cast1->value.type)) |
| 11837 | return ira->codegen->invalid_instruction; | 12742 | return ira->codegen->invalid_instruction; |
| 11838 | | 12743 | |
| 11839 | IrInstruction *cast2 = ir_analyze_cast(ira, source_instr, wanted_type, cast1); | 12744 | IrInstruction *cast2 = ir_analyze_cast(ira, source_instr, wanted_type, cast1, result_loc); |
| 11840 | if (type_is_invalid(cast2->value.type)) | 12745 | if (type_is_invalid(cast2->value.type)) |
| 11841 | return ira->codegen->invalid_instruction; | 12746 | return ira->codegen->invalid_instruction; |
| 11842 | | 12747 | |
| ... | @@ -11848,7 +12753,7 @@ static IrInstruction *ir_analyze_cast(IrAnalyze *ira, IrInstruction *source_inst | ... | @@ -11848,7 +12753,7 @@ static IrInstruction *ir_analyze_cast(IrAnalyze *ira, IrInstruction *source_inst |
| 11848 | if (wanted_type->id == ZigTypeIdErrorUnion && | 12753 | if (wanted_type->id == ZigTypeIdErrorUnion && |
| 11849 | actual_type->id == ZigTypeIdErrorSet) | 12754 | actual_type->id == ZigTypeIdErrorSet) |
| 11850 | { | 12755 | { |
| 11851 | return ir_analyze_err_wrap_code(ira, source_instr, value, wanted_type); | 12756 | return ir_analyze_err_wrap_code(ira, source_instr, value, wanted_type, result_loc); |
| 11852 | } | 12757 | } |
| 11853 | | 12758 | |
| 11854 | // cast from typed number to integer or float literal. | 12759 | // cast from typed number to integer or float literal. |
| ... | @@ -11972,7 +12877,7 @@ static IrInstruction *ir_analyze_cast(IrAnalyze *ira, IrInstruction *source_inst | ... | @@ -11972,7 +12877,7 @@ static IrInstruction *ir_analyze_cast(IrAnalyze *ira, IrInstruction *source_inst |
| 11972 | types_match_const_cast_only(ira, wanted_type->data.array.child_type, | 12877 | types_match_const_cast_only(ira, wanted_type->data.array.child_type, |
| 11973 | actual_type->data.vector.elem_type, source_node, false).id == ConstCastResultIdOk) | 12878 | actual_type->data.vector.elem_type, source_node, false).id == ConstCastResultIdOk) |
| 11974 | { | 12879 | { |
| 11975 | return ir_analyze_vector_to_array(ira, source_instr, value, wanted_type); | 12880 | return ir_analyze_vector_to_array(ira, source_instr, value, wanted_type, result_loc); |
| 11976 | } | 12881 | } |
| 11977 | | 12882 | |
| 11978 | // cast from [N]T to @Vector(N, T) | 12883 | // cast from [N]T to @Vector(N, T) |
| ... | @@ -12014,7 +12919,9 @@ static IrInstruction *ir_analyze_cast(IrAnalyze *ira, IrInstruction *source_inst | ... | @@ -12014,7 +12919,9 @@ static IrInstruction *ir_analyze_cast(IrAnalyze *ira, IrInstruction *source_inst |
| 12014 | return ira->codegen->invalid_instruction; | 12919 | return ira->codegen->invalid_instruction; |
| 12015 | } | 12920 | } |
| 12016 | | 12921 | |
| 12017 | static IrInstruction *ir_implicit_cast(IrAnalyze *ira, IrInstruction *value, ZigType *expected_type) { | 12922 | static IrInstruction *ir_implicit_cast_with_result(IrAnalyze *ira, IrInstruction *value, ZigType *expected_type, |
| | 12923 | ResultLoc *result_loc) |
| | 12924 | { |
| 12018 | assert(value); | 12925 | assert(value); |
| 12019 | assert(value != ira->codegen->invalid_instruction); | 12926 | assert(value != ira->codegen->invalid_instruction); |
| 12020 | assert(!expected_type || !type_is_invalid(expected_type)); | 12927 | assert(!expected_type || !type_is_invalid(expected_type)); |
| ... | @@ -12027,63 +12934,76 @@ static IrInstruction *ir_implicit_cast(IrAnalyze *ira, IrInstruction *value, Zig | ... | @@ -12027,63 +12934,76 @@ static IrInstruction *ir_implicit_cast(IrAnalyze *ira, IrInstruction *value, Zig |
| 12027 | if (value->value.type->id == ZigTypeIdUnreachable) | 12934 | if (value->value.type->id == ZigTypeIdUnreachable) |
| 12028 | return value; | 12935 | return value; |
| 12029 | | 12936 | |
| 12030 | return ir_analyze_cast(ira, value, expected_type, value); | 12937 | return ir_analyze_cast(ira, value, expected_type, value, result_loc); |
| | 12938 | } |
| | 12939 | |
| | 12940 | static IrInstruction *ir_implicit_cast(IrAnalyze *ira, IrInstruction *value, ZigType *expected_type) { |
| | 12941 | return ir_implicit_cast_with_result(ira, value, expected_type, nullptr); |
| 12031 | } | 12942 | } |
| 12032 | | 12943 | |
| 12033 | static IrInstruction *ir_get_deref(IrAnalyze *ira, IrInstruction *source_instruction, IrInstruction *ptr) { | 12944 | static IrInstruction *ir_get_deref(IrAnalyze *ira, IrInstruction *source_instruction, IrInstruction *ptr, |
| | 12945 | ResultLoc *result_loc) |
| | 12946 | { |
| 12034 | Error err; | 12947 | Error err; |
| 12035 | ZigType *type_entry = ptr->value.type; | 12948 | ZigType *type_entry = ptr->value.type; |
| 12036 | if (type_is_invalid(type_entry)) { | 12949 | if (type_is_invalid(type_entry)) |
| 12037 | return ira->codegen->invalid_instruction; | 12950 | return ira->codegen->invalid_instruction; |
| 12038 | } else if (type_entry->id == ZigTypeIdPointer) { | 12951 | |
| 12039 | ZigType *child_type = type_entry->data.pointer.child_type; | 12952 | if (type_entry->id != ZigTypeIdPointer) { |
| 12040 | // if the child type has one possible value, the deref is comptime | 12953 | ir_add_error_node(ira, source_instruction->source_node, |
| 12041 | switch (type_has_one_possible_value(ira->codegen, child_type)) { | 12954 | buf_sprintf("attempt to dereference non-pointer type '%s'", |
| 12042 | case OnePossibleValueInvalid: | 12955 | buf_ptr(&type_entry->name))); |
| 12043 | return ira->codegen->invalid_instruction; | 12956 | return ira->codegen->invalid_instruction; |
| 12044 | case OnePossibleValueYes: | 12957 | } |
| 12045 | return ir_const(ira, source_instruction, child_type); | 12958 | |
| 12046 | case OnePossibleValueNo: | 12959 | ZigType *child_type = type_entry->data.pointer.child_type; |
| 12047 | break; | 12960 | // if the child type has one possible value, the deref is comptime |
| | 12961 | switch (type_has_one_possible_value(ira->codegen, child_type)) { |
| | 12962 | case OnePossibleValueInvalid: |
| | 12963 | return ira->codegen->invalid_instruction; |
| | 12964 | case OnePossibleValueYes: |
| | 12965 | return ir_const(ira, source_instruction, child_type); |
| | 12966 | case OnePossibleValueNo: |
| | 12967 | break; |
| | 12968 | } |
| | 12969 | if (instr_is_comptime(ptr)) { |
| | 12970 | if (ptr->value.special == ConstValSpecialUndef) { |
| | 12971 | ir_add_error(ira, ptr, buf_sprintf("attempt to dereference undefined value")); |
| | 12972 | return ira->codegen->invalid_instruction; |
| 12048 | } | 12973 | } |
| 12049 | if (instr_is_comptime(ptr)) { | 12974 | if (ptr->value.data.x_ptr.mut != ConstPtrMutRuntimeVar) { |
| 12050 | if (ptr->value.special == ConstValSpecialUndef) { | 12975 | ConstExprValue *pointee = const_ptr_pointee_unchecked(ira->codegen, &ptr->value); |
| 12051 | ir_add_error(ira, ptr, buf_sprintf("attempt to dereference undefined value")); | 12976 | if (pointee->special != ConstValSpecialRuntime) { |
| 12052 | return ira->codegen->invalid_instruction; | 12977 | IrInstruction *result = ir_const(ira, source_instruction, child_type); |
| 12053 | } | | |
| 12054 | if (ptr->value.data.x_ptr.mut == ConstPtrMutComptimeConst || | | |
| 12055 | ptr->value.data.x_ptr.mut == ConstPtrMutComptimeVar) | | |
| 12056 | { | | |
| 12057 | ConstExprValue *pointee = const_ptr_pointee_unchecked(ira->codegen, &ptr->value); | | |
| 12058 | if (pointee->special != ConstValSpecialRuntime) { | | |
| 12059 | IrInstruction *result = ir_const(ira, source_instruction, child_type); | | |
| 12060 | | 12978 | |
| 12061 | if ((err = ir_read_const_ptr(ira, ira->codegen, source_instruction->source_node, &result->value, | 12979 | if ((err = ir_read_const_ptr(ira, ira->codegen, source_instruction->source_node, &result->value, |
| 12062 | &ptr->value))) | 12980 | &ptr->value))) |
| 12063 | { | 12981 | { |
| 12064 | return ira->codegen->invalid_instruction; | 12982 | return ira->codegen->invalid_instruction; |
| 12065 | } | | |
| 12066 | result->value.type = child_type; | | |
| 12067 | return result; | | |
| 12068 | } | 12983 | } |
| | 12984 | result->value.type = child_type; |
| | 12985 | return result; |
| 12069 | } | 12986 | } |
| 12070 | } | 12987 | } |
| 12071 | // if the instruction is a const ref instruction we can skip it | 12988 | } |
| 12072 | if (ptr->id == IrInstructionIdRef) { | 12989 | // if the instruction is a const ref instruction we can skip it |
| 12073 | IrInstructionRef *ref_inst = reinterpret_cast<IrInstructionRef *>(ptr); | 12990 | if (ptr->id == IrInstructionIdRef) { |
| 12074 | return ref_inst->value; | 12991 | IrInstructionRef *ref_inst = reinterpret_cast<IrInstructionRef *>(ptr); |
| 12075 | } | 12992 | return ref_inst->value; |
| 12076 | IrInstruction *result = ir_build_load_ptr_gen(ira, source_instruction, ptr, child_type); | 12993 | } |
| 12077 | if (type_entry->data.pointer.host_int_bytes != 0 && handle_is_ptr(child_type)) { | 12994 | |
| 12078 | ir_add_alloca(ira, result, child_type); | 12995 | IrInstruction *result_loc_inst; |
| | 12996 | if (type_entry->data.pointer.host_int_bytes != 0 && handle_is_ptr(child_type)) { |
| | 12997 | if (result_loc == nullptr) result_loc = no_result_loc(); |
| | 12998 | result_loc_inst = ir_resolve_result(ira, source_instruction, result_loc, child_type, nullptr, true, false); |
| | 12999 | if (type_is_invalid(result_loc_inst->value.type) || instr_is_unreachable(result_loc_inst)) { |
| | 13000 | return result_loc_inst; |
| 12079 | } | 13001 | } |
| 12080 | return result; | | |
| 12081 | } else { | 13002 | } else { |
| 12082 | ir_add_error_node(ira, source_instruction->source_node, | 13003 | result_loc_inst = nullptr; |
| 12083 | buf_sprintf("attempt to dereference non-pointer type '%s'", | | |
| 12084 | buf_ptr(&type_entry->name))); | | |
| 12085 | return ira->codegen->invalid_instruction; | | |
| 12086 | } | 13004 | } |
| | 13005 | |
| | 13006 | return ir_build_load_ptr_gen(ira, source_instruction, ptr, child_type, result_loc_inst); |
| 12087 | } | 13007 | } |
| 12088 | | 13008 | |
| 12089 | static bool ir_resolve_align(IrAnalyze *ira, IrInstruction *value, uint32_t *out) { | 13009 | static bool ir_resolve_align(IrAnalyze *ira, IrInstruction *value, uint32_t *out) { |
| ... | @@ -12297,6 +13217,14 @@ static IrInstruction *ir_analyze_instruction_return(IrAnalyze *ira, IrInstructio | ... | @@ -12297,6 +13217,14 @@ static IrInstruction *ir_analyze_instruction_return(IrAnalyze *ira, IrInstructio |
| 12297 | if (type_is_invalid(value->value.type)) | 13217 | if (type_is_invalid(value->value.type)) |
| 12298 | return ir_unreach_error(ira); | 13218 | return ir_unreach_error(ira); |
| 12299 | | 13219 | |
| | 13220 | if (!instr_is_comptime(value) && handle_is_ptr(ira->explicit_return_type)) { |
| | 13221 | // result location mechanism took care of it. |
| | 13222 | IrInstruction *result = ir_build_return(&ira->new_irb, instruction->base.scope, |
| | 13223 | instruction->base.source_node, nullptr); |
| | 13224 | result->value.type = ira->codegen->builtin_types.entry_unreachable; |
| | 13225 | return ir_finish_anal(ira, result); |
| | 13226 | } |
| | 13227 | |
| 12300 | IrInstruction *casted_value = ir_implicit_cast(ira, value, ira->explicit_return_type); | 13228 | IrInstruction *casted_value = ir_implicit_cast(ira, value, ira->explicit_return_type); |
| 12301 | if (type_is_invalid(casted_value->value.type)) { | 13229 | if (type_is_invalid(casted_value->value.type)) { |
| 12302 | AstNode *source_node = ira->explicit_return_type_source_node; | 13230 | AstNode *source_node = ira->explicit_return_type_source_node; |
| ... | @@ -12459,7 +13387,7 @@ static IrInstruction *ir_analyze_bin_op_cmp(IrAnalyze *ira, IrInstructionBinOp * | ... | @@ -12459,7 +13387,7 @@ static IrInstruction *ir_analyze_bin_op_cmp(IrAnalyze *ira, IrInstructionBinOp * |
| 12459 | } else { | 13387 | } else { |
| 12460 | return is_non_null; | 13388 | return is_non_null; |
| 12461 | } | 13389 | } |
| 12462 | } else if (is_equality_cmp && | 13390 | } else if (is_equality_cmp && |
| 12463 | ((op1->value.type->id == ZigTypeIdNull && op2->value.type->id == ZigTypeIdPointer && | 13391 | ((op1->value.type->id == ZigTypeIdNull && op2->value.type->id == ZigTypeIdPointer && |
| 12464 | op2->value.type->data.pointer.ptr_len == PtrLenC) || | 13392 | op2->value.type->data.pointer.ptr_len == PtrLenC) || |
| 12465 | (op2->value.type->id == ZigTypeIdNull && op1->value.type->id == ZigTypeIdPointer && | 13393 | (op2->value.type->id == ZigTypeIdNull && op1->value.type->id == ZigTypeIdPointer && |
| ... | @@ -12901,7 +13829,7 @@ static ErrorMsg *ir_eval_math_op_scalar(IrAnalyze *ira, IrInstruction *source_in | ... | @@ -12901,7 +13829,7 @@ static ErrorMsg *ir_eval_math_op_scalar(IrAnalyze *ira, IrInstruction *source_in |
| 12901 | } | 13829 | } |
| 12902 | } else { | 13830 | } else { |
| 12903 | float_div_trunc(out_val, op1_val, op2_val); | 13831 | float_div_trunc(out_val, op1_val, op2_val); |
| 12904 | ConstExprValue remainder; | 13832 | ConstExprValue remainder = {}; |
| 12905 | float_rem(&remainder, op1_val, op2_val); | 13833 | float_rem(&remainder, op1_val, op2_val); |
| 12906 | if (float_cmp_zero(&remainder) != CmpEQ) { | 13834 | if (float_cmp_zero(&remainder) != CmpEQ) { |
| 12907 | return ir_add_error(ira, source_instr, buf_sprintf("exact division had a remainder")); | 13835 | return ir_add_error(ira, source_instr, buf_sprintf("exact division had a remainder")); |
| ... | @@ -13276,8 +14204,8 @@ static IrInstruction *ir_analyze_bin_op_math(IrAnalyze *ira, IrInstructionBinOp | ... | @@ -13276,8 +14204,8 @@ static IrInstruction *ir_analyze_bin_op_math(IrAnalyze *ira, IrInstructionBinOp |
| 13276 | // have a remainder function ambiguity problem | 14204 | // have a remainder function ambiguity problem |
| 13277 | ok = true; | 14205 | ok = true; |
| 13278 | } else { | 14206 | } else { |
| 13279 | ConstExprValue rem_result; | 14207 | ConstExprValue rem_result = {}; |
| 13280 | ConstExprValue mod_result; | 14208 | ConstExprValue mod_result = {}; |
| 13281 | float_rem(&rem_result, op1_val, op2_val); | 14209 | float_rem(&rem_result, op1_val, op2_val); |
| 13282 | float_mod(&mod_result, op1_val, op2_val); | 14210 | float_mod(&mod_result, op1_val, op2_val); |
| 13283 | ok = float_cmp(&rem_result, &mod_result) == CmpEQ; | 14211 | ok = float_cmp(&rem_result, &mod_result) == CmpEQ; |
| ... | @@ -13500,10 +14428,12 @@ static IrInstruction *ir_analyze_array_cat(IrAnalyze *ira, IrInstructionBinOp *i | ... | @@ -13500,10 +14428,12 @@ static IrInstruction *ir_analyze_array_cat(IrAnalyze *ira, IrInstructionBinOp *i |
| 13500 | | 14428 | |
| 13501 | size_t next_index = 0; | 14429 | size_t next_index = 0; |
| 13502 | for (size_t i = op1_array_index; i < op1_array_end; i += 1, next_index += 1) { | 14430 | for (size_t i = op1_array_index; i < op1_array_end; i += 1, next_index += 1) { |
| 13503 | out_array_val->data.x_array.data.s_none.elements[next_index] = op1_array_val->data.x_array.data.s_none.elements[i]; | 14431 | copy_const_val(&out_array_val->data.x_array.data.s_none.elements[next_index], |
| | 14432 | &op1_array_val->data.x_array.data.s_none.elements[i], true); |
| 13504 | } | 14433 | } |
| 13505 | for (size_t i = op2_array_index; i < op2_array_end; i += 1, next_index += 1) { | 14434 | for (size_t i = op2_array_index; i < op2_array_end; i += 1, next_index += 1) { |
| 13506 | out_array_val->data.x_array.data.s_none.elements[next_index] = op2_array_val->data.x_array.data.s_none.elements[i]; | 14435 | copy_const_val(&out_array_val->data.x_array.data.s_none.elements[next_index], |
| | 14436 | &op2_array_val->data.x_array.data.s_none.elements[i], true); |
| 13507 | } | 14437 | } |
| 13508 | if (next_index < new_len) { | 14438 | if (next_index < new_len) { |
| 13509 | ConstExprValue *null_byte = &out_array_val->data.x_array.data.s_none.elements[next_index]; | 14439 | ConstExprValue *null_byte = &out_array_val->data.x_array.data.s_none.elements[next_index]; |
| ... | @@ -13564,7 +14494,8 @@ static IrInstruction *ir_analyze_array_mult(IrAnalyze *ira, IrInstructionBinOp * | ... | @@ -13564,7 +14494,8 @@ static IrInstruction *ir_analyze_array_mult(IrAnalyze *ira, IrInstructionBinOp * |
| 13564 | uint64_t i = 0; | 14494 | uint64_t i = 0; |
| 13565 | for (uint64_t x = 0; x < mult_amt; x += 1) { | 14495 | for (uint64_t x = 0; x < mult_amt; x += 1) { |
| 13566 | for (uint64_t y = 0; y < old_array_len; y += 1) { | 14496 | for (uint64_t y = 0; y < old_array_len; y += 1) { |
| 13567 | out_val->data.x_array.data.s_none.elements[i] = array_val->data.x_array.data.s_none.elements[y]; | 14497 | copy_const_val(&out_val->data.x_array.data.s_none.elements[i], |
| | 14498 | &array_val->data.x_array.data.s_none.elements[y], true); |
| 13568 | i += 1; | 14499 | i += 1; |
| 13569 | } | 14500 | } |
| 13570 | } | 14501 | } |
| ... | @@ -13661,12 +14592,6 @@ static IrInstruction *ir_analyze_instruction_decl_var(IrAnalyze *ira, | ... | @@ -13661,12 +14592,6 @@ static IrInstruction *ir_analyze_instruction_decl_var(IrAnalyze *ira, |
| 13661 | Error err; | 14592 | Error err; |
| 13662 | ZigVar *var = decl_var_instruction->var; | 14593 | ZigVar *var = decl_var_instruction->var; |
| 13663 | | 14594 | |
| 13664 | IrInstruction *init_value = decl_var_instruction->init_value->child; | | |
| 13665 | if (type_is_invalid(init_value->value.type)) { | | |
| 13666 | var->var_type = ira->codegen->builtin_types.entry_invalid; | | |
| 13667 | return ira->codegen->invalid_instruction; | | |
| 13668 | } | | |
| 13669 | | | |
| 13670 | ZigType *explicit_type = nullptr; | 14595 | ZigType *explicit_type = nullptr; |
| 13671 | IrInstruction *var_type = nullptr; | 14596 | IrInstruction *var_type = nullptr; |
| 13672 | if (decl_var_instruction->var_type != nullptr) { | 14597 | if (decl_var_instruction->var_type != nullptr) { |
| ... | @@ -13681,18 +14606,40 @@ static IrInstruction *ir_analyze_instruction_decl_var(IrAnalyze *ira, | ... | @@ -13681,18 +14606,40 @@ static IrInstruction *ir_analyze_instruction_decl_var(IrAnalyze *ira, |
| 13681 | | 14606 | |
| 13682 | AstNode *source_node = decl_var_instruction->base.source_node; | 14607 | AstNode *source_node = decl_var_instruction->base.source_node; |
| 13683 | | 14608 | |
| 13684 | IrInstruction *casted_init_value = ir_implicit_cast(ira, init_value, explicit_type); | | |
| 13685 | bool is_comptime_var = ir_get_var_is_comptime(var); | 14609 | bool is_comptime_var = ir_get_var_is_comptime(var); |
| 13686 | | 14610 | |
| 13687 | bool var_class_requires_const = false; | 14611 | bool var_class_requires_const = false; |
| 13688 | | 14612 | |
| 13689 | ZigType *result_type = casted_init_value->value.type; | 14613 | IrInstruction *var_ptr = decl_var_instruction->ptr->child; |
| | 14614 | // if this is null, a compiler error happened and did not initialize the variable. |
| | 14615 | // if there are no compile errors there may be a missing ir_expr_wrap in pass1 IR generation. |
| | 14616 | if (var_ptr == nullptr || type_is_invalid(var_ptr->value.type)) { |
| | 14617 | ir_assert(var_ptr != nullptr || ira->codegen->errors.length != 0, &decl_var_instruction->base); |
| | 14618 | var->var_type = ira->codegen->builtin_types.entry_invalid; |
| | 14619 | return ira->codegen->invalid_instruction; |
| | 14620 | } |
| | 14621 | |
| | 14622 | // The ir_build_var_decl_src call is supposed to pass a pointer to the allocation, not an initialization value. |
| | 14623 | ir_assert(var_ptr->value.type->id == ZigTypeIdPointer, &decl_var_instruction->base); |
| | 14624 | |
| | 14625 | ZigType *result_type = var_ptr->value.type->data.pointer.child_type; |
| 13690 | if (type_is_invalid(result_type)) { | 14626 | if (type_is_invalid(result_type)) { |
| 13691 | result_type = ira->codegen->builtin_types.entry_invalid; | 14627 | result_type = ira->codegen->builtin_types.entry_invalid; |
| 13692 | } else if (result_type->id == ZigTypeIdUnreachable || result_type->id == ZigTypeIdOpaque) { | 14628 | } else if (result_type->id == ZigTypeIdUnreachable || result_type->id == ZigTypeIdOpaque) { |
| 13693 | ir_add_error_node(ira, source_node, | 14629 | zig_unreachable(); |
| 13694 | buf_sprintf("variable of type '%s' not allowed", buf_ptr(&result_type->name))); | 14630 | } |
| 13695 | result_type = ira->codegen->builtin_types.entry_invalid; | 14631 | |
| | 14632 | ConstExprValue *init_val = nullptr; |
| | 14633 | if (instr_is_comptime(var_ptr) && var_ptr->value.data.x_ptr.mut != ConstPtrMutRuntimeVar) { |
| | 14634 | init_val = const_ptr_pointee(ira, ira->codegen, &var_ptr->value, decl_var_instruction->base.source_node); |
| | 14635 | if (is_comptime_var) { |
| | 14636 | if (var->gen_is_const) { |
| | 14637 | var->const_value = init_val; |
| | 14638 | } else { |
| | 14639 | var->const_value = create_const_vals(1); |
| | 14640 | copy_const_val(var->const_value, init_val, false); |
| | 14641 | } |
| | 14642 | } |
| 13696 | } | 14643 | } |
| 13697 | | 14644 | |
| 13698 | switch (type_requires_comptime(ira->codegen, result_type)) { | 14645 | switch (type_requires_comptime(ira->codegen, result_type)) { |
| ... | @@ -13709,18 +14656,20 @@ static IrInstruction *ir_analyze_instruction_decl_var(IrAnalyze *ira, | ... | @@ -13709,18 +14656,20 @@ static IrInstruction *ir_analyze_instruction_decl_var(IrAnalyze *ira, |
| 13709 | } | 14656 | } |
| 13710 | break; | 14657 | break; |
| 13711 | case ReqCompTimeNo: | 14658 | case ReqCompTimeNo: |
| 13712 | if (casted_init_value->value.special == ConstValSpecialStatic && | 14659 | if (init_val != nullptr) { |
| 13713 | casted_init_value->value.type->id == ZigTypeIdFn && | 14660 | if (init_val->special == ConstValSpecialStatic && |
| 13714 | casted_init_value->value.data.x_ptr.special != ConstPtrSpecialHardCodedAddr && | 14661 | init_val->type->id == ZigTypeIdFn && |
| 13715 | casted_init_value->value.data.x_ptr.data.fn.fn_entry->fn_inline == FnInlineAlways) | 14662 | init_val->data.x_ptr.special != ConstPtrSpecialHardCodedAddr && |
| 13716 | { | 14663 | init_val->data.x_ptr.data.fn.fn_entry->fn_inline == FnInlineAlways) |
| 13717 | var_class_requires_const = true; | 14664 | { |
| 13718 | if (!var->src_is_const && !is_comptime_var) { | 14665 | var_class_requires_const = true; |
| 13719 | ErrorMsg *msg = ir_add_error_node(ira, source_node, | 14666 | if (!var->src_is_const && !is_comptime_var) { |
| 13720 | buf_sprintf("functions marked inline must be stored in const or comptime var")); | 14667 | ErrorMsg *msg = ir_add_error_node(ira, source_node, |
| 13721 | AstNode *proto_node = casted_init_value->value.data.x_ptr.data.fn.fn_entry->proto_node; | 14668 | buf_sprintf("functions marked inline must be stored in const or comptime var")); |
| 13722 | add_error_note(ira->codegen, msg, proto_node, buf_sprintf("declared here")); | 14669 | AstNode *proto_node = init_val->data.x_ptr.data.fn.fn_entry->proto_node; |
| 13723 | result_type = ira->codegen->builtin_types.entry_invalid; | 14670 | add_error_note(ira->codegen, msg, proto_node, buf_sprintf("declared here")); |
| | 14671 | result_type = ira->codegen->builtin_types.entry_invalid; |
| | 14672 | } |
| 13724 | } | 14673 | } |
| 13725 | } | 14674 | } |
| 13726 | break; | 14675 | break; |
| ... | @@ -13767,11 +14716,29 @@ static IrInstruction *ir_analyze_instruction_decl_var(IrAnalyze *ira, | ... | @@ -13767,11 +14716,29 @@ static IrInstruction *ir_analyze_instruction_decl_var(IrAnalyze *ira, |
| 13767 | } | 14716 | } |
| 13768 | } | 14717 | } |
| 13769 | | 14718 | |
| 13770 | if (casted_init_value->value.special != ConstValSpecialRuntime) { | 14719 | if (init_val != nullptr && init_val->special != ConstValSpecialRuntime) { |
| 13771 | if (var->mem_slot_index != SIZE_MAX) { | 14720 | // Resolve ConstPtrMutInfer |
| | 14721 | if (var->gen_is_const) { |
| | 14722 | var_ptr->value.data.x_ptr.mut = ConstPtrMutComptimeConst; |
| | 14723 | } else if (is_comptime_var) { |
| | 14724 | var_ptr->value.data.x_ptr.mut = ConstPtrMutComptimeVar; |
| | 14725 | } else { |
| | 14726 | // we need a runtime ptr but we have a comptime val. |
| | 14727 | // since it's a comptime val there are no instructions for it. |
| | 14728 | // we memcpy the init value here |
| | 14729 | IrInstruction *deref = ir_get_deref(ira, var_ptr, var_ptr, nullptr); |
| | 14730 | // If this assertion trips, something is wrong with the IR instructions, because |
| | 14731 | // we expected the above deref to return a constant value, but it created a runtime |
| | 14732 | // instruction. |
| | 14733 | assert(deref->value.special != ConstValSpecialRuntime); |
| | 14734 | var_ptr->value.special = ConstValSpecialRuntime; |
| | 14735 | ir_analyze_store_ptr(ira, var_ptr, var_ptr, deref); |
| | 14736 | } |
| | 14737 | |
| | 14738 | if (var_ptr->value.special == ConstValSpecialStatic && var->mem_slot_index != SIZE_MAX) { |
| 13772 | assert(var->mem_slot_index < ira->exec_context.mem_slot_list.length); | 14739 | assert(var->mem_slot_index < ira->exec_context.mem_slot_list.length); |
| 13773 | ConstExprValue *mem_slot = ira->exec_context.mem_slot_list.at(var->mem_slot_index); | 14740 | ConstExprValue *mem_slot = ira->exec_context.mem_slot_list.at(var->mem_slot_index); |
| 13774 | copy_const_val(mem_slot, &casted_init_value->value, !is_comptime_var || var->gen_is_const); | 14741 | copy_const_val(mem_slot, init_val, !is_comptime_var || var->gen_is_const); |
| 13775 | | 14742 | |
| 13776 | if (is_comptime_var || (var_class_requires_const && var->gen_is_const)) { | 14743 | if (is_comptime_var || (var_class_requires_const && var->gen_is_const)) { |
| 13777 | return ir_const_void(ira, &decl_var_instruction->base); | 14744 | return ir_const_void(ira, &decl_var_instruction->base); |
| ... | @@ -13788,7 +14755,7 @@ static IrInstruction *ir_analyze_instruction_decl_var(IrAnalyze *ira, | ... | @@ -13788,7 +14755,7 @@ static IrInstruction *ir_analyze_instruction_decl_var(IrAnalyze *ira, |
| 13788 | if (fn_entry) | 14755 | if (fn_entry) |
| 13789 | fn_entry->variable_list.append(var); | 14756 | fn_entry->variable_list.append(var); |
| 13790 | | 14757 | |
| 13791 | return ir_build_var_decl_gen(ira, &decl_var_instruction->base, var, casted_init_value); | 14758 | return ir_build_var_decl_gen(ira, &decl_var_instruction->base, var, var_ptr); |
| 13792 | } | 14759 | } |
| 13793 | | 14760 | |
| 13794 | static IrInstruction *ir_analyze_instruction_export(IrAnalyze *ira, IrInstructionExport *instruction) { | 14761 | static IrInstruction *ir_analyze_instruction_export(IrAnalyze *ira, IrInstructionExport *instruction) { |
| ... | @@ -14082,7 +15049,7 @@ IrInstruction *ir_get_implicit_allocator(IrAnalyze *ira, IrInstruction *source_i | ... | @@ -14082,7 +15049,7 @@ IrInstruction *ir_get_implicit_allocator(IrAnalyze *ira, IrInstruction *source_i |
| 14082 | ZigVar *coro_allocator_var = ira->old_irb.exec->coro_allocator_var; | 15049 | ZigVar *coro_allocator_var = ira->old_irb.exec->coro_allocator_var; |
| 14083 | assert(coro_allocator_var != nullptr); | 15050 | assert(coro_allocator_var != nullptr); |
| 14084 | IrInstruction *var_ptr_inst = ir_get_var_ptr(ira, source_instr, coro_allocator_var); | 15051 | IrInstruction *var_ptr_inst = ir_get_var_ptr(ira, source_instr, coro_allocator_var); |
| 14085 | IrInstruction *result = ir_get_deref(ira, source_instr, var_ptr_inst); | 15052 | IrInstruction *result = ir_get_deref(ira, source_instr, var_ptr_inst, nullptr); |
| 14086 | assert(result->value.type != nullptr); | 15053 | assert(result->value.type != nullptr); |
| 14087 | return result; | 15054 | return result; |
| 14088 | } | 15055 | } |
| ... | @@ -14090,109 +15057,543 @@ IrInstruction *ir_get_implicit_allocator(IrAnalyze *ira, IrInstruction *source_i | ... | @@ -14090,109 +15057,543 @@ IrInstruction *ir_get_implicit_allocator(IrAnalyze *ira, IrInstruction *source_i |
| 14090 | zig_unreachable(); | 15057 | zig_unreachable(); |
| 14091 | } | 15058 | } |
| 14092 | | 15059 | |
| 14093 | static IrInstruction *ir_analyze_async_call(IrAnalyze *ira, IrInstructionCall *call_instruction, ZigFn *fn_entry, | 15060 | static IrInstruction *ir_analyze_alloca(IrAnalyze *ira, IrInstruction *source_inst, ZigType *var_type, |
| 14094 | ZigType *fn_type, IrInstruction *fn_ref, IrInstruction **casted_args, size_t arg_count, | 15061 | uint32_t align, const char *name_hint, bool force_comptime) |
| 14095 | IrInstruction *async_allocator_inst) | | |
| 14096 | { | 15062 | { |
| 14097 | Buf *realloc_field_name = buf_create_from_str(ASYNC_REALLOC_FIELD_NAME); | 15063 | Error err; |
| 14098 | ir_assert(async_allocator_inst->value.type->id == ZigTypeIdPointer, &call_instruction->base); | | |
| 14099 | ZigType *container_type = async_allocator_inst->value.type->data.pointer.child_type; | | |
| 14100 | IrInstruction *field_ptr_inst = ir_analyze_container_field_ptr(ira, realloc_field_name, &call_instruction->base, | | |
| 14101 | async_allocator_inst, container_type); | | |
| 14102 | if (type_is_invalid(field_ptr_inst->value.type)) { | | |
| 14103 | return ira->codegen->invalid_instruction; | | |
| 14104 | } | | |
| 14105 | ZigType *ptr_to_realloc_fn_type = field_ptr_inst->value.type; | | |
| 14106 | ir_assert(ptr_to_realloc_fn_type->id == ZigTypeIdPointer, &call_instruction->base); | | |
| 14107 | | 15064 | |
| 14108 | ZigType *realloc_fn_type = ptr_to_realloc_fn_type->data.pointer.child_type; | 15065 | ConstExprValue *pointee = create_const_vals(1); |
| 14109 | if (realloc_fn_type->id != ZigTypeIdFn) { | 15066 | pointee->special = ConstValSpecialUndef; |
| 14110 | ir_add_error(ira, &call_instruction->base, | | |
| 14111 | buf_sprintf("expected reallocation function, found '%s'", buf_ptr(&realloc_fn_type->name))); | | |
| 14112 | return ira->codegen->invalid_instruction; | | |
| 14113 | } | | |
| 14114 | | 15067 | |
| 14115 | ZigType *realloc_fn_return_type = realloc_fn_type->data.fn.fn_type_id.return_type; | 15068 | IrInstructionAllocaGen *result = ir_create_alloca_gen(ira, source_inst, align, name_hint); |
| 14116 | if (realloc_fn_return_type->id != ZigTypeIdErrorUnion) { | 15069 | result->base.value.special = ConstValSpecialStatic; |
| 14117 | ir_add_error(ira, fn_ref, | 15070 | result->base.value.data.x_ptr.special = ConstPtrSpecialRef; |
| 14118 | buf_sprintf("expected allocation function to return error union, but it returns '%s'", buf_ptr(&realloc_fn_return_type->name))); | 15071 | result->base.value.data.x_ptr.mut = force_comptime ? ConstPtrMutComptimeVar : ConstPtrMutInfer; |
| | 15072 | result->base.value.data.x_ptr.data.ref.pointee = pointee; |
| | 15073 | |
| | 15074 | if ((err = type_resolve(ira->codegen, var_type, ResolveStatusZeroBitsKnown))) |
| 14119 | return ira->codegen->invalid_instruction; | 15075 | return ira->codegen->invalid_instruction; |
| 14120 | } | 15076 | assert(result->base.value.data.x_ptr.special != ConstPtrSpecialInvalid); |
| 14121 | ZigType *alloc_fn_error_set_type = realloc_fn_return_type->data.error_union.err_set_type; | | |
| 14122 | ZigType *return_type = fn_type->data.fn.fn_type_id.return_type; | | |
| 14123 | ZigType *promise_type = get_promise_type(ira->codegen, return_type); | | |
| 14124 | ZigType *async_return_type = get_error_union_type(ira->codegen, alloc_fn_error_set_type, promise_type); | | |
| 14125 | | 15077 | |
| 14126 | IrInstruction *result = ir_build_call(&ira->new_irb, call_instruction->base.scope, call_instruction->base.source_node, | 15078 | pointee->type = var_type; |
| 14127 | fn_entry, fn_ref, arg_count, casted_args, false, FnInlineAuto, true, async_allocator_inst, nullptr); | 15079 | result->base.value.type = get_pointer_to_type_extra(ira->codegen, var_type, false, false, |
| 14128 | result->value.type = async_return_type; | 15080 | PtrLenSingle, align, 0, 0, false); |
| 14129 | return result; | 15081 | |
| | 15082 | ZigFn *fn_entry = exec_fn_entry(ira->new_irb.exec); |
| | 15083 | if (fn_entry != nullptr) { |
| | 15084 | fn_entry->alloca_gen_list.append(result); |
| | 15085 | } |
| | 15086 | result->base.is_gen = true; |
| | 15087 | return &result->base; |
| 14130 | } | 15088 | } |
| 14131 | | 15089 | |
| 14132 | static bool ir_analyze_fn_call_inline_arg(IrAnalyze *ira, AstNode *fn_proto_node, | 15090 | static ZigType *ir_result_loc_expected_type(IrAnalyze *ira, IrInstruction *suspend_source_instr, |
| 14133 | IrInstruction *arg, Scope **exec_scope, size_t *next_proto_i) | 15091 | ResultLoc *result_loc) |
| 14134 | { | 15092 | { |
| 14135 | AstNode *param_decl_node = fn_proto_node->data.fn_proto.params.at(*next_proto_i); | 15093 | switch (result_loc->id) { |
| 14136 | assert(param_decl_node->type == NodeTypeParamDecl); | 15094 | case ResultLocIdInvalid: |
| 14137 | | 15095 | case ResultLocIdPeerParent: |
| 14138 | IrInstruction *casted_arg; | 15096 | zig_unreachable(); |
| 14139 | if (param_decl_node->data.param_decl.var_token == nullptr) { | 15097 | case ResultLocIdNone: |
| 14140 | AstNode *param_type_node = param_decl_node->data.param_decl.type; | 15098 | case ResultLocIdVar: |
| 14141 | ZigType *param_type = ir_analyze_type_expr(ira, *exec_scope, param_type_node); | 15099 | case ResultLocIdBitCast: |
| 14142 | if (type_is_invalid(param_type)) | 15100 | return nullptr; |
| 14143 | return false; | 15101 | case ResultLocIdInstruction: |
| | 15102 | return result_loc->source_instruction->child->value.type; |
| | 15103 | case ResultLocIdReturn: |
| | 15104 | return ira->explicit_return_type; |
| | 15105 | case ResultLocIdPeer: |
| | 15106 | return reinterpret_cast<ResultLocPeer*>(result_loc)->parent->resolved_type; |
| | 15107 | } |
| | 15108 | zig_unreachable(); |
| | 15109 | } |
| 14144 | | 15110 | |
| 14145 | casted_arg = ir_implicit_cast(ira, arg, param_type); | 15111 | static bool type_can_bit_cast(ZigType *t) { |
| 14146 | if (type_is_invalid(casted_arg->value.type)) | 15112 | switch (t->id) { |
| | 15113 | case ZigTypeIdInvalid: |
| | 15114 | zig_unreachable(); |
| | 15115 | case ZigTypeIdMetaType: |
| | 15116 | case ZigTypeIdOpaque: |
| | 15117 | case ZigTypeIdBoundFn: |
| | 15118 | case ZigTypeIdArgTuple: |
| | 15119 | case ZigTypeIdUnreachable: |
| | 15120 | case ZigTypeIdComptimeFloat: |
| | 15121 | case ZigTypeIdComptimeInt: |
| | 15122 | case ZigTypeIdEnumLiteral: |
| | 15123 | case ZigTypeIdUndefined: |
| | 15124 | case ZigTypeIdNull: |
| | 15125 | case ZigTypeIdPointer: |
| 14147 | return false; | 15126 | return false; |
| 14148 | } else { | 15127 | default: |
| 14149 | casted_arg = arg; | 15128 | // TODO list these types out explicitly, there are probably some other invalid ones here |
| | 15129 | return true; |
| 14150 | } | 15130 | } |
| | 15131 | } |
| 14151 | | 15132 | |
| 14152 | ConstExprValue *arg_val = ir_resolve_const(ira, casted_arg, UndefBad); | 15133 | static void set_up_result_loc_for_inferred_comptime(IrInstruction *ptr) { |
| 14153 | if (!arg_val) | 15134 | ConstExprValue *undef_child = create_const_vals(1); |
| 14154 | return false; | 15135 | undef_child->type = ptr->value.type->data.pointer.child_type; |
| 14155 | | 15136 | undef_child->special = ConstValSpecialUndef; |
| 14156 | Buf *param_name = param_decl_node->data.param_decl.name; | 15137 | ptr->value.special = ConstValSpecialStatic; |
| 14157 | ZigVar *var = add_variable(ira->codegen, param_decl_node, | 15138 | ptr->value.data.x_ptr.mut = ConstPtrMutInfer; |
| 14158 | *exec_scope, param_name, true, arg_val, nullptr, arg_val->type); | 15139 | ptr->value.data.x_ptr.special = ConstPtrSpecialRef; |
| 14159 | *exec_scope = var->child_scope; | 15140 | ptr->value.data.x_ptr.data.ref.pointee = undef_child; |
| 14160 | *next_proto_i += 1; | | |
| 14161 | | | |
| 14162 | return true; | | |
| 14163 | } | 15141 | } |
| 14164 | | 15142 | |
| 14165 | static bool ir_analyze_fn_call_generic_arg(IrAnalyze *ira, AstNode *fn_proto_node, | 15143 | // when calling this function, at the callsite must check for result type noreturn and propagate it up |
| 14166 | IrInstruction *arg, Scope **child_scope, size_t *next_proto_i, | 15144 | static IrInstruction *ir_resolve_result_raw(IrAnalyze *ira, IrInstruction *suspend_source_instr, |
| 14167 | GenericFnTypeId *generic_id, FnTypeId *fn_type_id, IrInstruction **casted_args, | 15145 | ResultLoc *result_loc, ZigType *value_type, IrInstruction *value, bool force_runtime, bool non_null_comptime) |
| 14168 | ZigFn *impl_fn) | | |
| 14169 | { | 15146 | { |
| 14170 | AstNode *param_decl_node = fn_proto_node->data.fn_proto.params.at(*next_proto_i); | 15147 | Error err; |
| 14171 | assert(param_decl_node->type == NodeTypeParamDecl); | 15148 | if (result_loc->resolved_loc != nullptr) { |
| 14172 | bool is_var_args = param_decl_node->data.param_decl.is_var_args; | 15149 | // allow to redo the result location if the value is known and comptime and the previous one isn't |
| 14173 | bool arg_part_of_generic_id = false; | 15150 | if (value == nullptr || !instr_is_comptime(value) || instr_is_comptime(result_loc->resolved_loc)) { |
| 14174 | IrInstruction *casted_arg; | 15151 | return result_loc->resolved_loc; |
| 14175 | if (is_var_args) { | | |
| 14176 | arg_part_of_generic_id = true; | | |
| 14177 | casted_arg = arg; | | |
| 14178 | } else { | | |
| 14179 | if (param_decl_node->data.param_decl.var_token == nullptr) { | | |
| 14180 | AstNode *param_type_node = param_decl_node->data.param_decl.type; | | |
| 14181 | ZigType *param_type = ir_analyze_type_expr(ira, *child_scope, param_type_node); | | |
| 14182 | if (type_is_invalid(param_type)) | | |
| 14183 | return false; | | |
| 14184 | | | |
| 14185 | casted_arg = ir_implicit_cast(ira, arg, param_type); | | |
| 14186 | if (type_is_invalid(casted_arg->value.type)) | | |
| 14187 | return false; | | |
| 14188 | } else { | | |
| 14189 | arg_part_of_generic_id = true; | | |
| 14190 | casted_arg = arg; | | |
| 14191 | } | 15152 | } |
| 14192 | } | 15153 | } |
| | 15154 | result_loc->gen_instruction = value; |
| | 15155 | result_loc->implicit_elem_type = value_type; |
| | 15156 | switch (result_loc->id) { |
| | 15157 | case ResultLocIdInvalid: |
| | 15158 | case ResultLocIdPeerParent: |
| | 15159 | zig_unreachable(); |
| | 15160 | case ResultLocIdNone: { |
| | 15161 | if (value != nullptr) { |
| | 15162 | return nullptr; |
| | 15163 | } |
| | 15164 | // need to return a result location and don't have one. use a stack allocation |
| | 15165 | IrInstructionAllocaGen *alloca_gen = ir_create_alloca_gen(ira, suspend_source_instr, 0, ""); |
| | 15166 | if ((err = type_resolve(ira->codegen, value_type, ResolveStatusZeroBitsKnown))) |
| | 15167 | return ira->codegen->invalid_instruction; |
| | 15168 | alloca_gen->base.value.type = get_pointer_to_type_extra(ira->codegen, value_type, false, false, |
| | 15169 | PtrLenSingle, 0, 0, 0, false); |
| | 15170 | set_up_result_loc_for_inferred_comptime(&alloca_gen->base); |
| | 15171 | ZigFn *fn_entry = exec_fn_entry(ira->new_irb.exec); |
| | 15172 | if (fn_entry != nullptr) { |
| | 15173 | fn_entry->alloca_gen_list.append(alloca_gen); |
| | 15174 | } |
| | 15175 | result_loc->written = true; |
| | 15176 | result_loc->resolved_loc = &alloca_gen->base; |
| | 15177 | return result_loc->resolved_loc; |
| | 15178 | } |
| | 15179 | case ResultLocIdVar: { |
| | 15180 | ResultLocVar *result_loc_var = reinterpret_cast<ResultLocVar *>(result_loc); |
| | 15181 | assert(result_loc->source_instruction->id == IrInstructionIdAllocaSrc); |
| | 15182 | |
| | 15183 | if (value_type->id == ZigTypeIdUnreachable || value_type->id == ZigTypeIdOpaque) { |
| | 15184 | ir_add_error(ira, result_loc->source_instruction, |
| | 15185 | buf_sprintf("variable of type '%s' not allowed", buf_ptr(&value_type->name))); |
| | 15186 | return ira->codegen->invalid_instruction; |
| | 15187 | } |
| 14193 | | 15188 | |
| 14194 | bool comptime_arg = param_decl_node->data.param_decl.is_inline || | 15189 | IrInstructionAllocaSrc *alloca_src = |
| 14195 | casted_arg->value.type->id == ZigTypeIdComptimeInt || casted_arg->value.type->id == ZigTypeIdComptimeFloat; | 15190 | reinterpret_cast<IrInstructionAllocaSrc *>(result_loc->source_instruction); |
| | 15191 | bool force_comptime; |
| | 15192 | if (!ir_resolve_comptime(ira, alloca_src->is_comptime->child, &force_comptime)) |
| | 15193 | return ira->codegen->invalid_instruction; |
| | 15194 | bool is_comptime = force_comptime || (value != nullptr && |
| | 15195 | value->value.special != ConstValSpecialRuntime && result_loc_var->var->gen_is_const); |
| | 15196 | |
| | 15197 | if (alloca_src->base.child == nullptr || is_comptime) { |
| | 15198 | uint32_t align = 0; |
| | 15199 | if (alloca_src->align != nullptr && !ir_resolve_align(ira, alloca_src->align->child, &align)) { |
| | 15200 | return ira->codegen->invalid_instruction; |
| | 15201 | } |
| | 15202 | IrInstruction *alloca_gen; |
| | 15203 | if (is_comptime && value != nullptr) { |
| | 15204 | if (align > value->value.global_refs->align) { |
| | 15205 | value->value.global_refs->align = align; |
| | 15206 | } |
| | 15207 | alloca_gen = ir_get_ref(ira, result_loc->source_instruction, value, true, false); |
| | 15208 | } else { |
| | 15209 | alloca_gen = ir_analyze_alloca(ira, result_loc->source_instruction, value_type, align, |
| | 15210 | alloca_src->name_hint, force_comptime); |
| | 15211 | } |
| | 15212 | if (alloca_src->base.child != nullptr) { |
| | 15213 | alloca_src->base.child->ref_count = 0; |
| | 15214 | } |
| | 15215 | alloca_src->base.child = alloca_gen; |
| | 15216 | } |
| | 15217 | result_loc->written = true; |
| | 15218 | result_loc->resolved_loc = is_comptime ? nullptr : alloca_src->base.child; |
| | 15219 | return result_loc->resolved_loc; |
| | 15220 | } |
| | 15221 | case ResultLocIdInstruction: { |
| | 15222 | result_loc->written = true; |
| | 15223 | result_loc->resolved_loc = result_loc->source_instruction->child; |
| | 15224 | return result_loc->resolved_loc; |
| | 15225 | } |
| | 15226 | case ResultLocIdReturn: { |
| | 15227 | if (!non_null_comptime) { |
| | 15228 | bool is_comptime = value != nullptr && value->value.special != ConstValSpecialRuntime; |
| | 15229 | if (is_comptime) |
| | 15230 | return nullptr; |
| | 15231 | } |
| | 15232 | if ((err = type_resolve(ira->codegen, ira->explicit_return_type, ResolveStatusZeroBitsKnown))) { |
| | 15233 | return ira->codegen->invalid_instruction; |
| | 15234 | } |
| | 15235 | if (!type_has_bits(ira->explicit_return_type) || !handle_is_ptr(ira->explicit_return_type)) |
| | 15236 | return nullptr; |
| | 15237 | |
| | 15238 | ZigType *ptr_return_type = get_pointer_to_type(ira->codegen, ira->explicit_return_type, false); |
| | 15239 | result_loc->written = true; |
| | 15240 | result_loc->resolved_loc = ir_build_return_ptr(ira, result_loc->source_instruction, ptr_return_type); |
| | 15241 | if (ir_should_inline(ira->old_irb.exec, result_loc->source_instruction->scope)) { |
| | 15242 | set_up_result_loc_for_inferred_comptime(result_loc->resolved_loc); |
| | 15243 | } |
| | 15244 | return result_loc->resolved_loc; |
| | 15245 | } |
| | 15246 | case ResultLocIdPeer: { |
| | 15247 | ResultLocPeer *result_peer = reinterpret_cast<ResultLocPeer *>(result_loc); |
| | 15248 | ResultLocPeerParent *peer_parent = result_peer->parent; |
| | 15249 | |
| | 15250 | if (peer_parent->peers.length == 1) { |
| | 15251 | IrInstruction *parent_result_loc = ir_resolve_result(ira, suspend_source_instr, peer_parent->parent, |
| | 15252 | value_type, value, force_runtime, non_null_comptime); |
| | 15253 | result_peer->suspend_pos.basic_block_index = SIZE_MAX; |
| | 15254 | result_peer->suspend_pos.instruction_index = SIZE_MAX; |
| | 15255 | if (parent_result_loc == nullptr || type_is_invalid(parent_result_loc->value.type) || |
| | 15256 | parent_result_loc->value.type->id == ZigTypeIdUnreachable) |
| | 15257 | { |
| | 15258 | return parent_result_loc; |
| | 15259 | } |
| | 15260 | result_loc->written = true; |
| | 15261 | result_loc->resolved_loc = parent_result_loc; |
| | 15262 | return result_loc->resolved_loc; |
| | 15263 | } |
| | 15264 | |
| | 15265 | bool is_comptime; |
| | 15266 | if (!ir_resolve_comptime(ira, peer_parent->is_comptime->child, &is_comptime)) |
| | 15267 | return ira->codegen->invalid_instruction; |
| | 15268 | peer_parent->skipped = is_comptime; |
| | 15269 | if (peer_parent->skipped) { |
| | 15270 | if (non_null_comptime) { |
| | 15271 | return ir_resolve_result(ira, suspend_source_instr, peer_parent->parent, |
| | 15272 | value_type, value, force_runtime, non_null_comptime); |
| | 15273 | } |
| | 15274 | return nullptr; |
| | 15275 | } |
| | 15276 | |
| | 15277 | if (peer_parent->resolved_type == nullptr) { |
| | 15278 | if (peer_parent->end_bb->suspend_instruction_ref == nullptr) { |
| | 15279 | peer_parent->end_bb->suspend_instruction_ref = suspend_source_instr; |
| | 15280 | } |
| | 15281 | IrInstruction *unreach_inst = ira_suspend(ira, suspend_source_instr, result_peer->next_bb, |
| | 15282 | &result_peer->suspend_pos); |
| | 15283 | if (result_peer->next_bb == nullptr) { |
| | 15284 | ir_start_next_bb(ira); |
| | 15285 | } |
| | 15286 | return unreach_inst; |
| | 15287 | } |
| | 15288 | |
| | 15289 | IrInstruction *parent_result_loc = ir_resolve_result(ira, suspend_source_instr, peer_parent->parent, |
| | 15290 | peer_parent->resolved_type, nullptr, force_runtime, non_null_comptime); |
| | 15291 | if (parent_result_loc == nullptr || type_is_invalid(parent_result_loc->value.type) || |
| | 15292 | parent_result_loc->value.type->id == ZigTypeIdUnreachable) |
| | 15293 | { |
| | 15294 | return parent_result_loc; |
| | 15295 | } |
| | 15296 | // because is_comptime is false, we mark this a runtime pointer |
| | 15297 | parent_result_loc->value.special = ConstValSpecialRuntime; |
| | 15298 | result_loc->written = true; |
| | 15299 | result_loc->resolved_loc = parent_result_loc; |
| | 15300 | return result_loc->resolved_loc; |
| | 15301 | } |
| | 15302 | case ResultLocIdBitCast: { |
| | 15303 | ResultLocBitCast *result_bit_cast = reinterpret_cast<ResultLocBitCast *>(result_loc); |
| | 15304 | ZigType *dest_type = ir_resolve_type(ira, result_bit_cast->base.source_instruction->child); |
| | 15305 | if (type_is_invalid(dest_type)) |
| | 15306 | return ira->codegen->invalid_instruction; |
| | 15307 | |
| | 15308 | if (get_codegen_ptr_type(dest_type) != nullptr) { |
| | 15309 | ir_add_error(ira, result_loc->source_instruction, |
| | 15310 | buf_sprintf("unable to @bitCast to pointer type '%s'", buf_ptr(&dest_type->name))); |
| | 15311 | return ira->codegen->invalid_instruction; |
| | 15312 | } |
| | 15313 | |
| | 15314 | if (!type_can_bit_cast(dest_type)) { |
| | 15315 | ir_add_error(ira, result_loc->source_instruction, |
| | 15316 | buf_sprintf("unable to @bitCast to type '%s'", buf_ptr(&dest_type->name))); |
| | 15317 | return ira->codegen->invalid_instruction; |
| | 15318 | } |
| | 15319 | |
| | 15320 | if (get_codegen_ptr_type(value_type) != nullptr) { |
| | 15321 | ir_add_error(ira, suspend_source_instr, |
| | 15322 | buf_sprintf("unable to @bitCast from pointer type '%s'", buf_ptr(&value_type->name))); |
| | 15323 | return ira->codegen->invalid_instruction; |
| | 15324 | } |
| | 15325 | |
| | 15326 | if (!type_can_bit_cast(value_type)) { |
| | 15327 | ir_add_error(ira, suspend_source_instr, |
| | 15328 | buf_sprintf("unable to @bitCast from type '%s'", buf_ptr(&value_type->name))); |
| | 15329 | return ira->codegen->invalid_instruction; |
| | 15330 | } |
| | 15331 | |
| | 15332 | IrInstruction *bitcasted_value; |
| | 15333 | if (value != nullptr) { |
| | 15334 | bitcasted_value = ir_analyze_bit_cast(ira, result_loc->source_instruction, value, dest_type); |
| | 15335 | } else { |
| | 15336 | bitcasted_value = nullptr; |
| | 15337 | } |
| | 15338 | |
| | 15339 | IrInstruction *parent_result_loc = ir_resolve_result(ira, suspend_source_instr, result_bit_cast->parent, |
| | 15340 | dest_type, bitcasted_value, force_runtime, non_null_comptime); |
| | 15341 | if (parent_result_loc == nullptr || type_is_invalid(parent_result_loc->value.type) || |
| | 15342 | parent_result_loc->value.type->id == ZigTypeIdUnreachable) |
| | 15343 | { |
| | 15344 | return parent_result_loc; |
| | 15345 | } |
| | 15346 | ZigType *parent_ptr_type = parent_result_loc->value.type; |
| | 15347 | assert(parent_ptr_type->id == ZigTypeIdPointer); |
| | 15348 | if ((err = type_resolve(ira->codegen, parent_ptr_type->data.pointer.child_type, |
| | 15349 | ResolveStatusAlignmentKnown))) |
| | 15350 | { |
| | 15351 | return ira->codegen->invalid_instruction; |
| | 15352 | } |
| | 15353 | uint64_t parent_ptr_align = get_ptr_align(ira->codegen, parent_ptr_type); |
| | 15354 | ZigType *ptr_type = get_pointer_to_type_extra(ira->codegen, value_type, |
| | 15355 | parent_ptr_type->data.pointer.is_const, parent_ptr_type->data.pointer.is_volatile, PtrLenSingle, |
| | 15356 | parent_ptr_align, 0, 0, parent_ptr_type->data.pointer.allow_zero); |
| | 15357 | |
| | 15358 | result_loc->written = true; |
| | 15359 | result_loc->resolved_loc = ir_analyze_ptr_cast(ira, suspend_source_instr, parent_result_loc, |
| | 15360 | ptr_type, result_bit_cast->base.source_instruction, false); |
| | 15361 | return result_loc->resolved_loc; |
| | 15362 | } |
| | 15363 | } |
| | 15364 | zig_unreachable(); |
| | 15365 | } |
| | 15366 | |
| | 15367 | static IrInstruction *ir_resolve_result(IrAnalyze *ira, IrInstruction *suspend_source_instr, |
| | 15368 | ResultLoc *result_loc_pass1, ZigType *value_type, IrInstruction *value, bool force_runtime, |
| | 15369 | bool non_null_comptime) |
| | 15370 | { |
| | 15371 | IrInstruction *result_loc = ir_resolve_result_raw(ira, suspend_source_instr, result_loc_pass1, value_type, |
| | 15372 | value, force_runtime, non_null_comptime); |
| | 15373 | if (result_loc == nullptr || (instr_is_unreachable(result_loc) || type_is_invalid(result_loc->value.type))) |
| | 15374 | return result_loc; |
| | 15375 | |
| | 15376 | if ((force_runtime || (value != nullptr && !instr_is_comptime(value))) && |
| | 15377 | result_loc_pass1->written && result_loc->value.data.x_ptr.mut == ConstPtrMutInfer) |
| | 15378 | { |
| | 15379 | result_loc->value.special = ConstValSpecialRuntime; |
| | 15380 | } |
| | 15381 | |
| | 15382 | ir_assert(result_loc->value.type->id == ZigTypeIdPointer, suspend_source_instr); |
| | 15383 | ZigType *actual_elem_type = result_loc->value.type->data.pointer.child_type; |
| | 15384 | if (actual_elem_type->id == ZigTypeIdOptional && value_type->id != ZigTypeIdOptional && |
| | 15385 | value_type->id != ZigTypeIdNull) |
| | 15386 | { |
| | 15387 | return ir_analyze_unwrap_optional_payload(ira, suspend_source_instr, result_loc, false, true); |
| | 15388 | } else if (actual_elem_type->id == ZigTypeIdErrorUnion && value_type->id != ZigTypeIdErrorUnion) { |
| | 15389 | if (value_type->id == ZigTypeIdErrorSet) { |
| | 15390 | return ir_analyze_unwrap_err_code(ira, suspend_source_instr, result_loc, true); |
| | 15391 | } else { |
| | 15392 | IrInstruction *unwrapped_err_ptr = ir_analyze_unwrap_error_payload(ira, suspend_source_instr, |
| | 15393 | result_loc, false, true); |
| | 15394 | ZigType *actual_payload_type = actual_elem_type->data.error_union.payload_type; |
| | 15395 | if (actual_payload_type->id == ZigTypeIdOptional && value_type->id != ZigTypeIdOptional) { |
| | 15396 | return ir_analyze_unwrap_optional_payload(ira, suspend_source_instr, unwrapped_err_ptr, false, true); |
| | 15397 | } else { |
| | 15398 | return unwrapped_err_ptr; |
| | 15399 | } |
| | 15400 | } |
| | 15401 | } else if (is_slice(actual_elem_type) && value_type->id == ZigTypeIdArray) { |
| | 15402 | // need to allow EndExpr to do the implicit cast from array to slice |
| | 15403 | result_loc_pass1->written = false; |
| | 15404 | } |
| | 15405 | return result_loc; |
| | 15406 | } |
| | 15407 | |
| | 15408 | static IrInstruction *ir_analyze_instruction_implicit_cast(IrAnalyze *ira, IrInstructionImplicitCast *instruction) { |
| | 15409 | ZigType *dest_type = ir_resolve_type(ira, instruction->dest_type->child); |
| | 15410 | if (type_is_invalid(dest_type)) |
| | 15411 | return ira->codegen->invalid_instruction; |
| | 15412 | |
| | 15413 | IrInstruction *target = instruction->target->child; |
| | 15414 | if (type_is_invalid(target->value.type)) |
| | 15415 | return ira->codegen->invalid_instruction; |
| | 15416 | |
| | 15417 | return ir_implicit_cast_with_result(ira, target, dest_type, instruction->result_loc); |
| | 15418 | } |
| | 15419 | |
| | 15420 | static IrInstruction *ir_analyze_instruction_resolve_result(IrAnalyze *ira, IrInstructionResolveResult *instruction) { |
| | 15421 | ZigType *implicit_elem_type = ir_resolve_type(ira, instruction->ty->child); |
| | 15422 | if (type_is_invalid(implicit_elem_type)) |
| | 15423 | return ira->codegen->invalid_instruction; |
| | 15424 | IrInstruction *result_loc = ir_resolve_result(ira, &instruction->base, instruction->result_loc, |
| | 15425 | implicit_elem_type, nullptr, false, true); |
| | 15426 | if (result_loc != nullptr) |
| | 15427 | return result_loc; |
| | 15428 | |
| | 15429 | ZigFn *fn = exec_fn_entry(ira->new_irb.exec); |
| | 15430 | if (fn != nullptr && fn->type_entry->data.fn.fn_type_id.cc == CallingConventionAsync && |
| | 15431 | instruction->result_loc->id == ResultLocIdReturn) |
| | 15432 | { |
| | 15433 | result_loc = ir_resolve_result(ira, &instruction->base, no_result_loc(), |
| | 15434 | implicit_elem_type, nullptr, false, true); |
| | 15435 | if (result_loc != nullptr && |
| | 15436 | (type_is_invalid(result_loc->value.type) || instr_is_unreachable(result_loc))) |
| | 15437 | { |
| | 15438 | return result_loc; |
| | 15439 | } |
| | 15440 | result_loc->value.special = ConstValSpecialRuntime; |
| | 15441 | return result_loc; |
| | 15442 | } |
| | 15443 | |
| | 15444 | IrInstruction *result = ir_const(ira, &instruction->base, implicit_elem_type); |
| | 15445 | result->value.special = ConstValSpecialUndef; |
| | 15446 | IrInstruction *ptr = ir_get_ref(ira, &instruction->base, result, false, false); |
| | 15447 | ptr->value.data.x_ptr.mut = ConstPtrMutComptimeVar; |
| | 15448 | return ptr; |
| | 15449 | } |
| | 15450 | |
| | 15451 | static void ir_reset_result(ResultLoc *result_loc) { |
| | 15452 | result_loc->written = false; |
| | 15453 | result_loc->resolved_loc = nullptr; |
| | 15454 | result_loc->gen_instruction = nullptr; |
| | 15455 | result_loc->implicit_elem_type = nullptr; |
| | 15456 | switch (result_loc->id) { |
| | 15457 | case ResultLocIdInvalid: |
| | 15458 | zig_unreachable(); |
| | 15459 | case ResultLocIdPeerParent: { |
| | 15460 | ResultLocPeerParent *peer_parent = reinterpret_cast<ResultLocPeerParent *>(result_loc); |
| | 15461 | peer_parent->skipped = false; |
| | 15462 | peer_parent->done_resuming = false; |
| | 15463 | peer_parent->resolved_type = nullptr; |
| | 15464 | for (size_t i = 0; i < peer_parent->peers.length; i += 1) { |
| | 15465 | ir_reset_result(&peer_parent->peers.at(i)->base); |
| | 15466 | } |
| | 15467 | break; |
| | 15468 | } |
| | 15469 | case ResultLocIdVar: { |
| | 15470 | IrInstructionAllocaSrc *alloca_src = |
| | 15471 | reinterpret_cast<IrInstructionAllocaSrc *>(result_loc->source_instruction); |
| | 15472 | alloca_src->base.child = nullptr; |
| | 15473 | break; |
| | 15474 | } |
| | 15475 | case ResultLocIdPeer: |
| | 15476 | case ResultLocIdNone: |
| | 15477 | case ResultLocIdReturn: |
| | 15478 | case ResultLocIdInstruction: |
| | 15479 | case ResultLocIdBitCast: |
| | 15480 | break; |
| | 15481 | } |
| | 15482 | } |
| | 15483 | |
| | 15484 | static IrInstruction *ir_analyze_instruction_reset_result(IrAnalyze *ira, IrInstructionResetResult *instruction) { |
| | 15485 | ir_reset_result(instruction->result_loc); |
| | 15486 | return ir_const_void(ira, &instruction->base); |
| | 15487 | } |
| | 15488 | |
| | 15489 | static IrInstruction *ir_analyze_async_call(IrAnalyze *ira, IrInstructionCallSrc *call_instruction, ZigFn *fn_entry, |
| | 15490 | ZigType *fn_type, IrInstruction *fn_ref, IrInstruction **casted_args, size_t arg_count, |
| | 15491 | IrInstruction *async_allocator_inst) |
| | 15492 | { |
| | 15493 | Buf *realloc_field_name = buf_create_from_str(ASYNC_REALLOC_FIELD_NAME); |
| | 15494 | ir_assert(async_allocator_inst->value.type->id == ZigTypeIdPointer, &call_instruction->base); |
| | 15495 | ZigType *container_type = async_allocator_inst->value.type->data.pointer.child_type; |
| | 15496 | IrInstruction *field_ptr_inst = ir_analyze_container_field_ptr(ira, realloc_field_name, &call_instruction->base, |
| | 15497 | async_allocator_inst, container_type, false); |
| | 15498 | if (type_is_invalid(field_ptr_inst->value.type)) { |
| | 15499 | return ira->codegen->invalid_instruction; |
| | 15500 | } |
| | 15501 | ZigType *ptr_to_realloc_fn_type = field_ptr_inst->value.type; |
| | 15502 | ir_assert(ptr_to_realloc_fn_type->id == ZigTypeIdPointer, &call_instruction->base); |
| | 15503 | |
| | 15504 | ZigType *realloc_fn_type = ptr_to_realloc_fn_type->data.pointer.child_type; |
| | 15505 | if (realloc_fn_type->id != ZigTypeIdFn) { |
| | 15506 | ir_add_error(ira, &call_instruction->base, |
| | 15507 | buf_sprintf("expected reallocation function, found '%s'", buf_ptr(&realloc_fn_type->name))); |
| | 15508 | return ira->codegen->invalid_instruction; |
| | 15509 | } |
| | 15510 | |
| | 15511 | ZigType *realloc_fn_return_type = realloc_fn_type->data.fn.fn_type_id.return_type; |
| | 15512 | if (realloc_fn_return_type->id != ZigTypeIdErrorUnion) { |
| | 15513 | ir_add_error(ira, fn_ref, |
| | 15514 | buf_sprintf("expected allocation function to return error union, but it returns '%s'", buf_ptr(&realloc_fn_return_type->name))); |
| | 15515 | return ira->codegen->invalid_instruction; |
| | 15516 | } |
| | 15517 | ZigType *alloc_fn_error_set_type = realloc_fn_return_type->data.error_union.err_set_type; |
| | 15518 | ZigType *return_type = fn_type->data.fn.fn_type_id.return_type; |
| | 15519 | ZigType *promise_type = get_promise_type(ira->codegen, return_type); |
| | 15520 | ZigType *async_return_type = get_error_union_type(ira->codegen, alloc_fn_error_set_type, promise_type); |
| | 15521 | |
| | 15522 | IrInstruction *result_loc = ir_resolve_result(ira, &call_instruction->base, no_result_loc(), |
| | 15523 | async_return_type, nullptr, true, true); |
| | 15524 | if (type_is_invalid(result_loc->value.type) || instr_is_unreachable(result_loc)) { |
| | 15525 | return result_loc; |
| | 15526 | } |
| | 15527 | |
| | 15528 | return ir_build_call_gen(ira, &call_instruction->base, fn_entry, fn_ref, arg_count, |
| | 15529 | casted_args, FnInlineAuto, true, async_allocator_inst, nullptr, result_loc, |
| | 15530 | async_return_type); |
| | 15531 | } |
| | 15532 | |
| | 15533 | static bool ir_analyze_fn_call_inline_arg(IrAnalyze *ira, AstNode *fn_proto_node, |
| | 15534 | IrInstruction *arg, Scope **exec_scope, size_t *next_proto_i) |
| | 15535 | { |
| | 15536 | AstNode *param_decl_node = fn_proto_node->data.fn_proto.params.at(*next_proto_i); |
| | 15537 | assert(param_decl_node->type == NodeTypeParamDecl); |
| | 15538 | |
| | 15539 | IrInstruction *casted_arg; |
| | 15540 | if (param_decl_node->data.param_decl.var_token == nullptr) { |
| | 15541 | AstNode *param_type_node = param_decl_node->data.param_decl.type; |
| | 15542 | ZigType *param_type = ir_analyze_type_expr(ira, *exec_scope, param_type_node); |
| | 15543 | if (type_is_invalid(param_type)) |
| | 15544 | return false; |
| | 15545 | |
| | 15546 | casted_arg = ir_implicit_cast(ira, arg, param_type); |
| | 15547 | if (type_is_invalid(casted_arg->value.type)) |
| | 15548 | return false; |
| | 15549 | } else { |
| | 15550 | casted_arg = arg; |
| | 15551 | } |
| | 15552 | |
| | 15553 | ConstExprValue *arg_val = ir_resolve_const(ira, casted_arg, UndefOk); |
| | 15554 | if (!arg_val) |
| | 15555 | return false; |
| | 15556 | |
| | 15557 | Buf *param_name = param_decl_node->data.param_decl.name; |
| | 15558 | ZigVar *var = add_variable(ira->codegen, param_decl_node, |
| | 15559 | *exec_scope, param_name, true, arg_val, nullptr, arg_val->type); |
| | 15560 | *exec_scope = var->child_scope; |
| | 15561 | *next_proto_i += 1; |
| | 15562 | |
| | 15563 | return true; |
| | 15564 | } |
| | 15565 | |
| | 15566 | static bool ir_analyze_fn_call_generic_arg(IrAnalyze *ira, AstNode *fn_proto_node, |
| | 15567 | IrInstruction *arg, Scope **child_scope, size_t *next_proto_i, |
| | 15568 | GenericFnTypeId *generic_id, FnTypeId *fn_type_id, IrInstruction **casted_args, |
| | 15569 | ZigFn *impl_fn) |
| | 15570 | { |
| | 15571 | AstNode *param_decl_node = fn_proto_node->data.fn_proto.params.at(*next_proto_i); |
| | 15572 | assert(param_decl_node->type == NodeTypeParamDecl); |
| | 15573 | bool is_var_args = param_decl_node->data.param_decl.is_var_args; |
| | 15574 | bool arg_part_of_generic_id = false; |
| | 15575 | IrInstruction *casted_arg; |
| | 15576 | if (is_var_args) { |
| | 15577 | arg_part_of_generic_id = true; |
| | 15578 | casted_arg = arg; |
| | 15579 | } else { |
| | 15580 | if (param_decl_node->data.param_decl.var_token == nullptr) { |
| | 15581 | AstNode *param_type_node = param_decl_node->data.param_decl.type; |
| | 15582 | ZigType *param_type = ir_analyze_type_expr(ira, *child_scope, param_type_node); |
| | 15583 | if (type_is_invalid(param_type)) |
| | 15584 | return false; |
| | 15585 | |
| | 15586 | casted_arg = ir_implicit_cast(ira, arg, param_type); |
| | 15587 | if (type_is_invalid(casted_arg->value.type)) |
| | 15588 | return false; |
| | 15589 | } else { |
| | 15590 | arg_part_of_generic_id = true; |
| | 15591 | casted_arg = arg; |
| | 15592 | } |
| | 15593 | } |
| | 15594 | |
| | 15595 | bool comptime_arg = param_decl_node->data.param_decl.is_inline || |
| | 15596 | casted_arg->value.type->id == ZigTypeIdComptimeInt || casted_arg->value.type->id == ZigTypeIdComptimeFloat; |
| 14196 | | 15597 | |
| 14197 | ConstExprValue *arg_val; | 15598 | ConstExprValue *arg_val; |
| 14198 | | 15599 | |
| ... | @@ -14205,7 +15606,7 @@ static bool ir_analyze_fn_call_generic_arg(IrAnalyze *ira, AstNode *fn_proto_nod | ... | @@ -14205,7 +15606,7 @@ static bool ir_analyze_fn_call_generic_arg(IrAnalyze *ira, AstNode *fn_proto_nod |
| 14205 | arg_val = create_const_runtime(casted_arg->value.type); | 15606 | arg_val = create_const_runtime(casted_arg->value.type); |
| 14206 | } | 15607 | } |
| 14207 | if (arg_part_of_generic_id) { | 15608 | if (arg_part_of_generic_id) { |
| 14208 | generic_id->params[generic_id->param_count] = *arg_val; | 15609 | copy_const_val(&generic_id->params[generic_id->param_count], arg_val, true); |
| 14209 | generic_id->param_count += 1; | 15610 | generic_id->param_count += 1; |
| 14210 | } | 15611 | } |
| 14211 | | 15612 | |
| ... | @@ -14376,7 +15777,9 @@ static IrInstruction *ir_analyze_store_ptr(IrAnalyze *ira, IrInstruction *source | ... | @@ -14376,7 +15777,9 @@ static IrInstruction *ir_analyze_store_ptr(IrAnalyze *ira, IrInstruction *source |
| 14376 | ir_add_error(ira, source_instr, buf_sprintf("cannot assign to constant")); | 15777 | ir_add_error(ira, source_instr, buf_sprintf("cannot assign to constant")); |
| 14377 | return ira->codegen->invalid_instruction; | 15778 | return ira->codegen->invalid_instruction; |
| 14378 | } | 15779 | } |
| 14379 | if (ptr->value.data.x_ptr.mut == ConstPtrMutComptimeVar) { | 15780 | if (ptr->value.data.x_ptr.mut == ConstPtrMutComptimeVar || |
| | 15781 | ptr->value.data.x_ptr.mut == ConstPtrMutInfer) |
| | 15782 | { |
| 14380 | if (instr_is_comptime(value)) { | 15783 | if (instr_is_comptime(value)) { |
| 14381 | ConstExprValue *dest_val = const_ptr_pointee(ira, ira->codegen, &ptr->value, source_instr->source_node); | 15784 | ConstExprValue *dest_val = const_ptr_pointee(ira, ira->codegen, &ptr->value, source_instr->source_node); |
| 14382 | if (dest_val == nullptr) | 15785 | if (dest_val == nullptr) |
| ... | @@ -14390,18 +15793,24 @@ static IrInstruction *ir_analyze_store_ptr(IrAnalyze *ira, IrInstruction *source | ... | @@ -14390,18 +15793,24 @@ static IrInstruction *ir_analyze_store_ptr(IrAnalyze *ira, IrInstruction *source |
| 14390 | // ConstPtrMutComptimeVar, thus defeating the logic below. | 15793 | // ConstPtrMutComptimeVar, thus defeating the logic below. |
| 14391 | bool same_global_refs = ptr->value.data.x_ptr.mut != ConstPtrMutComptimeVar; | 15794 | bool same_global_refs = ptr->value.data.x_ptr.mut != ConstPtrMutComptimeVar; |
| 14392 | copy_const_val(dest_val, &value->value, same_global_refs); | 15795 | copy_const_val(dest_val, &value->value, same_global_refs); |
| 14393 | if (!ira->new_irb.current_basic_block->must_be_comptime_source_instr) { | 15796 | if (ptr->value.data.x_ptr.mut == ConstPtrMutComptimeVar && |
| | 15797 | !ira->new_irb.current_basic_block->must_be_comptime_source_instr) |
| | 15798 | { |
| 14394 | ira->new_irb.current_basic_block->must_be_comptime_source_instr = source_instr; | 15799 | ira->new_irb.current_basic_block->must_be_comptime_source_instr = source_instr; |
| 14395 | } | 15800 | } |
| 14396 | return ir_const_void(ira, source_instr); | 15801 | return ir_const_void(ira, source_instr); |
| 14397 | } | 15802 | } |
| 14398 | } | 15803 | } |
| 14399 | ir_add_error(ira, source_instr, | 15804 | if (ptr->value.data.x_ptr.mut == ConstPtrMutInfer) { |
| 14400 | buf_sprintf("cannot store runtime value in compile time variable")); | 15805 | ptr->value.special = ConstValSpecialRuntime; |
| 14401 | ConstExprValue *dest_val = const_ptr_pointee_unchecked(ira->codegen, &ptr->value); | 15806 | } else { |
| 14402 | dest_val->type = ira->codegen->builtin_types.entry_invalid; | 15807 | ir_add_error(ira, source_instr, |
| | 15808 | buf_sprintf("cannot store runtime value in compile time variable")); |
| | 15809 | ConstExprValue *dest_val = const_ptr_pointee_unchecked(ira->codegen, &ptr->value); |
| | 15810 | dest_val->type = ira->codegen->builtin_types.entry_invalid; |
| 14403 | | 15811 | |
| 14404 | return ira->codegen->invalid_instruction; | 15812 | return ira->codegen->invalid_instruction; |
| | 15813 | } |
| 14405 | } | 15814 | } |
| 14406 | } | 15815 | } |
| 14407 | | 15816 | |
| ... | @@ -14430,7 +15839,7 @@ static IrInstruction *ir_analyze_store_ptr(IrAnalyze *ira, IrInstruction *source | ... | @@ -14430,7 +15839,7 @@ static IrInstruction *ir_analyze_store_ptr(IrAnalyze *ira, IrInstruction *source |
| 14430 | return result; | 15839 | return result; |
| 14431 | } | 15840 | } |
| 14432 | | 15841 | |
| 14433 | static IrInstruction *ir_analyze_fn_call(IrAnalyze *ira, IrInstructionCall *call_instruction, | 15842 | static IrInstruction *ir_analyze_fn_call(IrAnalyze *ira, IrInstructionCallSrc *call_instruction, |
| 14434 | ZigFn *fn_entry, ZigType *fn_type, IrInstruction *fn_ref, | 15843 | ZigFn *fn_entry, ZigType *fn_type, IrInstruction *fn_ref, |
| 14435 | IrInstruction *first_arg_ptr, bool comptime_fn_call, FnInline fn_inline) | 15844 | IrInstruction *first_arg_ptr, bool comptime_fn_call, FnInline fn_inline) |
| 14436 | { | 15845 | { |
| ... | @@ -14533,7 +15942,7 @@ static IrInstruction *ir_analyze_fn_call(IrAnalyze *ira, IrInstructionCall *call | ... | @@ -14533,7 +15942,7 @@ static IrInstruction *ir_analyze_fn_call(IrAnalyze *ira, IrInstructionCall *call |
| 14533 | if (!first_arg_known_bare && handle_is_ptr(first_arg_ptr->value.type->data.pointer.child_type)) { | 15942 | if (!first_arg_known_bare && handle_is_ptr(first_arg_ptr->value.type->data.pointer.child_type)) { |
| 14534 | first_arg = first_arg_ptr; | 15943 | first_arg = first_arg_ptr; |
| 14535 | } else { | 15944 | } else { |
| 14536 | first_arg = ir_get_deref(ira, first_arg_ptr, first_arg_ptr); | 15945 | first_arg = ir_get_deref(ira, first_arg_ptr, first_arg_ptr, nullptr); |
| 14537 | if (type_is_invalid(first_arg->value.type)) | 15946 | if (type_is_invalid(first_arg->value.type)) |
| 14538 | return ira->codegen->invalid_instruction; | 15947 | return ira->codegen->invalid_instruction; |
| 14539 | } | 15948 | } |
| ... | @@ -14692,7 +16101,7 @@ static IrInstruction *ir_analyze_fn_call(IrAnalyze *ira, IrInstructionCall *call | ... | @@ -14692,7 +16101,7 @@ static IrInstruction *ir_analyze_fn_call(IrAnalyze *ira, IrInstructionCall *call |
| 14692 | if (!first_arg_known_bare && handle_is_ptr(first_arg_ptr->value.type->data.pointer.child_type)) { | 16101 | if (!first_arg_known_bare && handle_is_ptr(first_arg_ptr->value.type->data.pointer.child_type)) { |
| 14693 | first_arg = first_arg_ptr; | 16102 | first_arg = first_arg_ptr; |
| 14694 | } else { | 16103 | } else { |
| 14695 | first_arg = ir_get_deref(ira, first_arg_ptr, first_arg_ptr); | 16104 | first_arg = ir_get_deref(ira, first_arg_ptr, first_arg_ptr, nullptr); |
| 14696 | if (type_is_invalid(first_arg->value.type)) | 16105 | if (type_is_invalid(first_arg->value.type)) |
| 14697 | return ira->codegen->invalid_instruction; | 16106 | return ira->codegen->invalid_instruction; |
| 14698 | } | 16107 | } |
| ... | @@ -14736,7 +16145,7 @@ static IrInstruction *ir_analyze_fn_call(IrAnalyze *ira, IrInstructionCall *call | ... | @@ -14736,7 +16145,7 @@ static IrInstruction *ir_analyze_fn_call(IrAnalyze *ira, IrInstructionCall *call |
| 14736 | if (type_is_invalid(arg_var_ptr_inst->value.type)) | 16145 | if (type_is_invalid(arg_var_ptr_inst->value.type)) |
| 14737 | return ira->codegen->invalid_instruction; | 16146 | return ira->codegen->invalid_instruction; |
| 14738 | | 16147 | |
| 14739 | IrInstruction *arg_tuple_arg = ir_get_deref(ira, arg, arg_var_ptr_inst); | 16148 | IrInstruction *arg_tuple_arg = ir_get_deref(ira, arg, arg_var_ptr_inst, nullptr); |
| 14740 | if (type_is_invalid(arg_tuple_arg->value.type)) | 16149 | if (type_is_invalid(arg_tuple_arg->value.type)) |
| 14741 | return ira->codegen->invalid_instruction; | 16150 | return ira->codegen->invalid_instruction; |
| 14742 | | 16151 | |
| ... | @@ -14785,7 +16194,7 @@ static IrInstruction *ir_analyze_fn_call(IrAnalyze *ira, IrInstructionCall *call | ... | @@ -14785,7 +16194,7 @@ static IrInstruction *ir_analyze_fn_call(IrAnalyze *ira, IrInstructionCall *call |
| 14785 | nullptr, nullptr, fn_proto_node->data.fn_proto.align_expr, nullptr, ira->new_irb.exec, nullptr); | 16194 | nullptr, nullptr, fn_proto_node->data.fn_proto.align_expr, nullptr, ira->new_irb.exec, nullptr); |
| 14786 | IrInstructionConst *const_instruction = ir_create_instruction<IrInstructionConst>(&ira->new_irb, | 16195 | IrInstructionConst *const_instruction = ir_create_instruction<IrInstructionConst>(&ira->new_irb, |
| 14787 | impl_fn->child_scope, fn_proto_node->data.fn_proto.align_expr); | 16196 | impl_fn->child_scope, fn_proto_node->data.fn_proto.align_expr); |
| 14788 | const_instruction->base.value = *align_result; | 16197 | copy_const_val(&const_instruction->base.value, align_result, true); |
| 14789 | | 16198 | |
| 14790 | uint32_t align_bytes = 0; | 16199 | uint32_t align_bytes = 0; |
| 14791 | ir_resolve_align(ira, &const_instruction->base, &align_bytes); | 16200 | ir_resolve_align(ira, &const_instruction->base, &align_bytes); |
| ... | @@ -14867,6 +16276,19 @@ static IrInstruction *ir_analyze_fn_call(IrAnalyze *ira, IrInstructionCall *call | ... | @@ -14867,6 +16276,19 @@ static IrInstruction *ir_analyze_fn_call(IrAnalyze *ira, IrInstructionCall *call |
| 14867 | } | 16276 | } |
| 14868 | | 16277 | |
| 14869 | FnTypeId *impl_fn_type_id = &impl_fn->type_entry->data.fn.fn_type_id; | 16278 | FnTypeId *impl_fn_type_id = &impl_fn->type_entry->data.fn.fn_type_id; |
| | 16279 | IrInstruction *result_loc; |
| | 16280 | if (handle_is_ptr(impl_fn_type_id->return_type)) { |
| | 16281 | result_loc = ir_resolve_result(ira, &call_instruction->base, call_instruction->result_loc, |
| | 16282 | impl_fn_type_id->return_type, nullptr, true, true); |
| | 16283 | if (result_loc != nullptr && (type_is_invalid(result_loc->value.type) || |
| | 16284 | instr_is_unreachable(result_loc))) |
| | 16285 | { |
| | 16286 | return result_loc; |
| | 16287 | } |
| | 16288 | } else { |
| | 16289 | result_loc = nullptr; |
| | 16290 | } |
| | 16291 | |
| 14870 | if (fn_type_can_fail(impl_fn_type_id)) { | 16292 | if (fn_type_can_fail(impl_fn_type_id)) { |
| 14871 | parent_fn_entry->calls_or_awaits_errorable_fn = true; | 16293 | parent_fn_entry->calls_or_awaits_errorable_fn = true; |
| 14872 | } | 16294 | } |
| ... | @@ -14875,18 +16297,14 @@ static IrInstruction *ir_analyze_fn_call(IrAnalyze *ira, IrInstructionCall *call | ... | @@ -14875,18 +16297,14 @@ static IrInstruction *ir_analyze_fn_call(IrAnalyze *ira, IrInstructionCall *call |
| 14875 | if (call_instruction->is_async) { | 16297 | if (call_instruction->is_async) { |
| 14876 | IrInstruction *result = ir_analyze_async_call(ira, call_instruction, impl_fn, impl_fn->type_entry, | 16298 | IrInstruction *result = ir_analyze_async_call(ira, call_instruction, impl_fn, impl_fn->type_entry, |
| 14877 | fn_ref, casted_args, impl_param_count, async_allocator_inst); | 16299 | fn_ref, casted_args, impl_param_count, async_allocator_inst); |
| 14878 | ir_add_alloca(ira, result, result->value.type); | | |
| 14879 | return ir_finish_anal(ira, result); | 16300 | return ir_finish_anal(ira, result); |
| 14880 | } | 16301 | } |
| 14881 | | 16302 | |
| 14882 | assert(async_allocator_inst == nullptr); | 16303 | assert(async_allocator_inst == nullptr); |
| 14883 | IrInstruction *new_call_instruction = ir_build_call(&ira->new_irb, | 16304 | IrInstruction *new_call_instruction = ir_build_call_gen(ira, &call_instruction->base, |
| 14884 | call_instruction->base.scope, call_instruction->base.source_node, | 16305 | impl_fn, nullptr, impl_param_count, casted_args, fn_inline, |
| 14885 | impl_fn, nullptr, impl_param_count, casted_args, false, fn_inline, | 16306 | call_instruction->is_async, nullptr, casted_new_stack, result_loc, |
| 14886 | call_instruction->is_async, nullptr, casted_new_stack); | 16307 | impl_fn_type_id->return_type); |
| 14887 | new_call_instruction->value.type = impl_fn_type_id->return_type; | | |
| 14888 | | | |
| 14889 | ir_add_alloca(ira, new_call_instruction, impl_fn_type_id->return_type); | | |
| 14890 | | 16308 | |
| 14891 | return ir_finish_anal(ira, new_call_instruction); | 16309 | return ir_finish_anal(ira, new_call_instruction); |
| 14892 | } | 16310 | } |
| ... | @@ -14914,7 +16332,7 @@ static IrInstruction *ir_analyze_fn_call(IrAnalyze *ira, IrInstructionCall *call | ... | @@ -14914,7 +16332,7 @@ static IrInstruction *ir_analyze_fn_call(IrAnalyze *ira, IrInstructionCall *call |
| 14914 | { | 16332 | { |
| 14915 | first_arg = first_arg_ptr; | 16333 | first_arg = first_arg_ptr; |
| 14916 | } else { | 16334 | } else { |
| 14917 | first_arg = ir_get_deref(ira, first_arg_ptr, first_arg_ptr); | 16335 | first_arg = ir_get_deref(ira, first_arg_ptr, first_arg_ptr, nullptr); |
| 14918 | if (type_is_invalid(first_arg->value.type)) | 16336 | if (type_is_invalid(first_arg->value.type)) |
| 14919 | return ira->codegen->invalid_instruction; | 16337 | return ira->codegen->invalid_instruction; |
| 14920 | } | 16338 | } |
| ... | @@ -14971,7 +16389,6 @@ static IrInstruction *ir_analyze_fn_call(IrAnalyze *ira, IrInstructionCall *call | ... | @@ -14971,7 +16389,6 @@ static IrInstruction *ir_analyze_fn_call(IrAnalyze *ira, IrInstructionCall *call |
| 14971 | | 16389 | |
| 14972 | IrInstruction *result = ir_analyze_async_call(ira, call_instruction, fn_entry, fn_type, fn_ref, | 16390 | IrInstruction *result = ir_analyze_async_call(ira, call_instruction, fn_entry, fn_type, fn_ref, |
| 14973 | casted_args, call_param_count, async_allocator_inst); | 16391 | casted_args, call_param_count, async_allocator_inst); |
| 14974 | ir_add_alloca(ira, result, result->value.type); | | |
| 14975 | return ir_finish_anal(ira, result); | 16392 | return ir_finish_anal(ira, result); |
| 14976 | } | 16393 | } |
| 14977 | | 16394 | |
| ... | @@ -14981,15 +16398,24 @@ static IrInstruction *ir_analyze_fn_call(IrAnalyze *ira, IrInstructionCall *call | ... | @@ -14981,15 +16398,24 @@ static IrInstruction *ir_analyze_fn_call(IrAnalyze *ira, IrInstructionCall *call |
| 14981 | return ira->codegen->invalid_instruction; | 16398 | return ira->codegen->invalid_instruction; |
| 14982 | } | 16399 | } |
| 14983 | | 16400 | |
| 14984 | IrInstruction *new_call_instruction = ir_build_call(&ira->new_irb, | 16401 | IrInstruction *result_loc; |
| 14985 | call_instruction->base.scope, call_instruction->base.source_node, | 16402 | if (handle_is_ptr(return_type)) { |
| 14986 | fn_entry, fn_ref, call_param_count, casted_args, false, fn_inline, false, nullptr, casted_new_stack); | 16403 | result_loc = ir_resolve_result(ira, &call_instruction->base, call_instruction->result_loc, |
| 14987 | new_call_instruction->value.type = return_type; | 16404 | return_type, nullptr, true, true); |
| 14988 | ir_add_alloca(ira, new_call_instruction, return_type); | 16405 | if (result_loc != nullptr && (type_is_invalid(result_loc->value.type) || instr_is_unreachable(result_loc))) { |
| | 16406 | return result_loc; |
| | 16407 | } |
| | 16408 | } else { |
| | 16409 | result_loc = nullptr; |
| | 16410 | } |
| | 16411 | |
| | 16412 | IrInstruction *new_call_instruction = ir_build_call_gen(ira, &call_instruction->base, fn_entry, fn_ref, |
| | 16413 | call_param_count, casted_args, fn_inline, false, nullptr, casted_new_stack, |
| | 16414 | result_loc, return_type); |
| 14989 | return ir_finish_anal(ira, new_call_instruction); | 16415 | return ir_finish_anal(ira, new_call_instruction); |
| 14990 | } | 16416 | } |
| 14991 | | 16417 | |
| 14992 | static IrInstruction *ir_analyze_instruction_call(IrAnalyze *ira, IrInstructionCall *call_instruction) { | 16418 | static IrInstruction *ir_analyze_instruction_call(IrAnalyze *ira, IrInstructionCallSrc *call_instruction) { |
| 14993 | IrInstruction *fn_ref = call_instruction->fn_ref->child; | 16419 | IrInstruction *fn_ref = call_instruction->fn_ref->child; |
| 14994 | if (type_is_invalid(fn_ref->value.type)) | 16420 | if (type_is_invalid(fn_ref->value.type)) |
| 14995 | return ira->codegen->invalid_instruction; | 16421 | return ira->codegen->invalid_instruction; |
| ... | @@ -15013,7 +16439,8 @@ static IrInstruction *ir_analyze_instruction_call(IrAnalyze *ira, IrInstructionC | ... | @@ -15013,7 +16439,8 @@ static IrInstruction *ir_analyze_instruction_call(IrAnalyze *ira, IrInstructionC |
| 15013 | | 16439 | |
| 15014 | IrInstruction *arg = call_instruction->args[0]->child; | 16440 | IrInstruction *arg = call_instruction->args[0]->child; |
| 15015 | | 16441 | |
| 15016 | IrInstruction *cast_instruction = ir_analyze_cast(ira, &call_instruction->base, dest_type, arg); | 16442 | IrInstruction *cast_instruction = ir_analyze_cast(ira, &call_instruction->base, dest_type, arg, |
| | 16443 | call_instruction->result_loc); |
| 15017 | if (type_is_invalid(cast_instruction->value.type)) | 16444 | if (type_is_invalid(cast_instruction->value.type)) |
| 15018 | return ira->codegen->invalid_instruction; | 16445 | return ira->codegen->invalid_instruction; |
| 15019 | return ir_finish_anal(ira, cast_instruction); | 16446 | return ir_finish_anal(ira, cast_instruction); |
| ... | @@ -15066,7 +16493,7 @@ static Error ir_read_const_ptr(IrAnalyze *ira, CodeGen *codegen, AstNode *source | ... | @@ -15066,7 +16493,7 @@ static Error ir_read_const_ptr(IrAnalyze *ira, CodeGen *codegen, AstNode *source |
| 15066 | | 16493 | |
| 15067 | if (dst_size <= src_size) { | 16494 | if (dst_size <= src_size) { |
| 15068 | if (src_size == dst_size && types_have_same_zig_comptime_repr(pointee->type, out_val->type)) { | 16495 | if (src_size == dst_size && types_have_same_zig_comptime_repr(pointee->type, out_val->type)) { |
| 15069 | copy_const_val(out_val, pointee, ptr_val->data.x_ptr.mut == ConstPtrMutComptimeConst); | 16496 | copy_const_val(out_val, pointee, ptr_val->data.x_ptr.mut != ConstPtrMutComptimeVar); |
| 15070 | return ErrorNone; | 16497 | return ErrorNone; |
| 15071 | } | 16498 | } |
| 15072 | Buf buf = BUF_INIT; | 16499 | Buf buf = BUF_INIT; |
| ... | @@ -15315,7 +16742,7 @@ static IrInstruction *ir_analyze_instruction_un_op(IrAnalyze *ira, IrInstruction | ... | @@ -15315,7 +16742,7 @@ static IrInstruction *ir_analyze_instruction_un_op(IrAnalyze *ira, IrInstruction |
| 15315 | return ira->codegen->invalid_instruction; | 16742 | return ira->codegen->invalid_instruction; |
| 15316 | } | 16743 | } |
| 15317 | | 16744 | |
| 15318 | IrInstruction *result = ir_get_deref(ira, &instruction->base, ptr); | 16745 | IrInstruction *result = ir_get_deref(ira, &instruction->base, ptr, instruction->result_loc); |
| 15319 | if (result == ira->codegen->invalid_instruction) | 16746 | if (result == ira->codegen->invalid_instruction) |
| 15320 | return ira->codegen->invalid_instruction; | 16747 | return ira->codegen->invalid_instruction; |
| 15321 | | 16748 | |
| ... | @@ -15334,6 +16761,19 @@ static IrInstruction *ir_analyze_instruction_un_op(IrAnalyze *ira, IrInstruction | ... | @@ -15334,6 +16761,19 @@ static IrInstruction *ir_analyze_instruction_un_op(IrAnalyze *ira, IrInstruction |
| 15334 | zig_unreachable(); | 16761 | zig_unreachable(); |
| 15335 | } | 16762 | } |
| 15336 | | 16763 | |
| | 16764 | static void ir_push_resume(IrAnalyze *ira, IrSuspendPosition pos) { |
| | 16765 | IrBasicBlock *old_bb = ira->old_irb.exec->basic_block_list.at(pos.basic_block_index); |
| | 16766 | if (old_bb->in_resume_stack) return; |
| | 16767 | ira->resume_stack.append(pos); |
| | 16768 | old_bb->in_resume_stack = true; |
| | 16769 | } |
| | 16770 | |
| | 16771 | static void ir_push_resume_block(IrAnalyze *ira, IrBasicBlock *old_bb) { |
| | 16772 | if (ira->resume_stack.length != 0) { |
| | 16773 | ir_push_resume(ira, {old_bb->index, 0}); |
| | 16774 | } |
| | 16775 | } |
| | 16776 | |
| 15337 | static IrInstruction *ir_analyze_instruction_br(IrAnalyze *ira, IrInstructionBr *br_instruction) { | 16777 | static IrInstruction *ir_analyze_instruction_br(IrAnalyze *ira, IrInstructionBr *br_instruction) { |
| 15338 | IrBasicBlock *old_dest_block = br_instruction->dest_block; | 16778 | IrBasicBlock *old_dest_block = br_instruction->dest_block; |
| 15339 | | 16779 | |
| ... | @@ -15341,13 +16781,15 @@ static IrInstruction *ir_analyze_instruction_br(IrAnalyze *ira, IrInstructionBr | ... | @@ -15341,13 +16781,15 @@ static IrInstruction *ir_analyze_instruction_br(IrAnalyze *ira, IrInstructionBr |
| 15341 | if (!ir_resolve_comptime(ira, br_instruction->is_comptime->child, &is_comptime)) | 16781 | if (!ir_resolve_comptime(ira, br_instruction->is_comptime->child, &is_comptime)) |
| 15342 | return ir_unreach_error(ira); | 16782 | return ir_unreach_error(ira); |
| 15343 | | 16783 | |
| 15344 | if (is_comptime || old_dest_block->ref_count == 1) | 16784 | if (is_comptime || (old_dest_block->ref_count == 1 && old_dest_block->suspend_instruction_ref == nullptr)) |
| 15345 | return ir_inline_bb(ira, &br_instruction->base, old_dest_block); | 16785 | return ir_inline_bb(ira, &br_instruction->base, old_dest_block); |
| 15346 | | 16786 | |
| 15347 | IrBasicBlock *new_bb = ir_get_new_bb_runtime(ira, old_dest_block, &br_instruction->base); | 16787 | IrBasicBlock *new_bb = ir_get_new_bb_runtime(ira, old_dest_block, &br_instruction->base); |
| 15348 | if (new_bb == nullptr) | 16788 | if (new_bb == nullptr) |
| 15349 | return ir_unreach_error(ira); | 16789 | return ir_unreach_error(ira); |
| 15350 | | 16790 | |
| | 16791 | ir_push_resume_block(ira, old_dest_block); |
| | 16792 | |
| 15351 | IrInstruction *result = ir_build_br(&ira->new_irb, | 16793 | IrInstruction *result = ir_build_br(&ira->new_irb, |
| 15352 | br_instruction->base.scope, br_instruction->base.source_node, new_bb, nullptr); | 16794 | br_instruction->base.scope, br_instruction->base.source_node, new_bb, nullptr); |
| 15353 | result->value.type = ira->codegen->builtin_types.entry_unreachable; | 16795 | result->value.type = ira->codegen->builtin_types.entry_unreachable; |
| ... | @@ -15376,13 +16818,15 @@ static IrInstruction *ir_analyze_instruction_cond_br(IrAnalyze *ira, IrInstructi | ... | @@ -15376,13 +16818,15 @@ static IrInstruction *ir_analyze_instruction_cond_br(IrAnalyze *ira, IrInstructi |
| 15376 | IrBasicBlock *old_dest_block = cond_is_true ? | 16818 | IrBasicBlock *old_dest_block = cond_is_true ? |
| 15377 | cond_br_instruction->then_block : cond_br_instruction->else_block; | 16819 | cond_br_instruction->then_block : cond_br_instruction->else_block; |
| 15378 | | 16820 | |
| 15379 | if (is_comptime || old_dest_block->ref_count == 1) | 16821 | if (is_comptime || (old_dest_block->ref_count == 1 && old_dest_block->suspend_instruction_ref == nullptr)) |
| 15380 | return ir_inline_bb(ira, &cond_br_instruction->base, old_dest_block); | 16822 | return ir_inline_bb(ira, &cond_br_instruction->base, old_dest_block); |
| 15381 | | 16823 | |
| 15382 | IrBasicBlock *new_dest_block = ir_get_new_bb_runtime(ira, old_dest_block, &cond_br_instruction->base); | 16824 | IrBasicBlock *new_dest_block = ir_get_new_bb_runtime(ira, old_dest_block, &cond_br_instruction->base); |
| 15383 | if (new_dest_block == nullptr) | 16825 | if (new_dest_block == nullptr) |
| 15384 | return ir_unreach_error(ira); | 16826 | return ir_unreach_error(ira); |
| 15385 | | 16827 | |
| | 16828 | ir_push_resume_block(ira, old_dest_block); |
| | 16829 | |
| 15386 | IrInstruction *result = ir_build_br(&ira->new_irb, | 16830 | IrInstruction *result = ir_build_br(&ira->new_irb, |
| 15387 | cond_br_instruction->base.scope, cond_br_instruction->base.source_node, new_dest_block, nullptr); | 16831 | cond_br_instruction->base.scope, cond_br_instruction->base.source_node, new_dest_block, nullptr); |
| 15388 | result->value.type = ira->codegen->builtin_types.entry_unreachable; | 16832 | result->value.type = ira->codegen->builtin_types.entry_unreachable; |
| ... | @@ -15398,6 +16842,9 @@ static IrInstruction *ir_analyze_instruction_cond_br(IrAnalyze *ira, IrInstructi | ... | @@ -15398,6 +16842,9 @@ static IrInstruction *ir_analyze_instruction_cond_br(IrAnalyze *ira, IrInstructi |
| 15398 | if (new_else_block == nullptr) | 16842 | if (new_else_block == nullptr) |
| 15399 | return ir_unreach_error(ira); | 16843 | return ir_unreach_error(ira); |
| 15400 | | 16844 | |
| | 16845 | ir_push_resume_block(ira, cond_br_instruction->else_block); |
| | 16846 | ir_push_resume_block(ira, cond_br_instruction->then_block); |
| | 16847 | |
| 15401 | IrInstruction *result = ir_build_cond_br(&ira->new_irb, | 16848 | IrInstruction *result = ir_build_cond_br(&ira->new_irb, |
| 15402 | cond_br_instruction->base.scope, cond_br_instruction->base.source_node, | 16849 | cond_br_instruction->base.scope, cond_br_instruction->base.source_node, |
| 15403 | casted_condition, new_then_block, new_else_block, nullptr); | 16850 | casted_condition, new_then_block, new_else_block, nullptr); |
| ... | @@ -15436,6 +16883,80 @@ static IrInstruction *ir_analyze_instruction_phi(IrAnalyze *ira, IrInstructionPh | ... | @@ -15436,6 +16883,80 @@ static IrInstruction *ir_analyze_instruction_phi(IrAnalyze *ira, IrInstructionPh |
| 15436 | zig_unreachable(); | 16883 | zig_unreachable(); |
| 15437 | } | 16884 | } |
| 15438 | | 16885 | |
| | 16886 | ResultLocPeerParent *peer_parent = phi_instruction->peer_parent; |
| | 16887 | if (peer_parent != nullptr && !peer_parent->skipped && !peer_parent->done_resuming && |
| | 16888 | peer_parent->peers.length >= 2) |
| | 16889 | { |
| | 16890 | if (peer_parent->resolved_type == nullptr) { |
| | 16891 | IrInstruction **instructions = allocate<IrInstruction *>(peer_parent->peers.length); |
| | 16892 | for (size_t i = 0; i < peer_parent->peers.length; i += 1) { |
| | 16893 | ResultLocPeer *this_peer = peer_parent->peers.at(i); |
| | 16894 | |
| | 16895 | IrInstruction *gen_instruction = this_peer->base.gen_instruction; |
| | 16896 | if (gen_instruction == nullptr) { |
| | 16897 | // unreachable instructions will cause implicit_elem_type to be null |
| | 16898 | if (this_peer->base.implicit_elem_type == nullptr) { |
| | 16899 | instructions[i] = ir_const_unreachable(ira, this_peer->base.source_instruction); |
| | 16900 | } else { |
| | 16901 | instructions[i] = ir_const(ira, this_peer->base.source_instruction, |
| | 16902 | this_peer->base.implicit_elem_type); |
| | 16903 | instructions[i]->value.special = ConstValSpecialRuntime; |
| | 16904 | } |
| | 16905 | } else { |
| | 16906 | instructions[i] = gen_instruction; |
| | 16907 | } |
| | 16908 | |
| | 16909 | } |
| | 16910 | ZigType *expected_type = ir_result_loc_expected_type(ira, &phi_instruction->base, peer_parent->parent); |
| | 16911 | peer_parent->resolved_type = ir_resolve_peer_types(ira, |
| | 16912 | peer_parent->base.source_instruction->source_node, expected_type, instructions, |
| | 16913 | peer_parent->peers.length); |
| | 16914 | |
| | 16915 | // the logic below assumes there are no instructions in the new current basic block yet |
| | 16916 | ir_assert(ira->new_irb.current_basic_block->instruction_list.length == 0, &phi_instruction->base); |
| | 16917 | |
| | 16918 | // In case resolving the parent activates a suspend, do it now |
| | 16919 | IrInstruction *parent_result_loc = ir_resolve_result(ira, &phi_instruction->base, peer_parent->parent, |
| | 16920 | peer_parent->resolved_type, nullptr, false, false); |
| | 16921 | if (parent_result_loc != nullptr && |
| | 16922 | (type_is_invalid(parent_result_loc->value.type) || instr_is_unreachable(parent_result_loc))) |
| | 16923 | { |
| | 16924 | return parent_result_loc; |
| | 16925 | } |
| | 16926 | // If the above code generated any instructions in the current basic block, we need |
| | 16927 | // to move them to the peer parent predecessor. |
| | 16928 | ZigList<IrInstruction *> instrs_to_move = {}; |
| | 16929 | while (ira->new_irb.current_basic_block->instruction_list.length != 0) { |
| | 16930 | instrs_to_move.append(ira->new_irb.current_basic_block->instruction_list.pop()); |
| | 16931 | } |
| | 16932 | if (instrs_to_move.length != 0) { |
| | 16933 | IrBasicBlock *predecessor = peer_parent->base.source_instruction->child->owner_bb; |
| | 16934 | IrInstruction *branch_instruction = predecessor->instruction_list.pop(); |
| | 16935 | ir_assert(branch_instruction->value.type->id == ZigTypeIdUnreachable, &phi_instruction->base); |
| | 16936 | while (instrs_to_move.length != 0) { |
| | 16937 | predecessor->instruction_list.append(instrs_to_move.pop()); |
| | 16938 | } |
| | 16939 | predecessor->instruction_list.append(branch_instruction); |
| | 16940 | } |
| | 16941 | } |
| | 16942 | |
| | 16943 | IrSuspendPosition suspend_pos; |
| | 16944 | ira_suspend(ira, &phi_instruction->base, nullptr, &suspend_pos); |
| | 16945 | ir_push_resume(ira, suspend_pos); |
| | 16946 | |
| | 16947 | for (size_t i = 0; i < peer_parent->peers.length; i += 1) { |
| | 16948 | ResultLocPeer *opposite_peer = peer_parent->peers.at(peer_parent->peers.length - i - 1); |
| | 16949 | if (opposite_peer->base.implicit_elem_type != nullptr && |
| | 16950 | opposite_peer->base.implicit_elem_type->id != ZigTypeIdUnreachable) |
| | 16951 | { |
| | 16952 | ir_push_resume(ira, opposite_peer->suspend_pos); |
| | 16953 | } |
| | 16954 | } |
| | 16955 | |
| | 16956 | peer_parent->done_resuming = true; |
| | 16957 | return ira_resume(ira); |
| | 16958 | } |
| | 16959 | |
| 15439 | ZigList<IrBasicBlock*> new_incoming_blocks = {0}; | 16960 | ZigList<IrBasicBlock*> new_incoming_blocks = {0}; |
| 15440 | ZigList<IrInstruction*> new_incoming_values = {0}; | 16961 | ZigList<IrInstruction*> new_incoming_values = {0}; |
| 15441 | | 16962 | |
| ... | @@ -15508,7 +17029,7 @@ static IrInstruction *ir_analyze_instruction_phi(IrAnalyze *ira, IrInstructionPh | ... | @@ -15508,7 +17029,7 @@ static IrInstruction *ir_analyze_instruction_phi(IrAnalyze *ira, IrInstructionPh |
| 15508 | IrInstruction *branch_instruction = predecessor->instruction_list.pop(); | 17029 | IrInstruction *branch_instruction = predecessor->instruction_list.pop(); |
| 15509 | ir_set_cursor_at_end(&ira->new_irb, predecessor); | 17030 | ir_set_cursor_at_end(&ira->new_irb, predecessor); |
| 15510 | IrInstruction *casted_value = ir_implicit_cast(ira, new_value, resolved_type); | 17031 | IrInstruction *casted_value = ir_implicit_cast(ira, new_value, resolved_type); |
| 15511 | if (casted_value == ira->codegen->invalid_instruction) { | 17032 | if (type_is_invalid(casted_value->value.type)) { |
| 15512 | return ira->codegen->invalid_instruction; | 17033 | return ira->codegen->invalid_instruction; |
| 15513 | } | 17034 | } |
| 15514 | new_incoming_values.items[i] = casted_value; | 17035 | new_incoming_values.items[i] = casted_value; |
| ... | @@ -15524,7 +17045,7 @@ static IrInstruction *ir_analyze_instruction_phi(IrAnalyze *ira, IrInstructionPh | ... | @@ -15524,7 +17045,7 @@ static IrInstruction *ir_analyze_instruction_phi(IrAnalyze *ira, IrInstructionPh |
| 15524 | | 17045 | |
| 15525 | IrInstruction *result = ir_build_phi(&ira->new_irb, | 17046 | IrInstruction *result = ir_build_phi(&ira->new_irb, |
| 15526 | phi_instruction->base.scope, phi_instruction->base.source_node, | 17047 | phi_instruction->base.scope, phi_instruction->base.source_node, |
| 15527 | new_incoming_blocks.length, new_incoming_blocks.items, new_incoming_values.items); | 17048 | new_incoming_blocks.length, new_incoming_blocks.items, new_incoming_values.items, nullptr); |
| 15528 | result->value.type = resolved_type; | 17049 | result->value.type = resolved_type; |
| 15529 | | 17050 | |
| 15530 | if (all_stack_ptrs) { | 17051 | if (all_stack_ptrs) { |
| ... | @@ -15742,6 +17263,52 @@ static IrInstruction *ir_analyze_instruction_elem_ptr(IrAnalyze *ira, IrInstruct | ... | @@ -15742,6 +17263,52 @@ static IrInstruction *ir_analyze_instruction_elem_ptr(IrAnalyze *ira, IrInstruct |
| 15742 | if (array_ptr_val == nullptr) | 17263 | if (array_ptr_val == nullptr) |
| 15743 | return ira->codegen->invalid_instruction; | 17264 | return ira->codegen->invalid_instruction; |
| 15744 | | 17265 | |
| | 17266 | if (array_ptr_val->special == ConstValSpecialUndef && elem_ptr_instruction->init_array_type != nullptr) { |
| | 17267 | if (array_type->id == ZigTypeIdArray) { |
| | 17268 | array_ptr_val->data.x_array.special = ConstArraySpecialNone; |
| | 17269 | array_ptr_val->data.x_array.data.s_none.elements = create_const_vals(array_type->data.array.len); |
| | 17270 | array_ptr_val->special = ConstValSpecialStatic; |
| | 17271 | for (size_t i = 0; i < array_type->data.array.len; i += 1) { |
| | 17272 | ConstExprValue *elem_val = &array_ptr_val->data.x_array.data.s_none.elements[i]; |
| | 17273 | elem_val->special = ConstValSpecialUndef; |
| | 17274 | elem_val->type = array_type->data.array.child_type; |
| | 17275 | elem_val->parent.id = ConstParentIdArray; |
| | 17276 | elem_val->parent.data.p_array.array_val = array_ptr_val; |
| | 17277 | elem_val->parent.data.p_array.elem_index = i; |
| | 17278 | } |
| | 17279 | } else if (is_slice(array_type)) { |
| | 17280 | ZigType *actual_array_type = ir_resolve_type(ira, elem_ptr_instruction->init_array_type->child); |
| | 17281 | if (type_is_invalid(actual_array_type)) |
| | 17282 | return ira->codegen->invalid_instruction; |
| | 17283 | if (actual_array_type->id != ZigTypeIdArray) { |
| | 17284 | ir_add_error(ira, elem_ptr_instruction->init_array_type, |
| | 17285 | buf_sprintf("expected array type or [_], found slice")); |
| | 17286 | return ira->codegen->invalid_instruction; |
| | 17287 | } |
| | 17288 | |
| | 17289 | ConstExprValue *array_init_val = create_const_vals(1); |
| | 17290 | array_init_val->special = ConstValSpecialStatic; |
| | 17291 | array_init_val->type = actual_array_type; |
| | 17292 | array_init_val->data.x_array.special = ConstArraySpecialNone; |
| | 17293 | array_init_val->data.x_array.data.s_none.elements = create_const_vals(actual_array_type->data.array.len); |
| | 17294 | array_init_val->special = ConstValSpecialStatic; |
| | 17295 | for (size_t i = 0; i < actual_array_type->data.array.len; i += 1) { |
| | 17296 | ConstExprValue *elem_val = &array_init_val->data.x_array.data.s_none.elements[i]; |
| | 17297 | elem_val->special = ConstValSpecialUndef; |
| | 17298 | elem_val->type = actual_array_type->data.array.child_type; |
| | 17299 | elem_val->parent.id = ConstParentIdArray; |
| | 17300 | elem_val->parent.data.p_array.array_val = array_init_val; |
| | 17301 | elem_val->parent.data.p_array.elem_index = i; |
| | 17302 | } |
| | 17303 | |
| | 17304 | init_const_slice(ira->codegen, array_ptr_val, array_init_val, 0, actual_array_type->data.array.len, |
| | 17305 | false); |
| | 17306 | array_ptr_val->data.x_struct.fields[slice_ptr_index].data.x_ptr.mut = ConstPtrMutInfer; |
| | 17307 | } else { |
| | 17308 | zig_unreachable(); |
| | 17309 | } |
| | 17310 | } |
| | 17311 | |
| 15745 | if (array_ptr_val->special != ConstValSpecialRuntime && | 17312 | if (array_ptr_val->special != ConstValSpecialRuntime && |
| 15746 | (array_type->id != ZigTypeIdPointer || | 17313 | (array_type->id != ZigTypeIdPointer || |
| 15747 | array_ptr_val->data.x_ptr.special != ConstPtrSpecialHardCodedAddr)) | 17314 | array_ptr_val->data.x_ptr.special != ConstPtrSpecialHardCodedAddr)) |
| ... | @@ -15807,8 +17374,9 @@ static IrInstruction *ir_analyze_instruction_elem_ptr(IrAnalyze *ira, IrInstruct | ... | @@ -15807,8 +17374,9 @@ static IrInstruction *ir_analyze_instruction_elem_ptr(IrAnalyze *ira, IrInstruct |
| 15807 | } else if (is_slice(array_type)) { | 17374 | } else if (is_slice(array_type)) { |
| 15808 | ConstExprValue *ptr_field = &array_ptr_val->data.x_struct.fields[slice_ptr_index]; | 17375 | ConstExprValue *ptr_field = &array_ptr_val->data.x_struct.fields[slice_ptr_index]; |
| 15809 | if (ptr_field->data.x_ptr.special == ConstPtrSpecialHardCodedAddr) { | 17376 | if (ptr_field->data.x_ptr.special == ConstPtrSpecialHardCodedAddr) { |
| 15810 | IrInstruction *result = ir_build_elem_ptr(&ira->new_irb, elem_ptr_instruction->base.scope, elem_ptr_instruction->base.source_node, | 17377 | IrInstruction *result = ir_build_elem_ptr(&ira->new_irb, elem_ptr_instruction->base.scope, |
| 15811 | array_ptr, casted_elem_index, false, elem_ptr_instruction->ptr_len); | 17378 | elem_ptr_instruction->base.source_node, array_ptr, casted_elem_index, false, |
| | 17379 | elem_ptr_instruction->ptr_len, nullptr); |
| 15812 | result->value.type = return_type; | 17380 | result->value.type = return_type; |
| 15813 | return result; | 17381 | return result; |
| 15814 | } | 17382 | } |
| ... | @@ -15861,7 +17429,16 @@ static IrInstruction *ir_analyze_instruction_elem_ptr(IrAnalyze *ira, IrInstruct | ... | @@ -15861,7 +17429,16 @@ static IrInstruction *ir_analyze_instruction_elem_ptr(IrAnalyze *ira, IrInstruct |
| 15861 | } | 17429 | } |
| 15862 | return result; | 17430 | return result; |
| 15863 | } else if (array_type->id == ZigTypeIdArray) { | 17431 | } else if (array_type->id == ZigTypeIdArray) { |
| 15864 | IrInstruction *result = ir_const(ira, &elem_ptr_instruction->base, return_type); | 17432 | IrInstruction *result; |
| | 17433 | if (orig_array_ptr_val->data.x_ptr.mut == ConstPtrMutInfer) { |
| | 17434 | result = ir_build_elem_ptr(&ira->new_irb, elem_ptr_instruction->base.scope, |
| | 17435 | elem_ptr_instruction->base.source_node, array_ptr, casted_elem_index, |
| | 17436 | false, elem_ptr_instruction->ptr_len, elem_ptr_instruction->init_array_type); |
| | 17437 | result->value.type = return_type; |
| | 17438 | result->value.special = ConstValSpecialStatic; |
| | 17439 | } else { |
| | 17440 | result = ir_const(ira, &elem_ptr_instruction->base, return_type); |
| | 17441 | } |
| 15865 | ConstExprValue *out_val = &result->value; | 17442 | ConstExprValue *out_val = &result->value; |
| 15866 | out_val->data.x_ptr.special = ConstPtrSpecialBaseArray; | 17443 | out_val->data.x_ptr.special = ConstPtrSpecialBaseArray; |
| 15867 | out_val->data.x_ptr.mut = orig_array_ptr_val->data.x_ptr.mut; | 17444 | out_val->data.x_ptr.mut = orig_array_ptr_val->data.x_ptr.mut; |
| ... | @@ -15873,7 +17450,6 @@ static IrInstruction *ir_analyze_instruction_elem_ptr(IrAnalyze *ira, IrInstruct | ... | @@ -15873,7 +17450,6 @@ static IrInstruction *ir_analyze_instruction_elem_ptr(IrAnalyze *ira, IrInstruct |
| 15873 | } | 17450 | } |
| 15874 | } | 17451 | } |
| 15875 | } | 17452 | } |
| 15876 | | | |
| 15877 | } else { | 17453 | } else { |
| 15878 | // runtime known element index | 17454 | // runtime known element index |
| 15879 | switch (type_requires_comptime(ira->codegen, return_type)) { | 17455 | switch (type_requires_comptime(ira->codegen, return_type)) { |
| ... | @@ -15899,8 +17475,9 @@ static IrInstruction *ir_analyze_instruction_elem_ptr(IrAnalyze *ira, IrInstruct | ... | @@ -15899,8 +17475,9 @@ static IrInstruction *ir_analyze_instruction_elem_ptr(IrAnalyze *ira, IrInstruct |
| 15899 | } | 17475 | } |
| 15900 | } | 17476 | } |
| 15901 | | 17477 | |
| 15902 | IrInstruction *result = ir_build_elem_ptr(&ira->new_irb, elem_ptr_instruction->base.scope, elem_ptr_instruction->base.source_node, | 17478 | IrInstruction *result = ir_build_elem_ptr(&ira->new_irb, elem_ptr_instruction->base.scope, |
| 15903 | array_ptr, casted_elem_index, safety_check_on, elem_ptr_instruction->ptr_len); | 17479 | elem_ptr_instruction->base.source_node, array_ptr, casted_elem_index, safety_check_on, |
| | 17480 | elem_ptr_instruction->ptr_len, elem_ptr_instruction->init_array_type); |
| 15904 | result->value.type = return_type; | 17481 | result->value.type = return_type; |
| 15905 | return result; | 17482 | return result; |
| 15906 | } | 17483 | } |
| ... | @@ -15945,8 +17522,80 @@ static IrInstruction *ir_analyze_container_member_access_inner(IrAnalyze *ira, | ... | @@ -15945,8 +17522,80 @@ static IrInstruction *ir_analyze_container_member_access_inner(IrAnalyze *ira, |
| 15945 | return ira->codegen->invalid_instruction; | 17522 | return ira->codegen->invalid_instruction; |
| 15946 | } | 17523 | } |
| 15947 | | 17524 | |
| | 17525 | static IrInstruction *ir_analyze_struct_field_ptr(IrAnalyze *ira, IrInstruction *source_instr, |
| | 17526 | TypeStructField *field, IrInstruction *struct_ptr, ZigType *struct_type, bool initializing) |
| | 17527 | { |
| | 17528 | switch (type_has_one_possible_value(ira->codegen, field->type_entry)) { |
| | 17529 | case OnePossibleValueInvalid: |
| | 17530 | return ira->codegen->invalid_instruction; |
| | 17531 | case OnePossibleValueYes: { |
| | 17532 | IrInstruction *elem = ir_const(ira, source_instr, field->type_entry); |
| | 17533 | return ir_get_ref(ira, source_instr, elem, false, false); |
| | 17534 | } |
| | 17535 | case OnePossibleValueNo: |
| | 17536 | break; |
| | 17537 | } |
| | 17538 | assert(struct_ptr->value.type->id == ZigTypeIdPointer); |
| | 17539 | bool is_packed = (struct_type->data.structure.layout == ContainerLayoutPacked); |
| | 17540 | uint32_t align_bytes = is_packed ? 1 : get_abi_alignment(ira->codegen, field->type_entry); |
| | 17541 | uint32_t ptr_bit_offset = struct_ptr->value.type->data.pointer.bit_offset_in_host; |
| | 17542 | uint32_t ptr_host_int_bytes = struct_ptr->value.type->data.pointer.host_int_bytes; |
| | 17543 | uint32_t host_int_bytes_for_result_type = (ptr_host_int_bytes == 0) ? |
| | 17544 | get_host_int_bytes(ira->codegen, struct_type, field) : ptr_host_int_bytes; |
| | 17545 | bool is_const = struct_ptr->value.type->data.pointer.is_const; |
| | 17546 | bool is_volatile = struct_ptr->value.type->data.pointer.is_volatile; |
| | 17547 | ZigType *ptr_type = get_pointer_to_type_extra(ira->codegen, field->type_entry, |
| | 17548 | is_const, is_volatile, PtrLenSingle, align_bytes, |
| | 17549 | (uint32_t)(ptr_bit_offset + field->bit_offset_in_host), |
| | 17550 | (uint32_t)host_int_bytes_for_result_type, false); |
| | 17551 | if (instr_is_comptime(struct_ptr)) { |
| | 17552 | ConstExprValue *ptr_val = ir_resolve_const(ira, struct_ptr, UndefBad); |
| | 17553 | if (!ptr_val) |
| | 17554 | return ira->codegen->invalid_instruction; |
| | 17555 | |
| | 17556 | if (ptr_val->data.x_ptr.special != ConstPtrSpecialHardCodedAddr) { |
| | 17557 | ConstExprValue *struct_val = const_ptr_pointee(ira, ira->codegen, ptr_val, source_instr->source_node); |
| | 17558 | if (struct_val == nullptr) |
| | 17559 | return ira->codegen->invalid_instruction; |
| | 17560 | if (type_is_invalid(struct_val->type)) |
| | 17561 | return ira->codegen->invalid_instruction; |
| | 17562 | if (struct_val->special == ConstValSpecialUndef && initializing) { |
| | 17563 | struct_val->data.x_struct.fields = create_const_vals(struct_type->data.structure.src_field_count); |
| | 17564 | struct_val->special = ConstValSpecialStatic; |
| | 17565 | for (size_t i = 0; i < struct_type->data.structure.src_field_count; i += 1) { |
| | 17566 | ConstExprValue *field_val = &struct_val->data.x_struct.fields[i]; |
| | 17567 | field_val->special = ConstValSpecialUndef; |
| | 17568 | field_val->type = struct_type->data.structure.fields[i].type_entry; |
| | 17569 | field_val->parent.id = ConstParentIdStruct; |
| | 17570 | field_val->parent.data.p_struct.struct_val = struct_val; |
| | 17571 | field_val->parent.data.p_struct.field_index = i; |
| | 17572 | } |
| | 17573 | } |
| | 17574 | IrInstruction *result; |
| | 17575 | if (ptr_val->data.x_ptr.mut == ConstPtrMutInfer) { |
| | 17576 | result = ir_build_struct_field_ptr(&ira->new_irb, source_instr->scope, |
| | 17577 | source_instr->source_node, struct_ptr, field); |
| | 17578 | result->value.type = ptr_type; |
| | 17579 | result->value.special = ConstValSpecialStatic; |
| | 17580 | } else { |
| | 17581 | result = ir_const(ira, source_instr, ptr_type); |
| | 17582 | } |
| | 17583 | ConstExprValue *const_val = &result->value; |
| | 17584 | const_val->data.x_ptr.special = ConstPtrSpecialBaseStruct; |
| | 17585 | const_val->data.x_ptr.mut = ptr_val->data.x_ptr.mut; |
| | 17586 | const_val->data.x_ptr.data.base_struct.struct_val = struct_val; |
| | 17587 | const_val->data.x_ptr.data.base_struct.field_index = field->src_index; |
| | 17588 | return result; |
| | 17589 | } |
| | 17590 | } |
| | 17591 | IrInstruction *result = ir_build_struct_field_ptr(&ira->new_irb, source_instr->scope, source_instr->source_node, |
| | 17592 | struct_ptr, field); |
| | 17593 | result->value.type = ptr_type; |
| | 17594 | return result; |
| | 17595 | } |
| | 17596 | |
| 15948 | static IrInstruction *ir_analyze_container_field_ptr(IrAnalyze *ira, Buf *field_name, | 17597 | static IrInstruction *ir_analyze_container_field_ptr(IrAnalyze *ira, Buf *field_name, |
| 15949 | IrInstruction *source_instr, IrInstruction *container_ptr, ZigType *container_type) | 17598 | IrInstruction *source_instr, IrInstruction *container_ptr, ZigType *container_type, bool initializing) |
| 15950 | { | 17599 | { |
| 15951 | Error err; | 17600 | Error err; |
| 15952 | | 17601 | |
| ... | @@ -15955,81 +17604,55 @@ static IrInstruction *ir_analyze_container_field_ptr(IrAnalyze *ira, Buf *field_ | ... | @@ -15955,81 +17604,55 @@ static IrInstruction *ir_analyze_container_field_ptr(IrAnalyze *ira, Buf *field_ |
| 15955 | return ira->codegen->invalid_instruction; | 17604 | return ira->codegen->invalid_instruction; |
| 15956 | | 17605 | |
| 15957 | assert(container_ptr->value.type->id == ZigTypeIdPointer); | 17606 | assert(container_ptr->value.type->id == ZigTypeIdPointer); |
| 15958 | bool is_const = container_ptr->value.type->data.pointer.is_const; | | |
| 15959 | bool is_volatile = container_ptr->value.type->data.pointer.is_volatile; | | |
| 15960 | if (bare_type->id == ZigTypeIdStruct) { | 17607 | if (bare_type->id == ZigTypeIdStruct) { |
| 15961 | TypeStructField *field = find_struct_type_field(bare_type, field_name); | 17608 | TypeStructField *field = find_struct_type_field(bare_type, field_name); |
| 15962 | if (field) { | 17609 | if (field != nullptr) { |
| 15963 | switch (type_has_one_possible_value(ira->codegen, field->type_entry)) { | 17610 | return ir_analyze_struct_field_ptr(ira, source_instr, field, container_ptr, bare_type, initializing); |
| 15964 | case OnePossibleValueInvalid: | | |
| 15965 | return ira->codegen->invalid_instruction; | | |
| 15966 | case OnePossibleValueYes: { | | |
| 15967 | IrInstruction *elem = ir_const(ira, source_instr, field->type_entry); | | |
| 15968 | return ir_get_ref(ira, source_instr, elem, false, false); | | |
| 15969 | } | | |
| 15970 | case OnePossibleValueNo: | | |
| 15971 | break; | | |
| 15972 | } | | |
| 15973 | bool is_packed = (bare_type->data.structure.layout == ContainerLayoutPacked); | | |
| 15974 | uint32_t align_bytes = is_packed ? 1 : get_abi_alignment(ira->codegen, field->type_entry); | | |
| 15975 | uint32_t ptr_bit_offset = container_ptr->value.type->data.pointer.bit_offset_in_host; | | |
| 15976 | uint32_t ptr_host_int_bytes = container_ptr->value.type->data.pointer.host_int_bytes; | | |
| 15977 | uint32_t host_int_bytes_for_result_type = (ptr_host_int_bytes == 0) ? | | |
| 15978 | get_host_int_bytes(ira->codegen, bare_type, field) : ptr_host_int_bytes; | | |
| 15979 | if (instr_is_comptime(container_ptr)) { | | |
| 15980 | ConstExprValue *ptr_val = ir_resolve_const(ira, container_ptr, UndefBad); | | |
| 15981 | if (!ptr_val) | | |
| 15982 | return ira->codegen->invalid_instruction; | | |
| 15983 | | | |
| 15984 | if (ptr_val->data.x_ptr.special != ConstPtrSpecialHardCodedAddr) { | | |
| 15985 | ConstExprValue *struct_val = const_ptr_pointee(ira, ira->codegen, ptr_val, source_instr->source_node); | | |
| 15986 | if (struct_val == nullptr) | | |
| 15987 | return ira->codegen->invalid_instruction; | | |
| 15988 | if (type_is_invalid(struct_val->type)) | | |
| 15989 | return ira->codegen->invalid_instruction; | | |
| 15990 | ZigType *ptr_type = get_pointer_to_type_extra(ira->codegen, field->type_entry, | | |
| 15991 | is_const, is_volatile, PtrLenSingle, align_bytes, | | |
| 15992 | (uint32_t)(ptr_bit_offset + field->bit_offset_in_host), | | |
| 15993 | (uint32_t)host_int_bytes_for_result_type, false); | | |
| 15994 | IrInstruction *result = ir_const(ira, source_instr, ptr_type); | | |
| 15995 | ConstExprValue *const_val = &result->value; | | |
| 15996 | const_val->data.x_ptr.special = ConstPtrSpecialBaseStruct; | | |
| 15997 | const_val->data.x_ptr.mut = container_ptr->value.data.x_ptr.mut; | | |
| 15998 | const_val->data.x_ptr.data.base_struct.struct_val = struct_val; | | |
| 15999 | const_val->data.x_ptr.data.base_struct.field_index = field->src_index; | | |
| 16000 | return result; | | |
| 16001 | } | | |
| 16002 | } | | |
| 16003 | IrInstruction *result = ir_build_struct_field_ptr(&ira->new_irb, source_instr->scope, source_instr->source_node, | | |
| 16004 | container_ptr, field); | | |
| 16005 | result->value.type = get_pointer_to_type_extra(ira->codegen, field->type_entry, is_const, is_volatile, | | |
| 16006 | PtrLenSingle, | | |
| 16007 | align_bytes, | | |
| 16008 | (uint32_t)(ptr_bit_offset + field->bit_offset_in_host), | | |
| 16009 | host_int_bytes_for_result_type, false); | | |
| 16010 | return result; | | |
| 16011 | } else { | 17611 | } else { |
| 16012 | return ir_analyze_container_member_access_inner(ira, bare_type, field_name, | 17612 | return ir_analyze_container_member_access_inner(ira, bare_type, field_name, |
| 16013 | source_instr, container_ptr, container_type); | 17613 | source_instr, container_ptr, container_type); |
| 16014 | } | 17614 | } |
| 16015 | } else if (bare_type->id == ZigTypeIdEnum) { | 17615 | } |
| | 17616 | |
| | 17617 | if (bare_type->id == ZigTypeIdEnum) { |
| 16016 | return ir_analyze_container_member_access_inner(ira, bare_type, field_name, | 17618 | return ir_analyze_container_member_access_inner(ira, bare_type, field_name, |
| 16017 | source_instr, container_ptr, container_type); | 17619 | source_instr, container_ptr, container_type); |
| 16018 | } else if (bare_type->id == ZigTypeIdUnion) { | 17620 | } |
| | 17621 | |
| | 17622 | if (bare_type->id == ZigTypeIdUnion) { |
| | 17623 | bool is_const = container_ptr->value.type->data.pointer.is_const; |
| | 17624 | bool is_volatile = container_ptr->value.type->data.pointer.is_volatile; |
| | 17625 | |
| 16019 | TypeUnionField *field = find_union_type_field(bare_type, field_name); | 17626 | TypeUnionField *field = find_union_type_field(bare_type, field_name); |
| 16020 | if (field) { | 17627 | if (field == nullptr) { |
| 16021 | if (instr_is_comptime(container_ptr)) { | 17628 | return ir_analyze_container_member_access_inner(ira, bare_type, field_name, |
| 16022 | ConstExprValue *ptr_val = ir_resolve_const(ira, container_ptr, UndefBad); | 17629 | source_instr, container_ptr, container_type); |
| 16023 | if (!ptr_val) | 17630 | } |
| | 17631 | ZigType *ptr_type = get_pointer_to_type_extra(ira->codegen, field->type_entry, |
| | 17632 | is_const, is_volatile, PtrLenSingle, 0, 0, 0, false); |
| | 17633 | if (instr_is_comptime(container_ptr)) { |
| | 17634 | ConstExprValue *ptr_val = ir_resolve_const(ira, container_ptr, UndefBad); |
| | 17635 | if (!ptr_val) |
| | 17636 | return ira->codegen->invalid_instruction; |
| | 17637 | |
| | 17638 | if (ptr_val->data.x_ptr.special != ConstPtrSpecialHardCodedAddr) { |
| | 17639 | ConstExprValue *union_val = const_ptr_pointee(ira, ira->codegen, ptr_val, source_instr->source_node); |
| | 17640 | if (union_val == nullptr) |
| | 17641 | return ira->codegen->invalid_instruction; |
| | 17642 | if (type_is_invalid(union_val->type)) |
| 16024 | return ira->codegen->invalid_instruction; | 17643 | return ira->codegen->invalid_instruction; |
| 16025 | | 17644 | |
| 16026 | if (ptr_val->data.x_ptr.special != ConstPtrSpecialHardCodedAddr) { | 17645 | if (initializing) { |
| 16027 | ConstExprValue *union_val = const_ptr_pointee(ira, ira->codegen, ptr_val, source_instr->source_node); | 17646 | ConstExprValue *payload_val = create_const_vals(1); |
| 16028 | if (union_val == nullptr) | 17647 | payload_val->special = ConstValSpecialUndef; |
| 16029 | return ira->codegen->invalid_instruction; | 17648 | payload_val->type = field->type_entry; |
| 16030 | if (type_is_invalid(union_val->type)) | 17649 | payload_val->parent.id = ConstParentIdUnion; |
| 16031 | return ira->codegen->invalid_instruction; | 17650 | payload_val->parent.data.p_union.union_val = union_val; |
| 16032 | | 17651 | |
| | 17652 | union_val->special = ConstValSpecialStatic; |
| | 17653 | bigint_init_bigint(&union_val->data.x_union.tag, &field->enum_field->value); |
| | 17654 | union_val->data.x_union.payload = payload_val; |
| | 17655 | } else { |
| 16033 | TypeUnionField *actual_field = find_union_field_by_tag(bare_type, &union_val->data.x_union.tag); | 17656 | TypeUnionField *actual_field = find_union_field_by_tag(bare_type, &union_val->data.x_union.tag); |
| 16034 | if (actual_field == nullptr) | 17657 | if (actual_field == nullptr) |
| 16035 | zig_unreachable(); | 17658 | zig_unreachable(); |
| ... | @@ -16040,33 +17663,35 @@ static IrInstruction *ir_analyze_container_field_ptr(IrAnalyze *ira, Buf *field_ | ... | @@ -16040,33 +17663,35 @@ static IrInstruction *ir_analyze_container_field_ptr(IrAnalyze *ira, Buf *field_ |
| 16040 | buf_ptr(actual_field->name))); | 17663 | buf_ptr(actual_field->name))); |
| 16041 | return ira->codegen->invalid_instruction; | 17664 | return ira->codegen->invalid_instruction; |
| 16042 | } | 17665 | } |
| | 17666 | } |
| 16043 | | 17667 | |
| 16044 | ConstExprValue *payload_val = union_val->data.x_union.payload; | 17668 | ConstExprValue *payload_val = union_val->data.x_union.payload; |
| 16045 | | 17669 | |
| 16046 | ZigType *field_type = field->type_entry; | | |
| 16047 | ZigType *ptr_type = get_pointer_to_type_extra(ira->codegen, field_type, | | |
| 16048 | is_const, is_volatile, PtrLenSingle, 0, 0, 0, false); | | |
| 16049 | | 17670 | |
| 16050 | IrInstruction *result = ir_const(ira, source_instr, ptr_type); | 17671 | IrInstruction *result; |
| 16051 | ConstExprValue *const_val = &result->value; | 17672 | if (ptr_val->data.x_ptr.mut == ConstPtrMutInfer) { |
| 16052 | const_val->data.x_ptr.special = ConstPtrSpecialRef; | 17673 | result = ir_build_union_field_ptr(&ira->new_irb, source_instr->scope, |
| 16053 | const_val->data.x_ptr.mut = container_ptr->value.data.x_ptr.mut; | 17674 | source_instr->source_node, container_ptr, field, true, initializing); |
| 16054 | const_val->data.x_ptr.data.ref.pointee = payload_val; | 17675 | result->value.type = ptr_type; |
| 16055 | return result; | 17676 | result->value.special = ConstValSpecialStatic; |
| | 17677 | } else { |
| | 17678 | result = ir_const(ira, source_instr, ptr_type); |
| 16056 | } | 17679 | } |
| | 17680 | ConstExprValue *const_val = &result->value; |
| | 17681 | const_val->data.x_ptr.special = ConstPtrSpecialRef; |
| | 17682 | const_val->data.x_ptr.mut = container_ptr->value.data.x_ptr.mut; |
| | 17683 | const_val->data.x_ptr.data.ref.pointee = payload_val; |
| | 17684 | return result; |
| 16057 | } | 17685 | } |
| 16058 | | | |
| 16059 | IrInstruction *result = ir_build_union_field_ptr(&ira->new_irb, source_instr->scope, source_instr->source_node, container_ptr, field); | | |
| 16060 | result->value.type = get_pointer_to_type_extra(ira->codegen, field->type_entry, is_const, is_volatile, | | |
| 16061 | PtrLenSingle, 0, 0, 0, false); | | |
| 16062 | return result; | | |
| 16063 | } else { | | |
| 16064 | return ir_analyze_container_member_access_inner(ira, bare_type, field_name, | | |
| 16065 | source_instr, container_ptr, container_type); | | |
| 16066 | } | 17686 | } |
| 16067 | } else { | 17687 | |
| 16068 | zig_unreachable(); | 17688 | IrInstruction *result = ir_build_union_field_ptr(&ira->new_irb, source_instr->scope, |
| | 17689 | source_instr->source_node, container_ptr, field, true, initializing); |
| | 17690 | result->value.type = ptr_type; |
| | 17691 | return result; |
| 16069 | } | 17692 | } |
| | 17693 | |
| | 17694 | zig_unreachable(); |
| 16070 | } | 17695 | } |
| 16071 | | 17696 | |
| 16072 | static void add_link_lib_symbol(IrAnalyze *ira, Buf *lib_name, Buf *symbol_name, AstNode *source_node) { | 17697 | static void add_link_lib_symbol(IrAnalyze *ira, Buf *lib_name, Buf *symbol_name, AstNode *source_node) { |
| ... | @@ -16104,6 +17729,11 @@ static void add_link_lib_symbol(IrAnalyze *ira, Buf *lib_name, Buf *symbol_name, | ... | @@ -16104,6 +17729,11 @@ static void add_link_lib_symbol(IrAnalyze *ira, Buf *lib_name, Buf *symbol_name, |
| 16104 | link_lib->symbols.append(symbol_name); | 17729 | link_lib->symbols.append(symbol_name); |
| 16105 | } | 17730 | } |
| 16106 | | 17731 | |
| | 17732 | static IrInstruction *ir_error_dependency_loop(IrAnalyze *ira, IrInstruction *source_instr) { |
| | 17733 | ErrorMsg *msg = ir_add_error(ira, source_instr, buf_sprintf("dependency loop detected")); |
| | 17734 | emit_error_notes_for_ref_stack(ira->codegen, msg); |
| | 17735 | return ira->codegen->invalid_instruction; |
| | 17736 | } |
| 16107 | | 17737 | |
| 16108 | static IrInstruction *ir_analyze_decl_ref(IrAnalyze *ira, IrInstruction *source_instruction, Tld *tld) { | 17738 | static IrInstruction *ir_analyze_decl_ref(IrAnalyze *ira, IrInstruction *source_instruction, Tld *tld) { |
| 16109 | resolve_top_level_decl(ira->codegen, tld, source_instruction->source_node); | 17739 | resolve_top_level_decl(ira->codegen, tld, source_instruction->source_node); |
| ... | @@ -16118,6 +17748,9 @@ static IrInstruction *ir_analyze_decl_ref(IrAnalyze *ira, IrInstruction *source_ | ... | @@ -16118,6 +17748,9 @@ static IrInstruction *ir_analyze_decl_ref(IrAnalyze *ira, IrInstruction *source_ |
| 16118 | { | 17748 | { |
| 16119 | TldVar *tld_var = (TldVar *)tld; | 17749 | TldVar *tld_var = (TldVar *)tld; |
| 16120 | ZigVar *var = tld_var->var; | 17750 | ZigVar *var = tld_var->var; |
| | 17751 | if (var == nullptr) { |
| | 17752 | return ir_error_dependency_loop(ira, source_instruction); |
| | 17753 | } |
| 16121 | if (tld_var->extern_lib_name != nullptr) { | 17754 | if (tld_var->extern_lib_name != nullptr) { |
| 16122 | add_link_lib_symbol(ira, tld_var->extern_lib_name, &var->name, source_instruction->source_node); | 17755 | add_link_lib_symbol(ira, tld_var->extern_lib_name, &var->name, source_instruction->source_node); |
| 16123 | } | 17756 | } |
| ... | @@ -16133,23 +17766,13 @@ static IrInstruction *ir_analyze_decl_ref(IrAnalyze *ira, IrInstruction *source_ | ... | @@ -16133,23 +17766,13 @@ static IrInstruction *ir_analyze_decl_ref(IrAnalyze *ira, IrInstruction *source_ |
| 16133 | if (type_is_invalid(fn_entry->type_entry)) | 17766 | if (type_is_invalid(fn_entry->type_entry)) |
| 16134 | return ira->codegen->invalid_instruction; | 17767 | return ira->codegen->invalid_instruction; |
| 16135 | | 17768 | |
| 16136 | // TODO instead of allocating this every time, put it in the tld value and we can reference | | |
| 16137 | // the same one every time | | |
| 16138 | ConstExprValue *const_val = create_const_vals(1); | | |
| 16139 | const_val->special = ConstValSpecialStatic; | | |
| 16140 | const_val->type = fn_entry->type_entry; | | |
| 16141 | const_val->data.x_ptr.data.fn.fn_entry = fn_entry; | | |
| 16142 | const_val->data.x_ptr.special = ConstPtrSpecialFunction; | | |
| 16143 | const_val->data.x_ptr.mut = ConstPtrMutComptimeConst; | | |
| 16144 | | | |
| 16145 | if (tld_fn->extern_lib_name != nullptr) { | 17769 | if (tld_fn->extern_lib_name != nullptr) { |
| 16146 | add_link_lib_symbol(ira, tld_fn->extern_lib_name, &fn_entry->symbol_name, source_instruction->source_node); | 17770 | add_link_lib_symbol(ira, tld_fn->extern_lib_name, &fn_entry->symbol_name, source_instruction->source_node); |
| 16147 | } | 17771 | } |
| 16148 | | 17772 | |
| 16149 | bool ptr_is_const = true; | 17773 | IrInstruction *fn_inst = ir_create_const_fn(&ira->new_irb, source_instruction->scope, |
| 16150 | bool ptr_is_volatile = false; | 17774 | source_instruction->source_node, fn_entry); |
| 16151 | return ir_get_const_ptr(ira, source_instruction, const_val, fn_entry->type_entry, | 17775 | return ir_get_ref(ira, source_instruction, fn_inst, true, false); |
| 16152 | ConstPtrMutComptimeConst, ptr_is_const, ptr_is_volatile, 0); | | |
| 16153 | } | 17776 | } |
| 16154 | } | 17777 | } |
| 16155 | zig_unreachable(); | 17778 | zig_unreachable(); |
| ... | @@ -16191,14 +17814,14 @@ static IrInstruction *ir_analyze_instruction_field_ptr(IrAnalyze *ira, IrInstruc | ... | @@ -16191,14 +17814,14 @@ static IrInstruction *ir_analyze_instruction_field_ptr(IrAnalyze *ira, IrInstruc |
| 16191 | assert(container_ptr->value.type->id == ZigTypeIdPointer); | 17814 | assert(container_ptr->value.type->id == ZigTypeIdPointer); |
| 16192 | if (container_type->id == ZigTypeIdPointer) { | 17815 | if (container_type->id == ZigTypeIdPointer) { |
| 16193 | ZigType *bare_type = container_ref_type(container_type); | 17816 | ZigType *bare_type = container_ref_type(container_type); |
| 16194 | IrInstruction *container_child = ir_get_deref(ira, &field_ptr_instruction->base, container_ptr); | 17817 | IrInstruction *container_child = ir_get_deref(ira, &field_ptr_instruction->base, container_ptr, nullptr); |
| 16195 | IrInstruction *result = ir_analyze_container_field_ptr(ira, field_name, &field_ptr_instruction->base, container_child, bare_type); | 17818 | IrInstruction *result = ir_analyze_container_field_ptr(ira, field_name, &field_ptr_instruction->base, container_child, bare_type, field_ptr_instruction->initializing); |
| 16196 | return result; | 17819 | return result; |
| 16197 | } else { | 17820 | } else { |
| 16198 | IrInstruction *result = ir_analyze_container_field_ptr(ira, field_name, &field_ptr_instruction->base, container_ptr, container_type); | 17821 | IrInstruction *result = ir_analyze_container_field_ptr(ira, field_name, &field_ptr_instruction->base, container_ptr, container_type, field_ptr_instruction->initializing); |
| 16199 | return result; | 17822 | return result; |
| 16200 | } | 17823 | } |
| 16201 | } else if (is_array_ref(container_type)) { | 17824 | } else if (is_array_ref(container_type) && !field_ptr_instruction->initializing) { |
| 16202 | if (buf_eql_str(field_name, "len")) { | 17825 | if (buf_eql_str(field_name, "len")) { |
| 16203 | ConstExprValue *len_val = create_const_vals(1); | 17826 | ConstExprValue *len_val = create_const_vals(1); |
| 16204 | if (container_type->id == ZigTypeIdPointer) { | 17827 | if (container_type->id == ZigTypeIdPointer) { |
| ... | @@ -16513,6 +18136,10 @@ static IrInstruction *ir_analyze_instruction_field_ptr(IrAnalyze *ira, IrInstruc | ... | @@ -16513,6 +18136,10 @@ static IrInstruction *ir_analyze_instruction_field_ptr(IrAnalyze *ira, IrInstruc |
| 16513 | buf_sprintf("type '%s' does not support field access", buf_ptr(&child_type->name))); | 18136 | buf_sprintf("type '%s' does not support field access", buf_ptr(&child_type->name))); |
| 16514 | return ira->codegen->invalid_instruction; | 18137 | return ira->codegen->invalid_instruction; |
| 16515 | } | 18138 | } |
| | 18139 | } else if (field_ptr_instruction->initializing) { |
| | 18140 | ir_add_error(ira, &field_ptr_instruction->base, |
| | 18141 | buf_sprintf("type '%s' does not support struct initialization syntax", buf_ptr(&container_type->name))); |
| | 18142 | return ira->codegen->invalid_instruction; |
| 16516 | } else { | 18143 | } else { |
| 16517 | ir_add_error_node(ira, field_ptr_instruction->base.source_node, | 18144 | ir_add_error_node(ira, field_ptr_instruction->base.source_node, |
| 16518 | buf_sprintf("type '%s' does not support field access", buf_ptr(&container_type->name))); | 18145 | buf_sprintf("type '%s' does not support field access", buf_ptr(&container_type->name))); |
| ... | @@ -16536,7 +18163,7 @@ static IrInstruction *ir_analyze_instruction_load_ptr(IrAnalyze *ira, IrInstruct | ... | @@ -16536,7 +18163,7 @@ static IrInstruction *ir_analyze_instruction_load_ptr(IrAnalyze *ira, IrInstruct |
| 16536 | IrInstruction *ptr = instruction->ptr->child; | 18163 | IrInstruction *ptr = instruction->ptr->child; |
| 16537 | if (type_is_invalid(ptr->value.type)) | 18164 | if (type_is_invalid(ptr->value.type)) |
| 16538 | return ira->codegen->invalid_instruction; | 18165 | return ira->codegen->invalid_instruction; |
| 16539 | return ir_get_deref(ira, &instruction->base, ptr); | 18166 | return ir_get_deref(ira, &instruction->base, ptr, nullptr); |
| 16540 | } | 18167 | } |
| 16541 | | 18168 | |
| 16542 | static IrInstruction *ir_analyze_instruction_typeof(IrAnalyze *ira, IrInstructionTypeOf *typeof_instruction) { | 18169 | static IrInstruction *ir_analyze_instruction_typeof(IrAnalyze *ira, IrInstructionTypeOf *typeof_instruction) { |
| ... | @@ -16547,64 +18174,6 @@ static IrInstruction *ir_analyze_instruction_typeof(IrAnalyze *ira, IrInstructio | ... | @@ -16547,64 +18174,6 @@ static IrInstruction *ir_analyze_instruction_typeof(IrAnalyze *ira, IrInstructio |
| 16547 | return ir_const_type(ira, &typeof_instruction->base, type_entry); | 18174 | return ir_const_type(ira, &typeof_instruction->base, type_entry); |
| 16548 | } | 18175 | } |
| 16549 | | 18176 | |
| 16550 | static IrInstruction *ir_analyze_instruction_to_ptr_type(IrAnalyze *ira, | | |
| 16551 | IrInstructionToPtrType *to_ptr_type_instruction) | | |
| 16552 | { | | |
| 16553 | Error err; | | |
| 16554 | IrInstruction *ptr_ptr = to_ptr_type_instruction->ptr->child; | | |
| 16555 | if (type_is_invalid(ptr_ptr->value.type)) | | |
| 16556 | return ira->codegen->invalid_instruction; | | |
| 16557 | | | |
| 16558 | ZigType *ptr_ptr_type = ptr_ptr->value.type; | | |
| 16559 | assert(ptr_ptr_type->id == ZigTypeIdPointer); | | |
| 16560 | ZigType *type_entry = ptr_ptr_type->data.pointer.child_type; | | |
| 16561 | | | |
| 16562 | ZigType *ptr_type; | | |
| 16563 | if (type_entry->id == ZigTypeIdArray) { | | |
| 16564 | ptr_type = get_pointer_to_type(ira->codegen, type_entry->data.array.child_type, ptr_ptr_type->data.pointer.is_const); | | |
| 16565 | } else if (is_array_ref(type_entry)) { | | |
| 16566 | ptr_type = get_pointer_to_type(ira->codegen, | | |
| 16567 | type_entry->data.pointer.child_type->data.array.child_type, type_entry->data.pointer.is_const); | | |
| 16568 | } else if (is_slice(type_entry)) { | | |
| 16569 | ZigType *slice_ptr_type = type_entry->data.structure.fields[0].type_entry; | | |
| 16570 | ptr_type = adjust_ptr_len(ira->codegen, slice_ptr_type, PtrLenSingle); | | |
| 16571 | // If the pointer is over-aligned, we may have to reduce it based on the alignment of the element type. | | |
| 16572 | if (slice_ptr_type->data.pointer.explicit_alignment != 0) { | | |
| 16573 | ZigType *elem_type = slice_ptr_type->data.pointer.child_type; | | |
| 16574 | if ((err = type_resolve(ira->codegen, elem_type, ResolveStatusAlignmentKnown))) | | |
| 16575 | return ira->codegen->invalid_instruction; | | |
| 16576 | uint32_t elem_align = get_abi_alignment(ira->codegen, elem_type); | | |
| 16577 | uint32_t reduced_align = min(elem_align, slice_ptr_type->data.pointer.explicit_alignment); | | |
| 16578 | ptr_type = adjust_ptr_align(ira->codegen, ptr_type, reduced_align); | | |
| 16579 | } | | |
| 16580 | } else if (type_entry->id == ZigTypeIdArgTuple) { | | |
| 16581 | zig_panic("TODO for loop on var args"); | | |
| 16582 | } else { | | |
| 16583 | ir_add_error_node(ira, to_ptr_type_instruction->base.source_node, | | |
| 16584 | buf_sprintf("expected array type, found '%s'", buf_ptr(&type_entry->name))); | | |
| 16585 | return ira->codegen->invalid_instruction; | | |
| 16586 | } | | |
| 16587 | | | |
| 16588 | return ir_const_type(ira, &to_ptr_type_instruction->base, ptr_type); | | |
| 16589 | } | | |
| 16590 | | | |
| 16591 | static IrInstruction *ir_analyze_instruction_ptr_type_child(IrAnalyze *ira, | | |
| 16592 | IrInstructionPtrTypeChild *ptr_type_child_instruction) | | |
| 16593 | { | | |
| 16594 | IrInstruction *type_value = ptr_type_child_instruction->value->child; | | |
| 16595 | ZigType *type_entry = ir_resolve_type(ira, type_value); | | |
| 16596 | if (type_is_invalid(type_entry)) | | |
| 16597 | return ira->codegen->invalid_instruction; | | |
| 16598 | | | |
| 16599 | if (type_entry->id != ZigTypeIdPointer) { | | |
| 16600 | ir_add_error_node(ira, ptr_type_child_instruction->base.source_node, | | |
| 16601 | buf_sprintf("expected pointer type, found '%s'", buf_ptr(&type_entry->name))); | | |
| 16602 | return ira->codegen->invalid_instruction; | | |
| 16603 | } | | |
| 16604 | | | |
| 16605 | return ir_const_type(ira, &ptr_type_child_instruction->base, type_entry->data.pointer.child_type); | | |
| 16606 | } | | |
| 16607 | | | |
| 16608 | static IrInstruction *ir_analyze_instruction_set_cold(IrAnalyze *ira, IrInstructionSetCold *instruction) { | 18177 | static IrInstruction *ir_analyze_instruction_set_cold(IrAnalyze *ira, IrInstructionSetCold *instruction) { |
| 16609 | if (ira->new_irb.exec->is_inline) { | 18178 | if (ira->new_irb.exec->is_inline) { |
| 16610 | // ignore setCold when running functions at compile time | 18179 | // ignore setCold when running functions at compile time |
| ... | @@ -17034,7 +18603,7 @@ static IrInstruction *ir_analyze_instruction_test_non_null(IrAnalyze *ira, IrIns | ... | @@ -17034,7 +18603,7 @@ static IrInstruction *ir_analyze_instruction_test_non_null(IrAnalyze *ira, IrIns |
| 17034 | } | 18603 | } |
| 17035 | | 18604 | |
| 17036 | static IrInstruction *ir_analyze_unwrap_optional_payload(IrAnalyze *ira, IrInstruction *source_instr, | 18605 | static IrInstruction *ir_analyze_unwrap_optional_payload(IrAnalyze *ira, IrInstruction *source_instr, |
| 17037 | IrInstruction *base_ptr, bool safety_check_on) | 18606 | IrInstruction *base_ptr, bool safety_check_on, bool initializing) |
| 17038 | { | 18607 | { |
| 17039 | ZigType *ptr_type = base_ptr->value.type; | 18608 | ZigType *ptr_type = base_ptr->value.type; |
| 17040 | assert(ptr_type->id == ZigTypeIdPointer); | 18609 | assert(ptr_type->id == ZigTypeIdPointer); |
| ... | @@ -17064,7 +18633,7 @@ static IrInstruction *ir_analyze_unwrap_optional_payload(IrAnalyze *ira, IrInstr | ... | @@ -17064,7 +18633,7 @@ static IrInstruction *ir_analyze_unwrap_optional_payload(IrAnalyze *ira, IrInstr |
| 17064 | } | 18633 | } |
| 17065 | if (!safety_check_on) | 18634 | if (!safety_check_on) |
| 17066 | return base_ptr; | 18635 | return base_ptr; |
| 17067 | IrInstruction *c_ptr_val = ir_get_deref(ira, source_instr, base_ptr); | 18636 | IrInstruction *c_ptr_val = ir_get_deref(ira, source_instr, base_ptr, nullptr); |
| 17068 | ir_build_assert_non_null(ira, source_instr, c_ptr_val); | 18637 | ir_build_assert_non_null(ira, source_instr, c_ptr_val); |
| 17069 | return base_ptr; | 18638 | return base_ptr; |
| 17070 | } | 18639 | } |
| ... | @@ -17079,34 +18648,84 @@ static IrInstruction *ir_analyze_unwrap_optional_payload(IrAnalyze *ira, IrInstr | ... | @@ -17079,34 +18648,84 @@ static IrInstruction *ir_analyze_unwrap_optional_payload(IrAnalyze *ira, IrInstr |
| 17079 | ZigType *result_type = get_pointer_to_type_extra(ira->codegen, child_type, | 18648 | ZigType *result_type = get_pointer_to_type_extra(ira->codegen, child_type, |
| 17080 | ptr_type->data.pointer.is_const, ptr_type->data.pointer.is_volatile, PtrLenSingle, 0, 0, 0, false); | 18649 | ptr_type->data.pointer.is_const, ptr_type->data.pointer.is_volatile, PtrLenSingle, 0, 0, 0, false); |
| 17081 | | 18650 | |
| | 18651 | bool same_comptime_repr = types_have_same_zig_comptime_repr(type_entry, child_type); |
| | 18652 | |
| 17082 | if (instr_is_comptime(base_ptr)) { | 18653 | if (instr_is_comptime(base_ptr)) { |
| 17083 | ConstExprValue *val = ir_resolve_const(ira, base_ptr, UndefBad); | 18654 | ConstExprValue *ptr_val = ir_resolve_const(ira, base_ptr, UndefBad); |
| 17084 | if (!val) | 18655 | if (!ptr_val) |
| 17085 | return ira->codegen->invalid_instruction; | 18656 | return ira->codegen->invalid_instruction; |
| 17086 | if (val->data.x_ptr.mut != ConstPtrMutRuntimeVar) { | 18657 | if (ptr_val->data.x_ptr.mut != ConstPtrMutRuntimeVar) { |
| 17087 | ConstExprValue *maybe_val = const_ptr_pointee(ira, ira->codegen, val, source_instr->source_node); | 18658 | ConstExprValue *optional_val = const_ptr_pointee(ira, ira->codegen, ptr_val, source_instr->source_node); |
| 17088 | if (maybe_val == nullptr) | 18659 | if (optional_val == nullptr) |
| 17089 | return ira->codegen->invalid_instruction; | 18660 | return ira->codegen->invalid_instruction; |
| 17090 | | 18661 | |
| 17091 | if (optional_value_is_null(maybe_val)) { | 18662 | if (initializing && optional_val->special == ConstValSpecialUndef) { |
| | 18663 | switch (type_has_one_possible_value(ira->codegen, child_type)) { |
| | 18664 | case OnePossibleValueInvalid: |
| | 18665 | return ira->codegen->invalid_instruction; |
| | 18666 | case OnePossibleValueNo: |
| | 18667 | if (!same_comptime_repr) { |
| | 18668 | ConstExprValue *payload_val = create_const_vals(1); |
| | 18669 | payload_val->type = child_type; |
| | 18670 | payload_val->special = ConstValSpecialUndef; |
| | 18671 | payload_val->parent.id = ConstParentIdOptionalPayload; |
| | 18672 | payload_val->parent.data.p_optional_payload.optional_val = optional_val; |
| | 18673 | |
| | 18674 | optional_val->data.x_optional = payload_val; |
| | 18675 | optional_val->special = ConstValSpecialStatic; |
| | 18676 | } |
| | 18677 | break; |
| | 18678 | case OnePossibleValueYes: { |
| | 18679 | ConstExprValue *pointee = create_const_vals(1); |
| | 18680 | pointee->special = ConstValSpecialStatic; |
| | 18681 | pointee->type = child_type; |
| | 18682 | pointee->parent.id = ConstParentIdOptionalPayload; |
| | 18683 | pointee->parent.data.p_optional_payload.optional_val = optional_val; |
| | 18684 | |
| | 18685 | optional_val->special = ConstValSpecialStatic; |
| | 18686 | optional_val->data.x_optional = pointee; |
| | 18687 | break; |
| | 18688 | } |
| | 18689 | } |
| | 18690 | } else if (optional_value_is_null(optional_val)) { |
| 17092 | ir_add_error(ira, source_instr, buf_sprintf("unable to unwrap null")); | 18691 | ir_add_error(ira, source_instr, buf_sprintf("unable to unwrap null")); |
| 17093 | return ira->codegen->invalid_instruction; | 18692 | return ira->codegen->invalid_instruction; |
| 17094 | } | 18693 | } |
| 17095 | IrInstruction *result = ir_const(ira, source_instr, result_type); | 18694 | |
| 17096 | ConstExprValue *out_val = &result->value; | 18695 | IrInstruction *result; |
| 17097 | out_val->data.x_ptr.special = ConstPtrSpecialRef; | 18696 | if (ptr_val->data.x_ptr.mut == ConstPtrMutInfer) { |
| 17098 | out_val->data.x_ptr.mut = val->data.x_ptr.mut; | 18697 | result = ir_build_optional_unwrap_ptr(&ira->new_irb, source_instr->scope, |
| 17099 | if (types_have_same_zig_comptime_repr(type_entry, child_type)) { | 18698 | source_instr->source_node, base_ptr, false, initializing); |
| 17100 | out_val->data.x_ptr.data.ref.pointee = maybe_val; | 18699 | result->value.type = result_type; |
| | 18700 | result->value.special = ConstValSpecialStatic; |
| 17101 | } else { | 18701 | } else { |
| 17102 | out_val->data.x_ptr.data.ref.pointee = maybe_val->data.x_optional; | 18702 | result = ir_const(ira, source_instr, result_type); |
| | 18703 | } |
| | 18704 | ConstExprValue *result_val = &result->value; |
| | 18705 | result_val->data.x_ptr.special = ConstPtrSpecialRef; |
| | 18706 | result_val->data.x_ptr.mut = ptr_val->data.x_ptr.mut; |
| | 18707 | switch (type_has_one_possible_value(ira->codegen, child_type)) { |
| | 18708 | case OnePossibleValueInvalid: |
| | 18709 | return ira->codegen->invalid_instruction; |
| | 18710 | case OnePossibleValueNo: |
| | 18711 | if (same_comptime_repr) { |
| | 18712 | result_val->data.x_ptr.data.ref.pointee = optional_val; |
| | 18713 | } else { |
| | 18714 | assert(optional_val->data.x_optional != nullptr); |
| | 18715 | result_val->data.x_ptr.data.ref.pointee = optional_val->data.x_optional; |
| | 18716 | } |
| | 18717 | break; |
| | 18718 | case OnePossibleValueYes: |
| | 18719 | assert(optional_val->data.x_optional != nullptr); |
| | 18720 | result_val->data.x_ptr.data.ref.pointee = optional_val->data.x_optional; |
| | 18721 | break; |
| 17103 | } | 18722 | } |
| 17104 | return result; | 18723 | return result; |
| 17105 | } | 18724 | } |
| 17106 | } | 18725 | } |
| 17107 | | 18726 | |
| 17108 | IrInstruction *result = ir_build_optional_unwrap_ptr(&ira->new_irb, source_instr->scope, | 18727 | IrInstruction *result = ir_build_optional_unwrap_ptr(&ira->new_irb, source_instr->scope, |
| 17109 | source_instr->source_node, base_ptr, safety_check_on); | 18728 | source_instr->source_node, base_ptr, safety_check_on, initializing); |
| 17110 | result->value.type = result_type; | 18729 | result->value.type = result_type; |
| 17111 | return result; | 18730 | return result; |
| 17112 | } | 18731 | } |
| ... | @@ -17118,7 +18737,8 @@ static IrInstruction *ir_analyze_instruction_optional_unwrap_ptr(IrAnalyze *ira, | ... | @@ -17118,7 +18737,8 @@ static IrInstruction *ir_analyze_instruction_optional_unwrap_ptr(IrAnalyze *ira, |
| 17118 | if (type_is_invalid(base_ptr->value.type)) | 18737 | if (type_is_invalid(base_ptr->value.type)) |
| 17119 | return ira->codegen->invalid_instruction; | 18738 | return ira->codegen->invalid_instruction; |
| 17120 | | 18739 | |
| 17121 | return ir_analyze_unwrap_optional_payload(ira, &instruction->base, base_ptr, instruction->safety_check_on); | 18740 | return ir_analyze_unwrap_optional_payload(ira, &instruction->base, base_ptr, |
| | 18741 | instruction->safety_check_on, false); |
| 17122 | } | 18742 | } |
| 17123 | | 18743 | |
| 17124 | static IrInstruction *ir_analyze_instruction_ctz(IrAnalyze *ira, IrInstructionCtz *instruction) { | 18744 | static IrInstruction *ir_analyze_instruction_ctz(IrAnalyze *ira, IrInstructionCtz *instruction) { |
| ... | @@ -17419,7 +19039,7 @@ static IrInstruction *ir_analyze_instruction_switch_target(IrAnalyze *ira, | ... | @@ -17419,7 +19039,7 @@ static IrInstruction *ir_analyze_instruction_switch_target(IrAnalyze *ira, |
| 17419 | return result; | 19039 | return result; |
| 17420 | } | 19040 | } |
| 17421 | | 19041 | |
| 17422 | IrInstruction *result = ir_get_deref(ira, &switch_target_instruction->base, target_value_ptr); | 19042 | IrInstruction *result = ir_get_deref(ira, &switch_target_instruction->base, target_value_ptr, nullptr); |
| 17423 | result->value.type = target_type; | 19043 | result->value.type = target_type; |
| 17424 | return result; | 19044 | return result; |
| 17425 | } | 19045 | } |
| ... | @@ -17449,7 +19069,7 @@ static IrInstruction *ir_analyze_instruction_switch_target(IrAnalyze *ira, | ... | @@ -17449,7 +19069,7 @@ static IrInstruction *ir_analyze_instruction_switch_target(IrAnalyze *ira, |
| 17449 | return result; | 19069 | return result; |
| 17450 | } | 19070 | } |
| 17451 | | 19071 | |
| 17452 | IrInstruction *union_value = ir_get_deref(ira, &switch_target_instruction->base, target_value_ptr); | 19072 | IrInstruction *union_value = ir_get_deref(ira, &switch_target_instruction->base, target_value_ptr, nullptr); |
| 17453 | union_value->value.type = target_type; | 19073 | union_value->value.type = target_type; |
| 17454 | | 19074 | |
| 17455 | IrInstruction *union_tag_inst = ir_build_union_tag(&ira->new_irb, switch_target_instruction->base.scope, | 19075 | IrInstruction *union_tag_inst = ir_build_union_tag(&ira->new_irb, switch_target_instruction->base.scope, |
| ... | @@ -17473,7 +19093,7 @@ static IrInstruction *ir_analyze_instruction_switch_target(IrAnalyze *ira, | ... | @@ -17473,7 +19093,7 @@ static IrInstruction *ir_analyze_instruction_switch_target(IrAnalyze *ira, |
| 17473 | return result; | 19093 | return result; |
| 17474 | } | 19094 | } |
| 17475 | | 19095 | |
| 17476 | IrInstruction *enum_value = ir_get_deref(ira, &switch_target_instruction->base, target_value_ptr); | 19096 | IrInstruction *enum_value = ir_get_deref(ira, &switch_target_instruction->base, target_value_ptr, nullptr); |
| 17477 | enum_value->value.type = target_type; | 19097 | enum_value->value.type = target_type; |
| 17478 | return enum_value; | 19098 | return enum_value; |
| 17479 | } | 19099 | } |
| ... | @@ -17546,7 +19166,7 @@ static IrInstruction *ir_analyze_instruction_switch_var(IrAnalyze *ira, IrInstru | ... | @@ -17546,7 +19166,7 @@ static IrInstruction *ir_analyze_instruction_switch_var(IrAnalyze *ira, IrInstru |
| 17546 | } | 19166 | } |
| 17547 | | 19167 | |
| 17548 | IrInstruction *result = ir_build_union_field_ptr(&ira->new_irb, | 19168 | IrInstruction *result = ir_build_union_field_ptr(&ira->new_irb, |
| 17549 | instruction->base.scope, instruction->base.source_node, target_value_ptr, field); | 19169 | instruction->base.scope, instruction->base.source_node, target_value_ptr, field, false, false); |
| 17550 | result->value.type = get_pointer_to_type(ira->codegen, field->type_entry, | 19170 | result->value.type = get_pointer_to_type(ira->codegen, field->type_entry, |
| 17551 | target_value_ptr->value.type->data.pointer.is_const); | 19171 | target_value_ptr->value.type->data.pointer.is_const); |
| 17552 | return result; | 19172 | return result; |
| ... | @@ -17756,7 +19376,8 @@ static IrInstruction *ir_analyze_instruction_ref(IrAnalyze *ira, IrInstructionRe | ... | @@ -17756,7 +19376,8 @@ static IrInstruction *ir_analyze_instruction_ref(IrAnalyze *ira, IrInstructionRe |
| 17756 | } | 19376 | } |
| 17757 | | 19377 | |
| 17758 | static IrInstruction *ir_analyze_container_init_fields_union(IrAnalyze *ira, IrInstruction *instruction, | 19378 | static IrInstruction *ir_analyze_container_init_fields_union(IrAnalyze *ira, IrInstruction *instruction, |
| 17759 | ZigType *container_type, size_t instr_field_count, IrInstructionContainerInitFieldsField *fields) | 19379 | ZigType *container_type, size_t instr_field_count, IrInstructionContainerInitFieldsField *fields, |
| | 19380 | IrInstruction *result_loc) |
| 17760 | { | 19381 | { |
| 17761 | Error err; | 19382 | Error err; |
| 17762 | assert(container_type->id == ZigTypeIdUnion); | 19383 | assert(container_type->id == ZigTypeIdUnion); |
| ... | @@ -17771,12 +19392,12 @@ static IrInstruction *ir_analyze_container_init_fields_union(IrAnalyze *ira, IrI | ... | @@ -17771,12 +19392,12 @@ static IrInstruction *ir_analyze_container_init_fields_union(IrAnalyze *ira, IrI |
| 17771 | } | 19392 | } |
| 17772 | | 19393 | |
| 17773 | IrInstructionContainerInitFieldsField *field = &fields[0]; | 19394 | IrInstructionContainerInitFieldsField *field = &fields[0]; |
| 17774 | IrInstruction *field_value = field->value->child; | 19395 | IrInstruction *field_result_loc = field->result_loc->child; |
| 17775 | if (type_is_invalid(field_value->value.type)) | 19396 | if (type_is_invalid(field_result_loc->value.type)) |
| 17776 | return ira->codegen->invalid_instruction; | 19397 | return ira->codegen->invalid_instruction; |
| 17777 | | 19398 | |
| 17778 | TypeUnionField *type_field = find_union_type_field(container_type, field->name); | 19399 | TypeUnionField *type_field = find_union_type_field(container_type, field->name); |
| 17779 | if (!type_field) { | 19400 | if (type_field == nullptr) { |
| 17780 | ir_add_error_node(ira, field->source_node, | 19401 | ir_add_error_node(ira, field->source_node, |
| 17781 | buf_sprintf("no member named '%s' in union '%s'", | 19402 | buf_sprintf("no member named '%s' in union '%s'", |
| 17782 | buf_ptr(field->name), buf_ptr(&container_type->name))); | 19403 | buf_ptr(field->name), buf_ptr(&container_type->name))); |
| ... | @@ -17786,46 +19407,36 @@ static IrInstruction *ir_analyze_container_init_fields_union(IrAnalyze *ira, IrI | ... | @@ -17786,46 +19407,36 @@ static IrInstruction *ir_analyze_container_init_fields_union(IrAnalyze *ira, IrI |
| 17786 | if (type_is_invalid(type_field->type_entry)) | 19407 | if (type_is_invalid(type_field->type_entry)) |
| 17787 | return ira->codegen->invalid_instruction; | 19408 | return ira->codegen->invalid_instruction; |
| 17788 | | 19409 | |
| 17789 | IrInstruction *casted_field_value = ir_implicit_cast(ira, field_value, type_field->type_entry); | 19410 | if (result_loc->value.data.x_ptr.mut == ConstPtrMutInfer) { |
| 17790 | if (casted_field_value == ira->codegen->invalid_instruction) | 19411 | if (instr_is_comptime(field_result_loc) && |
| 17791 | return ira->codegen->invalid_instruction; | 19412 | field_result_loc->value.data.x_ptr.mut != ConstPtrMutRuntimeVar) |
| 17792 | | 19413 | { |
| 17793 | if ((err = type_resolve(ira->codegen, casted_field_value->value.type, ResolveStatusZeroBitsKnown))) | 19414 | // nothing |
| 17794 | return ira->codegen->invalid_instruction; | 19415 | } else { |
| | 19416 | result_loc->value.special = ConstValSpecialRuntime; |
| | 19417 | } |
| | 19418 | } |
| 17795 | | 19419 | |
| 17796 | bool is_comptime = ir_should_inline(ira->new_irb.exec, instruction->scope) | 19420 | bool is_comptime = ir_should_inline(ira->new_irb.exec, instruction->scope) |
| 17797 | || type_requires_comptime(ira->codegen, container_type) == ReqCompTimeYes; | 19421 | || type_requires_comptime(ira->codegen, container_type) == ReqCompTimeYes; |
| 17798 | if (is_comptime || casted_field_value->value.special != ConstValSpecialRuntime || | | |
| 17799 | !type_has_bits(casted_field_value->value.type)) | | |
| 17800 | { | | |
| 17801 | ConstExprValue *field_val = ir_resolve_const(ira, casted_field_value, UndefOk); | | |
| 17802 | if (!field_val) | | |
| 17803 | return ira->codegen->invalid_instruction; | | |
| 17804 | | | |
| 17805 | IrInstruction *result = ir_const(ira, instruction, container_type); | | |
| 17806 | ConstExprValue *out_val = &result->value; | | |
| 17807 | out_val->data.x_union.payload = field_val; | | |
| 17808 | out_val->data.x_union.tag = type_field->enum_field->value; | | |
| 17809 | out_val->parent.id = ConstParentIdUnion; | | |
| 17810 | out_val->parent.data.p_union.union_val = out_val; | | |
| 17811 | | 19422 | |
| 17812 | return result; | 19423 | IrInstruction *result = ir_get_deref(ira, instruction, result_loc, nullptr); |
| | 19424 | if (is_comptime && !instr_is_comptime(result)) { |
| | 19425 | ir_add_error(ira, field->result_loc, |
| | 19426 | buf_sprintf("unable to evaluate constant expression")); |
| | 19427 | return ira->codegen->invalid_instruction; |
| 17813 | } | 19428 | } |
| 17814 | | 19429 | return result; |
| 17815 | IrInstruction *new_instruction = ir_build_union_init(&ira->new_irb, | | |
| 17816 | instruction->scope, instruction->source_node, | | |
| 17817 | container_type, type_field, casted_field_value); | | |
| 17818 | new_instruction->value.type = container_type; | | |
| 17819 | ir_add_alloca(ira, new_instruction, container_type); | | |
| 17820 | return new_instruction; | | |
| 17821 | } | 19430 | } |
| 17822 | | 19431 | |
| 17823 | static IrInstruction *ir_analyze_container_init_fields(IrAnalyze *ira, IrInstruction *instruction, | 19432 | static IrInstruction *ir_analyze_container_init_fields(IrAnalyze *ira, IrInstruction *instruction, |
| 17824 | ZigType *container_type, size_t instr_field_count, IrInstructionContainerInitFieldsField *fields) | 19433 | ZigType *container_type, size_t instr_field_count, IrInstructionContainerInitFieldsField *fields, |
| | 19434 | IrInstruction *result_loc) |
| 17825 | { | 19435 | { |
| 17826 | Error err; | 19436 | Error err; |
| 17827 | if (container_type->id == ZigTypeIdUnion) { | 19437 | if (container_type->id == ZigTypeIdUnion) { |
| 17828 | return ir_analyze_container_init_fields_union(ira, instruction, container_type, instr_field_count, fields); | 19438 | return ir_analyze_container_init_fields_union(ira, instruction, container_type, instr_field_count, |
| | 19439 | fields, result_loc); |
| 17829 | } | 19440 | } |
| 17830 | if (container_type->id != ZigTypeIdStruct || is_slice(container_type)) { | 19441 | if (container_type->id != ZigTypeIdStruct || is_slice(container_type)) { |
| 17831 | ir_add_error(ira, instruction, | 19442 | ir_add_error(ira, instruction, |
| ... | @@ -17842,22 +19453,28 @@ static IrInstruction *ir_analyze_container_init_fields(IrAnalyze *ira, IrInstruc | ... | @@ -17842,22 +19453,28 @@ static IrInstruction *ir_analyze_container_init_fields(IrAnalyze *ira, IrInstruc |
| 17842 | IrInstruction *first_non_const_instruction = nullptr; | 19453 | IrInstruction *first_non_const_instruction = nullptr; |
| 17843 | | 19454 | |
| 17844 | AstNode **field_assign_nodes = allocate<AstNode *>(actual_field_count); | 19455 | AstNode **field_assign_nodes = allocate<AstNode *>(actual_field_count); |
| 17845 | | 19456 | ZigList<IrInstruction *> const_ptrs = {}; |
| 17846 | IrInstructionStructInitField *new_fields = allocate<IrInstructionStructInitField>(actual_field_count); | | |
| 17847 | | 19457 | |
| 17848 | bool is_comptime = ir_should_inline(ira->new_irb.exec, instruction->scope) | 19458 | bool is_comptime = ir_should_inline(ira->new_irb.exec, instruction->scope) |
| 17849 | || type_requires_comptime(ira->codegen, container_type) == ReqCompTimeYes; | 19459 | || type_requires_comptime(ira->codegen, container_type) == ReqCompTimeYes; |
| 17850 | | 19460 | |
| 17851 | ConstExprValue const_val = {}; | 19461 | |
| 17852 | const_val.special = ConstValSpecialStatic; | 19462 | // Here we iterate over the fields that have been initialized, and emit |
| 17853 | const_val.type = container_type; | 19463 | // compile errors for missing fields and duplicate fields. |
| 17854 | // const_val.global_refs = allocate<ConstGlobalRefs>(1); | 19464 | // It is only now that we find out whether the struct initialization can be a comptime |
| 17855 | const_val.data.x_struct.fields = create_const_vals(actual_field_count); | 19465 | // value, but we have already emitted runtime instructions for the fields that |
| | 19466 | // were initialized with runtime values, and have omitted instructions that would have |
| | 19467 | // initialized fields with comptime values. |
| | 19468 | // So now we must clean up this situation. If it turns out the struct initialization can |
| | 19469 | // be a comptime value, overwrite ConstPtrMutInfer with ConstPtrMutComptimeConst. |
| | 19470 | // Otherwise, we must emit instructions to runtime-initialize the fields that have |
| | 19471 | // comptime-known values. |
| | 19472 | |
| 17856 | for (size_t i = 0; i < instr_field_count; i += 1) { | 19473 | for (size_t i = 0; i < instr_field_count; i += 1) { |
| 17857 | IrInstructionContainerInitFieldsField *field = &fields[i]; | 19474 | IrInstructionContainerInitFieldsField *field = &fields[i]; |
| 17858 | | 19475 | |
| 17859 | IrInstruction *field_value = field->value->child; | 19476 | IrInstruction *field_result_loc = field->result_loc->child; |
| 17860 | if (type_is_invalid(field_value->value.type)) | 19477 | if (type_is_invalid(field_result_loc->value.type)) |
| 17861 | return ira->codegen->invalid_instruction; | 19478 | return ira->codegen->invalid_instruction; |
| 17862 | | 19479 | |
| 17863 | TypeStructField *type_field = find_struct_type_field(container_type, field->name); | 19480 | TypeStructField *type_field = find_struct_type_field(container_type, field->name); |
| ... | @@ -17871,10 +19488,6 @@ static IrInstruction *ir_analyze_container_init_fields(IrAnalyze *ira, IrInstruc | ... | @@ -17871,10 +19488,6 @@ static IrInstruction *ir_analyze_container_init_fields(IrAnalyze *ira, IrInstruc |
| 17871 | if (type_is_invalid(type_field->type_entry)) | 19488 | if (type_is_invalid(type_field->type_entry)) |
| 17872 | return ira->codegen->invalid_instruction; | 19489 | return ira->codegen->invalid_instruction; |
| 17873 | | 19490 | |
| 17874 | IrInstruction *casted_field_value = ir_implicit_cast(ira, field_value, type_field->type_entry); | | |
| 17875 | if (casted_field_value == ira->codegen->invalid_instruction) | | |
| 17876 | return ira->codegen->invalid_instruction; | | |
| 17877 | | | |
| 17878 | size_t field_index = type_field->src_index; | 19491 | size_t field_index = type_field->src_index; |
| 17879 | AstNode *existing_assign_node = field_assign_nodes[field_index]; | 19492 | AstNode *existing_assign_node = field_assign_nodes[field_index]; |
| 17880 | if (existing_assign_node) { | 19493 | if (existing_assign_node) { |
| ... | @@ -17884,26 +19497,18 @@ static IrInstruction *ir_analyze_container_init_fields(IrAnalyze *ira, IrInstruc | ... | @@ -17884,26 +19497,18 @@ static IrInstruction *ir_analyze_container_init_fields(IrAnalyze *ira, IrInstruc |
| 17884 | } | 19497 | } |
| 17885 | field_assign_nodes[field_index] = field->source_node; | 19498 | field_assign_nodes[field_index] = field->source_node; |
| 17886 | | 19499 | |
| 17887 | new_fields[field_index].value = casted_field_value; | 19500 | if (instr_is_comptime(field_result_loc) && |
| 17888 | new_fields[field_index].type_struct_field = type_field; | 19501 | field_result_loc->value.data.x_ptr.mut != ConstPtrMutRuntimeVar) |
| 17889 | | 19502 | { |
| 17890 | if (const_val.special == ConstValSpecialStatic) { | 19503 | const_ptrs.append(field_result_loc); |
| 17891 | if (is_comptime || casted_field_value->value.special != ConstValSpecialRuntime) { | 19504 | } else { |
| 17892 | ConstExprValue *field_val = ir_resolve_const(ira, casted_field_value, UndefOk); | 19505 | first_non_const_instruction = field_result_loc; |
| 17893 | if (!field_val) | | |
| 17894 | return ira->codegen->invalid_instruction; | | |
| 17895 | | | |
| 17896 | copy_const_val(&const_val.data.x_struct.fields[field_index], field_val, true); | | |
| 17897 | } else { | | |
| 17898 | first_non_const_instruction = casted_field_value; | | |
| 17899 | const_val.special = ConstValSpecialRuntime; | | |
| 17900 | } | | |
| 17901 | } | 19506 | } |
| 17902 | } | 19507 | } |
| 17903 | | 19508 | |
| 17904 | bool any_missing = false; | 19509 | bool any_missing = false; |
| 17905 | for (size_t i = 0; i < actual_field_count; i += 1) { | 19510 | for (size_t i = 0; i < actual_field_count; i += 1) { |
| 17906 | if (field_assign_nodes[i]) continue; | 19511 | if (field_assign_nodes[i] != nullptr) continue; |
| 17907 | | 19512 | |
| 17908 | // look for a default field value | 19513 | // look for a default field value |
| 17909 | TypeStructField *field = &container_type->data.structure.fields[i]; | 19514 | TypeStructField *field = &container_type->data.structure.fields[i]; |
| ... | @@ -17929,182 +19534,177 @@ static IrInstruction *ir_analyze_container_init_fields(IrAnalyze *ira, IrInstruc | ... | @@ -17929,182 +19534,177 @@ static IrInstruction *ir_analyze_container_init_fields(IrAnalyze *ira, IrInstruc |
| 17929 | IrInstruction *runtime_inst = ir_const(ira, instruction, field->init_val->type); | 19534 | IrInstruction *runtime_inst = ir_const(ira, instruction, field->init_val->type); |
| 17930 | copy_const_val(&runtime_inst->value, field->init_val, true); | 19535 | copy_const_val(&runtime_inst->value, field->init_val, true); |
| 17931 | | 19536 | |
| 17932 | new_fields[i].value = runtime_inst; | 19537 | IrInstruction *field_ptr = ir_analyze_struct_field_ptr(ira, instruction, field, result_loc, |
| 17933 | new_fields[i].type_struct_field = field; | 19538 | container_type, true); |
| 17934 | | 19539 | ir_analyze_store_ptr(ira, instruction, field_ptr, runtime_inst); |
| 17935 | if (const_val.special == ConstValSpecialStatic) { | 19540 | if (instr_is_comptime(field_ptr) && field_ptr->value.data.x_ptr.mut != ConstPtrMutRuntimeVar) { |
| 17936 | copy_const_val(&const_val.data.x_struct.fields[i], field->init_val, true); | 19541 | const_ptrs.append(field_ptr); |
| | 19542 | } else { |
| | 19543 | first_non_const_instruction = result_loc; |
| 17937 | } | 19544 | } |
| 17938 | } | 19545 | } |
| 17939 | if (any_missing) | 19546 | if (any_missing) |
| 17940 | return ira->codegen->invalid_instruction; | 19547 | return ira->codegen->invalid_instruction; |
| 17941 | | 19548 | |
| 17942 | if (const_val.special == ConstValSpecialStatic) { | 19549 | if (result_loc->value.data.x_ptr.mut == ConstPtrMutInfer) { |
| 17943 | IrInstruction *result = ir_const(ira, instruction, nullptr); | 19550 | if (const_ptrs.length != actual_field_count) { |
| 17944 | ConstExprValue *out_val = &result->value; | 19551 | result_loc->value.special = ConstValSpecialRuntime; |
| 17945 | copy_const_val(out_val, &const_val, false); | 19552 | for (size_t i = 0; i < const_ptrs.length; i += 1) { |
| 17946 | out_val->type = container_type; | 19553 | IrInstruction *field_result_loc = const_ptrs.at(i); |
| 17947 | | 19554 | IrInstruction *deref = ir_get_deref(ira, field_result_loc, field_result_loc, nullptr); |
| 17948 | for (size_t i = 0; i < instr_field_count; i += 1) { | 19555 | field_result_loc->value.special = ConstValSpecialRuntime; |
| 17949 | ConstExprValue *field_val = &out_val->data.x_struct.fields[i]; | 19556 | ir_analyze_store_ptr(ira, field_result_loc, field_result_loc, deref); |
| 17950 | ConstParent *parent = get_const_val_parent(ira->codegen, field_val); | | |
| 17951 | if (parent != nullptr) { | | |
| 17952 | parent->id = ConstParentIdStruct; | | |
| 17953 | parent->data.p_struct.field_index = i; | | |
| 17954 | parent->data.p_struct.struct_val = out_val; | | |
| 17955 | } | 19557 | } |
| 17956 | } | 19558 | } |
| 17957 | | | |
| 17958 | return result; | | |
| 17959 | } | 19559 | } |
| 17960 | | 19560 | |
| 17961 | if (is_comptime) { | 19561 | IrInstruction *result = ir_get_deref(ira, instruction, result_loc, nullptr); |
| | 19562 | |
| | 19563 | if (is_comptime && !instr_is_comptime(result)) { |
| 17962 | ir_add_error_node(ira, first_non_const_instruction->source_node, | 19564 | ir_add_error_node(ira, first_non_const_instruction->source_node, |
| 17963 | buf_sprintf("unable to evaluate constant expression")); | 19565 | buf_sprintf("unable to evaluate constant expression")); |
| 17964 | return ira->codegen->invalid_instruction; | 19566 | return ira->codegen->invalid_instruction; |
| 17965 | } | 19567 | } |
| 17966 | | 19568 | |
| 17967 | IrInstruction *new_instruction = ir_build_struct_init(&ira->new_irb, | 19569 | return result; |
| 17968 | instruction->scope, instruction->source_node, | | |
| 17969 | container_type, actual_field_count, new_fields); | | |
| 17970 | new_instruction->value.type = container_type; | | |
| 17971 | ir_add_alloca(ira, new_instruction, container_type); | | |
| 17972 | return new_instruction; | | |
| 17973 | } | 19570 | } |
| 17974 | | 19571 | |
| 17975 | static IrInstruction *ir_analyze_instruction_container_init_list(IrAnalyze *ira, | 19572 | static IrInstruction *ir_analyze_instruction_container_init_list(IrAnalyze *ira, |
| 17976 | IrInstructionContainerInitList *instruction) | 19573 | IrInstructionContainerInitList *instruction) |
| 17977 | { | 19574 | { |
| 17978 | Error err; | 19575 | ZigType *container_type = ir_resolve_type(ira, instruction->container_type->child); |
| | 19576 | if (type_is_invalid(container_type)) |
| | 19577 | return ira->codegen->invalid_instruction; |
| 17979 | | 19578 | |
| 17980 | size_t elem_count = instruction->item_count; | 19579 | size_t elem_count = instruction->item_count; |
| 17981 | | 19580 | |
| 17982 | ZigType *container_type; | | |
| 17983 | if (instruction->container_type != nullptr) { | | |
| 17984 | container_type = ir_resolve_type(ira, instruction->container_type->child); | | |
| 17985 | if (type_is_invalid(container_type)) | | |
| 17986 | return ira->codegen->invalid_instruction; | | |
| 17987 | } else { | | |
| 17988 | ZigType *elem_type = ir_resolve_type(ira, instruction->elem_type->child); | | |
| 17989 | if (type_is_invalid(elem_type)) | | |
| 17990 | return ira->codegen->invalid_instruction; | | |
| 17991 | if ((err = type_resolve(ira->codegen, elem_type, ResolveStatusSizeKnown))) { | | |
| 17992 | return ira->codegen->invalid_instruction; | | |
| 17993 | } | | |
| 17994 | container_type = get_array_type(ira->codegen, elem_type, elem_count); | | |
| 17995 | } | | |
| 17996 | | | |
| 17997 | if (is_slice(container_type)) { | 19581 | if (is_slice(container_type)) { |
| 17998 | ir_add_error(ira, &instruction->base, | 19582 | ir_add_error(ira, instruction->container_type, |
| 17999 | buf_sprintf("expected array type or [_], found slice")); | 19583 | buf_sprintf("expected array type or [_], found slice")); |
| 18000 | return ira->codegen->invalid_instruction; | 19584 | return ira->codegen->invalid_instruction; |
| 18001 | } else if (container_type->id == ZigTypeIdStruct && !is_slice(container_type) && elem_count == 0) { | 19585 | } |
| 18002 | return ir_analyze_container_init_fields(ira, &instruction->base, container_type, | | |
| 18003 | 0, nullptr); | | |
| 18004 | } else if (container_type->id == ZigTypeIdArray) { | | |
| 18005 | // array is same as slice init but we make a compile error if the length is wrong | | |
| 18006 | ZigType *child_type; | | |
| 18007 | if (container_type->id == ZigTypeIdArray) { | | |
| 18008 | child_type = container_type->data.array.child_type; | | |
| 18009 | if (container_type->data.array.len != elem_count) { | | |
| 18010 | ZigType *literal_type = get_array_type(ira->codegen, child_type, elem_count); | | |
| 18011 | | | |
| 18012 | ir_add_error(ira, &instruction->base, | | |
| 18013 | buf_sprintf("expected %s literal, found %s literal", | | |
| 18014 | buf_ptr(&container_type->name), buf_ptr(&literal_type->name))); | | |
| 18015 | return ira->codegen->invalid_instruction; | | |
| 18016 | } | | |
| 18017 | } else { | | |
| 18018 | ZigType *pointer_type = container_type->data.structure.fields[slice_ptr_index].type_entry; | | |
| 18019 | assert(pointer_type->id == ZigTypeIdPointer); | | |
| 18020 | child_type = pointer_type->data.pointer.child_type; | | |
| 18021 | } | | |
| 18022 | | 19586 | |
| 18023 | if ((err = type_resolve(ira->codegen, child_type, ResolveStatusSizeKnown))) { | 19587 | if (container_type->id == ZigTypeIdVoid) { |
| | 19588 | if (elem_count != 0) { |
| | 19589 | ir_add_error_node(ira, instruction->base.source_node, |
| | 19590 | buf_sprintf("void expression expects no arguments")); |
| 18024 | return ira->codegen->invalid_instruction; | 19591 | return ira->codegen->invalid_instruction; |
| 18025 | } | 19592 | } |
| | 19593 | return ir_const_void(ira, &instruction->base); |
| | 19594 | } |
| 18026 | | 19595 | |
| 18027 | ZigType *fixed_size_array_type = get_array_type(ira->codegen, child_type, elem_count); | 19596 | if (container_type->id == ZigTypeIdStruct && elem_count == 0) { |
| | 19597 | ir_assert(instruction->result_loc != nullptr, &instruction->base); |
| | 19598 | IrInstruction *result_loc = instruction->result_loc->child; |
| | 19599 | if (type_is_invalid(result_loc->value.type)) |
| | 19600 | return result_loc; |
| | 19601 | return ir_analyze_container_init_fields(ira, &instruction->base, container_type, 0, nullptr, result_loc); |
| | 19602 | } |
| 18028 | | 19603 | |
| 18029 | ConstExprValue const_val = {}; | 19604 | if (container_type->id != ZigTypeIdArray) { |
| 18030 | const_val.special = ConstValSpecialStatic; | 19605 | ir_add_error_node(ira, instruction->base.source_node, |
| 18031 | const_val.type = fixed_size_array_type; | 19606 | buf_sprintf("type '%s' does not support array initialization", |
| 18032 | // const_val.global_refs = allocate<ConstGlobalRefs>(1); | 19607 | buf_ptr(&container_type->name))); |
| 18033 | const_val.data.x_array.data.s_none.elements = create_const_vals(elem_count); | 19608 | return ira->codegen->invalid_instruction; |
| | 19609 | } |
| 18034 | | 19610 | |
| 18035 | bool is_comptime = ir_should_inline(ira->new_irb.exec, instruction->base.scope); | 19611 | ir_assert(instruction->result_loc != nullptr, &instruction->base); |
| | 19612 | IrInstruction *result_loc = instruction->result_loc->child; |
| | 19613 | if (type_is_invalid(result_loc->value.type)) |
| | 19614 | return result_loc; |
| | 19615 | ir_assert(result_loc->value.type->id == ZigTypeIdPointer, &instruction->base); |
| 18036 | | 19616 | |
| 18037 | IrInstruction **new_items = allocate<IrInstruction *>(elem_count); | 19617 | ZigType *child_type = container_type->data.array.child_type; |
| | 19618 | if (container_type->data.array.len != elem_count) { |
| | 19619 | ZigType *literal_type = get_array_type(ira->codegen, child_type, elem_count); |
| 18038 | | 19620 | |
| 18039 | IrInstruction *first_non_const_instruction = nullptr; | 19621 | ir_add_error(ira, &instruction->base, |
| | 19622 | buf_sprintf("expected %s literal, found %s literal", |
| | 19623 | buf_ptr(&container_type->name), buf_ptr(&literal_type->name))); |
| | 19624 | return ira->codegen->invalid_instruction; |
| | 19625 | } |
| 18040 | | 19626 | |
| 18041 | for (size_t i = 0; i < elem_count; i += 1) { | 19627 | switch (type_has_one_possible_value(ira->codegen, container_type)) { |
| 18042 | IrInstruction *arg_value = instruction->items[i]->child; | 19628 | case OnePossibleValueInvalid: |
| 18043 | if (type_is_invalid(arg_value->value.type)) | 19629 | return ira->codegen->invalid_instruction; |
| 18044 | return ira->codegen->invalid_instruction; | 19630 | case OnePossibleValueYes: |
| | 19631 | return ir_const(ira, &instruction->base, container_type); |
| | 19632 | case OnePossibleValueNo: |
| | 19633 | break; |
| | 19634 | } |
| 18045 | | 19635 | |
| 18046 | IrInstruction *casted_arg = ir_implicit_cast(ira, arg_value, child_type); | 19636 | bool is_comptime; |
| 18047 | if (casted_arg == ira->codegen->invalid_instruction) | 19637 | switch (type_requires_comptime(ira->codegen, container_type)) { |
| 18048 | return ira->codegen->invalid_instruction; | 19638 | case ReqCompTimeInvalid: |
| | 19639 | return ira->codegen->invalid_instruction; |
| | 19640 | case ReqCompTimeNo: |
| | 19641 | is_comptime = ir_should_inline(ira->new_irb.exec, instruction->base.scope); |
| | 19642 | break; |
| | 19643 | case ReqCompTimeYes: |
| | 19644 | is_comptime = true; |
| | 19645 | break; |
| | 19646 | } |
| 18049 | | 19647 | |
| 18050 | new_items[i] = casted_arg; | 19648 | IrInstruction *first_non_const_instruction = nullptr; |
| 18051 | | 19649 | |
| 18052 | if (const_val.special == ConstValSpecialStatic) { | 19650 | // The Result Location Mechanism has already emitted runtime instructions to |
| 18053 | if (is_comptime || casted_arg->value.special != ConstValSpecialRuntime) { | 19651 | // initialize runtime elements and has omitted instructions for the comptime |
| 18054 | ConstExprValue *elem_val = ir_resolve_const(ira, casted_arg, UndefBad); | 19652 | // elements. However it is only now that we find out whether the array initialization |
| 18055 | if (!elem_val) | 19653 | // can be a comptime value. So we must clean up the situation. If it turns out |
| 18056 | return ira->codegen->invalid_instruction; | 19654 | // array initialization can be a comptime value, overwrite ConstPtrMutInfer with |
| | 19655 | // ConstPtrMutComptimeConst. Otherwise, emit instructions to runtime-initialize the |
| | 19656 | // elements that have comptime-known values. |
| | 19657 | ZigList<IrInstruction *> const_ptrs = {}; |
| | 19658 | |
| | 19659 | for (size_t i = 0; i < elem_count; i += 1) { |
| | 19660 | IrInstruction *elem_result_loc = instruction->elem_result_loc_list[i]->child; |
| | 19661 | if (type_is_invalid(elem_result_loc->value.type)) |
| | 19662 | return ira->codegen->invalid_instruction; |
| 18057 | | 19663 | |
| 18058 | copy_const_val(&const_val.data.x_array.data.s_none.elements[i], elem_val, true); | 19664 | assert(elem_result_loc->value.type->id == ZigTypeIdPointer); |
| 18059 | } else { | 19665 | |
| 18060 | first_non_const_instruction = casted_arg; | 19666 | if (instr_is_comptime(elem_result_loc) && |
| 18061 | const_val.special = ConstValSpecialRuntime; | 19667 | elem_result_loc->value.data.x_ptr.mut != ConstPtrMutRuntimeVar) |
| 18062 | } | 19668 | { |
| 18063 | } | 19669 | const_ptrs.append(elem_result_loc); |
| | 19670 | } else { |
| | 19671 | first_non_const_instruction = elem_result_loc; |
| 18064 | } | 19672 | } |
| | 19673 | } |
| 18065 | | 19674 | |
| 18066 | if (const_val.special == ConstValSpecialStatic) { | 19675 | if (result_loc->value.data.x_ptr.mut == ConstPtrMutInfer) { |
| 18067 | IrInstruction *result = ir_const(ira, &instruction->base, nullptr); | 19676 | if (const_ptrs.length != elem_count) { |
| 18068 | ConstExprValue *out_val = &result->value; | 19677 | result_loc->value.special = ConstValSpecialRuntime; |
| 18069 | copy_const_val(out_val, &const_val, false); | 19678 | for (size_t i = 0; i < const_ptrs.length; i += 1) { |
| 18070 | result->value.type = fixed_size_array_type; | 19679 | IrInstruction *elem_result_loc = const_ptrs.at(i); |
| 18071 | for (size_t i = 0; i < elem_count; i += 1) { | 19680 | assert(elem_result_loc->value.special == ConstValSpecialStatic); |
| 18072 | ConstExprValue *elem_val = &out_val->data.x_array.data.s_none.elements[i]; | 19681 | IrInstruction *deref = ir_get_deref(ira, elem_result_loc, elem_result_loc, nullptr); |
| 18073 | ConstParent *parent = get_const_val_parent(ira->codegen, elem_val); | 19682 | elem_result_loc->value.special = ConstValSpecialRuntime; |
| 18074 | if (parent != nullptr) { | 19683 | ir_analyze_store_ptr(ira, elem_result_loc, elem_result_loc, deref); |
| 18075 | parent->id = ConstParentIdArray; | | |
| 18076 | parent->data.p_array.array_val = out_val; | | |
| 18077 | parent->data.p_array.elem_index = i; | | |
| 18078 | } | | |
| 18079 | } | 19684 | } |
| 18080 | return result; | | |
| 18081 | } | 19685 | } |
| | 19686 | } |
| 18082 | | 19687 | |
| 18083 | if (is_comptime) { | 19688 | IrInstruction *result = ir_get_deref(ira, &instruction->base, result_loc, nullptr); |
| 18084 | ir_add_error_node(ira, first_non_const_instruction->source_node, | 19689 | if (instr_is_comptime(result)) |
| 18085 | buf_sprintf("unable to evaluate constant expression")); | 19690 | return result; |
| 18086 | return ira->codegen->invalid_instruction; | | |
| 18087 | } | | |
| 18088 | | 19691 | |
| 18089 | IrInstruction *new_instruction = ir_build_container_init_list(&ira->new_irb, | 19692 | if (is_comptime) { |
| 18090 | instruction->base.scope, instruction->base.source_node, | 19693 | ir_add_error_node(ira, first_non_const_instruction->source_node, |
| 18091 | nullptr, nullptr, elem_count, new_items); | 19694 | buf_sprintf("unable to evaluate constant expression")); |
| 18092 | new_instruction->value.type = fixed_size_array_type; | 19695 | return ira->codegen->invalid_instruction; |
| 18093 | ir_add_alloca(ira, new_instruction, fixed_size_array_type); | 19696 | } |
| 18094 | return new_instruction; | 19697 | |
| 18095 | } else if (container_type->id == ZigTypeIdVoid) { | 19698 | ZigType *result_elem_type = result_loc->value.type->data.pointer.child_type; |
| 18096 | if (elem_count != 0) { | 19699 | if (is_slice(result_elem_type)) { |
| 18097 | ir_add_error_node(ira, instruction->base.source_node, | 19700 | ErrorMsg *msg = ir_add_error(ira, &instruction->base, |
| 18098 | buf_sprintf("void expression expects no arguments")); | 19701 | buf_sprintf("runtime-initialized array cannot be casted to slice type '%s'", |
| 18099 | return ira->codegen->invalid_instruction; | 19702 | buf_ptr(&result_elem_type->name))); |
| 18100 | } | 19703 | add_error_note(ira->codegen, msg, first_non_const_instruction->source_node, |
| 18101 | return ir_const_void(ira, &instruction->base); | 19704 | buf_sprintf("this value is not comptime-known")); |
| 18102 | } else { | | |
| 18103 | ir_add_error_node(ira, instruction->base.source_node, | | |
| 18104 | buf_sprintf("type '%s' does not support array initialization", | | |
| 18105 | buf_ptr(&container_type->name))); | | |
| 18106 | return ira->codegen->invalid_instruction; | 19705 | return ira->codegen->invalid_instruction; |
| 18107 | } | 19706 | } |
| | 19707 | return result; |
| 18108 | } | 19708 | } |
| 18109 | | 19709 | |
| 18110 | static IrInstruction *ir_analyze_instruction_container_init_fields(IrAnalyze *ira, | 19710 | static IrInstruction *ir_analyze_instruction_container_init_fields(IrAnalyze *ira, |
| ... | @@ -18115,8 +19715,13 @@ static IrInstruction *ir_analyze_instruction_container_init_fields(IrAnalyze *ir | ... | @@ -18115,8 +19715,13 @@ static IrInstruction *ir_analyze_instruction_container_init_fields(IrAnalyze *ir |
| 18115 | if (type_is_invalid(container_type)) | 19715 | if (type_is_invalid(container_type)) |
| 18116 | return ira->codegen->invalid_instruction; | 19716 | return ira->codegen->invalid_instruction; |
| 18117 | | 19717 | |
| | 19718 | ir_assert(instruction->result_loc != nullptr, &instruction->base); |
| | 19719 | IrInstruction *result_loc = instruction->result_loc->child; |
| | 19720 | if (type_is_invalid(result_loc->value.type)) |
| | 19721 | return result_loc; |
| | 19722 | |
| 18118 | return ir_analyze_container_init_fields(ira, &instruction->base, container_type, | 19723 | return ir_analyze_container_init_fields(ira, &instruction->base, container_type, |
| 18119 | instruction->field_count, instruction->fields); | 19724 | instruction->field_count, instruction->fields, result_loc); |
| 18120 | } | 19725 | } |
| 18121 | | 19726 | |
| 18122 | static IrInstruction *ir_analyze_instruction_compile_err(IrAnalyze *ira, | 19727 | static IrInstruction *ir_analyze_instruction_compile_err(IrAnalyze *ira, |
| ... | @@ -18385,12 +19990,6 @@ static IrInstruction *ir_analyze_instruction_bit_offset_of(IrAnalyze *ira, | ... | @@ -18385,12 +19990,6 @@ static IrInstruction *ir_analyze_instruction_bit_offset_of(IrAnalyze *ira, |
| 18385 | return ir_const_unsigned(ira, &instruction->base, bit_offset); | 19990 | return ir_const_unsigned(ira, &instruction->base, bit_offset); |
| 18386 | } | 19991 | } |
| 18387 | | 19992 | |
| 18388 | static IrInstruction *ir_error_dependency_loop(IrAnalyze *ira, IrInstruction *source_instr) { | | |
| 18389 | ErrorMsg *msg = ir_add_error(ira, source_instr, buf_sprintf("dependency loop detected")); | | |
| 18390 | emit_error_notes_for_ref_stack(ira->codegen, msg); | | |
| 18391 | return ira->codegen->invalid_instruction; | | |
| 18392 | } | | |
| 18393 | | | |
| 18394 | static void ensure_field_index(ZigType *type, const char *field_name, size_t index) { | 19993 | static void ensure_field_index(ZigType *type, const char *field_name, size_t index) { |
| 18395 | Buf *field_name_buf; | 19994 | Buf *field_name_buf; |
| 18396 | | 19995 | |
| ... | @@ -19509,7 +21108,7 @@ static IrInstruction *ir_analyze_instruction_c_import(IrAnalyze *ira, IrInstruct | ... | @@ -19509,7 +21108,7 @@ static IrInstruction *ir_analyze_instruction_c_import(IrAnalyze *ira, IrInstruct |
| 19509 | ir_add_error_node(ira, node, buf_sprintf("C import failed: unable to make dir: %s", err_str(err))); | 21108 | ir_add_error_node(ira, node, buf_sprintf("C import failed: unable to make dir: %s", err_str(err))); |
| 19510 | return ira->codegen->invalid_instruction; | 21109 | return ira->codegen->invalid_instruction; |
| 19511 | } | 21110 | } |
| 19512 | | 21111 | |
| 19513 | if ((err = os_write_file(&tmp_c_file_path, &cimport_scope->buf))) { | 21112 | if ((err = os_write_file(&tmp_c_file_path, &cimport_scope->buf))) { |
| 19514 | ir_add_error_node(ira, node, buf_sprintf("C import failed: unable to write .h file: %s", err_str(err))); | 21113 | ir_add_error_node(ira, node, buf_sprintf("C import failed: unable to write .h file: %s", err_str(err))); |
| 19515 | return ira->codegen->invalid_instruction; | 21114 | return ira->codegen->invalid_instruction; |
| ... | @@ -19796,12 +21395,21 @@ static IrInstruction *ir_analyze_instruction_cmpxchg(IrAnalyze *ira, IrInstructi | ... | @@ -19796,12 +21395,21 @@ static IrInstruction *ir_analyze_instruction_cmpxchg(IrAnalyze *ira, IrInstructi |
| 19796 | zig_panic("TODO compile-time execution of cmpxchg"); | 21395 | zig_panic("TODO compile-time execution of cmpxchg"); |
| 19797 | } | 21396 | } |
| 19798 | | 21397 | |
| 19799 | IrInstruction *result = ir_build_cmpxchg_gen(ira, &instruction->base, | 21398 | ZigType *result_type = get_optional_type(ira->codegen, operand_type); |
| | 21399 | IrInstruction *result_loc; |
| | 21400 | if (handle_is_ptr(result_type)) { |
| | 21401 | result_loc = ir_resolve_result(ira, &instruction->base, instruction->result_loc, |
| | 21402 | result_type, nullptr, true, false); |
| | 21403 | if (type_is_invalid(result_loc->value.type) || instr_is_unreachable(result_loc)) { |
| | 21404 | return result_loc; |
| | 21405 | } |
| | 21406 | } else { |
| | 21407 | result_loc = nullptr; |
| | 21408 | } |
| | 21409 | |
| | 21410 | return ir_build_cmpxchg_gen(ira, &instruction->base, result_type, |
| 19800 | casted_ptr, casted_cmp_value, casted_new_value, | 21411 | casted_ptr, casted_cmp_value, casted_new_value, |
| 19801 | success_order, failure_order, instruction->is_weak); | 21412 | success_order, failure_order, instruction->is_weak, result_loc); |
| 19802 | result->value.type = get_optional_type(ira->codegen, operand_type); | | |
| 19803 | ir_add_alloca(ira, result, result->value.type); | | |
| 19804 | return result; | | |
| 19805 | } | 21413 | } |
| 19806 | | 21414 | |
| 19807 | static IrInstruction *ir_analyze_instruction_fence(IrAnalyze *ira, IrInstructionFence *instruction) { | 21415 | static IrInstruction *ir_analyze_instruction_fence(IrAnalyze *ira, IrInstructionFence *instruction) { |
| ... | @@ -19939,7 +21547,7 @@ static IrInstruction *ir_analyze_instruction_float_cast(IrAnalyze *ira, IrInstru | ... | @@ -19939,7 +21547,7 @@ static IrInstruction *ir_analyze_instruction_float_cast(IrAnalyze *ira, IrInstru |
| 19939 | } else { | 21547 | } else { |
| 19940 | op = CastOpNumLitToConcrete; | 21548 | op = CastOpNumLitToConcrete; |
| 19941 | } | 21549 | } |
| 19942 | return ir_resolve_cast(ira, &instruction->base, target, dest_type, op, false); | 21550 | return ir_resolve_cast(ira, &instruction->base, target, dest_type, op); |
| 19943 | } else { | 21551 | } else { |
| 19944 | return ira->codegen->invalid_instruction; | 21552 | return ira->codegen->invalid_instruction; |
| 19945 | } | 21553 | } |
| ... | @@ -20047,6 +21655,12 @@ static IrInstruction *ir_analyze_instruction_from_bytes(IrAnalyze *ira, IrInstru | ... | @@ -20047,6 +21655,12 @@ static IrInstruction *ir_analyze_instruction_from_bytes(IrAnalyze *ira, IrInstru |
| 20047 | } | 21655 | } |
| 20048 | } | 21656 | } |
| 20049 | | 21657 | |
| | 21658 | IrInstruction *result_loc = ir_resolve_result(ira, &instruction->base, instruction->result_loc, |
| | 21659 | dest_slice_type, nullptr, true, false); |
| | 21660 | if (result_loc != nullptr && (type_is_invalid(result_loc->value.type) || instr_is_unreachable(result_loc))) { |
| | 21661 | return result_loc; |
| | 21662 | } |
| | 21663 | |
| 20050 | if (casted_value->value.data.rh_slice.id == RuntimeHintSliceIdLen) { | 21664 | if (casted_value->value.data.rh_slice.id == RuntimeHintSliceIdLen) { |
| 20051 | known_len = casted_value->value.data.rh_slice.len; | 21665 | known_len = casted_value->value.data.rh_slice.len; |
| 20052 | have_known_len = true; | 21666 | have_known_len = true; |
| ... | @@ -20066,9 +21680,7 @@ static IrInstruction *ir_analyze_instruction_from_bytes(IrAnalyze *ira, IrInstru | ... | @@ -20066,9 +21680,7 @@ static IrInstruction *ir_analyze_instruction_from_bytes(IrAnalyze *ira, IrInstru |
| 20066 | } | 21680 | } |
| 20067 | } | 21681 | } |
| 20068 | | 21682 | |
| 20069 | IrInstruction *result = ir_build_resize_slice(ira, &instruction->base, casted_value, dest_slice_type); | 21683 | return ir_build_resize_slice(ira, &instruction->base, casted_value, dest_slice_type, result_loc); |
| 20070 | ir_add_alloca(ira, result, dest_slice_type); | | |
| 20071 | return result; | | |
| 20072 | } | 21684 | } |
| 20073 | | 21685 | |
| 20074 | static IrInstruction *ir_analyze_instruction_to_bytes(IrAnalyze *ira, IrInstructionToBytes *instruction) { | 21686 | static IrInstruction *ir_analyze_instruction_to_bytes(IrAnalyze *ira, IrInstructionToBytes *instruction) { |
| ... | @@ -20120,9 +21732,13 @@ static IrInstruction *ir_analyze_instruction_to_bytes(IrAnalyze *ira, IrInstruct | ... | @@ -20120,9 +21732,13 @@ static IrInstruction *ir_analyze_instruction_to_bytes(IrAnalyze *ira, IrInstruct |
| 20120 | return result; | 21732 | return result; |
| 20121 | } | 21733 | } |
| 20122 | | 21734 | |
| 20123 | IrInstruction *result = ir_build_resize_slice(ira, &instruction->base, target, dest_slice_type); | 21735 | IrInstruction *result_loc = ir_resolve_result(ira, &instruction->base, instruction->result_loc, |
| 20124 | ir_add_alloca(ira, result, dest_slice_type); | 21736 | dest_slice_type, nullptr, true, false); |
| 20125 | return result; | 21737 | if (type_is_invalid(result_loc->value.type) || instr_is_unreachable(result_loc)) { |
| | 21738 | return result_loc; |
| | 21739 | } |
| | 21740 | |
| | 21741 | return ir_build_resize_slice(ira, &instruction->base, target, dest_slice_type, result_loc); |
| 20126 | } | 21742 | } |
| 20127 | | 21743 | |
| 20128 | static Error resolve_ptr_align(IrAnalyze *ira, ZigType *ty, uint32_t *result_align) { | 21744 | static Error resolve_ptr_align(IrAnalyze *ira, ZigType *ty, uint32_t *result_align) { |
| ... | @@ -20154,7 +21770,7 @@ static IrInstruction *ir_analyze_instruction_int_to_float(IrAnalyze *ira, IrInst | ... | @@ -20154,7 +21770,7 @@ static IrInstruction *ir_analyze_instruction_int_to_float(IrAnalyze *ira, IrInst |
| 20154 | return ira->codegen->invalid_instruction; | 21770 | return ira->codegen->invalid_instruction; |
| 20155 | } | 21771 | } |
| 20156 | | 21772 | |
| 20157 | return ir_resolve_cast(ira, &instruction->base, target, dest_type, CastOpIntToFloat, false); | 21773 | return ir_resolve_cast(ira, &instruction->base, target, dest_type, CastOpIntToFloat); |
| 20158 | } | 21774 | } |
| 20159 | | 21775 | |
| 20160 | static IrInstruction *ir_analyze_instruction_float_to_int(IrAnalyze *ira, IrInstructionFloatToInt *instruction) { | 21776 | static IrInstruction *ir_analyze_instruction_float_to_int(IrAnalyze *ira, IrInstructionFloatToInt *instruction) { |
| ... | @@ -20176,7 +21792,7 @@ static IrInstruction *ir_analyze_instruction_float_to_int(IrAnalyze *ira, IrInst | ... | @@ -20176,7 +21792,7 @@ static IrInstruction *ir_analyze_instruction_float_to_int(IrAnalyze *ira, IrInst |
| 20176 | return ira->codegen->invalid_instruction; | 21792 | return ira->codegen->invalid_instruction; |
| 20177 | } | 21793 | } |
| 20178 | | 21794 | |
| 20179 | return ir_resolve_cast(ira, &instruction->base, target, dest_type, CastOpFloatToInt, false); | 21795 | return ir_resolve_cast(ira, &instruction->base, target, dest_type, CastOpFloatToInt); |
| 20180 | } | 21796 | } |
| 20181 | | 21797 | |
| 20182 | static IrInstruction *ir_analyze_instruction_err_to_int(IrAnalyze *ira, IrInstructionErrToInt *instruction) { | 21798 | static IrInstruction *ir_analyze_instruction_err_to_int(IrAnalyze *ira, IrInstructionErrToInt *instruction) { |
| ... | @@ -20228,7 +21844,7 @@ static IrInstruction *ir_analyze_instruction_bool_to_int(IrAnalyze *ira, IrInstr | ... | @@ -20228,7 +21844,7 @@ static IrInstruction *ir_analyze_instruction_bool_to_int(IrAnalyze *ira, IrInstr |
| 20228 | } | 21844 | } |
| 20229 | | 21845 | |
| 20230 | ZigType *u1_type = get_int_type(ira->codegen, false, 1); | 21846 | ZigType *u1_type = get_int_type(ira->codegen, false, 1); |
| 20231 | return ir_resolve_cast(ira, &instruction->base, target, u1_type, CastOpBoolToInt, false); | 21847 | return ir_resolve_cast(ira, &instruction->base, target, u1_type, CastOpBoolToInt); |
| 20232 | } | 21848 | } |
| 20233 | | 21849 | |
| 20234 | static IrInstruction *ir_analyze_instruction_int_type(IrAnalyze *ira, IrInstructionIntType *instruction) { | 21850 | static IrInstruction *ir_analyze_instruction_int_type(IrAnalyze *ira, IrInstructionIntType *instruction) { |
| ... | @@ -20389,7 +22005,7 @@ static IrInstruction *ir_analyze_instruction_memset(IrAnalyze *ira, IrInstructio | ... | @@ -20389,7 +22005,7 @@ static IrInstruction *ir_analyze_instruction_memset(IrAnalyze *ira, IrInstructio |
| 20389 | | 22005 | |
| 20390 | ConstExprValue *byte_val = &casted_byte->value; | 22006 | ConstExprValue *byte_val = &casted_byte->value; |
| 20391 | for (size_t i = start; i < end; i += 1) { | 22007 | for (size_t i = start; i < end; i += 1) { |
| 20392 | dest_elements[i] = *byte_val; | 22008 | copy_const_val(&dest_elements[i], byte_val, true); |
| 20393 | } | 22009 | } |
| 20394 | | 22010 | |
| 20395 | return ir_const_void(ira, &instruction->base); | 22011 | return ir_const_void(ira, &instruction->base); |
| ... | @@ -20459,7 +22075,7 @@ static IrInstruction *ir_analyze_instruction_memcpy(IrAnalyze *ira, IrInstructio | ... | @@ -20459,7 +22075,7 @@ static IrInstruction *ir_analyze_instruction_memcpy(IrAnalyze *ira, IrInstructio |
| 20459 | return ira->codegen->invalid_instruction; | 22075 | return ira->codegen->invalid_instruction; |
| 20460 | | 22076 | |
| 20461 | // TODO test this at comptime with u8 and non-u8 types | 22077 | // TODO test this at comptime with u8 and non-u8 types |
| 20462 | // TODO test with dest ptr being a global runtime variable | 22078 | // TODO test with dest ptr being a global runtime variable |
| 20463 | if (casted_dest_ptr->value.special == ConstValSpecialStatic && | 22079 | if (casted_dest_ptr->value.special == ConstValSpecialStatic && |
| 20464 | casted_src_ptr->value.special == ConstValSpecialStatic && | 22080 | casted_src_ptr->value.special == ConstValSpecialStatic && |
| 20465 | casted_count->value.special == ConstValSpecialStatic && | 22081 | casted_count->value.special == ConstValSpecialStatic && |
| ... | @@ -20557,7 +22173,7 @@ static IrInstruction *ir_analyze_instruction_memcpy(IrAnalyze *ira, IrInstructio | ... | @@ -20557,7 +22173,7 @@ static IrInstruction *ir_analyze_instruction_memcpy(IrAnalyze *ira, IrInstructio |
| 20557 | // TODO check for noalias violations - this should be generalized to work for any function | 22173 | // TODO check for noalias violations - this should be generalized to work for any function |
| 20558 | | 22174 | |
| 20559 | for (size_t i = 0; i < count; i += 1) { | 22175 | for (size_t i = 0; i < count; i += 1) { |
| 20560 | dest_elements[dest_start + i] = src_elements[src_start + i]; | 22176 | copy_const_val(&dest_elements[dest_start + i], &src_elements[src_start + i], true); |
| 20561 | } | 22177 | } |
| 20562 | | 22178 | |
| 20563 | return ir_const_void(ira, &instruction->base); | 22179 | return ir_const_void(ira, &instruction->base); |
| ... | @@ -20569,7 +22185,7 @@ static IrInstruction *ir_analyze_instruction_memcpy(IrAnalyze *ira, IrInstructio | ... | @@ -20569,7 +22185,7 @@ static IrInstruction *ir_analyze_instruction_memcpy(IrAnalyze *ira, IrInstructio |
| 20569 | return result; | 22185 | return result; |
| 20570 | } | 22186 | } |
| 20571 | | 22187 | |
| 20572 | static IrInstruction *ir_analyze_instruction_slice(IrAnalyze *ira, IrInstructionSlice *instruction) { | 22188 | static IrInstruction *ir_analyze_instruction_slice(IrAnalyze *ira, IrInstructionSliceSrc *instruction) { |
| 20573 | IrInstruction *ptr_ptr = instruction->ptr->child; | 22189 | IrInstruction *ptr_ptr = instruction->ptr->child; |
| 20574 | if (type_is_invalid(ptr_ptr->value.type)) | 22190 | if (type_is_invalid(ptr_ptr->value.type)) |
| 20575 | return ira->codegen->invalid_instruction; | 22191 | return ira->codegen->invalid_instruction; |
| ... | @@ -20858,12 +22474,13 @@ static IrInstruction *ir_analyze_instruction_slice(IrAnalyze *ira, IrInstruction | ... | @@ -20858,12 +22474,13 @@ static IrInstruction *ir_analyze_instruction_slice(IrAnalyze *ira, IrInstruction |
| 20858 | return result; | 22474 | return result; |
| 20859 | } | 22475 | } |
| 20860 | | 22476 | |
| 20861 | IrInstruction *new_instruction = ir_build_slice(&ira->new_irb, | 22477 | IrInstruction *result_loc = ir_resolve_result(ira, &instruction->base, instruction->result_loc, |
| 20862 | instruction->base.scope, instruction->base.source_node, | 22478 | return_type, nullptr, true, false); |
| 20863 | ptr_ptr, casted_start, end, instruction->safety_check_on); | 22479 | if (type_is_invalid(result_loc->value.type) || instr_is_unreachable(result_loc)) { |
| 20864 | new_instruction->value.type = return_type; | 22480 | return result_loc; |
| 20865 | ir_add_alloca(ira, new_instruction, return_type); | 22481 | } |
| 20866 | return new_instruction; | 22482 | return ir_build_slice_gen(ira, &instruction->base, return_type, |
| | 22483 | ptr_ptr, casted_start, end, instruction->safety_check_on, result_loc); |
| 20867 | } | 22484 | } |
| 20868 | | 22485 | |
| 20869 | static IrInstruction *ir_analyze_instruction_member_count(IrAnalyze *ira, IrInstructionMemberCount *instruction) { | 22486 | static IrInstruction *ir_analyze_instruction_member_count(IrAnalyze *ira, IrInstructionMemberCount *instruction) { |
| ... | @@ -21187,15 +22804,149 @@ static IrInstruction *ir_analyze_instruction_overflow_op(IrAnalyze *ira, IrInstr | ... | @@ -21187,15 +22804,149 @@ static IrInstruction *ir_analyze_instruction_overflow_op(IrAnalyze *ira, IrInstr |
| 21187 | return result; | 22804 | return result; |
| 21188 | } | 22805 | } |
| 21189 | | 22806 | |
| 21190 | static IrInstruction *ir_analyze_instruction_test_err(IrAnalyze *ira, IrInstructionTestErr *instruction) { | 22807 | static IrInstruction *ir_analyze_instruction_result_ptr(IrAnalyze *ira, IrInstructionResultPtr *instruction) { |
| 21191 | IrInstruction *value = instruction->value->child; | 22808 | IrInstruction *result = instruction->result->child; |
| 21192 | if (type_is_invalid(value->value.type)) | 22809 | if (type_is_invalid(result->value.type)) |
| | 22810 | return result; |
| | 22811 | |
| | 22812 | if (instruction->result_loc->written && instruction->result_loc->resolved_loc != nullptr && |
| | 22813 | !instr_is_comptime(result)) |
| | 22814 | { |
| | 22815 | return instruction->result_loc->resolved_loc; |
| | 22816 | } |
| | 22817 | return ir_get_ref(ira, &instruction->base, result, true, false); |
| | 22818 | } |
| | 22819 | |
| | 22820 | static void ir_eval_mul_add(IrAnalyze *ira, IrInstructionMulAdd *source_instr, ZigType *float_type, |
| | 22821 | ConstExprValue *op1, ConstExprValue *op2, ConstExprValue *op3, ConstExprValue *out_val) { |
| | 22822 | if (float_type->id == ZigTypeIdComptimeFloat) { |
| | 22823 | f128M_mulAdd(&out_val->data.x_bigfloat.value, &op1->data.x_bigfloat.value, &op2->data.x_bigfloat.value, |
| | 22824 | &op3->data.x_bigfloat.value); |
| | 22825 | } else if (float_type->id == ZigTypeIdFloat) { |
| | 22826 | switch (float_type->data.floating.bit_count) { |
| | 22827 | case 16: |
| | 22828 | out_val->data.x_f16 = f16_mulAdd(op1->data.x_f16, op2->data.x_f16, op3->data.x_f16); |
| | 22829 | break; |
| | 22830 | case 32: |
| | 22831 | out_val->data.x_f32 = fmaf(op1->data.x_f32, op2->data.x_f32, op3->data.x_f32); |
| | 22832 | break; |
| | 22833 | case 64: |
| | 22834 | out_val->data.x_f64 = fma(op1->data.x_f64, op2->data.x_f64, op3->data.x_f64); |
| | 22835 | break; |
| | 22836 | case 128: |
| | 22837 | f128M_mulAdd(&op1->data.x_f128, &op2->data.x_f128, &op3->data.x_f128, &out_val->data.x_f128); |
| | 22838 | break; |
| | 22839 | default: |
| | 22840 | zig_unreachable(); |
| | 22841 | } |
| | 22842 | } else { |
| | 22843 | zig_unreachable(); |
| | 22844 | } |
| | 22845 | } |
| | 22846 | |
| | 22847 | static IrInstruction *ir_analyze_instruction_mul_add(IrAnalyze *ira, IrInstructionMulAdd *instruction) { |
| | 22848 | IrInstruction *type_value = instruction->type_value->child; |
| | 22849 | if (type_is_invalid(type_value->value.type)) |
| | 22850 | return ira->codegen->invalid_instruction; |
| | 22851 | |
| | 22852 | ZigType *expr_type = ir_resolve_type(ira, type_value); |
| | 22853 | if (type_is_invalid(expr_type)) |
| | 22854 | return ira->codegen->invalid_instruction; |
| | 22855 | |
| | 22856 | // Only allow float types, and vectors of floats. |
| | 22857 | ZigType *float_type = (expr_type->id == ZigTypeIdVector) ? expr_type->data.vector.elem_type : expr_type; |
| | 22858 | if (float_type->id != ZigTypeIdFloat) { |
| | 22859 | ir_add_error(ira, type_value, |
| | 22860 | buf_sprintf("expected float or vector of float type, found '%s'", buf_ptr(&float_type->name))); |
| | 22861 | return ira->codegen->invalid_instruction; |
| | 22862 | } |
| | 22863 | |
| | 22864 | IrInstruction *op1 = instruction->op1->child; |
| | 22865 | if (type_is_invalid(op1->value.type)) |
| | 22866 | return ira->codegen->invalid_instruction; |
| | 22867 | |
| | 22868 | IrInstruction *casted_op1 = ir_implicit_cast(ira, op1, expr_type); |
| | 22869 | if (type_is_invalid(casted_op1->value.type)) |
| | 22870 | return ira->codegen->invalid_instruction; |
| | 22871 | |
| | 22872 | IrInstruction *op2 = instruction->op2->child; |
| | 22873 | if (type_is_invalid(op2->value.type)) |
| | 22874 | return ira->codegen->invalid_instruction; |
| | 22875 | |
| | 22876 | IrInstruction *casted_op2 = ir_implicit_cast(ira, op2, expr_type); |
| | 22877 | if (type_is_invalid(casted_op2->value.type)) |
| | 22878 | return ira->codegen->invalid_instruction; |
| | 22879 | |
| | 22880 | IrInstruction *op3 = instruction->op3->child; |
| | 22881 | if (type_is_invalid(op3->value.type)) |
| | 22882 | return ira->codegen->invalid_instruction; |
| | 22883 | |
| | 22884 | IrInstruction *casted_op3 = ir_implicit_cast(ira, op3, expr_type); |
| | 22885 | if (type_is_invalid(casted_op3->value.type)) |
| | 22886 | return ira->codegen->invalid_instruction; |
| | 22887 | |
| | 22888 | if (instr_is_comptime(casted_op1) && |
| | 22889 | instr_is_comptime(casted_op2) && |
| | 22890 | instr_is_comptime(casted_op3)) { |
| | 22891 | ConstExprValue *op1_const = ir_resolve_const(ira, casted_op1, UndefBad); |
| | 22892 | if (!op1_const) |
| | 22893 | return ira->codegen->invalid_instruction; |
| | 22894 | ConstExprValue *op2_const = ir_resolve_const(ira, casted_op2, UndefBad); |
| | 22895 | if (!op2_const) |
| | 22896 | return ira->codegen->invalid_instruction; |
| | 22897 | ConstExprValue *op3_const = ir_resolve_const(ira, casted_op3, UndefBad); |
| | 22898 | if (!op3_const) |
| | 22899 | return ira->codegen->invalid_instruction; |
| | 22900 | |
| | 22901 | IrInstruction *result = ir_const(ira, &instruction->base, expr_type); |
| | 22902 | ConstExprValue *out_val = &result->value; |
| | 22903 | |
| | 22904 | if (expr_type->id == ZigTypeIdVector) { |
| | 22905 | expand_undef_array(ira->codegen, op1_const); |
| | 22906 | expand_undef_array(ira->codegen, op2_const); |
| | 22907 | expand_undef_array(ira->codegen, op3_const); |
| | 22908 | out_val->special = ConstValSpecialUndef; |
| | 22909 | expand_undef_array(ira->codegen, out_val); |
| | 22910 | size_t len = expr_type->data.vector.len; |
| | 22911 | for (size_t i = 0; i < len; i += 1) { |
| | 22912 | ConstExprValue *float_operand_op1 = &op1_const->data.x_array.data.s_none.elements[i]; |
| | 22913 | ConstExprValue *float_operand_op2 = &op2_const->data.x_array.data.s_none.elements[i]; |
| | 22914 | ConstExprValue *float_operand_op3 = &op3_const->data.x_array.data.s_none.elements[i]; |
| | 22915 | ConstExprValue *float_out_val = &out_val->data.x_array.data.s_none.elements[i]; |
| | 22916 | assert(float_operand_op1->type == float_type); |
| | 22917 | assert(float_operand_op2->type == float_type); |
| | 22918 | assert(float_operand_op3->type == float_type); |
| | 22919 | assert(float_out_val->type == float_type); |
| | 22920 | ir_eval_mul_add(ira, instruction, float_type, |
| | 22921 | op1_const, op2_const, op3_const, float_out_val); |
| | 22922 | float_out_val->type = float_type; |
| | 22923 | } |
| | 22924 | out_val->type = expr_type; |
| | 22925 | out_val->special = ConstValSpecialStatic; |
| | 22926 | } else { |
| | 22927 | ir_eval_mul_add(ira, instruction, float_type, op1_const, op2_const, op3_const, out_val); |
| | 22928 | } |
| | 22929 | return result; |
| | 22930 | } |
| | 22931 | |
| | 22932 | IrInstruction *result = ir_build_mul_add(&ira->new_irb, |
| | 22933 | instruction->base.scope, instruction->base.source_node, |
| | 22934 | type_value, casted_op1, casted_op2, casted_op3); |
| | 22935 | result->value.type = expr_type; |
| | 22936 | return result; |
| | 22937 | } |
| | 22938 | |
| | 22939 | static IrInstruction *ir_analyze_instruction_test_err(IrAnalyze *ira, IrInstructionTestErrSrc *instruction) { |
| | 22940 | IrInstruction *base_ptr = instruction->base_ptr->child; |
| | 22941 | if (type_is_invalid(base_ptr->value.type)) |
| 21193 | return ira->codegen->invalid_instruction; | 22942 | return ira->codegen->invalid_instruction; |
| 21194 | | 22943 | |
| | 22944 | IrInstruction *value = ir_get_deref(ira, &instruction->base, base_ptr, nullptr); |
| 21195 | ZigType *type_entry = value->value.type; | 22945 | ZigType *type_entry = value->value.type; |
| 21196 | if (type_is_invalid(type_entry)) { | 22946 | if (type_is_invalid(type_entry)) |
| 21197 | return ira->codegen->invalid_instruction; | 22947 | return ira->codegen->invalid_instruction; |
| 21198 | } else if (type_entry->id == ZigTypeIdErrorUnion) { | 22948 | |
| | 22949 | if (type_entry->id == ZigTypeIdErrorUnion) { |
| 21199 | if (instr_is_comptime(value)) { | 22950 | if (instr_is_comptime(value)) { |
| 21200 | ConstExprValue *err_union_val = ir_resolve_const(ira, value, UndefBad); | 22951 | ConstExprValue *err_union_val = ir_resolve_const(ira, value, UndefBad); |
| 21201 | if (!err_union_val) | 22952 | if (!err_union_val) |
| ... | @@ -21207,21 +22958,20 @@ static IrInstruction *ir_analyze_instruction_test_err(IrAnalyze *ira, IrInstruct | ... | @@ -21207,21 +22958,20 @@ static IrInstruction *ir_analyze_instruction_test_err(IrAnalyze *ira, IrInstruct |
| 21207 | } | 22958 | } |
| 21208 | } | 22959 | } |
| 21209 | | 22960 | |
| 21210 | ZigType *err_set_type = type_entry->data.error_union.err_set_type; | 22961 | if (instruction->resolve_err_set) { |
| 21211 | if (!resolve_inferred_error_set(ira->codegen, err_set_type, instruction->base.source_node)) { | 22962 | ZigType *err_set_type = type_entry->data.error_union.err_set_type; |
| 21212 | return ira->codegen->invalid_instruction; | 22963 | if (!resolve_inferred_error_set(ira->codegen, err_set_type, instruction->base.source_node)) { |
| 21213 | } | 22964 | return ira->codegen->invalid_instruction; |
| 21214 | if (!type_is_global_error_set(err_set_type) && | 22965 | } |
| 21215 | err_set_type->data.error_set.err_count == 0) | 22966 | if (!type_is_global_error_set(err_set_type) && |
| 21216 | { | 22967 | err_set_type->data.error_set.err_count == 0) |
| 21217 | assert(err_set_type->data.error_set.infer_fn == nullptr); | 22968 | { |
| 21218 | return ir_const_bool(ira, &instruction->base, false); | 22969 | assert(err_set_type->data.error_set.infer_fn == nullptr); |
| | 22970 | return ir_const_bool(ira, &instruction->base, false); |
| | 22971 | } |
| 21219 | } | 22972 | } |
| 21220 | | 22973 | |
| 21221 | IrInstruction *result = ir_build_test_err(&ira->new_irb, | 22974 | return ir_build_test_err_gen(ira, &instruction->base, value); |
| 21222 | instruction->base.scope, instruction->base.source_node, value); | | |
| 21223 | result->value.type = ira->codegen->builtin_types.entry_bool; | | |
| 21224 | return result; | | |
| 21225 | } else if (type_entry->id == ZigTypeIdErrorSet) { | 22975 | } else if (type_entry->id == ZigTypeIdErrorSet) { |
| 21226 | return ir_const_bool(ira, &instruction->base, true); | 22976 | return ir_const_bool(ira, &instruction->base, true); |
| 21227 | } else { | 22977 | } else { |
| ... | @@ -21229,10 +22979,9 @@ static IrInstruction *ir_analyze_instruction_test_err(IrAnalyze *ira, IrInstruct | ... | @@ -21229,10 +22979,9 @@ static IrInstruction *ir_analyze_instruction_test_err(IrAnalyze *ira, IrInstruct |
| 21229 | } | 22979 | } |
| 21230 | } | 22980 | } |
| 21231 | | 22981 | |
| 21232 | static IrInstruction *ir_analyze_instruction_unwrap_err_code(IrAnalyze *ira, IrInstructionUnwrapErrCode *instruction) { | 22982 | static IrInstruction *ir_analyze_unwrap_err_code(IrAnalyze *ira, IrInstruction *source_instr, |
| 21233 | IrInstruction *base_ptr = instruction->err_union->child; | 22983 | IrInstruction *base_ptr, bool initializing) |
| 21234 | if (type_is_invalid(base_ptr->value.type)) | 22984 | { |
| 21235 | return ira->codegen->invalid_instruction; | | |
| 21236 | ZigType *ptr_type = base_ptr->value.type; | 22985 | ZigType *ptr_type = base_ptr->value.type; |
| 21237 | | 22986 | |
| 21238 | // This will be a pointer type because unwrap err payload IR instruction operates on a pointer to a thing. | 22987 | // This will be a pointer type because unwrap err payload IR instruction operates on a pointer to a thing. |
| ... | @@ -21248,40 +22997,79 @@ static IrInstruction *ir_analyze_instruction_unwrap_err_code(IrAnalyze *ira, IrI | ... | @@ -21248,40 +22997,79 @@ static IrInstruction *ir_analyze_instruction_unwrap_err_code(IrAnalyze *ira, IrI |
| 21248 | return ira->codegen->invalid_instruction; | 22997 | return ira->codegen->invalid_instruction; |
| 21249 | } | 22998 | } |
| 21250 | | 22999 | |
| | 23000 | ZigType *err_set_type = type_entry->data.error_union.err_set_type; |
| | 23001 | ZigType *result_type = get_pointer_to_type_extra(ira->codegen, err_set_type, |
| | 23002 | ptr_type->data.pointer.is_const, ptr_type->data.pointer.is_volatile, PtrLenSingle, |
| | 23003 | ptr_type->data.pointer.explicit_alignment, 0, 0, false); |
| | 23004 | |
| 21251 | if (instr_is_comptime(base_ptr)) { | 23005 | if (instr_is_comptime(base_ptr)) { |
| 21252 | ConstExprValue *ptr_val = ir_resolve_const(ira, base_ptr, UndefBad); | 23006 | ConstExprValue *ptr_val = ir_resolve_const(ira, base_ptr, UndefBad); |
| 21253 | if (!ptr_val) | 23007 | if (!ptr_val) |
| 21254 | return ira->codegen->invalid_instruction; | 23008 | return ira->codegen->invalid_instruction; |
| 21255 | if (ptr_val->data.x_ptr.mut != ConstPtrMutRuntimeVar) { | 23009 | if (ptr_val->data.x_ptr.mut != ConstPtrMutRuntimeVar && |
| 21256 | ConstExprValue *err_union_val = const_ptr_pointee(ira, ira->codegen, ptr_val, instruction->base.source_node); | 23010 | ptr_val->data.x_ptr.special != ConstPtrSpecialHardCodedAddr) |
| | 23011 | { |
| | 23012 | ConstExprValue *err_union_val = const_ptr_pointee(ira, ira->codegen, ptr_val, source_instr->source_node); |
| 21257 | if (err_union_val == nullptr) | 23013 | if (err_union_val == nullptr) |
| 21258 | return ira->codegen->invalid_instruction; | 23014 | return ira->codegen->invalid_instruction; |
| 21259 | if (err_union_val->special != ConstValSpecialRuntime) { | | |
| 21260 | ErrorTableEntry *err = err_union_val->data.x_err_union.error_set->data.x_err_set; | | |
| 21261 | assert(err); | | |
| 21262 | | 23015 | |
| 21263 | IrInstruction *result = ir_const(ira, &instruction->base, | 23016 | if (initializing && err_union_val->special == ConstValSpecialUndef) { |
| 21264 | type_entry->data.error_union.err_set_type); | 23017 | ConstExprValue *vals = create_const_vals(2); |
| 21265 | result->value.data.x_err_set = err; | 23018 | ConstExprValue *err_set_val = &vals[0]; |
| 21266 | return result; | 23019 | ConstExprValue *payload_val = &vals[1]; |
| | 23020 | |
| | 23021 | err_set_val->special = ConstValSpecialUndef; |
| | 23022 | err_set_val->type = err_set_type; |
| | 23023 | err_set_val->parent.id = ConstParentIdErrUnionCode; |
| | 23024 | err_set_val->parent.data.p_err_union_code.err_union_val = err_union_val; |
| | 23025 | |
| | 23026 | payload_val->special = ConstValSpecialUndef; |
| | 23027 | payload_val->type = type_entry->data.error_union.payload_type; |
| | 23028 | payload_val->parent.id = ConstParentIdErrUnionPayload; |
| | 23029 | payload_val->parent.data.p_err_union_payload.err_union_val = err_union_val; |
| | 23030 | |
| | 23031 | err_union_val->special = ConstValSpecialStatic; |
| | 23032 | err_union_val->data.x_err_union.error_set = err_set_val; |
| | 23033 | err_union_val->data.x_err_union.payload = payload_val; |
| | 23034 | } |
| | 23035 | ir_assert(err_union_val->special != ConstValSpecialRuntime, source_instr); |
| | 23036 | |
| | 23037 | IrInstruction *result; |
| | 23038 | if (ptr_val->data.x_ptr.mut == ConstPtrMutInfer) { |
| | 23039 | result = ir_build_unwrap_err_code(&ira->new_irb, source_instr->scope, |
| | 23040 | source_instr->source_node, base_ptr); |
| | 23041 | result->value.type = result_type; |
| | 23042 | result->value.special = ConstValSpecialStatic; |
| | 23043 | } else { |
| | 23044 | result = ir_const(ira, source_instr, result_type); |
| 21267 | } | 23045 | } |
| | 23046 | ConstExprValue *const_val = &result->value; |
| | 23047 | const_val->data.x_ptr.special = ConstPtrSpecialBaseErrorUnionCode; |
| | 23048 | const_val->data.x_ptr.data.base_err_union_code.err_union_val = err_union_val; |
| | 23049 | const_val->data.x_ptr.mut = ptr_val->data.x_ptr.mut; |
| | 23050 | return result; |
| 21268 | } | 23051 | } |
| 21269 | } | 23052 | } |
| 21270 | | 23053 | |
| 21271 | IrInstruction *result = ir_build_unwrap_err_code(&ira->new_irb, | 23054 | IrInstruction *result = ir_build_unwrap_err_code(&ira->new_irb, |
| 21272 | instruction->base.scope, instruction->base.source_node, base_ptr); | 23055 | source_instr->scope, source_instr->source_node, base_ptr); |
| 21273 | result->value.type = type_entry->data.error_union.err_set_type; | 23056 | result->value.type = result_type; |
| 21274 | return result; | 23057 | return result; |
| 21275 | } | 23058 | } |
| 21276 | | 23059 | |
| 21277 | static IrInstruction *ir_analyze_instruction_unwrap_err_payload(IrAnalyze *ira, | 23060 | static IrInstruction *ir_analyze_instruction_unwrap_err_code(IrAnalyze *ira, |
| 21278 | IrInstructionUnwrapErrPayload *instruction) | 23061 | IrInstructionUnwrapErrCode *instruction) |
| 21279 | { | 23062 | { |
| 21280 | assert(instruction->value->child); | 23063 | IrInstruction *base_ptr = instruction->err_union_ptr->child; |
| 21281 | IrInstruction *value = instruction->value->child; | 23064 | if (type_is_invalid(base_ptr->value.type)) |
| 21282 | if (type_is_invalid(value->value.type)) | | |
| 21283 | return ira->codegen->invalid_instruction; | 23065 | return ira->codegen->invalid_instruction; |
| 21284 | ZigType *ptr_type = value->value.type; | 23066 | return ir_analyze_unwrap_err_code(ira, &instruction->base, base_ptr, false); |
| | 23067 | } |
| | 23068 | |
| | 23069 | static IrInstruction *ir_analyze_unwrap_error_payload(IrAnalyze *ira, IrInstruction *source_instr, |
| | 23070 | IrInstruction *base_ptr, bool safety_check_on, bool initializing) |
| | 23071 | { |
| | 23072 | ZigType *ptr_type = base_ptr->value.type; |
| 21285 | | 23073 | |
| 21286 | // This will be a pointer type because unwrap err payload IR instruction operates on a pointer to a thing. | 23074 | // This will be a pointer type because unwrap err payload IR instruction operates on a pointer to a thing. |
| 21287 | assert(ptr_type->id == ZigTypeIdPointer); | 23075 | assert(ptr_type->id == ZigTypeIdPointer); |
| ... | @@ -21291,7 +23079,7 @@ static IrInstruction *ir_analyze_instruction_unwrap_err_payload(IrAnalyze *ira, | ... | @@ -21291,7 +23079,7 @@ static IrInstruction *ir_analyze_instruction_unwrap_err_payload(IrAnalyze *ira, |
| 21291 | return ira->codegen->invalid_instruction; | 23079 | return ira->codegen->invalid_instruction; |
| 21292 | | 23080 | |
| 21293 | if (type_entry->id != ZigTypeIdErrorUnion) { | 23081 | if (type_entry->id != ZigTypeIdErrorUnion) { |
| 21294 | ir_add_error(ira, value, | 23082 | ir_add_error(ira, base_ptr, |
| 21295 | buf_sprintf("expected error union type, found '%s'", buf_ptr(&type_entry->name))); | 23083 | buf_sprintf("expected error union type, found '%s'", buf_ptr(&type_entry->name))); |
| 21296 | return ira->codegen->invalid_instruction; | 23084 | return ira->codegen->invalid_instruction; |
| 21297 | } | 23085 | } |
| ... | @@ -21303,36 +23091,73 @@ static IrInstruction *ir_analyze_instruction_unwrap_err_payload(IrAnalyze *ira, | ... | @@ -21303,36 +23091,73 @@ static IrInstruction *ir_analyze_instruction_unwrap_err_payload(IrAnalyze *ira, |
| 21303 | ZigType *result_type = get_pointer_to_type_extra(ira->codegen, payload_type, | 23091 | ZigType *result_type = get_pointer_to_type_extra(ira->codegen, payload_type, |
| 21304 | ptr_type->data.pointer.is_const, ptr_type->data.pointer.is_volatile, | 23092 | ptr_type->data.pointer.is_const, ptr_type->data.pointer.is_volatile, |
| 21305 | PtrLenSingle, 0, 0, 0, false); | 23093 | PtrLenSingle, 0, 0, 0, false); |
| 21306 | if (instr_is_comptime(value)) { | 23094 | if (instr_is_comptime(base_ptr)) { |
| 21307 | ConstExprValue *ptr_val = ir_resolve_const(ira, value, UndefBad); | 23095 | ConstExprValue *ptr_val = ir_resolve_const(ira, base_ptr, UndefBad); |
| 21308 | if (!ptr_val) | 23096 | if (!ptr_val) |
| 21309 | return ira->codegen->invalid_instruction; | 23097 | return ira->codegen->invalid_instruction; |
| 21310 | if (ptr_val->data.x_ptr.mut != ConstPtrMutRuntimeVar) { | 23098 | if (ptr_val->data.x_ptr.mut != ConstPtrMutRuntimeVar) { |
| 21311 | ConstExprValue *err_union_val = const_ptr_pointee(ira, ira->codegen, ptr_val, instruction->base.source_node); | 23099 | ConstExprValue *err_union_val = const_ptr_pointee(ira, ira->codegen, ptr_val, source_instr->source_node); |
| 21312 | if (err_union_val == nullptr) | 23100 | if (err_union_val == nullptr) |
| 21313 | return ira->codegen->invalid_instruction; | 23101 | return ira->codegen->invalid_instruction; |
| | 23102 | if (err_union_val->special == ConstValSpecialUndef && initializing) { |
| | 23103 | ConstExprValue *vals = create_const_vals(2); |
| | 23104 | ConstExprValue *err_set_val = &vals[0]; |
| | 23105 | ConstExprValue *payload_val = &vals[1]; |
| | 23106 | |
| | 23107 | err_set_val->special = ConstValSpecialStatic; |
| | 23108 | err_set_val->type = type_entry->data.error_union.err_set_type; |
| | 23109 | err_set_val->data.x_err_set = nullptr; |
| | 23110 | |
| | 23111 | payload_val->special = ConstValSpecialUndef; |
| | 23112 | payload_val->type = payload_type; |
| | 23113 | |
| | 23114 | err_union_val->special = ConstValSpecialStatic; |
| | 23115 | err_union_val->data.x_err_union.error_set = err_set_val; |
| | 23116 | err_union_val->data.x_err_union.payload = payload_val; |
| | 23117 | } |
| | 23118 | |
| 21314 | if (err_union_val->special != ConstValSpecialRuntime) { | 23119 | if (err_union_val->special != ConstValSpecialRuntime) { |
| 21315 | ErrorTableEntry *err = err_union_val->data.x_err_union.error_set->data.x_err_set; | 23120 | ErrorTableEntry *err = err_union_val->data.x_err_union.error_set->data.x_err_set; |
| 21316 | if (err != nullptr) { | 23121 | if (err != nullptr) { |
| 21317 | ir_add_error(ira, &instruction->base, | 23122 | ir_add_error(ira, source_instr, |
| 21318 | buf_sprintf("caught unexpected error '%s'", buf_ptr(&err->name))); | 23123 | buf_sprintf("caught unexpected error '%s'", buf_ptr(&err->name))); |
| 21319 | return ira->codegen->invalid_instruction; | 23124 | return ira->codegen->invalid_instruction; |
| 21320 | } | 23125 | } |
| 21321 | | 23126 | |
| 21322 | IrInstruction *result = ir_const(ira, &instruction->base, result_type); | 23127 | IrInstruction *result; |
| | 23128 | if (ptr_val->data.x_ptr.mut == ConstPtrMutInfer) { |
| | 23129 | result = ir_build_unwrap_err_payload(&ira->new_irb, source_instr->scope, |
| | 23130 | source_instr->source_node, base_ptr, safety_check_on, initializing); |
| | 23131 | result->value.type = result_type; |
| | 23132 | result->value.special = ConstValSpecialStatic; |
| | 23133 | } else { |
| | 23134 | result = ir_const(ira, source_instr, result_type); |
| | 23135 | } |
| 21323 | result->value.data.x_ptr.special = ConstPtrSpecialRef; | 23136 | result->value.data.x_ptr.special = ConstPtrSpecialRef; |
| 21324 | result->value.data.x_ptr.data.ref.pointee = err_union_val->data.x_err_union.payload; | 23137 | result->value.data.x_ptr.data.ref.pointee = err_union_val->data.x_err_union.payload; |
| | 23138 | result->value.data.x_ptr.mut = ptr_val->data.x_ptr.mut; |
| 21325 | return result; | 23139 | return result; |
| 21326 | } | 23140 | } |
| 21327 | } | 23141 | } |
| 21328 | } | 23142 | } |
| 21329 | | 23143 | |
| 21330 | IrInstruction *result = ir_build_unwrap_err_payload(&ira->new_irb, | 23144 | IrInstruction *result = ir_build_unwrap_err_payload(&ira->new_irb, source_instr->scope, |
| 21331 | instruction->base.scope, instruction->base.source_node, value, instruction->safety_check_on); | 23145 | source_instr->source_node, base_ptr, safety_check_on, initializing); |
| 21332 | result->value.type = result_type; | 23146 | result->value.type = result_type; |
| 21333 | return result; | 23147 | return result; |
| 21334 | } | 23148 | } |
| 21335 | | 23149 | |
| | 23150 | static IrInstruction *ir_analyze_instruction_unwrap_err_payload(IrAnalyze *ira, |
| | 23151 | IrInstructionUnwrapErrPayload *instruction) |
| | 23152 | { |
| | 23153 | assert(instruction->value->child); |
| | 23154 | IrInstruction *value = instruction->value->child; |
| | 23155 | if (type_is_invalid(value->value.type)) |
| | 23156 | return ira->codegen->invalid_instruction; |
| | 23157 | |
| | 23158 | return ir_analyze_unwrap_error_payload(ira, &instruction->base, value, instruction->safety_check_on, false); |
| | 23159 | } |
| | 23160 | |
| 21336 | static IrInstruction *ir_analyze_instruction_fn_proto(IrAnalyze *ira, IrInstructionFnProto *instruction) { | 23161 | static IrInstruction *ir_analyze_instruction_fn_proto(IrAnalyze *ira, IrInstructionFnProto *instruction) { |
| 21337 | AstNode *proto_node = instruction->base.source_node; | 23162 | AstNode *proto_node = instruction->base.source_node; |
| 21338 | assert(proto_node->type == NodeTypeFnProto); | 23163 | assert(proto_node->type == NodeTypeFnProto); |
| ... | @@ -21824,14 +23649,19 @@ static IrInstruction *ir_analyze_ptr_cast(IrAnalyze *ira, IrInstruction *source_ | ... | @@ -21824,14 +23649,19 @@ static IrInstruction *ir_analyze_ptr_cast(IrAnalyze *ira, IrInstruction *source_ |
| 21824 | } | 23649 | } |
| 21825 | } | 23650 | } |
| 21826 | | 23651 | |
| 21827 | IrInstruction *result = ir_const(ira, source_instr, dest_type); | 23652 | IrInstruction *result; |
| | 23653 | if (ptr->value.data.x_ptr.mut == ConstPtrMutInfer) { |
| | 23654 | result = ir_build_ptr_cast_gen(ira, source_instr, dest_type, ptr, safety_check_on); |
| | 23655 | } else { |
| | 23656 | result = ir_const(ira, source_instr, dest_type); |
| | 23657 | } |
| 21828 | copy_const_val(&result->value, val, true); | 23658 | copy_const_val(&result->value, val, true); |
| 21829 | result->value.type = dest_type; | 23659 | result->value.type = dest_type; |
| 21830 | | 23660 | |
| 21831 | // Keep the bigger alignment, it can only help- | 23661 | // Keep the bigger alignment, it can only help- |
| 21832 | // unless the target is zero bits. | 23662 | // unless the target is zero bits. |
| 21833 | if (src_align_bytes > dest_align_bytes && type_has_bits(dest_type)) { | 23663 | if (src_align_bytes > dest_align_bytes && type_has_bits(dest_type)) { |
| 21834 | result = ir_align_cast(ira, result, src_align_bytes, false); | 23664 | result = ir_align_cast(ira, result, src_align_bytes, false); |
| 21835 | } | 23665 | } |
| 21836 | | 23666 | |
| 21837 | return result; | 23667 | return result; |
| ... | @@ -21915,6 +23745,8 @@ static void buf_write_value_bytes(CodeGen *codegen, uint8_t *buf, ConstExprValue | ... | @@ -21915,6 +23745,8 @@ static void buf_write_value_bytes(CodeGen *codegen, uint8_t *buf, ConstExprValue |
| 21915 | case ZigTypeIdUndefined: | 23745 | case ZigTypeIdUndefined: |
| 21916 | case ZigTypeIdNull: | 23746 | case ZigTypeIdNull: |
| 21917 | case ZigTypeIdPromise: | 23747 | case ZigTypeIdPromise: |
| | 23748 | case ZigTypeIdErrorUnion: |
| | 23749 | case ZigTypeIdErrorSet: |
| 21918 | zig_unreachable(); | 23750 | zig_unreachable(); |
| 21919 | case ZigTypeIdVoid: | 23751 | case ZigTypeIdVoid: |
| 21920 | return; | 23752 | return; |
| ... | @@ -22018,10 +23850,6 @@ static void buf_write_value_bytes(CodeGen *codegen, uint8_t *buf, ConstExprValue | ... | @@ -22018,10 +23850,6 @@ static void buf_write_value_bytes(CodeGen *codegen, uint8_t *buf, ConstExprValue |
| 22018 | } | 23850 | } |
| 22019 | case ZigTypeIdOptional: | 23851 | case ZigTypeIdOptional: |
| 22020 | zig_panic("TODO buf_write_value_bytes maybe type"); | 23852 | zig_panic("TODO buf_write_value_bytes maybe type"); |
| 22021 | case ZigTypeIdErrorUnion: | | |
| 22022 | zig_panic("TODO buf_write_value_bytes error union"); | | |
| 22023 | case ZigTypeIdErrorSet: | | |
| 22024 | zig_panic("TODO buf_write_value_bytes pure error type"); | | |
| 22025 | case ZigTypeIdFn: | 23853 | case ZigTypeIdFn: |
| 22026 | zig_panic("TODO buf_write_value_bytes fn type"); | 23854 | zig_panic("TODO buf_write_value_bytes fn type"); |
| 22027 | case ZigTypeIdUnion: | 23855 | case ZigTypeIdUnion: |
| ... | @@ -22210,28 +24038,6 @@ static Error buf_read_value_bytes(IrAnalyze *ira, CodeGen *codegen, AstNode *sou | ... | @@ -22210,28 +24038,6 @@ static Error buf_read_value_bytes(IrAnalyze *ira, CodeGen *codegen, AstNode *sou |
| 22210 | zig_unreachable(); | 24038 | zig_unreachable(); |
| 22211 | } | 24039 | } |
| 22212 | | 24040 | |
| 22213 | static bool type_can_bit_cast(ZigType *t) { | | |
| 22214 | switch (t->id) { | | |
| 22215 | case ZigTypeIdInvalid: | | |
| 22216 | zig_unreachable(); | | |
| 22217 | case ZigTypeIdMetaType: | | |
| 22218 | case ZigTypeIdOpaque: | | |
| 22219 | case ZigTypeIdBoundFn: | | |
| 22220 | case ZigTypeIdArgTuple: | | |
| 22221 | case ZigTypeIdUnreachable: | | |
| 22222 | case ZigTypeIdComptimeFloat: | | |
| 22223 | case ZigTypeIdComptimeInt: | | |
| 22224 | case ZigTypeIdEnumLiteral: | | |
| 22225 | case ZigTypeIdUndefined: | | |
| 22226 | case ZigTypeIdNull: | | |
| 22227 | case ZigTypeIdPointer: | | |
| 22228 | return false; | | |
| 22229 | default: | | |
| 22230 | // TODO list these types out explicitly, there are probably some other invalid ones here | | |
| 22231 | return true; | | |
| 22232 | } | | |
| 22233 | } | | |
| 22234 | | | |
| 22235 | static IrInstruction *ir_analyze_bit_cast(IrAnalyze *ira, IrInstruction *source_instr, IrInstruction *value, | 24041 | static IrInstruction *ir_analyze_bit_cast(IrAnalyze *ira, IrInstruction *source_instr, IrInstruction *value, |
| 22236 | ZigType *dest_type) | 24042 | ZigType *dest_type) |
| 22237 | { | 24043 | { |
| ... | @@ -22283,49 +24089,7 @@ static IrInstruction *ir_analyze_bit_cast(IrAnalyze *ira, IrInstruction *source_ | ... | @@ -22283,49 +24089,7 @@ static IrInstruction *ir_analyze_bit_cast(IrAnalyze *ira, IrInstruction *source_ |
| 22283 | return result; | 24089 | return result; |
| 22284 | } | 24090 | } |
| 22285 | | 24091 | |
| 22286 | IrInstruction *result = ir_build_bit_cast_gen(ira, source_instr, value, dest_type); | 24092 | return ir_build_bit_cast_gen(ira, source_instr, value, dest_type); |
| 22287 | if (handle_is_ptr(dest_type) && !handle_is_ptr(src_type)) { | | |
| 22288 | ir_add_alloca(ira, result, dest_type); | | |
| 22289 | } | | |
| 22290 | return result; | | |
| 22291 | } | | |
| 22292 | | | |
| 22293 | static IrInstruction *ir_analyze_instruction_bit_cast(IrAnalyze *ira, IrInstructionBitCast *instruction) { | | |
| 22294 | IrInstruction *dest_type_value = instruction->dest_type->child; | | |
| 22295 | ZigType *dest_type = ir_resolve_type(ira, dest_type_value); | | |
| 22296 | if (type_is_invalid(dest_type)) | | |
| 22297 | return ira->codegen->invalid_instruction; | | |
| 22298 | | | |
| 22299 | IrInstruction *value = instruction->value->child; | | |
| 22300 | ZigType *src_type = value->value.type; | | |
| 22301 | if (type_is_invalid(src_type)) | | |
| 22302 | return ira->codegen->invalid_instruction; | | |
| 22303 | | | |
| 22304 | if (get_codegen_ptr_type(src_type) != nullptr) { | | |
| 22305 | ir_add_error(ira, value, | | |
| 22306 | buf_sprintf("unable to @bitCast from pointer type '%s'", buf_ptr(&src_type->name))); | | |
| 22307 | return ira->codegen->invalid_instruction; | | |
| 22308 | } | | |
| 22309 | | | |
| 22310 | if (!type_can_bit_cast(src_type)) { | | |
| 22311 | ir_add_error(ira, dest_type_value, | | |
| 22312 | buf_sprintf("unable to @bitCast from type '%s'", buf_ptr(&src_type->name))); | | |
| 22313 | return ira->codegen->invalid_instruction; | | |
| 22314 | } | | |
| 22315 | | | |
| 22316 | if (get_codegen_ptr_type(dest_type) != nullptr) { | | |
| 22317 | ir_add_error(ira, dest_type_value, | | |
| 22318 | buf_sprintf("unable to @bitCast to pointer type '%s'", buf_ptr(&dest_type->name))); | | |
| 22319 | return ira->codegen->invalid_instruction; | | |
| 22320 | } | | |
| 22321 | | | |
| 22322 | if (!type_can_bit_cast(dest_type)) { | | |
| 22323 | ir_add_error(ira, dest_type_value, | | |
| 22324 | buf_sprintf("unable to @bitCast to type '%s'", buf_ptr(&dest_type->name))); | | |
| 22325 | return ira->codegen->invalid_instruction; | | |
| 22326 | } | | |
| 22327 | | | |
| 22328 | return ir_analyze_bit_cast(ira, &instruction->base, value, dest_type); | | |
| 22329 | } | 24093 | } |
| 22330 | | 24094 | |
| 22331 | static IrInstruction *ir_analyze_int_to_ptr(IrAnalyze *ira, IrInstruction *source_instr, IrInstruction *target, | 24095 | static IrInstruction *ir_analyze_int_to_ptr(IrAnalyze *ira, IrInstruction *source_instr, IrInstruction *target, |
| ... | @@ -22395,58 +24159,15 @@ static IrInstruction *ir_analyze_instruction_int_to_ptr(IrAnalyze *ira, IrInstru | ... | @@ -22395,58 +24159,15 @@ static IrInstruction *ir_analyze_instruction_int_to_ptr(IrAnalyze *ira, IrInstru |
| 22395 | static IrInstruction *ir_analyze_instruction_decl_ref(IrAnalyze *ira, | 24159 | static IrInstruction *ir_analyze_instruction_decl_ref(IrAnalyze *ira, |
| 22396 | IrInstructionDeclRef *instruction) | 24160 | IrInstructionDeclRef *instruction) |
| 22397 | { | 24161 | { |
| 22398 | Tld *tld = instruction->tld; | 24162 | IrInstruction *ref_instruction = ir_analyze_decl_ref(ira, &instruction->base, instruction->tld); |
| 22399 | LVal lval = instruction->lval; | 24163 | if (type_is_invalid(ref_instruction->value.type)) |
| 22400 | | | |
| 22401 | resolve_top_level_decl(ira->codegen, tld, instruction->base.source_node); | | |
| 22402 | if (tld->resolution == TldResolutionInvalid) | | |
| 22403 | return ira->codegen->invalid_instruction; | 24164 | return ira->codegen->invalid_instruction; |
| 22404 | | 24165 | |
| 22405 | switch (tld->id) { | 24166 | if (instruction->lval == LValPtr) { |
| 22406 | case TldIdContainer: | 24167 | return ref_instruction; |
| 22407 | case TldIdCompTime: | 24168 | } else { |
| 22408 | zig_unreachable(); | 24169 | return ir_get_deref(ira, &instruction->base, ref_instruction, nullptr); |
| 22409 | case TldIdVar: { | | |
| 22410 | TldVar *tld_var = (TldVar *)tld; | | |
| 22411 | ZigVar *var = tld_var->var; | | |
| 22412 | | | |
| 22413 | if (var == nullptr) { | | |
| 22414 | return ir_error_dependency_loop(ira, &instruction->base); | | |
| 22415 | } | | |
| 22416 | | | |
| 22417 | IrInstruction *var_ptr = ir_get_var_ptr(ira, &instruction->base, var); | | |
| 22418 | if (type_is_invalid(var_ptr->value.type)) | | |
| 22419 | return ira->codegen->invalid_instruction; | | |
| 22420 | | | |
| 22421 | if (tld_var->extern_lib_name != nullptr) { | | |
| 22422 | add_link_lib_symbol(ira, tld_var->extern_lib_name, &var->name, instruction->base.source_node); | | |
| 22423 | } | | |
| 22424 | | | |
| 22425 | if (lval == LValPtr) { | | |
| 22426 | return var_ptr; | | |
| 22427 | } else { | | |
| 22428 | return ir_get_deref(ira, &instruction->base, var_ptr); | | |
| 22429 | } | | |
| 22430 | } | | |
| 22431 | case TldIdFn: { | | |
| 22432 | TldFn *tld_fn = (TldFn *)tld; | | |
| 22433 | ZigFn *fn_entry = tld_fn->fn_entry; | | |
| 22434 | ir_assert(fn_entry->type_entry, &instruction->base); | | |
| 22435 | | | |
| 22436 | if (tld_fn->extern_lib_name != nullptr) { | | |
| 22437 | add_link_lib_symbol(ira, tld_fn->extern_lib_name, &fn_entry->symbol_name, instruction->base.source_node); | | |
| 22438 | } | | |
| 22439 | | | |
| 22440 | IrInstruction *ref_instruction = ir_create_const_fn(&ira->new_irb, instruction->base.scope, | | |
| 22441 | instruction->base.source_node, fn_entry); | | |
| 22442 | if (lval == LValPtr) { | | |
| 22443 | return ir_get_ref(ira, &instruction->base, ref_instruction, true, false); | | |
| 22444 | } else { | | |
| 22445 | return ref_instruction; | | |
| 22446 | } | | |
| 22447 | } | | |
| 22448 | } | 24170 | } |
| 22449 | zig_unreachable(); | | |
| 22450 | } | 24171 | } |
| 22451 | | 24172 | |
| 22452 | static IrInstruction *ir_analyze_instruction_ptr_to_int(IrAnalyze *ira, IrInstructionPtrToInt *instruction) { | 24173 | static IrInstruction *ir_analyze_instruction_ptr_to_int(IrAnalyze *ira, IrInstructionPtrToInt *instruction) { |
| ... | @@ -22960,7 +24681,7 @@ static IrInstruction *ir_analyze_instruction_atomic_load(IrAnalyze *ira, IrInstr | ... | @@ -22960,7 +24681,7 @@ static IrInstruction *ir_analyze_instruction_atomic_load(IrAnalyze *ira, IrInstr |
| 22960 | } | 24681 | } |
| 22961 | | 24682 | |
| 22962 | if (instr_is_comptime(casted_ptr)) { | 24683 | if (instr_is_comptime(casted_ptr)) { |
| 22963 | IrInstruction *result = ir_get_deref(ira, &instruction->base, casted_ptr); | 24684 | IrInstruction *result = ir_get_deref(ira, &instruction->base, casted_ptr, nullptr); |
| 22964 | ir_assert(result->value.type != nullptr, &instruction->base); | 24685 | ir_assert(result->value.type != nullptr, &instruction->base); |
| 22965 | return result; | 24686 | return result; |
| 22966 | } | 24687 | } |
| ... | @@ -23048,70 +24769,254 @@ static IrInstruction *ir_analyze_instruction_mark_err_ret_trace_ptr(IrAnalyze *i | ... | @@ -23048,70 +24769,254 @@ static IrInstruction *ir_analyze_instruction_mark_err_ret_trace_ptr(IrAnalyze *i |
| 23048 | return result; | 24769 | return result; |
| 23049 | } | 24770 | } |
| 23050 | | 24771 | |
| 23051 | static IrInstruction *ir_analyze_instruction_sqrt(IrAnalyze *ira, IrInstructionSqrt *instruction) { | 24772 | static void ir_eval_float_op(IrAnalyze *ira, IrInstructionFloatOp *source_instr, ZigType *float_type, |
| 23052 | ZigType *float_type = ir_resolve_type(ira, instruction->type->child); | 24773 | ConstExprValue *op, ConstExprValue *out_val) { |
| 23053 | if (type_is_invalid(float_type)) | 24774 | assert(ira && source_instr && float_type && out_val && op); |
| 23054 | return ira->codegen->invalid_instruction; | 24775 | assert(float_type->id == ZigTypeIdFloat || |
| | 24776 | float_type->id == ZigTypeIdComptimeFloat); |
| 23055 | | 24777 | |
| 23056 | IrInstruction *op = instruction->op->child; | 24778 | BuiltinFnId fop = source_instr->op; |
| 23057 | if (type_is_invalid(op->value.type)) | 24779 | unsigned bits; |
| | 24780 | |
| | 24781 | switch (float_type->id) { |
| | 24782 | case ZigTypeIdComptimeFloat: |
| | 24783 | bits = 128; |
| | 24784 | break; |
| | 24785 | case ZigTypeIdFloat: |
| | 24786 | bits = float_type->data.floating.bit_count; |
| | 24787 | break; |
| | 24788 | default: |
| | 24789 | zig_unreachable(); |
| | 24790 | } |
| | 24791 | |
| | 24792 | switch (bits) { |
| | 24793 | case 16: { |
| | 24794 | switch (fop) { |
| | 24795 | case BuiltinFnIdSqrt: |
| | 24796 | out_val->data.x_f16 = f16_sqrt(op->data.x_f16); |
| | 24797 | break; |
| | 24798 | case BuiltinFnIdSin: |
| | 24799 | case BuiltinFnIdCos: |
| | 24800 | case BuiltinFnIdExp: |
| | 24801 | case BuiltinFnIdExp2: |
| | 24802 | case BuiltinFnIdLn: |
| | 24803 | case BuiltinFnIdLog10: |
| | 24804 | case BuiltinFnIdLog2: |
| | 24805 | case BuiltinFnIdFabs: |
| | 24806 | case BuiltinFnIdFloor: |
| | 24807 | case BuiltinFnIdCeil: |
| | 24808 | case BuiltinFnIdTrunc: |
| | 24809 | case BuiltinFnIdNearbyInt: |
| | 24810 | case BuiltinFnIdRound: |
| | 24811 | zig_panic("unimplemented f16 builtin"); |
| | 24812 | default: |
| | 24813 | zig_unreachable(); |
| | 24814 | }; |
| | 24815 | break; |
| | 24816 | }; |
| | 24817 | case 32: { |
| | 24818 | switch (fop) { |
| | 24819 | case BuiltinFnIdSqrt: |
| | 24820 | out_val->data.x_f32 = sqrtf(op->data.x_f32); |
| | 24821 | break; |
| | 24822 | case BuiltinFnIdSin: |
| | 24823 | out_val->data.x_f32 = sinf(op->data.x_f32); |
| | 24824 | break; |
| | 24825 | case BuiltinFnIdCos: |
| | 24826 | out_val->data.x_f32 = cosf(op->data.x_f32); |
| | 24827 | break; |
| | 24828 | case BuiltinFnIdExp: |
| | 24829 | out_val->data.x_f32 = expf(op->data.x_f32); |
| | 24830 | break; |
| | 24831 | case BuiltinFnIdExp2: |
| | 24832 | out_val->data.x_f32 = exp2f(op->data.x_f32); |
| | 24833 | break; |
| | 24834 | case BuiltinFnIdLn: |
| | 24835 | out_val->data.x_f32 = logf(op->data.x_f32); |
| | 24836 | break; |
| | 24837 | case BuiltinFnIdLog10: |
| | 24838 | out_val->data.x_f32 = log10f(op->data.x_f32); |
| | 24839 | break; |
| | 24840 | case BuiltinFnIdLog2: |
| | 24841 | out_val->data.x_f32 = log2f(op->data.x_f32); |
| | 24842 | break; |
| | 24843 | case BuiltinFnIdFabs: |
| | 24844 | out_val->data.x_f32 = fabsf(op->data.x_f32); |
| | 24845 | break; |
| | 24846 | case BuiltinFnIdFloor: |
| | 24847 | out_val->data.x_f32 = floorf(op->data.x_f32); |
| | 24848 | break; |
| | 24849 | case BuiltinFnIdCeil: |
| | 24850 | out_val->data.x_f32 = ceilf(op->data.x_f32); |
| | 24851 | break; |
| | 24852 | case BuiltinFnIdTrunc: |
| | 24853 | out_val->data.x_f32 = truncf(op->data.x_f32); |
| | 24854 | break; |
| | 24855 | case BuiltinFnIdNearbyInt: |
| | 24856 | out_val->data.x_f32 = nearbyintf(op->data.x_f32); |
| | 24857 | break; |
| | 24858 | case BuiltinFnIdRound: |
| | 24859 | out_val->data.x_f32 = roundf(op->data.x_f32); |
| | 24860 | break; |
| | 24861 | default: |
| | 24862 | zig_unreachable(); |
| | 24863 | }; |
| | 24864 | break; |
| | 24865 | }; |
| | 24866 | case 64: { |
| | 24867 | switch (fop) { |
| | 24868 | case BuiltinFnIdSqrt: |
| | 24869 | out_val->data.x_f64 = sqrt(op->data.x_f64); |
| | 24870 | break; |
| | 24871 | case BuiltinFnIdSin: |
| | 24872 | out_val->data.x_f64 = sin(op->data.x_f64); |
| | 24873 | break; |
| | 24874 | case BuiltinFnIdCos: |
| | 24875 | out_val->data.x_f64 = cos(op->data.x_f64); |
| | 24876 | break; |
| | 24877 | case BuiltinFnIdExp: |
| | 24878 | out_val->data.x_f64 = exp(op->data.x_f64); |
| | 24879 | break; |
| | 24880 | case BuiltinFnIdExp2: |
| | 24881 | out_val->data.x_f64 = exp2(op->data.x_f64); |
| | 24882 | break; |
| | 24883 | case BuiltinFnIdLn: |
| | 24884 | out_val->data.x_f64 = log(op->data.x_f64); |
| | 24885 | break; |
| | 24886 | case BuiltinFnIdLog10: |
| | 24887 | out_val->data.x_f64 = log10(op->data.x_f64); |
| | 24888 | break; |
| | 24889 | case BuiltinFnIdLog2: |
| | 24890 | out_val->data.x_f64 = log2(op->data.x_f64); |
| | 24891 | break; |
| | 24892 | case BuiltinFnIdFabs: |
| | 24893 | out_val->data.x_f64 = fabs(op->data.x_f64); |
| | 24894 | break; |
| | 24895 | case BuiltinFnIdFloor: |
| | 24896 | out_val->data.x_f64 = floor(op->data.x_f64); |
| | 24897 | break; |
| | 24898 | case BuiltinFnIdCeil: |
| | 24899 | out_val->data.x_f64 = ceil(op->data.x_f64); |
| | 24900 | break; |
| | 24901 | case BuiltinFnIdTrunc: |
| | 24902 | out_val->data.x_f64 = trunc(op->data.x_f64); |
| | 24903 | break; |
| | 24904 | case BuiltinFnIdNearbyInt: |
| | 24905 | out_val->data.x_f64 = nearbyint(op->data.x_f64); |
| | 24906 | break; |
| | 24907 | case BuiltinFnIdRound: |
| | 24908 | out_val->data.x_f64 = round(op->data.x_f64); |
| | 24909 | break; |
| | 24910 | default: |
| | 24911 | zig_unreachable(); |
| | 24912 | } |
| | 24913 | break; |
| | 24914 | }; |
| | 24915 | case 128: { |
| | 24916 | float128_t *out, *in; |
| | 24917 | if (float_type->id == ZigTypeIdComptimeFloat) { |
| | 24918 | out = &out_val->data.x_bigfloat.value; |
| | 24919 | in = &op->data.x_bigfloat.value; |
| | 24920 | } else { |
| | 24921 | out = &out_val->data.x_f128; |
| | 24922 | in = &op->data.x_f128; |
| | 24923 | } |
| | 24924 | switch (fop) { |
| | 24925 | case BuiltinFnIdSqrt: |
| | 24926 | f128M_sqrt(in, out); |
| | 24927 | break; |
| | 24928 | case BuiltinFnIdNearbyInt: |
| | 24929 | case BuiltinFnIdSin: |
| | 24930 | case BuiltinFnIdCos: |
| | 24931 | case BuiltinFnIdExp: |
| | 24932 | case BuiltinFnIdExp2: |
| | 24933 | case BuiltinFnIdLn: |
| | 24934 | case BuiltinFnIdLog10: |
| | 24935 | case BuiltinFnIdLog2: |
| | 24936 | case BuiltinFnIdFabs: |
| | 24937 | case BuiltinFnIdFloor: |
| | 24938 | case BuiltinFnIdCeil: |
| | 24939 | case BuiltinFnIdTrunc: |
| | 24940 | case BuiltinFnIdRound: |
| | 24941 | zig_panic("unimplemented f128 builtin"); |
| | 24942 | default: |
| | 24943 | zig_unreachable(); |
| | 24944 | } |
| | 24945 | break; |
| | 24946 | }; |
| | 24947 | default: |
| | 24948 | zig_unreachable(); |
| | 24949 | } |
| | 24950 | } |
| | 24951 | |
| | 24952 | static IrInstruction *ir_analyze_instruction_float_op(IrAnalyze *ira, IrInstructionFloatOp *instruction) { |
| | 24953 | IrInstruction *type = instruction->type->child; |
| | 24954 | if (type_is_invalid(type->value.type)) |
| | 24955 | return ira->codegen->invalid_instruction; |
| | 24956 | |
| | 24957 | ZigType *expr_type = ir_resolve_type(ira, type); |
| | 24958 | if (type_is_invalid(expr_type)) |
| 23058 | return ira->codegen->invalid_instruction; | 24959 | return ira->codegen->invalid_instruction; |
| 23059 | | 24960 | |
| 23060 | bool ok_type = float_type->id == ZigTypeIdComptimeFloat || float_type->id == ZigTypeIdFloat; | 24961 | // Only allow float types, and vectors of floats. |
| 23061 | if (!ok_type) { | 24962 | ZigType *float_type = (expr_type->id == ZigTypeIdVector) ? expr_type->data.vector.elem_type : expr_type; |
| 23062 | ir_add_error(ira, instruction->type, buf_sprintf("@sqrt does not support type '%s'", buf_ptr(&float_type->name))); | 24963 | if (float_type->id != ZigTypeIdFloat && float_type->id != ZigTypeIdComptimeFloat) { |
| | 24964 | ir_add_error(ira, instruction->type, buf_sprintf("@%s does not support type '%s'", float_op_to_name(instruction->op, false), buf_ptr(&float_type->name))); |
| 23063 | return ira->codegen->invalid_instruction; | 24965 | return ira->codegen->invalid_instruction; |
| 23064 | } | 24966 | } |
| 23065 | | 24967 | |
| 23066 | IrInstruction *casted_op = ir_implicit_cast(ira, op, float_type); | 24968 | IrInstruction *op1 = instruction->op1->child; |
| 23067 | if (type_is_invalid(casted_op->value.type)) | 24969 | if (type_is_invalid(op1->value.type)) |
| | 24970 | return ira->codegen->invalid_instruction; |
| | 24971 | |
| | 24972 | IrInstruction *casted_op1 = ir_implicit_cast(ira, op1, float_type); |
| | 24973 | if (type_is_invalid(casted_op1->value.type)) |
| 23068 | return ira->codegen->invalid_instruction; | 24974 | return ira->codegen->invalid_instruction; |
| 23069 | | 24975 | |
| 23070 | if (instr_is_comptime(casted_op)) { | 24976 | if (instr_is_comptime(casted_op1)) { |
| 23071 | ConstExprValue *val = ir_resolve_const(ira, casted_op, UndefBad); | 24977 | // Our comptime 16-bit and 128-bit support is quite limited. |
| 23072 | if (!val) | 24978 | if ((float_type->id == ZigTypeIdComptimeFloat || |
| | 24979 | float_type->data.floating.bit_count == 16 || |
| | 24980 | float_type->data.floating.bit_count == 128) && |
| | 24981 | instruction->op != BuiltinFnIdSqrt) { |
| | 24982 | ir_add_error(ira, instruction->type, buf_sprintf("@%s does not support type '%s'", float_op_to_name(instruction->op, false), buf_ptr(&float_type->name))); |
| | 24983 | return ira->codegen->invalid_instruction; |
| | 24984 | } |
| | 24985 | |
| | 24986 | ConstExprValue *op1_const = ir_resolve_const(ira, casted_op1, UndefBad); |
| | 24987 | if (!op1_const) |
| 23073 | return ira->codegen->invalid_instruction; | 24988 | return ira->codegen->invalid_instruction; |
| 23074 | | 24989 | |
| 23075 | IrInstruction *result = ir_const(ira, &instruction->base, float_type); | 24990 | IrInstruction *result = ir_const(ira, &instruction->base, expr_type); |
| 23076 | ConstExprValue *out_val = &result->value; | 24991 | ConstExprValue *out_val = &result->value; |
| 23077 | | 24992 | |
| 23078 | if (float_type->id == ZigTypeIdComptimeFloat) { | 24993 | if (expr_type->id == ZigTypeIdVector) { |
| 23079 | bigfloat_sqrt(&out_val->data.x_bigfloat, &val->data.x_bigfloat); | 24994 | expand_undef_array(ira->codegen, op1_const); |
| 23080 | } else if (float_type->id == ZigTypeIdFloat) { | 24995 | out_val->special = ConstValSpecialUndef; |
| 23081 | switch (float_type->data.floating.bit_count) { | 24996 | expand_undef_array(ira->codegen, out_val); |
| 23082 | case 16: | 24997 | size_t len = expr_type->data.vector.len; |
| 23083 | out_val->data.x_f16 = f16_sqrt(val->data.x_f16); | 24998 | for (size_t i = 0; i < len; i += 1) { |
| 23084 | break; | 24999 | ConstExprValue *float_operand_op1 = &op1_const->data.x_array.data.s_none.elements[i]; |
| 23085 | case 32: | 25000 | ConstExprValue *float_out_val = &out_val->data.x_array.data.s_none.elements[i]; |
| 23086 | out_val->data.x_f32 = sqrtf(val->data.x_f32); | 25001 | assert(float_operand_op1->type == float_type); |
| 23087 | break; | 25002 | assert(float_out_val->type == float_type); |
| 23088 | case 64: | 25003 | ir_eval_float_op(ira, instruction, float_type, |
| 23089 | out_val->data.x_f64 = sqrt(val->data.x_f64); | 25004 | op1_const, float_out_val); |
| 23090 | break; | 25005 | float_out_val->type = float_type; |
| 23091 | case 128: | | |
| 23092 | f128M_sqrt(&val->data.x_f128, &out_val->data.x_f128); | | |
| 23093 | break; | | |
| 23094 | default: | | |
| 23095 | zig_unreachable(); | | |
| 23096 | } | 25006 | } |
| | 25007 | out_val->type = expr_type; |
| | 25008 | out_val->special = ConstValSpecialStatic; |
| 23097 | } else { | 25009 | } else { |
| 23098 | zig_unreachable(); | 25010 | ir_eval_float_op(ira, instruction, float_type, op1_const, out_val); |
| 23099 | } | 25011 | } |
| 23100 | | | |
| 23101 | return result; | 25012 | return result; |
| 23102 | } | 25013 | } |
| 23103 | | 25014 | |
| 23104 | ir_assert(float_type->id == ZigTypeIdFloat, &instruction->base); | 25015 | ir_assert(float_type->id == ZigTypeIdFloat, &instruction->base); |
| 23105 | if (float_type->data.floating.bit_count != 16 && | | |
| 23106 | float_type->data.floating.bit_count != 32 && | | |
| 23107 | float_type->data.floating.bit_count != 64) { | | |
| 23108 | ir_add_error(ira, instruction->type, buf_sprintf("compiler TODO: add implementation of sqrt for '%s'", buf_ptr(&float_type->name))); | | |
| 23109 | return ira->codegen->invalid_instruction; | | |
| 23110 | } | | |
| 23111 | | 25016 | |
| 23112 | IrInstruction *result = ir_build_sqrt(&ira->new_irb, instruction->base.scope, | 25017 | IrInstruction *result = ir_build_float_op(&ira->new_irb, instruction->base.scope, |
| 23113 | instruction->base.source_node, nullptr, casted_op); | 25018 | instruction->base.source_node, nullptr, casted_op1, instruction->op); |
| 23114 | result->value.type = float_type; | 25019 | result->value.type = expr_type; |
| 23115 | return result; | 25020 | return result; |
| 23116 | } | 25021 | } |
| 23117 | | 25022 | |
| ... | @@ -23314,12 +25219,56 @@ static IrInstruction *ir_analyze_instruction_undeclared_ident(IrAnalyze *ira, Ir | ... | @@ -23314,12 +25219,56 @@ static IrInstruction *ir_analyze_instruction_undeclared_ident(IrAnalyze *ira, Ir |
| 23314 | return ira->codegen->invalid_instruction; | 25219 | return ira->codegen->invalid_instruction; |
| 23315 | } | 25220 | } |
| 23316 | | 25221 | |
| 23317 | static IrInstruction *ir_analyze_instruction_nocast(IrAnalyze *ira, IrInstruction *instruction) { | 25222 | static IrInstruction *ir_analyze_instruction_end_expr(IrAnalyze *ira, IrInstructionEndExpr *instruction) { |
| | 25223 | IrInstruction *value = instruction->value->child; |
| | 25224 | if (type_is_invalid(value->value.type)) |
| | 25225 | return ira->codegen->invalid_instruction; |
| | 25226 | |
| | 25227 | bool was_written = instruction->result_loc->written; |
| | 25228 | IrInstruction *result_loc = ir_resolve_result(ira, &instruction->base, instruction->result_loc, |
| | 25229 | value->value.type, value, false, false); |
| | 25230 | if (result_loc != nullptr) { |
| | 25231 | if (type_is_invalid(result_loc->value.type)) |
| | 25232 | return ira->codegen->invalid_instruction; |
| | 25233 | if (result_loc->value.type->id == ZigTypeIdUnreachable) |
| | 25234 | return result_loc; |
| | 25235 | |
| | 25236 | if (!was_written) { |
| | 25237 | IrInstruction *store_ptr = ir_analyze_store_ptr(ira, &instruction->base, result_loc, value); |
| | 25238 | if (type_is_invalid(store_ptr->value.type)) { |
| | 25239 | return ira->codegen->invalid_instruction; |
| | 25240 | } |
| | 25241 | } |
| | 25242 | |
| | 25243 | if (result_loc->value.data.x_ptr.mut == ConstPtrMutInfer) { |
| | 25244 | if (instr_is_comptime(value)) { |
| | 25245 | result_loc->value.data.x_ptr.mut = ConstPtrMutComptimeConst; |
| | 25246 | } else { |
| | 25247 | result_loc->value.special = ConstValSpecialRuntime; |
| | 25248 | } |
| | 25249 | } |
| | 25250 | } |
| | 25251 | |
| | 25252 | return ir_const_void(ira, &instruction->base); |
| | 25253 | } |
| | 25254 | |
| | 25255 | static IrInstruction *ir_analyze_instruction_bit_cast_src(IrAnalyze *ira, IrInstructionBitCastSrc *instruction) { |
| | 25256 | IrInstruction *operand = instruction->operand->child; |
| | 25257 | if (type_is_invalid(operand->value.type)) |
| | 25258 | return operand; |
| | 25259 | |
| | 25260 | IrInstruction *result_loc = ir_resolve_result(ira, &instruction->base, |
| | 25261 | &instruction->result_loc_bit_cast->base, operand->value.type, operand, false, false); |
| | 25262 | if (result_loc != nullptr && (type_is_invalid(result_loc->value.type) || instr_is_unreachable(result_loc))) |
| | 25263 | return result_loc; |
| | 25264 | |
| | 25265 | return instruction->result_loc_bit_cast->parent->gen_instruction; |
| | 25266 | } |
| | 25267 | |
| | 25268 | static IrInstruction *ir_analyze_instruction_base(IrAnalyze *ira, IrInstruction *instruction) { |
| 23318 | switch (instruction->id) { | 25269 | switch (instruction->id) { |
| 23319 | case IrInstructionIdInvalid: | 25270 | case IrInstructionIdInvalid: |
| 23320 | case IrInstructionIdWidenOrShorten: | 25271 | case IrInstructionIdWidenOrShorten: |
| 23321 | case IrInstructionIdStructInit: | | |
| 23322 | case IrInstructionIdUnionInit: | | |
| 23323 | case IrInstructionIdStructFieldPtr: | 25272 | case IrInstructionIdStructFieldPtr: |
| 23324 | case IrInstructionIdUnionFieldPtr: | 25273 | case IrInstructionIdUnionFieldPtr: |
| 23325 | case IrInstructionIdOptionalWrap: | 25274 | case IrInstructionIdOptionalWrap: |
| ... | @@ -23331,11 +25280,18 @@ static IrInstruction *ir_analyze_instruction_nocast(IrAnalyze *ira, IrInstructio | ... | @@ -23331,11 +25280,18 @@ static IrInstruction *ir_analyze_instruction_nocast(IrAnalyze *ira, IrInstructio |
| 23331 | case IrInstructionIdCmpxchgGen: | 25280 | case IrInstructionIdCmpxchgGen: |
| 23332 | case IrInstructionIdArrayToVector: | 25281 | case IrInstructionIdArrayToVector: |
| 23333 | case IrInstructionIdVectorToArray: | 25282 | case IrInstructionIdVectorToArray: |
| | 25283 | case IrInstructionIdPtrOfArrayToSlice: |
| 23334 | case IrInstructionIdAssertZero: | 25284 | case IrInstructionIdAssertZero: |
| 23335 | case IrInstructionIdAssertNonNull: | 25285 | case IrInstructionIdAssertNonNull: |
| 23336 | case IrInstructionIdResizeSlice: | 25286 | case IrInstructionIdResizeSlice: |
| 23337 | case IrInstructionIdLoadPtrGen: | 25287 | case IrInstructionIdLoadPtrGen: |
| 23338 | case IrInstructionIdBitCastGen: | 25288 | case IrInstructionIdBitCastGen: |
| | 25289 | case IrInstructionIdCallGen: |
| | 25290 | case IrInstructionIdReturnPtr: |
| | 25291 | case IrInstructionIdAllocaGen: |
| | 25292 | case IrInstructionIdSliceGen: |
| | 25293 | case IrInstructionIdRefGen: |
| | 25294 | case IrInstructionIdTestErrGen: |
| 23339 | zig_unreachable(); | 25295 | zig_unreachable(); |
| 23340 | | 25296 | |
| 23341 | case IrInstructionIdReturn: | 25297 | case IrInstructionIdReturn: |
| ... | @@ -23358,8 +25314,8 @@ static IrInstruction *ir_analyze_instruction_nocast(IrAnalyze *ira, IrInstructio | ... | @@ -23358,8 +25314,8 @@ static IrInstruction *ir_analyze_instruction_nocast(IrAnalyze *ira, IrInstructio |
| 23358 | return ir_analyze_instruction_var_ptr(ira, (IrInstructionVarPtr *)instruction); | 25314 | return ir_analyze_instruction_var_ptr(ira, (IrInstructionVarPtr *)instruction); |
| 23359 | case IrInstructionIdFieldPtr: | 25315 | case IrInstructionIdFieldPtr: |
| 23360 | return ir_analyze_instruction_field_ptr(ira, (IrInstructionFieldPtr *)instruction); | 25316 | return ir_analyze_instruction_field_ptr(ira, (IrInstructionFieldPtr *)instruction); |
| 23361 | case IrInstructionIdCall: | 25317 | case IrInstructionIdCallSrc: |
| 23362 | return ir_analyze_instruction_call(ira, (IrInstructionCall *)instruction); | 25318 | return ir_analyze_instruction_call(ira, (IrInstructionCallSrc *)instruction); |
| 23363 | case IrInstructionIdBr: | 25319 | case IrInstructionIdBr: |
| 23364 | return ir_analyze_instruction_br(ira, (IrInstructionBr *)instruction); | 25320 | return ir_analyze_instruction_br(ira, (IrInstructionBr *)instruction); |
| 23365 | case IrInstructionIdCondBr: | 25321 | case IrInstructionIdCondBr: |
| ... | @@ -23370,10 +25326,6 @@ static IrInstruction *ir_analyze_instruction_nocast(IrAnalyze *ira, IrInstructio | ... | @@ -23370,10 +25326,6 @@ static IrInstruction *ir_analyze_instruction_nocast(IrAnalyze *ira, IrInstructio |
| 23370 | return ir_analyze_instruction_phi(ira, (IrInstructionPhi *)instruction); | 25326 | return ir_analyze_instruction_phi(ira, (IrInstructionPhi *)instruction); |
| 23371 | case IrInstructionIdTypeOf: | 25327 | case IrInstructionIdTypeOf: |
| 23372 | return ir_analyze_instruction_typeof(ira, (IrInstructionTypeOf *)instruction); | 25328 | return ir_analyze_instruction_typeof(ira, (IrInstructionTypeOf *)instruction); |
| 23373 | case IrInstructionIdToPtrType: | | |
| 23374 | return ir_analyze_instruction_to_ptr_type(ira, (IrInstructionToPtrType *)instruction); | | |
| 23375 | case IrInstructionIdPtrTypeChild: | | |
| 23376 | return ir_analyze_instruction_ptr_type_child(ira, (IrInstructionPtrTypeChild *)instruction); | | |
| 23377 | case IrInstructionIdSetCold: | 25329 | case IrInstructionIdSetCold: |
| 23378 | return ir_analyze_instruction_set_cold(ira, (IrInstructionSetCold *)instruction); | 25330 | return ir_analyze_instruction_set_cold(ira, (IrInstructionSetCold *)instruction); |
| 23379 | case IrInstructionIdSetRuntimeSafety: | 25331 | case IrInstructionIdSetRuntimeSafety: |
| ... | @@ -23474,8 +25426,8 @@ static IrInstruction *ir_analyze_instruction_nocast(IrAnalyze *ira, IrInstructio | ... | @@ -23474,8 +25426,8 @@ static IrInstruction *ir_analyze_instruction_nocast(IrAnalyze *ira, IrInstructio |
| 23474 | return ir_analyze_instruction_memset(ira, (IrInstructionMemset *)instruction); | 25426 | return ir_analyze_instruction_memset(ira, (IrInstructionMemset *)instruction); |
| 23475 | case IrInstructionIdMemcpy: | 25427 | case IrInstructionIdMemcpy: |
| 23476 | return ir_analyze_instruction_memcpy(ira, (IrInstructionMemcpy *)instruction); | 25428 | return ir_analyze_instruction_memcpy(ira, (IrInstructionMemcpy *)instruction); |
| 23477 | case IrInstructionIdSlice: | 25429 | case IrInstructionIdSliceSrc: |
| 23478 | return ir_analyze_instruction_slice(ira, (IrInstructionSlice *)instruction); | 25430 | return ir_analyze_instruction_slice(ira, (IrInstructionSliceSrc *)instruction); |
| 23479 | case IrInstructionIdMemberCount: | 25431 | case IrInstructionIdMemberCount: |
| 23480 | return ir_analyze_instruction_member_count(ira, (IrInstructionMemberCount *)instruction); | 25432 | return ir_analyze_instruction_member_count(ira, (IrInstructionMemberCount *)instruction); |
| 23481 | case IrInstructionIdMemberType: | 25433 | case IrInstructionIdMemberType: |
| ... | @@ -23494,8 +25446,8 @@ static IrInstruction *ir_analyze_instruction_nocast(IrAnalyze *ira, IrInstructio | ... | @@ -23494,8 +25446,8 @@ static IrInstruction *ir_analyze_instruction_nocast(IrAnalyze *ira, IrInstructio |
| 23494 | return ir_analyze_instruction_align_of(ira, (IrInstructionAlignOf *)instruction); | 25446 | return ir_analyze_instruction_align_of(ira, (IrInstructionAlignOf *)instruction); |
| 23495 | case IrInstructionIdOverflowOp: | 25447 | case IrInstructionIdOverflowOp: |
| 23496 | return ir_analyze_instruction_overflow_op(ira, (IrInstructionOverflowOp *)instruction); | 25448 | return ir_analyze_instruction_overflow_op(ira, (IrInstructionOverflowOp *)instruction); |
| 23497 | case IrInstructionIdTestErr: | 25449 | case IrInstructionIdTestErrSrc: |
| 23498 | return ir_analyze_instruction_test_err(ira, (IrInstructionTestErr *)instruction); | 25450 | return ir_analyze_instruction_test_err(ira, (IrInstructionTestErrSrc *)instruction); |
| 23499 | case IrInstructionIdUnwrapErrCode: | 25451 | case IrInstructionIdUnwrapErrCode: |
| 23500 | return ir_analyze_instruction_unwrap_err_code(ira, (IrInstructionUnwrapErrCode *)instruction); | 25452 | return ir_analyze_instruction_unwrap_err_code(ira, (IrInstructionUnwrapErrCode *)instruction); |
| 23501 | case IrInstructionIdUnwrapErrPayload: | 25453 | case IrInstructionIdUnwrapErrPayload: |
| ... | @@ -23514,8 +25466,6 @@ static IrInstruction *ir_analyze_instruction_nocast(IrAnalyze *ira, IrInstructio | ... | @@ -23514,8 +25466,6 @@ static IrInstruction *ir_analyze_instruction_nocast(IrAnalyze *ira, IrInstructio |
| 23514 | return ir_analyze_instruction_panic(ira, (IrInstructionPanic *)instruction); | 25466 | return ir_analyze_instruction_panic(ira, (IrInstructionPanic *)instruction); |
| 23515 | case IrInstructionIdPtrCastSrc: | 25467 | case IrInstructionIdPtrCastSrc: |
| 23516 | return ir_analyze_instruction_ptr_cast(ira, (IrInstructionPtrCastSrc *)instruction); | 25468 | return ir_analyze_instruction_ptr_cast(ira, (IrInstructionPtrCastSrc *)instruction); |
| 23517 | case IrInstructionIdBitCast: | | |
| 23518 | return ir_analyze_instruction_bit_cast(ira, (IrInstructionBitCast *)instruction); | | |
| 23519 | case IrInstructionIdIntToPtr: | 25469 | case IrInstructionIdIntToPtr: |
| 23520 | return ir_analyze_instruction_int_to_ptr(ira, (IrInstructionIntToPtr *)instruction); | 25470 | return ir_analyze_instruction_int_to_ptr(ira, (IrInstructionIntToPtr *)instruction); |
| 23521 | case IrInstructionIdPtrToInt: | 25471 | case IrInstructionIdPtrToInt: |
| ... | @@ -23538,6 +25488,14 @@ static IrInstruction *ir_analyze_instruction_nocast(IrAnalyze *ira, IrInstructio | ... | @@ -23538,6 +25488,14 @@ static IrInstruction *ir_analyze_instruction_nocast(IrAnalyze *ira, IrInstructio |
| 23538 | return ir_analyze_instruction_ptr_type(ira, (IrInstructionPtrType *)instruction); | 25488 | return ir_analyze_instruction_ptr_type(ira, (IrInstructionPtrType *)instruction); |
| 23539 | case IrInstructionIdAlignCast: | 25489 | case IrInstructionIdAlignCast: |
| 23540 | return ir_analyze_instruction_align_cast(ira, (IrInstructionAlignCast *)instruction); | 25490 | return ir_analyze_instruction_align_cast(ira, (IrInstructionAlignCast *)instruction); |
| | 25491 | case IrInstructionIdImplicitCast: |
| | 25492 | return ir_analyze_instruction_implicit_cast(ira, (IrInstructionImplicitCast *)instruction); |
| | 25493 | case IrInstructionIdResolveResult: |
| | 25494 | return ir_analyze_instruction_resolve_result(ira, (IrInstructionResolveResult *)instruction); |
| | 25495 | case IrInstructionIdResetResult: |
| | 25496 | return ir_analyze_instruction_reset_result(ira, (IrInstructionResetResult *)instruction); |
| | 25497 | case IrInstructionIdResultPtr: |
| | 25498 | return ir_analyze_instruction_result_ptr(ira, (IrInstructionResultPtr *)instruction); |
| 23541 | case IrInstructionIdOpaqueType: | 25499 | case IrInstructionIdOpaqueType: |
| 23542 | return ir_analyze_instruction_opaque_type(ira, (IrInstructionOpaqueType *)instruction); | 25500 | return ir_analyze_instruction_opaque_type(ira, (IrInstructionOpaqueType *)instruction); |
| 23543 | case IrInstructionIdSetAlignStack: | 25501 | case IrInstructionIdSetAlignStack: |
| ... | @@ -23596,8 +25554,10 @@ static IrInstruction *ir_analyze_instruction_nocast(IrAnalyze *ira, IrInstructio | ... | @@ -23596,8 +25554,10 @@ static IrInstruction *ir_analyze_instruction_nocast(IrAnalyze *ira, IrInstructio |
| 23596 | return ir_analyze_instruction_merge_err_ret_traces(ira, (IrInstructionMergeErrRetTraces *)instruction); | 25554 | return ir_analyze_instruction_merge_err_ret_traces(ira, (IrInstructionMergeErrRetTraces *)instruction); |
| 23597 | case IrInstructionIdMarkErrRetTracePtr: | 25555 | case IrInstructionIdMarkErrRetTracePtr: |
| 23598 | return ir_analyze_instruction_mark_err_ret_trace_ptr(ira, (IrInstructionMarkErrRetTracePtr *)instruction); | 25556 | return ir_analyze_instruction_mark_err_ret_trace_ptr(ira, (IrInstructionMarkErrRetTracePtr *)instruction); |
| 23599 | case IrInstructionIdSqrt: | 25557 | case IrInstructionIdFloatOp: |
| 23600 | return ir_analyze_instruction_sqrt(ira, (IrInstructionSqrt *)instruction); | 25558 | return ir_analyze_instruction_float_op(ira, (IrInstructionFloatOp *)instruction); |
| | 25559 | case IrInstructionIdMulAdd: |
| | 25560 | return ir_analyze_instruction_mul_add(ira, (IrInstructionMulAdd *)instruction); |
| 23601 | case IrInstructionIdIntToErr: | 25561 | case IrInstructionIdIntToErr: |
| 23602 | return ir_analyze_instruction_int_to_err(ira, (IrInstructionIntToErr *)instruction); | 25562 | return ir_analyze_instruction_int_to_err(ira, (IrInstructionIntToErr *)instruction); |
| 23603 | case IrInstructionIdErrToInt: | 25563 | case IrInstructionIdErrToInt: |
| ... | @@ -23612,17 +25572,16 @@ static IrInstruction *ir_analyze_instruction_nocast(IrAnalyze *ira, IrInstructio | ... | @@ -23612,17 +25572,16 @@ static IrInstruction *ir_analyze_instruction_nocast(IrAnalyze *ira, IrInstructio |
| 23612 | return ir_analyze_instruction_has_decl(ira, (IrInstructionHasDecl *)instruction); | 25572 | return ir_analyze_instruction_has_decl(ira, (IrInstructionHasDecl *)instruction); |
| 23613 | case IrInstructionIdUndeclaredIdent: | 25573 | case IrInstructionIdUndeclaredIdent: |
| 23614 | return ir_analyze_instruction_undeclared_ident(ira, (IrInstructionUndeclaredIdent *)instruction); | 25574 | return ir_analyze_instruction_undeclared_ident(ira, (IrInstructionUndeclaredIdent *)instruction); |
| | 25575 | case IrInstructionIdAllocaSrc: |
| | 25576 | return nullptr; |
| | 25577 | case IrInstructionIdEndExpr: |
| | 25578 | return ir_analyze_instruction_end_expr(ira, (IrInstructionEndExpr *)instruction); |
| | 25579 | case IrInstructionIdBitCastSrc: |
| | 25580 | return ir_analyze_instruction_bit_cast_src(ira, (IrInstructionBitCastSrc *)instruction); |
| 23615 | } | 25581 | } |
| 23616 | zig_unreachable(); | 25582 | zig_unreachable(); |
| 23617 | } | 25583 | } |
| 23618 | | 25584 | |
| 23619 | static IrInstruction *ir_analyze_instruction(IrAnalyze *ira, IrInstruction *old_instruction) { | | |
| 23620 | IrInstruction *new_instruction = ir_analyze_instruction_nocast(ira, old_instruction); | | |
| 23621 | ir_assert(new_instruction->value.type != nullptr, old_instruction); | | |
| 23622 | old_instruction->child = new_instruction; | | |
| 23623 | return new_instruction; | | |
| 23624 | } | | |
| 23625 | | | |
| 23626 | // This function attempts to evaluate IR code while doing type checking and other analysis. | 25585 | // This function attempts to evaluate IR code while doing type checking and other analysis. |
| 23627 | // It emits a new IrExecutable which is partially evaluated IR code. | 25586 | // It emits a new IrExecutable which is partially evaluated IR code. |
| 23628 | ZigType *ir_analyze(CodeGen *codegen, IrExecutable *old_exec, IrExecutable *new_exec, | 25587 | ZigType *ir_analyze(CodeGen *codegen, IrExecutable *old_exec, IrExecutable *new_exec, |
| ... | @@ -23668,14 +25627,22 @@ ZigType *ir_analyze(CodeGen *codegen, IrExecutable *old_exec, IrExecutable *new_ | ... | @@ -23668,14 +25627,22 @@ ZigType *ir_analyze(CodeGen *codegen, IrExecutable *old_exec, IrExecutable *new_ |
| 23668 | continue; | 25627 | continue; |
| 23669 | } | 25628 | } |
| 23670 | | 25629 | |
| 23671 | IrInstruction *new_instruction = ir_analyze_instruction(ira, old_instruction); | 25630 | if (ira->codegen->verbose_ir) { |
| 23672 | if (type_is_invalid(new_instruction->value.type) && ir_should_inline(new_exec, old_instruction->scope)) { | 25631 | fprintf(stderr, "analyze #%zu\n", old_instruction->debug_id); |
| 23673 | return ira->codegen->builtin_types.entry_invalid; | | |
| 23674 | } | 25632 | } |
| | 25633 | IrInstruction *new_instruction = ir_analyze_instruction_base(ira, old_instruction); |
| | 25634 | if (new_instruction != nullptr) { |
| | 25635 | ir_assert(new_instruction->value.type != nullptr || new_instruction->value.type != nullptr, old_instruction); |
| | 25636 | old_instruction->child = new_instruction; |
| 23675 | | 25637 | |
| 23676 | // unreachable instructions do their own control flow. | 25638 | if (type_is_invalid(new_instruction->value.type)) { |
| 23677 | if (new_instruction->value.type->id == ZigTypeIdUnreachable) | 25639 | return ira->codegen->builtin_types.entry_invalid; |
| 23678 | continue; | 25640 | } |
| | 25641 | |
| | 25642 | // unreachable instructions do their own control flow. |
| | 25643 | if (new_instruction->value.type->id == ZigTypeIdUnreachable) |
| | 25644 | continue; |
| | 25645 | } |
| 23679 | | 25646 | |
| 23680 | ira->instruction_index += 1; | 25647 | ira->instruction_index += 1; |
| 23681 | } | 25648 | } |
| ... | @@ -23700,7 +25667,8 @@ bool ir_has_side_effects(IrInstruction *instruction) { | ... | @@ -23700,7 +25667,8 @@ bool ir_has_side_effects(IrInstruction *instruction) { |
| 23700 | case IrInstructionIdDeclVarSrc: | 25667 | case IrInstructionIdDeclVarSrc: |
| 23701 | case IrInstructionIdDeclVarGen: | 25668 | case IrInstructionIdDeclVarGen: |
| 23702 | case IrInstructionIdStorePtr: | 25669 | case IrInstructionIdStorePtr: |
| 23703 | case IrInstructionIdCall: | 25670 | case IrInstructionIdCallSrc: |
| | 25671 | case IrInstructionIdCallGen: |
| 23704 | case IrInstructionIdReturn: | 25672 | case IrInstructionIdReturn: |
| 23705 | case IrInstructionIdUnreachable: | 25673 | case IrInstructionIdUnreachable: |
| 23706 | case IrInstructionIdSetCold: | 25674 | case IrInstructionIdSetCold: |
| ... | @@ -23747,27 +25715,28 @@ bool ir_has_side_effects(IrInstruction *instruction) { | ... | @@ -23747,27 +25715,28 @@ bool ir_has_side_effects(IrInstruction *instruction) { |
| 23747 | case IrInstructionIdResizeSlice: | 25715 | case IrInstructionIdResizeSlice: |
| 23748 | case IrInstructionIdGlobalAsm: | 25716 | case IrInstructionIdGlobalAsm: |
| 23749 | case IrInstructionIdUndeclaredIdent: | 25717 | case IrInstructionIdUndeclaredIdent: |
| | 25718 | case IrInstructionIdEndExpr: |
| | 25719 | case IrInstructionIdPtrOfArrayToSlice: |
| | 25720 | case IrInstructionIdSliceGen: |
| | 25721 | case IrInstructionIdOptionalWrap: |
| | 25722 | case IrInstructionIdVectorToArray: |
| | 25723 | case IrInstructionIdResetResult: |
| 23750 | return true; | 25724 | return true; |
| 23751 | | 25725 | |
| 23752 | case IrInstructionIdPhi: | 25726 | case IrInstructionIdPhi: |
| 23753 | case IrInstructionIdUnOp: | 25727 | case IrInstructionIdUnOp: |
| 23754 | case IrInstructionIdBinOp: | 25728 | case IrInstructionIdBinOp: |
| 23755 | case IrInstructionIdLoadPtr: | 25729 | case IrInstructionIdLoadPtr: |
| 23756 | case IrInstructionIdLoadPtrGen: | | |
| 23757 | case IrInstructionIdConst: | 25730 | case IrInstructionIdConst: |
| 23758 | case IrInstructionIdCast: | 25731 | case IrInstructionIdCast: |
| 23759 | case IrInstructionIdContainerInitList: | 25732 | case IrInstructionIdContainerInitList: |
| 23760 | case IrInstructionIdContainerInitFields: | 25733 | case IrInstructionIdContainerInitFields: |
| 23761 | case IrInstructionIdStructInit: | | |
| 23762 | case IrInstructionIdUnionInit: | | |
| 23763 | case IrInstructionIdFieldPtr: | 25734 | case IrInstructionIdFieldPtr: |
| 23764 | case IrInstructionIdElemPtr: | 25735 | case IrInstructionIdElemPtr: |
| 23765 | case IrInstructionIdVarPtr: | 25736 | case IrInstructionIdVarPtr: |
| | 25737 | case IrInstructionIdReturnPtr: |
| 23766 | case IrInstructionIdTypeOf: | 25738 | case IrInstructionIdTypeOf: |
| 23767 | case IrInstructionIdToPtrType: | | |
| 23768 | case IrInstructionIdPtrTypeChild: | | |
| 23769 | case IrInstructionIdStructFieldPtr: | 25739 | case IrInstructionIdStructFieldPtr: |
| 23770 | case IrInstructionIdUnionFieldPtr: | | |
| 23771 | case IrInstructionIdArrayType: | 25740 | case IrInstructionIdArrayType: |
| 23772 | case IrInstructionIdPromiseType: | 25741 | case IrInstructionIdPromiseType: |
| 23773 | case IrInstructionIdSliceType: | 25742 | case IrInstructionIdSliceType: |
| ... | @@ -23789,7 +25758,7 @@ bool ir_has_side_effects(IrInstruction *instruction) { | ... | @@ -23789,7 +25758,7 @@ bool ir_has_side_effects(IrInstruction *instruction) { |
| 23789 | case IrInstructionIdIntType: | 25758 | case IrInstructionIdIntType: |
| 23790 | case IrInstructionIdVectorType: | 25759 | case IrInstructionIdVectorType: |
| 23791 | case IrInstructionIdBoolNot: | 25760 | case IrInstructionIdBoolNot: |
| 23792 | case IrInstructionIdSlice: | 25761 | case IrInstructionIdSliceSrc: |
| 23793 | case IrInstructionIdMemberCount: | 25762 | case IrInstructionIdMemberCount: |
| 23794 | case IrInstructionIdMemberType: | 25763 | case IrInstructionIdMemberType: |
| 23795 | case IrInstructionIdMemberName: | 25764 | case IrInstructionIdMemberName: |
| ... | @@ -23797,16 +25766,13 @@ bool ir_has_side_effects(IrInstruction *instruction) { | ... | @@ -23797,16 +25766,13 @@ bool ir_has_side_effects(IrInstruction *instruction) { |
| 23797 | case IrInstructionIdReturnAddress: | 25766 | case IrInstructionIdReturnAddress: |
| 23798 | case IrInstructionIdFrameAddress: | 25767 | case IrInstructionIdFrameAddress: |
| 23799 | case IrInstructionIdHandle: | 25768 | case IrInstructionIdHandle: |
| 23800 | case IrInstructionIdTestErr: | 25769 | case IrInstructionIdTestErrSrc: |
| 23801 | case IrInstructionIdUnwrapErrCode: | 25770 | case IrInstructionIdTestErrGen: |
| 23802 | case IrInstructionIdOptionalWrap: | | |
| 23803 | case IrInstructionIdErrWrapCode: | | |
| 23804 | case IrInstructionIdErrWrapPayload: | | |
| 23805 | case IrInstructionIdFnProto: | 25771 | case IrInstructionIdFnProto: |
| 23806 | case IrInstructionIdTestComptime: | 25772 | case IrInstructionIdTestComptime: |
| 23807 | case IrInstructionIdPtrCastSrc: | 25773 | case IrInstructionIdPtrCastSrc: |
| 23808 | case IrInstructionIdPtrCastGen: | 25774 | case IrInstructionIdPtrCastGen: |
| 23809 | case IrInstructionIdBitCast: | 25775 | case IrInstructionIdBitCastSrc: |
| 23810 | case IrInstructionIdBitCastGen: | 25776 | case IrInstructionIdBitCastGen: |
| 23811 | case IrInstructionIdWidenOrShorten: | 25777 | case IrInstructionIdWidenOrShorten: |
| 23812 | case IrInstructionIdPtrToInt: | 25778 | case IrInstructionIdPtrToInt: |
| ... | @@ -23824,6 +25790,8 @@ bool ir_has_side_effects(IrInstruction *instruction) { | ... | @@ -23824,6 +25790,8 @@ bool ir_has_side_effects(IrInstruction *instruction) { |
| 23824 | case IrInstructionIdTypeInfo: | 25790 | case IrInstructionIdTypeInfo: |
| 23825 | case IrInstructionIdTypeId: | 25791 | case IrInstructionIdTypeId: |
| 23826 | case IrInstructionIdAlignCast: | 25792 | case IrInstructionIdAlignCast: |
| | 25793 | case IrInstructionIdImplicitCast: |
| | 25794 | case IrInstructionIdResolveResult: |
| 23827 | case IrInstructionIdOpaqueType: | 25795 | case IrInstructionIdOpaqueType: |
| 23828 | case IrInstructionIdArgType: | 25796 | case IrInstructionIdArgType: |
| 23829 | case IrInstructionIdTagType: | 25797 | case IrInstructionIdTagType: |
| ... | @@ -23836,7 +25804,8 @@ bool ir_has_side_effects(IrInstruction *instruction) { | ... | @@ -23836,7 +25804,8 @@ bool ir_has_side_effects(IrInstruction *instruction) { |
| 23836 | case IrInstructionIdCoroFree: | 25804 | case IrInstructionIdCoroFree: |
| 23837 | case IrInstructionIdCoroPromise: | 25805 | case IrInstructionIdCoroPromise: |
| 23838 | case IrInstructionIdPromiseResultType: | 25806 | case IrInstructionIdPromiseResultType: |
| 23839 | case IrInstructionIdSqrt: | 25807 | case IrInstructionIdFloatOp: |
| | 25808 | case IrInstructionIdMulAdd: |
| 23840 | case IrInstructionIdAtomicLoad: | 25809 | case IrInstructionIdAtomicLoad: |
| 23841 | case IrInstructionIdIntCast: | 25810 | case IrInstructionIdIntCast: |
| 23842 | case IrInstructionIdFloatCast: | 25811 | case IrInstructionIdFloatCast: |
| ... | @@ -23847,9 +25816,11 @@ bool ir_has_side_effects(IrInstruction *instruction) { | ... | @@ -23847,9 +25816,11 @@ bool ir_has_side_effects(IrInstruction *instruction) { |
| 23847 | case IrInstructionIdFromBytes: | 25816 | case IrInstructionIdFromBytes: |
| 23848 | case IrInstructionIdToBytes: | 25817 | case IrInstructionIdToBytes: |
| 23849 | case IrInstructionIdEnumToInt: | 25818 | case IrInstructionIdEnumToInt: |
| 23850 | case IrInstructionIdVectorToArray: | | |
| 23851 | case IrInstructionIdArrayToVector: | 25819 | case IrInstructionIdArrayToVector: |
| 23852 | case IrInstructionIdHasDecl: | 25820 | case IrInstructionIdHasDecl: |
| | 25821 | case IrInstructionIdAllocaSrc: |
| | 25822 | case IrInstructionIdAllocaGen: |
| | 25823 | case IrInstructionIdResultPtr: |
| 23853 | return false; | 25824 | return false; |
| 23854 | | 25825 | |
| 23855 | case IrInstructionIdAsm: | 25826 | case IrInstructionIdAsm: |
| ... | @@ -23861,8 +25832,21 @@ bool ir_has_side_effects(IrInstruction *instruction) { | ... | @@ -23861,8 +25832,21 @@ bool ir_has_side_effects(IrInstruction *instruction) { |
| 23861 | { | 25832 | { |
| 23862 | IrInstructionUnwrapErrPayload *unwrap_err_payload_instruction = | 25833 | IrInstructionUnwrapErrPayload *unwrap_err_payload_instruction = |
| 23863 | (IrInstructionUnwrapErrPayload *)instruction; | 25834 | (IrInstructionUnwrapErrPayload *)instruction; |
| 23864 | return unwrap_err_payload_instruction->safety_check_on; | 25835 | return unwrap_err_payload_instruction->safety_check_on || |
| | 25836 | unwrap_err_payload_instruction->initializing; |
| 23865 | } | 25837 | } |
| | 25838 | case IrInstructionIdUnwrapErrCode: |
| | 25839 | return reinterpret_cast<IrInstructionUnwrapErrCode *>(instruction)->initializing; |
| | 25840 | case IrInstructionIdUnionFieldPtr: |
| | 25841 | return reinterpret_cast<IrInstructionUnionFieldPtr *>(instruction)->initializing; |
| | 25842 | case IrInstructionIdErrWrapPayload: |
| | 25843 | return reinterpret_cast<IrInstructionErrWrapPayload *>(instruction)->result_loc != nullptr; |
| | 25844 | case IrInstructionIdErrWrapCode: |
| | 25845 | return reinterpret_cast<IrInstructionErrWrapCode *>(instruction)->result_loc != nullptr; |
| | 25846 | case IrInstructionIdLoadPtrGen: |
| | 25847 | return reinterpret_cast<IrInstructionLoadPtrGen *>(instruction)->result_loc != nullptr; |
| | 25848 | case IrInstructionIdRefGen: |
| | 25849 | return reinterpret_cast<IrInstructionRefGen *>(instruction)->result_loc != nullptr; |
| 23866 | } | 25850 | } |
| 23867 | zig_unreachable(); | 25851 | zig_unreachable(); |
| 23868 | } | 25852 | } |