| ... | @@ -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,12 @@ static constexpr IrInstructionId ir_instruction_id(IrInstructionOverflowOp *) { | ... | @@ -743,8 +769,12 @@ 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; |
| 748 | } | 778 | } |
| 749 | | 779 | |
| 750 | static constexpr IrInstructionId ir_instruction_id(IrInstructionMulAdd *) { | 780 | static constexpr IrInstructionId ir_instruction_id(IrInstructionMulAdd *) { |
| ... | @@ -787,8 +817,8 @@ static constexpr IrInstructionId ir_instruction_id(IrInstructionPtrCastGen *) { | ... | @@ -787,8 +817,8 @@ static constexpr IrInstructionId ir_instruction_id(IrInstructionPtrCastGen *) { |
| 787 | return IrInstructionIdPtrCastGen; | 817 | return IrInstructionIdPtrCastGen; |
| 788 | } | 818 | } |
| 789 | | 819 | |
| 790 | static constexpr IrInstructionId ir_instruction_id(IrInstructionBitCast *) { | 820 | static constexpr IrInstructionId ir_instruction_id(IrInstructionBitCastSrc *) { |
| 791 | return IrInstructionIdBitCast; | 821 | return IrInstructionIdBitCastSrc; |
| 792 | } | 822 | } |
| 793 | | 823 | |
| 794 | static constexpr IrInstructionId ir_instruction_id(IrInstructionBitCastGen *) { | 824 | static constexpr IrInstructionId ir_instruction_id(IrInstructionBitCastGen *) { |
| ... | @@ -883,6 +913,26 @@ static constexpr IrInstructionId ir_instruction_id(IrInstructionAlignCast *) { | ... | @@ -883,6 +913,26 @@ static constexpr IrInstructionId ir_instruction_id(IrInstructionAlignCast *) { |
| 883 | return IrInstructionIdAlignCast; | 913 | return IrInstructionIdAlignCast; |
| 884 | } | 914 | } |
| 885 | | 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 | |
| 886 | static constexpr IrInstructionId ir_instruction_id(IrInstructionOpaqueType *) { | 936 | static constexpr IrInstructionId ir_instruction_id(IrInstructionOpaqueType *) { |
| 887 | return IrInstructionIdOpaqueType; | 937 | return IrInstructionIdOpaqueType; |
| 888 | } | 938 | } |
| ... | @@ -1023,6 +1073,18 @@ static constexpr IrInstructionId ir_instruction_id(IrInstructionUndeclaredIdent | ... | @@ -1023,6 +1073,18 @@ static constexpr IrInstructionId ir_instruction_id(IrInstructionUndeclaredIdent |
| 1023 | return IrInstructionIdUndeclaredIdent; | 1073 | return IrInstructionIdUndeclaredIdent; |
| 1024 | } | 1074 | } |
| 1025 | | 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 | |
| 1026 | template<typename T> | 1088 | template<typename T> |
| 1027 | 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) { |
| 1028 | T *special_instruction = allocate<T>(1); | 1090 | T *special_instruction = allocate<T>(1); |
| ... | @@ -1074,13 +1136,15 @@ static IrInstruction *ir_build_cond_br(IrBuilder *irb, Scope *scope, AstNode *so | ... | @@ -1074,13 +1136,15 @@ static IrInstruction *ir_build_cond_br(IrBuilder *irb, Scope *scope, AstNode *so |
| 1074 | return &cond_br_instruction->base; | 1136 | return &cond_br_instruction->base; |
| 1075 | } | 1137 | } |
| 1076 | | 1138 | |
| 1077 | 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 | { |
| 1078 | IrInstructionReturn *return_instruction = ir_build_instruction<IrInstructionReturn>(irb, scope, source_node); | 1142 | IrInstructionReturn *return_instruction = ir_build_instruction<IrInstructionReturn>(irb, scope, source_node); |
| 1079 | return_instruction->base.value.type = irb->codegen->builtin_types.entry_unreachable; | 1143 | return_instruction->base.value.type = irb->codegen->builtin_types.entry_unreachable; |
| 1080 | return_instruction->base.value.special = ConstValSpecialStatic; | 1144 | return_instruction->base.value.special = ConstValSpecialStatic; |
| 1081 | return_instruction->value = return_value; | 1145 | return_instruction->value = return_value; |
| 1082 | | 1146 | |
| 1083 | ir_ref_instruction(return_value, irb->current_basic_block); | 1147 | if (return_value != nullptr) ir_ref_instruction(return_value, irb->current_basic_block); |
| 1084 | | 1148 | |
| 1085 | return &return_instruction->base; | 1149 | return &return_instruction->base; |
| 1086 | } | 1150 | } |
| ... | @@ -1258,17 +1322,27 @@ static IrInstruction *ir_build_var_ptr(IrBuilder *irb, Scope *scope, AstNode *so | ... | @@ -1258,17 +1322,27 @@ static IrInstruction *ir_build_var_ptr(IrBuilder *irb, Scope *scope, AstNode *so |
| 1258 | 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); |
| 1259 | } | 1323 | } |
| 1260 | | 1324 | |
| 1261 | 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) { |
| 1262 | 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) |
| 1263 | { | 1335 | { |
| 1264 | IrInstructionElemPtr *instruction = ir_build_instruction<IrInstructionElemPtr>(irb, scope, source_node); | 1336 | IrInstructionElemPtr *instruction = ir_build_instruction<IrInstructionElemPtr>(irb, scope, source_node); |
| 1265 | instruction->array_ptr = array_ptr; | 1337 | instruction->array_ptr = array_ptr; |
| 1266 | instruction->elem_index = elem_index; | 1338 | instruction->elem_index = elem_index; |
| 1267 | instruction->safety_check_on = safety_check_on; | 1339 | instruction->safety_check_on = safety_check_on; |
| 1268 | instruction->ptr_len = ptr_len; | 1340 | instruction->ptr_len = ptr_len; |
| | 1341 | instruction->init_array_type = init_array_type; |
| 1269 | | 1342 | |
| 1270 | ir_ref_instruction(array_ptr, irb->current_basic_block); | 1343 | ir_ref_instruction(array_ptr, irb->current_basic_block); |
| 1271 | 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); |
| 1272 | | 1346 | |
| 1273 | return &instruction->base; | 1347 | return &instruction->base; |
| 1274 | } | 1348 | } |
| ... | @@ -1288,12 +1362,13 @@ static IrInstruction *ir_build_field_ptr_instruction(IrBuilder *irb, Scope *scop | ... | @@ -1288,12 +1362,13 @@ static IrInstruction *ir_build_field_ptr_instruction(IrBuilder *irb, Scope *scop |
| 1288 | } | 1362 | } |
| 1289 | | 1363 | |
| 1290 | 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, |
| 1291 | IrInstruction *container_ptr, Buf *field_name) | 1365 | IrInstruction *container_ptr, Buf *field_name, bool initializing) |
| 1292 | { | 1366 | { |
| 1293 | IrInstructionFieldPtr *instruction = ir_build_instruction<IrInstructionFieldPtr>(irb, scope, source_node); | 1367 | IrInstructionFieldPtr *instruction = ir_build_instruction<IrInstructionFieldPtr>(irb, scope, source_node); |
| 1294 | instruction->container_ptr = container_ptr; | 1368 | instruction->container_ptr = container_ptr; |
| 1295 | instruction->field_name_buffer = field_name; | 1369 | instruction->field_name_buffer = field_name; |
| 1296 | instruction->field_name_expr = nullptr; | 1370 | instruction->field_name_expr = nullptr; |
| | 1371 | instruction->initializing = initializing; |
| 1297 | | 1372 | |
| 1298 | ir_ref_instruction(container_ptr, irb->current_basic_block); | 1373 | ir_ref_instruction(container_ptr, irb->current_basic_block); |
| 1299 | | 1374 | |
| ... | @@ -1313,9 +1388,11 @@ static IrInstruction *ir_build_struct_field_ptr(IrBuilder *irb, Scope *scope, As | ... | @@ -1313,9 +1388,11 @@ static IrInstruction *ir_build_struct_field_ptr(IrBuilder *irb, Scope *scope, As |
| 1313 | } | 1388 | } |
| 1314 | | 1389 | |
| 1315 | 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, |
| 1316 | IrInstruction *union_ptr, TypeUnionField *field) | 1391 | IrInstruction *union_ptr, TypeUnionField *field, bool safety_check_on, bool initializing) |
| 1317 | { | 1392 | { |
| 1318 | 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; |
| 1319 | instruction->union_ptr = union_ptr; | 1396 | instruction->union_ptr = union_ptr; |
| 1320 | instruction->field = field; | 1397 | instruction->field = field; |
| 1321 | | 1398 | |
| ... | @@ -1324,12 +1401,12 @@ static IrInstruction *ir_build_union_field_ptr(IrBuilder *irb, Scope *scope, Ast | ... | @@ -1324,12 +1401,12 @@ static IrInstruction *ir_build_union_field_ptr(IrBuilder *irb, Scope *scope, Ast |
| 1324 | return &instruction->base; | 1401 | return &instruction->base; |
| 1325 | } | 1402 | } |
| 1326 | | 1403 | |
| 1327 | 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, |
| 1328 | 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, |
| 1329 | 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, |
| 1330 | IrInstruction *new_stack) | 1407 | IrInstruction *new_stack, ResultLoc *result_loc) |
| 1331 | { | 1408 | { |
| 1332 | IrInstructionCall *call_instruction = ir_build_instruction<IrInstructionCall>(irb, scope, source_node); | 1409 | IrInstructionCallSrc *call_instruction = ir_build_instruction<IrInstructionCallSrc>(irb, scope, source_node); |
| 1333 | call_instruction->fn_entry = fn_entry; | 1410 | call_instruction->fn_entry = fn_entry; |
| 1334 | call_instruction->fn_ref = fn_ref; | 1411 | call_instruction->fn_ref = fn_ref; |
| 1335 | call_instruction->is_comptime = is_comptime; | 1412 | call_instruction->is_comptime = is_comptime; |
| ... | @@ -1339,6 +1416,7 @@ static IrInstruction *ir_build_call(IrBuilder *irb, Scope *scope, AstNode *sourc | ... | @@ -1339,6 +1416,7 @@ static IrInstruction *ir_build_call(IrBuilder *irb, Scope *scope, AstNode *sourc |
| 1339 | call_instruction->is_async = is_async; | 1416 | call_instruction->is_async = is_async; |
| 1340 | call_instruction->async_allocator = async_allocator; | 1417 | call_instruction->async_allocator = async_allocator; |
| 1341 | call_instruction->new_stack = new_stack; | 1418 | call_instruction->new_stack = new_stack; |
| | 1419 | call_instruction->result_loc = result_loc; |
| 1342 | | 1420 | |
| 1343 | 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); |
| 1344 | for (size_t i = 0; i < arg_count; i += 1) | 1422 | for (size_t i = 0; i < arg_count; i += 1) |
| ... | @@ -1349,8 +1427,37 @@ static IrInstruction *ir_build_call(IrBuilder *irb, Scope *scope, AstNode *sourc | ... | @@ -1349,8 +1427,37 @@ static IrInstruction *ir_build_call(IrBuilder *irb, Scope *scope, AstNode *sourc |
| 1349 | return &call_instruction->base; | 1427 | return &call_instruction->base; |
| 1350 | } | 1428 | } |
| 1351 | | 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 | |
| 1352 | 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, |
| 1353 | 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) |
| 1354 | { | 1461 | { |
| 1355 | assert(incoming_count != 0); | 1462 | assert(incoming_count != 0); |
| 1356 | assert(incoming_count != SIZE_MAX); | 1463 | assert(incoming_count != SIZE_MAX); |
| ... | @@ -1359,6 +1466,7 @@ static IrInstruction *ir_build_phi(IrBuilder *irb, Scope *scope, AstNode *source | ... | @@ -1359,6 +1466,7 @@ static IrInstruction *ir_build_phi(IrBuilder *irb, Scope *scope, AstNode *source |
| 1359 | phi_instruction->incoming_count = incoming_count; | 1466 | phi_instruction->incoming_count = incoming_count; |
| 1360 | phi_instruction->incoming_blocks = incoming_blocks; | 1467 | phi_instruction->incoming_blocks = incoming_blocks; |
| 1361 | phi_instruction->incoming_values = incoming_values; | 1468 | phi_instruction->incoming_values = incoming_values; |
| | 1469 | phi_instruction->peer_parent = peer_parent; |
| 1362 | | 1470 | |
| 1363 | for (size_t i = 0; i < incoming_count; i += 1) { | 1471 | for (size_t i = 0; i < incoming_count; i += 1) { |
| 1364 | ir_ref_bb(incoming_blocks[i]); | 1472 | ir_ref_bb(incoming_blocks[i]); |
| ... | @@ -1412,12 +1520,13 @@ static IrInstruction *ir_build_ptr_type(IrBuilder *irb, Scope *scope, AstNode *s | ... | @@ -1412,12 +1520,13 @@ static IrInstruction *ir_build_ptr_type(IrBuilder *irb, Scope *scope, AstNode *s |
| 1412 | } | 1520 | } |
| 1413 | | 1521 | |
| 1414 | 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, |
| 1415 | IrInstruction *value, LVal lval) | 1523 | IrInstruction *value, LVal lval, ResultLoc *result_loc) |
| 1416 | { | 1524 | { |
| 1417 | IrInstructionUnOp *instruction = ir_build_instruction<IrInstructionUnOp>(irb, scope, source_node); | 1525 | IrInstructionUnOp *instruction = ir_build_instruction<IrInstructionUnOp>(irb, scope, source_node); |
| 1418 | instruction->op_id = op_id; | 1526 | instruction->op_id = op_id; |
| 1419 | instruction->value = value; | 1527 | instruction->value = value; |
| 1420 | instruction->lval = lval; | 1528 | instruction->lval = lval; |
| | 1529 | instruction->result_loc = result_loc; |
| 1421 | | 1530 | |
| 1422 | ir_ref_instruction(value, irb->current_basic_block); | 1531 | ir_ref_instruction(value, irb->current_basic_block); |
| 1423 | | 1532 | |
| ... | @@ -1427,72 +1536,49 @@ static IrInstruction *ir_build_un_op_lval(IrBuilder *irb, Scope *scope, AstNode | ... | @@ -1427,72 +1536,49 @@ static IrInstruction *ir_build_un_op_lval(IrBuilder *irb, Scope *scope, AstNode |
| 1427 | 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, |
| 1428 | IrInstruction *value) | 1537 | IrInstruction *value) |
| 1429 | { | 1538 | { |
| 1430 | 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); |
| 1431 | } | 1540 | } |
| 1432 | | 1541 | |
| 1433 | 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, |
| 1434 | 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) |
| 1435 | { | 1545 | { |
| 1436 | IrInstructionContainerInitList *container_init_list_instruction = | 1546 | IrInstructionContainerInitList *container_init_list_instruction = |
| 1437 | ir_build_instruction<IrInstructionContainerInitList>(irb, scope, source_node); | 1547 | ir_build_instruction<IrInstructionContainerInitList>(irb, scope, source_node); |
| 1438 | container_init_list_instruction->container_type = container_type; | 1548 | container_init_list_instruction->container_type = container_type; |
| 1439 | container_init_list_instruction->elem_type = elem_type; | | |
| 1440 | container_init_list_instruction->item_count = item_count; | 1549 | container_init_list_instruction->item_count = item_count; |
| 1441 | 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; |
| 1442 | | 1552 | |
| 1443 | if (container_type != nullptr) ir_ref_instruction(container_type, irb->current_basic_block); | 1553 | ir_ref_instruction(container_type, irb->current_basic_block); |
| 1444 | if (elem_type != nullptr) ir_ref_instruction(elem_type, irb->current_basic_block); | | |
| 1445 | for (size_t i = 0; i < item_count; i += 1) { | 1554 | for (size_t i = 0; i < item_count; i += 1) { |
| 1446 | ir_ref_instruction(items[i], irb->current_basic_block); | 1555 | ir_ref_instruction(elem_result_loc_list[i], irb->current_basic_block); |
| 1447 | } | 1556 | } |
| | 1557 | if (result_loc != nullptr) ir_ref_instruction(result_loc, irb->current_basic_block); |
| 1448 | | 1558 | |
| 1449 | return &container_init_list_instruction->base; | 1559 | return &container_init_list_instruction->base; |
| 1450 | } | 1560 | } |
| 1451 | | 1561 | |
| 1452 | 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, |
| 1453 | IrInstruction *container_type, size_t field_count, IrInstructionContainerInitFieldsField *fields) | 1563 | IrInstruction *container_type, size_t field_count, IrInstructionContainerInitFieldsField *fields, |
| | 1564 | IrInstruction *result_loc) |
| 1454 | { | 1565 | { |
| 1455 | IrInstructionContainerInitFields *container_init_fields_instruction = | 1566 | IrInstructionContainerInitFields *container_init_fields_instruction = |
| 1456 | ir_build_instruction<IrInstructionContainerInitFields>(irb, scope, source_node); | 1567 | ir_build_instruction<IrInstructionContainerInitFields>(irb, scope, source_node); |
| 1457 | container_init_fields_instruction->container_type = container_type; | 1568 | container_init_fields_instruction->container_type = container_type; |
| 1458 | container_init_fields_instruction->field_count = field_count; | 1569 | container_init_fields_instruction->field_count = field_count; |
| 1459 | container_init_fields_instruction->fields = fields; | 1570 | container_init_fields_instruction->fields = fields; |
| | 1571 | container_init_fields_instruction->result_loc = result_loc; |
| 1460 | | 1572 | |
| 1461 | ir_ref_instruction(container_type, irb->current_basic_block); | 1573 | ir_ref_instruction(container_type, irb->current_basic_block); |
| 1462 | for (size_t i = 0; i < field_count; i += 1) { | 1574 | for (size_t i = 0; i < field_count; i += 1) { |
| 1463 | ir_ref_instruction(fields[i].value, irb->current_basic_block); | 1575 | ir_ref_instruction(fields[i].result_loc, irb->current_basic_block); |
| 1464 | } | 1576 | } |
| | 1577 | if (result_loc != nullptr) ir_ref_instruction(result_loc, irb->current_basic_block); |
| 1465 | | 1578 | |
| 1466 | return &container_init_fields_instruction->base; | 1579 | return &container_init_fields_instruction->base; |
| 1467 | } | 1580 | } |
| 1468 | | 1581 | |
| 1469 | static IrInstruction *ir_build_struct_init(IrBuilder *irb, Scope *scope, AstNode *source_node, | | |
| 1470 | ZigType *struct_type, size_t field_count, IrInstructionStructInitField *fields) | | |
| 1471 | { | | |
| 1472 | IrInstructionStructInit *struct_init_instruction = ir_build_instruction<IrInstructionStructInit>(irb, scope, source_node); | | |
| 1473 | struct_init_instruction->struct_type = struct_type; | | |
| 1474 | struct_init_instruction->field_count = field_count; | | |
| 1475 | struct_init_instruction->fields = fields; | | |
| 1476 | | | |
| 1477 | for (size_t i = 0; i < field_count; i += 1) | | |
| 1478 | ir_ref_instruction(fields[i].value, irb->current_basic_block); | | |
| 1479 | | | |
| 1480 | return &struct_init_instruction->base; | | |
| 1481 | } | | |
| 1482 | | | |
| 1483 | static IrInstruction *ir_build_union_init(IrBuilder *irb, Scope *scope, AstNode *source_node, | | |
| 1484 | ZigType *union_type, TypeUnionField *field, IrInstruction *init_value) | | |
| 1485 | { | | |
| 1486 | IrInstructionUnionInit *union_init_instruction = ir_build_instruction<IrInstructionUnionInit>(irb, scope, source_node); | | |
| 1487 | union_init_instruction->union_type = union_type; | | |
| 1488 | union_init_instruction->field = field; | | |
| 1489 | union_init_instruction->init_value = init_value; | | |
| 1490 | | | |
| 1491 | ir_ref_instruction(init_value, irb->current_basic_block); | | |
| 1492 | | | |
| 1493 | return &union_init_instruction->base; | | |
| 1494 | } | | |
| 1495 | | | |
| 1496 | 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) { |
| 1497 | IrInstructionUnreachable *unreachable_instruction = | 1583 | IrInstructionUnreachable *unreachable_instruction = |
| 1498 | ir_build_instruction<IrInstructionUnreachable>(irb, scope, source_node); | 1584 | ir_build_instruction<IrInstructionUnreachable>(irb, scope, source_node); |
| ... | @@ -1517,47 +1603,47 @@ static IrInstruction *ir_build_store_ptr(IrBuilder *irb, Scope *scope, AstNode * | ... | @@ -1517,47 +1603,47 @@ static IrInstruction *ir_build_store_ptr(IrBuilder *irb, Scope *scope, AstNode * |
| 1517 | } | 1603 | } |
| 1518 | | 1604 | |
| 1519 | 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, |
| 1520 | ZigVar *var, IrInstruction *var_type, IrInstruction *align_value, IrInstruction *init_value) | 1606 | ZigVar *var, IrInstruction *align_value, IrInstruction *ptr) |
| 1521 | { | 1607 | { |
| 1522 | 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); |
| 1523 | decl_var_instruction->base.value.special = ConstValSpecialStatic; | 1609 | decl_var_instruction->base.value.special = ConstValSpecialStatic; |
| 1524 | 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; |
| 1525 | decl_var_instruction->var = var; | 1611 | decl_var_instruction->var = var; |
| 1526 | decl_var_instruction->var_type = var_type; | | |
| 1527 | decl_var_instruction->align_value = align_value; | 1612 | decl_var_instruction->align_value = align_value; |
| 1528 | decl_var_instruction->init_value = init_value; | 1613 | decl_var_instruction->ptr = ptr; |
| 1529 | | 1614 | |
| 1530 | if (var_type != nullptr) ir_ref_instruction(var_type, irb->current_basic_block); | | |
| 1531 | 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); |
| 1532 | ir_ref_instruction(init_value, irb->current_basic_block); | 1616 | ir_ref_instruction(ptr, irb->current_basic_block); |
| 1533 | | 1617 | |
| 1534 | return &decl_var_instruction->base; | 1618 | return &decl_var_instruction->base; |
| 1535 | } | 1619 | } |
| 1536 | | 1620 | |
| 1537 | 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, |
| 1538 | ZigVar *var, IrInstruction *init_value) | 1622 | ZigVar *var, IrInstruction *var_ptr) |
| 1539 | { | 1623 | { |
| 1540 | IrInstructionDeclVarGen *decl_var_instruction = ir_build_instruction<IrInstructionDeclVarGen>(&ira->new_irb, | 1624 | IrInstructionDeclVarGen *decl_var_instruction = ir_build_instruction<IrInstructionDeclVarGen>(&ira->new_irb, |
| 1541 | source_instruction->scope, source_instruction->source_node); | 1625 | source_instruction->scope, source_instruction->source_node); |
| 1542 | decl_var_instruction->base.value.special = ConstValSpecialStatic; | 1626 | decl_var_instruction->base.value.special = ConstValSpecialStatic; |
| 1543 | 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; |
| 1544 | decl_var_instruction->var = var; | 1628 | decl_var_instruction->var = var; |
| 1545 | decl_var_instruction->init_value = init_value; | 1629 | decl_var_instruction->var_ptr = var_ptr; |
| 1546 | | 1630 | |
| 1547 | ir_ref_instruction(init_value, ira->new_irb.current_basic_block); | 1631 | ir_ref_instruction(var_ptr, ira->new_irb.current_basic_block); |
| 1548 | | 1632 | |
| 1549 | return &decl_var_instruction->base; | 1633 | return &decl_var_instruction->base; |
| 1550 | } | 1634 | } |
| 1551 | | 1635 | |
| 1552 | static IrInstruction *ir_build_resize_slice(IrAnalyze *ira, IrInstruction *source_instruction, | 1636 | static IrInstruction *ir_build_resize_slice(IrAnalyze *ira, IrInstruction *source_instruction, |
| 1553 | IrInstruction *operand, ZigType *ty) | 1637 | IrInstruction *operand, ZigType *ty, IrInstruction *result_loc) |
| 1554 | { | 1638 | { |
| 1555 | IrInstructionResizeSlice *instruction = ir_build_instruction<IrInstructionResizeSlice>(&ira->new_irb, | 1639 | IrInstructionResizeSlice *instruction = ir_build_instruction<IrInstructionResizeSlice>(&ira->new_irb, |
| 1556 | source_instruction->scope, source_instruction->source_node); | 1640 | source_instruction->scope, source_instruction->source_node); |
| 1557 | instruction->base.value.type = ty; | 1641 | instruction->base.value.type = ty; |
| 1558 | instruction->operand = operand; | 1642 | instruction->operand = operand; |
| | 1643 | instruction->result_loc = result_loc; |
| 1559 | | 1644 | |
| 1560 | 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); |
| 1561 | | 1647 | |
| 1562 | return &instruction->base; | 1648 | return &instruction->base; |
| 1563 | } | 1649 | } |
| ... | @@ -1598,27 +1684,6 @@ static IrInstruction *ir_build_typeof(IrBuilder *irb, Scope *scope, AstNode *sou | ... | @@ -1598,27 +1684,6 @@ static IrInstruction *ir_build_typeof(IrBuilder *irb, Scope *scope, AstNode *sou |
| 1598 | return &instruction->base; | 1684 | return &instruction->base; |
| 1599 | } | 1685 | } |
| 1600 | | 1686 | |
| 1601 | static IrInstruction *ir_build_to_ptr_type(IrBuilder *irb, Scope *scope, AstNode *source_node, IrInstruction *ptr) { | | |
| 1602 | IrInstructionToPtrType *instruction = ir_build_instruction<IrInstructionToPtrType>(irb, scope, source_node); | | |
| 1603 | instruction->ptr = ptr; | | |
| 1604 | | | |
| 1605 | ir_ref_instruction(ptr, irb->current_basic_block); | | |
| 1606 | | | |
| 1607 | return &instruction->base; | | |
| 1608 | } | | |
| 1609 | | | |
| 1610 | static IrInstruction *ir_build_ptr_type_child(IrBuilder *irb, Scope *scope, AstNode *source_node, | | |
| 1611 | IrInstruction *value) | | |
| 1612 | { | | |
| 1613 | IrInstructionPtrTypeChild *instruction = ir_build_instruction<IrInstructionPtrTypeChild>( | | |
| 1614 | irb, scope, source_node); | | |
| 1615 | instruction->value = value; | | |
| 1616 | | | |
| 1617 | ir_ref_instruction(value, irb->current_basic_block); | | |
| 1618 | | | |
| 1619 | return &instruction->base; | | |
| 1620 | } | | |
| 1621 | | | |
| 1622 | 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) { |
| 1623 | IrInstructionSetCold *instruction = ir_build_instruction<IrInstructionSetCold>(irb, scope, source_node); | 1688 | IrInstructionSetCold *instruction = ir_build_instruction<IrInstructionSetCold>(irb, scope, source_node); |
| 1624 | instruction->is_cold = is_cold; | 1689 | instruction->is_cold = is_cold; |
| ... | @@ -1744,40 +1809,59 @@ static IrInstruction *ir_build_test_nonnull(IrBuilder *irb, Scope *scope, AstNod | ... | @@ -1744,40 +1809,59 @@ static IrInstruction *ir_build_test_nonnull(IrBuilder *irb, Scope *scope, AstNod |
| 1744 | } | 1809 | } |
| 1745 | | 1810 | |
| 1746 | 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, |
| 1747 | IrInstruction *base_ptr, bool safety_check_on) | 1812 | IrInstruction *base_ptr, bool safety_check_on, bool initializing) |
| 1748 | { | 1813 | { |
| 1749 | IrInstructionOptionalUnwrapPtr *instruction = ir_build_instruction<IrInstructionOptionalUnwrapPtr>(irb, scope, source_node); | 1814 | IrInstructionOptionalUnwrapPtr *instruction = ir_build_instruction<IrInstructionOptionalUnwrapPtr>(irb, scope, source_node); |
| 1750 | instruction->base_ptr = base_ptr; | 1815 | instruction->base_ptr = base_ptr; |
| 1751 | instruction->safety_check_on = safety_check_on; | 1816 | instruction->safety_check_on = safety_check_on; |
| | 1817 | instruction->initializing = initializing; |
| 1752 | | 1818 | |
| 1753 | ir_ref_instruction(base_ptr, irb->current_basic_block); | 1819 | ir_ref_instruction(base_ptr, irb->current_basic_block); |
| 1754 | | 1820 | |
| 1755 | return &instruction->base; | 1821 | return &instruction->base; |
| 1756 | } | 1822 | } |
| 1757 | | 1823 | |
| 1758 | 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, |
| 1759 | IrInstructionOptionalWrap *instruction = ir_build_instruction<IrInstructionOptionalWrap>(irb, scope, source_node); | 1825 | IrInstruction *operand, IrInstruction *result_loc) |
| 1760 | 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; |
| 1761 | | 1832 | |
| 1762 | 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); |
| 1763 | | 1835 | |
| 1764 | return &instruction->base; | 1836 | return &instruction->base; |
| 1765 | } | 1837 | } |
| 1766 | | 1838 | |
| 1767 | 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, |
| 1768 | IrInstructionErrWrapPayload *instruction = ir_build_instruction<IrInstructionErrWrapPayload>(irb, scope, source_node); | 1840 | ZigType *result_type, IrInstruction *operand, IrInstruction *result_loc) |
| 1769 | 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; |
| 1770 | | 1847 | |
| 1771 | 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); |
| 1772 | | 1850 | |
| 1773 | return &instruction->base; | 1851 | return &instruction->base; |
| 1774 | } | 1852 | } |
| 1775 | | 1853 | |
| 1776 | 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, |
| 1777 | IrInstructionErrWrapCode *instruction = ir_build_instruction<IrInstructionErrWrapCode>(irb, scope, source_node); | 1855 | ZigType *result_type, IrInstruction *operand, IrInstruction *result_loc) |
| 1778 | 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; |
| 1779 | | 1862 | |
| 1780 | 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); |
| 1781 | | 1865 | |
| 1782 | return &instruction->base; | 1866 | return &instruction->base; |
| 1783 | } | 1867 | } |
| ... | @@ -1934,6 +2018,21 @@ static IrInstruction *ir_build_ref(IrBuilder *irb, Scope *scope, AstNode *source | ... | @@ -1934,6 +2018,21 @@ static IrInstruction *ir_build_ref(IrBuilder *irb, Scope *scope, AstNode *source |
| 1934 | return &instruction->base; | 2018 | return &instruction->base; |
| 1935 | } | 2019 | } |
| 1936 | | 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 | |
| 1937 | 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) { |
| 1938 | IrInstructionCompileErr *instruction = ir_build_instruction<IrInstructionCompileErr>(irb, scope, source_node); | 2037 | IrInstructionCompileErr *instruction = ir_build_instruction<IrInstructionCompileErr>(irb, scope, source_node); |
| 1939 | instruction->msg = msg; | 2038 | instruction->msg = msg; |
| ... | @@ -2011,8 +2110,7 @@ static IrInstruction *ir_build_embed_file(IrBuilder *irb, Scope *scope, AstNode | ... | @@ -2011,8 +2110,7 @@ static IrInstruction *ir_build_embed_file(IrBuilder *irb, Scope *scope, AstNode |
| 2011 | | 2110 | |
| 2012 | 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, |
| 2013 | IrInstruction *type_value, IrInstruction *ptr, IrInstruction *cmp_value, IrInstruction *new_value, | 2112 | IrInstruction *type_value, IrInstruction *ptr, IrInstruction *cmp_value, IrInstruction *new_value, |
| 2014 | IrInstruction *success_order_value, IrInstruction *failure_order_value, | 2113 | IrInstruction *success_order_value, IrInstruction *failure_order_value, bool is_weak, ResultLoc *result_loc) |
| 2015 | bool is_weak) | | |
| 2016 | { | 2114 | { |
| 2017 | IrInstructionCmpxchgSrc *instruction = ir_build_instruction<IrInstructionCmpxchgSrc>(irb, scope, source_node); | 2115 | IrInstructionCmpxchgSrc *instruction = ir_build_instruction<IrInstructionCmpxchgSrc>(irb, scope, source_node); |
| 2018 | instruction->type_value = type_value; | 2116 | instruction->type_value = type_value; |
| ... | @@ -2022,6 +2120,7 @@ static IrInstruction *ir_build_cmpxchg_src(IrBuilder *irb, Scope *scope, AstNode | ... | @@ -2022,6 +2120,7 @@ static IrInstruction *ir_build_cmpxchg_src(IrBuilder *irb, Scope *scope, AstNode |
| 2022 | instruction->success_order_value = success_order_value; | 2120 | instruction->success_order_value = success_order_value; |
| 2023 | instruction->failure_order_value = failure_order_value; | 2121 | instruction->failure_order_value = failure_order_value; |
| 2024 | instruction->is_weak = is_weak; | 2122 | instruction->is_weak = is_weak; |
| | 2123 | instruction->result_loc = result_loc; |
| 2025 | | 2124 | |
| 2026 | ir_ref_instruction(type_value, irb->current_basic_block); | 2125 | ir_ref_instruction(type_value, irb->current_basic_block); |
| 2027 | ir_ref_instruction(ptr, irb->current_basic_block); | 2126 | ir_ref_instruction(ptr, irb->current_basic_block); |
| ... | @@ -2033,22 +2132,25 @@ static IrInstruction *ir_build_cmpxchg_src(IrBuilder *irb, Scope *scope, AstNode | ... | @@ -2033,22 +2132,25 @@ static IrInstruction *ir_build_cmpxchg_src(IrBuilder *irb, Scope *scope, AstNode |
| 2033 | return &instruction->base; | 2132 | return &instruction->base; |
| 2034 | } | 2133 | } |
| 2035 | | 2134 | |
| 2036 | 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, |
| 2037 | IrInstruction *ptr, IrInstruction *cmp_value, IrInstruction *new_value, | 2136 | IrInstruction *ptr, IrInstruction *cmp_value, IrInstruction *new_value, |
| 2038 | AtomicOrder success_order, AtomicOrder failure_order, bool is_weak) | 2137 | AtomicOrder success_order, AtomicOrder failure_order, bool is_weak, IrInstruction *result_loc) |
| 2039 | { | 2138 | { |
| 2040 | IrInstructionCmpxchgGen *instruction = ir_build_instruction<IrInstructionCmpxchgGen>(&ira->new_irb, | 2139 | IrInstructionCmpxchgGen *instruction = ir_build_instruction<IrInstructionCmpxchgGen>(&ira->new_irb, |
| 2041 | source_instruction->scope, source_instruction->source_node); | 2140 | source_instruction->scope, source_instruction->source_node); |
| | 2141 | instruction->base.value.type = result_type; |
| 2042 | instruction->ptr = ptr; | 2142 | instruction->ptr = ptr; |
| 2043 | instruction->cmp_value = cmp_value; | 2143 | instruction->cmp_value = cmp_value; |
| 2044 | instruction->new_value = new_value; | 2144 | instruction->new_value = new_value; |
| 2045 | instruction->success_order = success_order; | 2145 | instruction->success_order = success_order; |
| 2046 | instruction->failure_order = failure_order; | 2146 | instruction->failure_order = failure_order; |
| 2047 | instruction->is_weak = is_weak; | 2147 | instruction->is_weak = is_weak; |
| | 2148 | instruction->result_loc = result_loc; |
| 2048 | | 2149 | |
| 2049 | ir_ref_instruction(ptr, ira->new_irb.current_basic_block); | 2150 | ir_ref_instruction(ptr, ira->new_irb.current_basic_block); |
| 2050 | ir_ref_instruction(cmp_value, ira->new_irb.current_basic_block); | 2151 | ir_ref_instruction(cmp_value, ira->new_irb.current_basic_block); |
| 2051 | 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); |
| 2052 | | 2154 | |
| 2053 | return &instruction->base; | 2155 | return &instruction->base; |
| 2054 | } | 2156 | } |
| ... | @@ -2107,19 +2209,25 @@ static IrInstruction *ir_build_err_set_cast(IrBuilder *irb, Scope *scope, AstNod | ... | @@ -2107,19 +2209,25 @@ static IrInstruction *ir_build_err_set_cast(IrBuilder *irb, Scope *scope, AstNod |
| 2107 | return &instruction->base; | 2209 | return &instruction->base; |
| 2108 | } | 2210 | } |
| 2109 | | 2211 | |
| 2110 | 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 | { |
| 2111 | IrInstructionToBytes *instruction = ir_build_instruction<IrInstructionToBytes>(irb, scope, source_node); | 2215 | IrInstructionToBytes *instruction = ir_build_instruction<IrInstructionToBytes>(irb, scope, source_node); |
| 2112 | instruction->target = target; | 2216 | instruction->target = target; |
| | 2217 | instruction->result_loc = result_loc; |
| 2113 | | 2218 | |
| 2114 | ir_ref_instruction(target, irb->current_basic_block); | 2219 | ir_ref_instruction(target, irb->current_basic_block); |
| 2115 | | 2220 | |
| 2116 | return &instruction->base; | 2221 | return &instruction->base; |
| 2117 | } | 2222 | } |
| 2118 | | 2223 | |
| 2119 | 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 | { |
| 2120 | IrInstructionFromBytes *instruction = ir_build_instruction<IrInstructionFromBytes>(irb, scope, source_node); | 2227 | IrInstructionFromBytes *instruction = ir_build_instruction<IrInstructionFromBytes>(irb, scope, source_node); |
| 2121 | instruction->dest_child_type = dest_child_type; | 2228 | instruction->dest_child_type = dest_child_type; |
| 2122 | instruction->target = target; | 2229 | instruction->target = target; |
| | 2230 | instruction->result_loc = result_loc; |
| 2123 | | 2231 | |
| 2124 | ir_ref_instruction(dest_child_type, irb->current_basic_block); | 2232 | ir_ref_instruction(dest_child_type, irb->current_basic_block); |
| 2125 | ir_ref_instruction(target, irb->current_basic_block); | 2233 | ir_ref_instruction(target, irb->current_basic_block); |
| ... | @@ -2221,14 +2329,15 @@ static IrInstruction *ir_build_memcpy(IrBuilder *irb, Scope *scope, AstNode *sou | ... | @@ -2221,14 +2329,15 @@ static IrInstruction *ir_build_memcpy(IrBuilder *irb, Scope *scope, AstNode *sou |
| 2221 | return &instruction->base; | 2329 | return &instruction->base; |
| 2222 | } | 2330 | } |
| 2223 | | 2331 | |
| 2224 | 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, |
| 2225 | IrInstruction *ptr, IrInstruction *start, IrInstruction *end, bool safety_check_on) | 2333 | IrInstruction *ptr, IrInstruction *start, IrInstruction *end, bool safety_check_on, ResultLoc *result_loc) |
| 2226 | { | 2334 | { |
| 2227 | IrInstructionSlice *instruction = ir_build_instruction<IrInstructionSlice>(irb, scope, source_node); | 2335 | IrInstructionSliceSrc *instruction = ir_build_instruction<IrInstructionSliceSrc>(irb, scope, source_node); |
| 2228 | instruction->ptr = ptr; | 2336 | instruction->ptr = ptr; |
| 2229 | instruction->start = start; | 2337 | instruction->start = start; |
| 2230 | instruction->end = end; | 2338 | instruction->end = end; |
| 2231 | instruction->safety_check_on = safety_check_on; | 2339 | instruction->safety_check_on = safety_check_on; |
| | 2340 | instruction->result_loc = result_loc; |
| 2232 | | 2341 | |
| 2233 | ir_ref_instruction(ptr, irb->current_basic_block); | 2342 | ir_ref_instruction(ptr, irb->current_basic_block); |
| 2234 | ir_ref_instruction(start, irb->current_basic_block); | 2343 | ir_ref_instruction(start, irb->current_basic_block); |
| ... | @@ -2237,6 +2346,26 @@ static IrInstruction *ir_build_slice(IrBuilder *irb, Scope *scope, AstNode *sour | ... | @@ -2237,6 +2346,26 @@ static IrInstruction *ir_build_slice(IrBuilder *irb, Scope *scope, AstNode *sour |
| 2237 | return &instruction->base; | 2346 | return &instruction->base; |
| 2238 | } | 2347 | } |
| 2239 | | 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 | |
| 2240 | 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) { |
| 2241 | IrInstructionMemberCount *instruction = ir_build_instruction<IrInstructionMemberCount>(irb, scope, source_node); | 2370 | IrInstructionMemberCount *instruction = ir_build_instruction<IrInstructionMemberCount>(irb, scope, source_node); |
| 2242 | instruction->container = container; | 2371 | instruction->container = container; |
| ... | @@ -2390,34 +2519,49 @@ static IrInstruction *ir_build_align_of(IrBuilder *irb, Scope *scope, AstNode *s | ... | @@ -2390,34 +2519,49 @@ static IrInstruction *ir_build_align_of(IrBuilder *irb, Scope *scope, AstNode *s |
| 2390 | return &instruction->base; | 2519 | return &instruction->base; |
| 2391 | } | 2520 | } |
| 2392 | | 2521 | |
| 2393 | 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, |
| 2394 | IrInstruction *value) | 2523 | IrInstruction *base_ptr, bool resolve_err_set) |
| 2395 | { | 2524 | { |
| 2396 | IrInstructionTestErr *instruction = ir_build_instruction<IrInstructionTestErr>(irb, scope, source_node); | 2525 | IrInstructionTestErrSrc *instruction = ir_build_instruction<IrInstructionTestErrSrc>(irb, scope, source_node); |
| 2397 | instruction->value = value; | 2526 | instruction->base_ptr = base_ptr; |
| | 2527 | instruction->resolve_err_set = resolve_err_set; |
| 2398 | | 2528 | |
| 2399 | ir_ref_instruction(value, irb->current_basic_block); | 2529 | ir_ref_instruction(base_ptr, irb->current_basic_block); |
| 2400 | | 2530 | |
| 2401 | return &instruction->base; | 2531 | return &instruction->base; |
| 2402 | } | 2532 | } |
| 2403 | | 2533 | |
| 2404 | 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, |
| 2405 | IrInstruction *err_union) | 2535 | IrInstruction *err_union) |
| 2406 | { | 2536 | { |
| 2407 | 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; |
| 2408 | instruction->err_union = err_union; | 2540 | instruction->err_union = err_union; |
| 2409 | | 2541 | |
| 2410 | 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); |
| 2411 | | 2554 | |
| 2412 | return &instruction->base; | 2555 | return &instruction->base; |
| 2413 | } | 2556 | } |
| 2414 | | 2557 | |
| 2415 | 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, |
| 2416 | IrInstruction *value, bool safety_check_on) | 2559 | IrInstruction *value, bool safety_check_on, bool initializing) |
| 2417 | { | 2560 | { |
| 2418 | IrInstructionUnwrapErrPayload *instruction = ir_build_instruction<IrInstructionUnwrapErrPayload>(irb, scope, source_node); | 2561 | IrInstructionUnwrapErrPayload *instruction = ir_build_instruction<IrInstructionUnwrapErrPayload>(irb, scope, source_node); |
| 2419 | instruction->value = value; | 2562 | instruction->value = value; |
| 2420 | instruction->safety_check_on = safety_check_on; | 2563 | instruction->safety_check_on = safety_check_on; |
| | 2564 | instruction->initializing = initializing; |
| 2421 | | 2565 | |
| 2422 | ir_ref_instruction(value, irb->current_basic_block); | 2566 | ir_ref_instruction(value, irb->current_basic_block); |
| 2423 | | 2567 | |
| ... | @@ -2487,28 +2631,28 @@ static IrInstruction *ir_build_ptr_cast_gen(IrAnalyze *ira, IrInstruction *sourc | ... | @@ -2487,28 +2631,28 @@ static IrInstruction *ir_build_ptr_cast_gen(IrAnalyze *ira, IrInstruction *sourc |
| 2487 | } | 2631 | } |
| 2488 | | 2632 | |
| 2489 | 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, |
| 2490 | IrInstruction *ptr, ZigType *ty) | 2634 | IrInstruction *ptr, ZigType *ty, IrInstruction *result_loc) |
| 2491 | { | 2635 | { |
| 2492 | IrInstructionLoadPtrGen *instruction = ir_build_instruction<IrInstructionLoadPtrGen>( | 2636 | IrInstructionLoadPtrGen *instruction = ir_build_instruction<IrInstructionLoadPtrGen>( |
| 2493 | &ira->new_irb, source_instruction->scope, source_instruction->source_node); | 2637 | &ira->new_irb, source_instruction->scope, source_instruction->source_node); |
| 2494 | instruction->base.value.type = ty; | 2638 | instruction->base.value.type = ty; |
| 2495 | instruction->ptr = ptr; | 2639 | instruction->ptr = ptr; |
| | 2640 | instruction->result_loc = result_loc; |
| 2496 | | 2641 | |
| 2497 | 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); |
| 2498 | | 2644 | |
| 2499 | return &instruction->base; | 2645 | return &instruction->base; |
| 2500 | } | 2646 | } |
| 2501 | | 2647 | |
| 2502 | 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, |
| 2503 | IrInstruction *dest_type, IrInstruction *value) | 2649 | IrInstruction *operand, ResultLocBitCast *result_loc_bit_cast) |
| 2504 | { | 2650 | { |
| 2505 | IrInstructionBitCast *instruction = ir_build_instruction<IrInstructionBitCast>( | 2651 | IrInstructionBitCastSrc *instruction = ir_build_instruction<IrInstructionBitCastSrc>(irb, scope, source_node); |
| 2506 | irb, scope, source_node); | 2652 | instruction->operand = operand; |
| 2507 | instruction->dest_type = dest_type; | 2653 | instruction->result_loc_bit_cast = result_loc_bit_cast; |
| 2508 | instruction->value = value; | | |
| 2509 | | 2654 | |
| 2510 | ir_ref_instruction(dest_type, irb->current_basic_block); | 2655 | ir_ref_instruction(operand, irb->current_basic_block); |
| 2511 | ir_ref_instruction(value, irb->current_basic_block); | | |
| 2512 | | 2656 | |
| 2513 | return &instruction->base; | 2657 | return &instruction->base; |
| 2514 | } | 2658 | } |
| ... | @@ -2660,11 +2804,8 @@ static IrInstruction *ir_build_type_name(IrBuilder *irb, Scope *scope, AstNode * | ... | @@ -2660,11 +2804,8 @@ static IrInstruction *ir_build_type_name(IrBuilder *irb, Scope *scope, AstNode * |
| 2660 | return &instruction->base; | 2804 | return &instruction->base; |
| 2661 | } | 2805 | } |
| 2662 | | 2806 | |
| 2663 | 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) { |
| 2664 | Tld *tld, LVal lval) | 2808 | IrInstructionDeclRef *instruction = ir_build_instruction<IrInstructionDeclRef>(irb, scope, source_node); |
| 2665 | { | | |
| 2666 | IrInstructionDeclRef *instruction = ir_build_instruction<IrInstructionDeclRef>( | | |
| 2667 | irb, scope, source_node); | | |
| 2668 | instruction->tld = tld; | 2809 | instruction->tld = tld; |
| 2669 | instruction->lval = lval; | 2810 | instruction->lval = lval; |
| 2670 | | 2811 | |
| ... | @@ -2792,6 +2933,53 @@ static IrInstruction *ir_build_align_cast(IrBuilder *irb, Scope *scope, AstNode | ... | @@ -2792,6 +2933,53 @@ static IrInstruction *ir_build_align_cast(IrBuilder *irb, Scope *scope, AstNode |
| 2792 | return &instruction->base; | 2933 | return &instruction->base; |
| 2793 | } | 2934 | } |
| 2794 | | 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 | |
| 2795 | 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) { |
| 2796 | IrInstructionOpaqueType *instruction = ir_build_instruction<IrInstructionOpaqueType>(irb, scope, source_node); | 2984 | IrInstructionOpaqueType *instruction = ir_build_instruction<IrInstructionOpaqueType>(irb, scope, source_node); |
| 2797 | | 2985 | |
| ... | @@ -3120,16 +3308,31 @@ static IrInstruction *ir_build_check_runtime_scope(IrBuilder *irb, Scope *scope, | ... | @@ -3120,16 +3308,31 @@ static IrInstruction *ir_build_check_runtime_scope(IrBuilder *irb, Scope *scope, |
| 3120 | } | 3308 | } |
| 3121 | | 3309 | |
| 3122 | 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, |
| 3123 | IrInstruction *vector, ZigType *result_type) | 3311 | ZigType *result_type, IrInstruction *vector, IrInstruction *result_loc) |
| 3124 | { | 3312 | { |
| 3125 | IrInstructionVectorToArray *instruction = ir_build_instruction<IrInstructionVectorToArray>(&ira->new_irb, | 3313 | IrInstructionVectorToArray *instruction = ir_build_instruction<IrInstructionVectorToArray>(&ira->new_irb, |
| 3126 | source_instruction->scope, source_instruction->source_node); | 3314 | source_instruction->scope, source_instruction->source_node); |
| 3127 | instruction->base.value.type = result_type; | 3315 | instruction->base.value.type = result_type; |
| 3128 | instruction->vector = vector; | 3316 | instruction->vector = vector; |
| | 3317 | instruction->result_loc = result_loc; |
| 3129 | | 3318 | |
| 3130 | 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; |
| 3131 | | 3333 | |
| 3132 | 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); |
| 3133 | | 3336 | |
| 3134 | return &instruction->base; | 3337 | return &instruction->base; |
| 3135 | } | 3338 | } |
| ... | @@ -3173,6 +3376,45 @@ static IrInstruction *ir_build_assert_non_null(IrAnalyze *ira, IrInstruction *so | ... | @@ -3173,6 +3376,45 @@ static IrInstruction *ir_build_assert_non_null(IrAnalyze *ira, IrInstruction *so |
| 3173 | return &instruction->base; | 3376 | return &instruction->base; |
| 3174 | } | 3377 | } |
| 3175 | | 3378 | |
| | 3379 | static IrInstruction *ir_build_alloca_src(IrBuilder *irb, Scope *scope, AstNode *source_node, |
| | 3380 | IrInstruction *align, const char *name_hint, IrInstruction *is_comptime) |
| | 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; |
| | 3387 | |
| | 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); |
| | 3390 | |
| | 3391 | return &instruction->base; |
| | 3392 | } |
| | 3393 | |
| | 3394 | static IrInstructionAllocaGen *ir_create_alloca_gen(IrAnalyze *ira, IrInstruction *source_instruction, |
| | 3395 | uint32_t align, const char *name_hint) |
| | 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 | |
| 3176 | static void ir_count_defers(IrBuilder *irb, Scope *inner_scope, Scope *outer_scope, size_t *results) { | 3418 | static void ir_count_defers(IrBuilder *irb, Scope *inner_scope, Scope *outer_scope, size_t *results) { |
| 3177 | results[ReturnKindUnconditional] = 0; | 3419 | results[ReturnKindUnconditional] = 0; |
| 3178 | results[ReturnKindError] = 0; | 3420 | results[ReturnKindError] = 0; |
| ... | @@ -3273,6 +3515,7 @@ static void ir_set_cursor_at_end(IrBuilder *irb, IrBasicBlock *basic_block) { | ... | @@ -3273,6 +3515,7 @@ static void ir_set_cursor_at_end(IrBuilder *irb, IrBasicBlock *basic_block) { |
| 3273 | } | 3515 | } |
| 3274 | | 3516 | |
| 3275 | 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; |
| 3276 | irb->exec->basic_block_list.append(basic_block); | 3519 | irb->exec->basic_block_list.append(basic_block); |
| 3277 | ir_set_cursor_at_end(irb, basic_block); | 3520 | ir_set_cursor_at_end(irb, basic_block); |
| 3278 | } | 3521 | } |
| ... | @@ -3361,7 +3604,7 @@ static IrInstruction *ir_gen_async_return(IrBuilder *irb, Scope *scope, AstNode | ... | @@ -3361,7 +3604,7 @@ static IrInstruction *ir_gen_async_return(IrBuilder *irb, Scope *scope, AstNode |
| 3361 | 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); |
| 3362 | } | 3605 | } |
| 3363 | | 3606 | |
| 3364 | 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) { |
| 3365 | assert(node->type == NodeTypeReturnExpr); | 3608 | assert(node->type == NodeTypeReturnExpr); |
| 3366 | | 3609 | |
| 3367 | ZigFn *fn_entry = exec_fn_entry(irb->exec); | 3610 | ZigFn *fn_entry = exec_fn_entry(irb->exec); |
| ... | @@ -3385,12 +3628,16 @@ static IrInstruction *ir_gen_return(IrBuilder *irb, Scope *scope, AstNode *node, | ... | @@ -3385,12 +3628,16 @@ static IrInstruction *ir_gen_return(IrBuilder *irb, Scope *scope, AstNode *node, |
| 3385 | switch (node->data.return_expr.kind) { | 3628 | switch (node->data.return_expr.kind) { |
| 3386 | case ReturnKindUnconditional: | 3629 | case ReturnKindUnconditional: |
| 3387 | { | 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 | |
| 3388 | IrInstruction *return_value; | 3635 | IrInstruction *return_value; |
| 3389 | if (expr_node) { | 3636 | if (expr_node) { |
| 3390 | // 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 |
| 3391 | ZigFn *prev_name_fn = irb->exec->name_fn; | 3638 | ZigFn *prev_name_fn = irb->exec->name_fn; |
| 3392 | irb->exec->name_fn = exec_fn_entry(irb->exec); | 3639 | irb->exec->name_fn = exec_fn_entry(irb->exec); |
| 3393 | 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); |
| 3394 | irb->exec->name_fn = prev_name_fn; | 3641 | irb->exec->name_fn = prev_name_fn; |
| 3395 | if (return_value == irb->codegen->invalid_instruction) | 3642 | if (return_value == irb->codegen->invalid_instruction) |
| 3396 | return irb->codegen->invalid_instruction; | 3643 | return irb->codegen->invalid_instruction; |
| ... | @@ -3408,7 +3655,9 @@ static IrInstruction *ir_gen_return(IrBuilder *irb, Scope *scope, AstNode *node, | ... | @@ -3408,7 +3655,9 @@ static IrInstruction *ir_gen_return(IrBuilder *irb, Scope *scope, AstNode *node, |
| 3408 | ir_gen_defers_for_block(irb, scope, outer_scope, false); | 3655 | ir_gen_defers_for_block(irb, scope, outer_scope, false); |
| 3409 | } | 3656 | } |
| 3410 | | 3657 | |
| 3411 | 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); |
| 3412 | | 3661 | |
| 3413 | bool should_inline = ir_should_inline(irb->exec, scope); | 3662 | bool should_inline = ir_should_inline(irb->exec, scope); |
| 3414 | IrInstruction *is_comptime; | 3663 | IrInstruction *is_comptime; |
| ... | @@ -3437,21 +3686,24 @@ static IrInstruction *ir_gen_return(IrBuilder *irb, Scope *scope, AstNode *node, | ... | @@ -3437,21 +3686,24 @@ static IrInstruction *ir_gen_return(IrBuilder *irb, Scope *scope, AstNode *node, |
| 3437 | ir_build_br(irb, scope, node, ret_stmt_block, is_comptime); | 3686 | ir_build_br(irb, scope, node, ret_stmt_block, is_comptime); |
| 3438 | | 3687 | |
| 3439 | 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); |
| 3440 | 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; |
| 3441 | } else { | 3692 | } else { |
| 3442 | // generate unconditional defers | 3693 | // generate unconditional defers |
| 3443 | ir_gen_defers_for_block(irb, scope, outer_scope, false); | 3694 | ir_gen_defers_for_block(irb, scope, outer_scope, false); |
| 3444 | 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; |
| 3445 | } | 3698 | } |
| 3446 | } | 3699 | } |
| 3447 | case ReturnKindError: | 3700 | case ReturnKindError: |
| 3448 | { | 3701 | { |
| 3449 | assert(expr_node); | 3702 | assert(expr_node); |
| 3450 | 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); |
| 3451 | if (err_union_ptr == irb->codegen->invalid_instruction) | 3704 | if (err_union_ptr == irb->codegen->invalid_instruction) |
| 3452 | return irb->codegen->invalid_instruction; | 3705 | return irb->codegen->invalid_instruction; |
| 3453 | 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); |
| 3454 | IrInstruction *is_err_val = ir_build_test_err(irb, scope, node, err_union_val); | | |
| 3455 | | 3707 | |
| 3456 | IrBasicBlock *return_block = ir_create_basic_block(irb, scope, "ErrRetReturn"); | 3708 | IrBasicBlock *return_block = ir_create_basic_block(irb, scope, "ErrRetReturn"); |
| 3457 | IrBasicBlock *continue_block = ir_create_basic_block(irb, scope, "ErrRetContinue"); | 3709 | IrBasicBlock *continue_block = ir_create_basic_block(irb, scope, "ErrRetContinue"); |
| ... | @@ -3466,19 +3718,27 @@ static IrInstruction *ir_gen_return(IrBuilder *irb, Scope *scope, AstNode *node, | ... | @@ -3466,19 +3718,27 @@ static IrInstruction *ir_gen_return(IrBuilder *irb, Scope *scope, AstNode *node, |
| 3466 | | 3718 | |
| 3467 | ir_set_cursor_at_end_and_append_block(irb, return_block); | 3719 | ir_set_cursor_at_end_and_append_block(irb, return_block); |
| 3468 | if (!ir_gen_defers_for_block(irb, scope, outer_scope, true)) { | 3720 | if (!ir_gen_defers_for_block(irb, scope, outer_scope, true)) { |
| 3469 | 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 | |
| 3470 | if (irb->codegen->have_err_ret_tracing && !should_inline) { | 3729 | if (irb->codegen->have_err_ret_tracing && !should_inline) { |
| 3471 | ir_build_save_err_ret_addr(irb, scope, node); | 3730 | ir_build_save_err_ret_addr(irb, scope, node); |
| 3472 | } | 3731 | } |
| 3473 | 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; |
| 3474 | } | 3734 | } |
| 3475 | | 3735 | |
| 3476 | ir_set_cursor_at_end_and_append_block(irb, continue_block); | 3736 | ir_set_cursor_at_end_and_append_block(irb, continue_block); |
| 3477 | 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); |
| 3478 | if (lval == LValPtr) | 3738 | if (lval == LValPtr) |
| 3479 | return unwrapped_ptr; | 3739 | return unwrapped_ptr; |
| 3480 | else | 3740 | else |
| 3481 | 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); |
| 3482 | } | 3742 | } |
| 3483 | } | 3743 | } |
| 3484 | zig_unreachable(); | 3744 | zig_unreachable(); |
| ... | @@ -3562,7 +3822,17 @@ static ZigVar *ir_create_var(IrBuilder *irb, AstNode *node, Scope *scope, Buf *n | ... | @@ -3562,7 +3822,17 @@ static ZigVar *ir_create_var(IrBuilder *irb, AstNode *node, Scope *scope, Buf *n |
| 3562 | return var; | 3822 | return var; |
| 3563 | } | 3823 | } |
| 3564 | | 3824 | |
| 3565 | 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 | { |
| 3566 | assert(block_node->type == NodeTypeBlock); | 3836 | assert(block_node->type == NodeTypeBlock); |
| 3567 | | 3837 | |
| 3568 | ZigList<IrInstruction *> incoming_values = {0}; | 3838 | ZigList<IrInstruction *> incoming_values = {0}; |
| ... | @@ -3580,15 +3850,24 @@ static IrInstruction *ir_gen_block(IrBuilder *irb, Scope *parent_scope, AstNode | ... | @@ -3580,15 +3850,24 @@ static IrInstruction *ir_gen_block(IrBuilder *irb, Scope *parent_scope, AstNode |
| 3580 | | 3850 | |
| 3581 | if (block_node->data.block.statements.length == 0) { | 3851 | if (block_node->data.block.statements.length == 0) { |
| 3582 | // {} | 3852 | // {} |
| 3583 | 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); |
| 3584 | } | 3854 | } |
| 3585 | | 3855 | |
| 3586 | if (block_node->data.block.name != nullptr) { | 3856 | if (block_node->data.block.name != nullptr) { |
| | 3857 | scope_block->lval = lval; |
| 3587 | scope_block->incoming_blocks = &incoming_blocks; | 3858 | scope_block->incoming_blocks = &incoming_blocks; |
| 3588 | scope_block->incoming_values = &incoming_values; | 3859 | scope_block->incoming_values = &incoming_values; |
| 3589 | 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"); |
| 3590 | 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, |
| 3591 | 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); |
| 3592 | } | 3871 | } |
| 3593 | | 3872 | |
| 3594 | bool is_continuation_unreachable = false; | 3873 | bool is_continuation_unreachable = false; |
| ... | @@ -3602,6 +3881,8 @@ static IrInstruction *ir_gen_block(IrBuilder *irb, Scope *parent_scope, AstNode | ... | @@ -3602,6 +3881,8 @@ static IrInstruction *ir_gen_block(IrBuilder *irb, Scope *parent_scope, AstNode |
| 3602 | // 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 |
| 3603 | noreturn_return_value = statement_value; | 3882 | noreturn_return_value = statement_value; |
| 3604 | } | 3883 | } |
| | 3884 | // This logic must be kept in sync with |
| | 3885 | // [STMT_EXPR_TEST_THING] <--- (search this token) |
| 3605 | if (statement_node->type == NodeTypeDefer && statement_value != irb->codegen->invalid_instruction) { | 3886 | if (statement_node->type == NodeTypeDefer && statement_value != irb->codegen->invalid_instruction) { |
| 3606 | // defer starts a new scope | 3887 | // defer starts a new scope |
| 3607 | child_scope = statement_node->data.defer.child_scope; | 3888 | child_scope = statement_node->data.defer.child_scope; |
| ... | @@ -3622,21 +3903,41 @@ static IrInstruction *ir_gen_block(IrBuilder *irb, Scope *parent_scope, AstNode | ... | @@ -3622,21 +3903,41 @@ static IrInstruction *ir_gen_block(IrBuilder *irb, Scope *parent_scope, AstNode |
| 3622 | return noreturn_return_value; | 3903 | return noreturn_return_value; |
| 3623 | } | 3904 | } |
| 3624 | | 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 | } |
| 3625 | 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); |
| 3626 | 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); |
| 3627 | } else { | 3913 | } else { |
| 3628 | incoming_blocks.append(irb->current_basic_block); | 3914 | incoming_blocks.append(irb->current_basic_block); |
| 3629 | 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); |
| 3630 | } | 3928 | } |
| 3631 | | 3929 | |
| 3632 | if (block_node->data.block.name != nullptr) { | 3930 | if (block_node->data.block.name != nullptr) { |
| 3633 | 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); |
| 3634 | 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)); |
| 3635 | 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); |
| 3636 | 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); |
| 3637 | } else { | 3937 | } else { |
| 3638 | 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); |
| 3639 | 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); |
| 3640 | } | 3941 | } |
| 3641 | } | 3942 | } |
| 3642 | | 3943 | |
| ... | @@ -3656,7 +3957,7 @@ static IrInstruction *ir_gen_bin_op_id(IrBuilder *irb, Scope *scope, AstNode *no | ... | @@ -3656,7 +3957,7 @@ static IrInstruction *ir_gen_bin_op_id(IrBuilder *irb, Scope *scope, AstNode *no |
| 3656 | } | 3957 | } |
| 3657 | | 3958 | |
| 3658 | static IrInstruction *ir_gen_assign(IrBuilder *irb, Scope *scope, AstNode *node) { | 3959 | static IrInstruction *ir_gen_assign(IrBuilder *irb, Scope *scope, AstNode *node) { |
| 3659 | 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); |
| 3660 | 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); |
| 3661 | | 3962 | |
| 3662 | if (lvalue == irb->codegen->invalid_instruction || rvalue == irb->codegen->invalid_instruction) | 3963 | if (lvalue == irb->codegen->invalid_instruction || rvalue == irb->codegen->invalid_instruction) |
| ... | @@ -3667,7 +3968,7 @@ static IrInstruction *ir_gen_assign(IrBuilder *irb, Scope *scope, AstNode *node) | ... | @@ -3667,7 +3968,7 @@ static IrInstruction *ir_gen_assign(IrBuilder *irb, Scope *scope, AstNode *node) |
| 3667 | } | 3968 | } |
| 3668 | | 3969 | |
| 3669 | 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) { |
| 3670 | 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); |
| 3671 | if (lvalue == irb->codegen->invalid_instruction) | 3972 | if (lvalue == irb->codegen->invalid_instruction) |
| 3672 | return lvalue; | 3973 | return lvalue; |
| 3673 | 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); |
| ... | @@ -3718,7 +4019,7 @@ static IrInstruction *ir_gen_bool_or(IrBuilder *irb, Scope *scope, AstNode *node | ... | @@ -3718,7 +4019,7 @@ static IrInstruction *ir_gen_bool_or(IrBuilder *irb, Scope *scope, AstNode *node |
| 3718 | incoming_blocks[0] = post_val1_block; | 4019 | incoming_blocks[0] = post_val1_block; |
| 3719 | incoming_blocks[1] = post_val2_block; | 4020 | incoming_blocks[1] = post_val2_block; |
| 3720 | | 4021 | |
| 3721 | 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); |
| 3722 | } | 4023 | } |
| 3723 | | 4024 | |
| 3724 | 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) { |
| ... | @@ -3760,16 +4061,51 @@ static IrInstruction *ir_gen_bool_and(IrBuilder *irb, Scope *scope, AstNode *nod | ... | @@ -3760,16 +4061,51 @@ static IrInstruction *ir_gen_bool_and(IrBuilder *irb, Scope *scope, AstNode *nod |
| 3760 | incoming_blocks[0] = post_val1_block; | 4061 | incoming_blocks[0] = post_val1_block; |
| 3761 | incoming_blocks[1] = post_val2_block; | 4062 | incoming_blocks[1] = post_val2_block; |
| 3762 | | 4063 | |
| 3763 | 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; |
| 3764 | } | 4084 | } |
| 3765 | | 4085 | |
| 3766 | static IrInstruction *ir_gen_orelse(IrBuilder *irb, Scope *parent_scope, AstNode *node) { | 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; |
| | 4098 | } |
| | 4099 | |
| | 4100 | static IrInstruction *ir_gen_orelse(IrBuilder *irb, Scope *parent_scope, AstNode *node, LVal lval, |
| | 4101 | ResultLoc *result_loc) |
| | 4102 | { |
| 3767 | assert(node->type == NodeTypeBinOpExpr); | 4103 | assert(node->type == NodeTypeBinOpExpr); |
| 3768 | | 4104 | |
| 3769 | AstNode *op1_node = node->data.bin_op_expr.op1; | 4105 | AstNode *op1_node = node->data.bin_op_expr.op1; |
| 3770 | AstNode *op2_node = node->data.bin_op_expr.op2; | 4106 | AstNode *op2_node = node->data.bin_op_expr.op2; |
| 3771 | | 4107 | |
| 3772 | 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); |
| 3773 | if (maybe_ptr == irb->codegen->invalid_instruction) | 4109 | if (maybe_ptr == irb->codegen->invalid_instruction) |
| 3774 | return irb->codegen->invalid_instruction; | 4110 | return irb->codegen->invalid_instruction; |
| 3775 | | 4111 | |
| ... | @@ -3786,10 +4122,14 @@ static IrInstruction *ir_gen_orelse(IrBuilder *irb, Scope *parent_scope, AstNode | ... | @@ -3786,10 +4122,14 @@ static IrInstruction *ir_gen_orelse(IrBuilder *irb, Scope *parent_scope, AstNode |
| 3786 | IrBasicBlock *ok_block = ir_create_basic_block(irb, parent_scope, "OptionalNonNull"); | 4122 | IrBasicBlock *ok_block = ir_create_basic_block(irb, parent_scope, "OptionalNonNull"); |
| 3787 | IrBasicBlock *null_block = ir_create_basic_block(irb, parent_scope, "OptionalNull"); | 4123 | IrBasicBlock *null_block = ir_create_basic_block(irb, parent_scope, "OptionalNull"); |
| 3788 | IrBasicBlock *end_block = ir_create_basic_block(irb, parent_scope, "OptionalEnd"); | 4124 | IrBasicBlock *end_block = ir_create_basic_block(irb, parent_scope, "OptionalEnd"); |
| 3789 | 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); |
| 3790 | | 4129 | |
| 3791 | ir_set_cursor_at_end_and_append_block(irb, null_block); | 4130 | ir_set_cursor_at_end_and_append_block(irb, null_block); |
| 3792 | 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); |
| 3793 | if (null_result == irb->codegen->invalid_instruction) | 4133 | if (null_result == irb->codegen->invalid_instruction) |
| 3794 | return irb->codegen->invalid_instruction; | 4134 | return irb->codegen->invalid_instruction; |
| 3795 | IrBasicBlock *after_null_block = irb->current_basic_block; | 4135 | IrBasicBlock *after_null_block = irb->current_basic_block; |
| ... | @@ -3797,8 +4137,9 @@ static IrInstruction *ir_gen_orelse(IrBuilder *irb, Scope *parent_scope, AstNode | ... | @@ -3797,8 +4137,9 @@ static IrInstruction *ir_gen_orelse(IrBuilder *irb, Scope *parent_scope, AstNode |
| 3797 | 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)); |
| 3798 | | 4138 | |
| 3799 | ir_set_cursor_at_end_and_append_block(irb, ok_block); | 4139 | ir_set_cursor_at_end_and_append_block(irb, ok_block); |
| 3800 | 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); |
| 3801 | 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); |
| 3802 | IrBasicBlock *after_ok_block = irb->current_basic_block; | 4143 | IrBasicBlock *after_ok_block = irb->current_basic_block; |
| 3803 | ir_build_br(irb, parent_scope, node, end_block, is_comptime); | 4144 | ir_build_br(irb, parent_scope, node, end_block, is_comptime); |
| 3804 | | 4145 | |
| ... | @@ -3809,7 +4150,8 @@ static IrInstruction *ir_gen_orelse(IrBuilder *irb, Scope *parent_scope, AstNode | ... | @@ -3809,7 +4150,8 @@ static IrInstruction *ir_gen_orelse(IrBuilder *irb, Scope *parent_scope, AstNode |
| 3809 | IrBasicBlock **incoming_blocks = allocate<IrBasicBlock *>(2); | 4150 | IrBasicBlock **incoming_blocks = allocate<IrBasicBlock *>(2); |
| 3810 | incoming_blocks[0] = after_null_block; | 4151 | incoming_blocks[0] = after_null_block; |
| 3811 | incoming_blocks[1] = after_ok_block; | 4152 | incoming_blocks[1] = after_ok_block; |
| 3812 | 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); |
| 3813 | } | 4155 | } |
| 3814 | | 4156 | |
| 3815 | 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) { |
| ... | @@ -3829,7 +4171,7 @@ static IrInstruction *ir_gen_error_union(IrBuilder *irb, Scope *parent_scope, As | ... | @@ -3829,7 +4171,7 @@ static IrInstruction *ir_gen_error_union(IrBuilder *irb, Scope *parent_scope, As |
| 3829 | 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); |
| 3830 | } | 4172 | } |
| 3831 | | 4173 | |
| 3832 | 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) { |
| 3833 | assert(node->type == NodeTypeBinOpExpr); | 4175 | assert(node->type == NodeTypeBinOpExpr); |
| 3834 | | 4176 | |
| 3835 | BinOpType bin_op_type = node->data.bin_op_expr.bin_op; | 4177 | BinOpType bin_op_type = node->data.bin_op_expr.bin_op; |
| ... | @@ -3837,87 +4179,87 @@ static IrInstruction *ir_gen_bin_op(IrBuilder *irb, Scope *scope, AstNode *node) | ... | @@ -3837,87 +4179,87 @@ static IrInstruction *ir_gen_bin_op(IrBuilder *irb, Scope *scope, AstNode *node) |
| 3837 | case BinOpTypeInvalid: | 4179 | case BinOpTypeInvalid: |
| 3838 | zig_unreachable(); | 4180 | zig_unreachable(); |
| 3839 | case BinOpTypeAssign: | 4181 | case BinOpTypeAssign: |
| 3840 | return ir_gen_assign(irb, scope, node); | 4182 | return ir_lval_wrap(irb, scope, ir_gen_assign(irb, scope, node), lval, result_loc); |
| 3841 | case BinOpTypeAssignTimes: | 4183 | case BinOpTypeAssignTimes: |
| 3842 | 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); |
| 3843 | case BinOpTypeAssignTimesWrap: | 4185 | case BinOpTypeAssignTimesWrap: |
| 3844 | 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); |
| 3845 | case BinOpTypeAssignDiv: | 4187 | case BinOpTypeAssignDiv: |
| 3846 | 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); |
| 3847 | case BinOpTypeAssignMod: | 4189 | case BinOpTypeAssignMod: |
| 3848 | 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); |
| 3849 | case BinOpTypeAssignPlus: | 4191 | case BinOpTypeAssignPlus: |
| 3850 | 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); |
| 3851 | case BinOpTypeAssignPlusWrap: | 4193 | case BinOpTypeAssignPlusWrap: |
| 3852 | 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); |
| 3853 | case BinOpTypeAssignMinus: | 4195 | case BinOpTypeAssignMinus: |
| 3854 | 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); |
| 3855 | case BinOpTypeAssignMinusWrap: | 4197 | case BinOpTypeAssignMinusWrap: |
| 3856 | 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); |
| 3857 | case BinOpTypeAssignBitShiftLeft: | 4199 | case BinOpTypeAssignBitShiftLeft: |
| 3858 | 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); |
| 3859 | case BinOpTypeAssignBitShiftRight: | 4201 | case BinOpTypeAssignBitShiftRight: |
| 3860 | 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); |
| 3861 | case BinOpTypeAssignBitAnd: | 4203 | case BinOpTypeAssignBitAnd: |
| 3862 | 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); |
| 3863 | case BinOpTypeAssignBitXor: | 4205 | case BinOpTypeAssignBitXor: |
| 3864 | 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); |
| 3865 | case BinOpTypeAssignBitOr: | 4207 | case BinOpTypeAssignBitOr: |
| 3866 | 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); |
| 3867 | case BinOpTypeAssignMergeErrorSets: | 4209 | case BinOpTypeAssignMergeErrorSets: |
| 3868 | 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); |
| 3869 | case BinOpTypeBoolOr: | 4211 | case BinOpTypeBoolOr: |
| 3870 | 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); |
| 3871 | case BinOpTypeBoolAnd: | 4213 | case BinOpTypeBoolAnd: |
| 3872 | 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); |
| 3873 | case BinOpTypeCmpEq: | 4215 | case BinOpTypeCmpEq: |
| 3874 | 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); |
| 3875 | case BinOpTypeCmpNotEq: | 4217 | case BinOpTypeCmpNotEq: |
| 3876 | 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); |
| 3877 | case BinOpTypeCmpLessThan: | 4219 | case BinOpTypeCmpLessThan: |
| 3878 | 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); |
| 3879 | case BinOpTypeCmpGreaterThan: | 4221 | case BinOpTypeCmpGreaterThan: |
| 3880 | 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); |
| 3881 | case BinOpTypeCmpLessOrEq: | 4223 | case BinOpTypeCmpLessOrEq: |
| 3882 | 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); |
| 3883 | case BinOpTypeCmpGreaterOrEq: | 4225 | case BinOpTypeCmpGreaterOrEq: |
| 3884 | 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); |
| 3885 | case BinOpTypeBinOr: | 4227 | case BinOpTypeBinOr: |
| 3886 | 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); |
| 3887 | case BinOpTypeBinXor: | 4229 | case BinOpTypeBinXor: |
| 3888 | 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); |
| 3889 | case BinOpTypeBinAnd: | 4231 | case BinOpTypeBinAnd: |
| 3890 | 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); |
| 3891 | case BinOpTypeBitShiftLeft: | 4233 | case BinOpTypeBitShiftLeft: |
| 3892 | 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); |
| 3893 | case BinOpTypeBitShiftRight: | 4235 | case BinOpTypeBitShiftRight: |
| 3894 | 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); |
| 3895 | case BinOpTypeAdd: | 4237 | case BinOpTypeAdd: |
| 3896 | 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); |
| 3897 | case BinOpTypeAddWrap: | 4239 | case BinOpTypeAddWrap: |
| 3898 | 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); |
| 3899 | case BinOpTypeSub: | 4241 | case BinOpTypeSub: |
| 3900 | 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); |
| 3901 | case BinOpTypeSubWrap: | 4243 | case BinOpTypeSubWrap: |
| 3902 | 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); |
| 3903 | case BinOpTypeMult: | 4245 | case BinOpTypeMult: |
| 3904 | 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); |
| 3905 | case BinOpTypeMultWrap: | 4247 | case BinOpTypeMultWrap: |
| 3906 | 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); |
| 3907 | case BinOpTypeDiv: | 4249 | case BinOpTypeDiv: |
| 3908 | 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); |
| 3909 | case BinOpTypeMod: | 4251 | case BinOpTypeMod: |
| 3910 | 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); |
| 3911 | case BinOpTypeArrayCat: | 4253 | case BinOpTypeArrayCat: |
| 3912 | 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); |
| 3913 | case BinOpTypeArrayMult: | 4255 | case BinOpTypeArrayMult: |
| 3914 | 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); |
| 3915 | case BinOpTypeMergeErrorSets: | 4257 | case BinOpTypeMergeErrorSets: |
| 3916 | 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); |
| 3917 | case BinOpTypeUnwrapOptional: | 4259 | case BinOpTypeUnwrapOptional: |
| 3918 | return ir_gen_orelse(irb, scope, node); | 4260 | return ir_gen_orelse(irb, scope, node, lval, result_loc); |
| 3919 | case BinOpTypeErrorUnion: | 4261 | case BinOpTypeErrorUnion: |
| 3920 | 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); |
| 3921 | } | 4263 | } |
| 3922 | zig_unreachable(); | 4264 | zig_unreachable(); |
| 3923 | } | 4265 | } |
| ... | @@ -3962,12 +4304,12 @@ static void populate_invalid_variable_in_scope(CodeGen *g, Scope *scope, AstNode | ... | @@ -3962,12 +4304,12 @@ static void populate_invalid_variable_in_scope(CodeGen *g, Scope *scope, AstNode |
| 3962 | TldVar *tld_var = allocate<TldVar>(1); | 4304 | TldVar *tld_var = allocate<TldVar>(1); |
| 3963 | 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); |
| 3964 | tld_var->base.resolution = TldResolutionInvalid; | 4306 | tld_var->base.resolution = TldResolutionInvalid; |
| 3965 | 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, |
| 3966 | &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); |
| 3967 | scope_decls->decl_table.put(var_name, &tld_var->base); | 4309 | scope_decls->decl_table.put(var_name, &tld_var->base); |
| 3968 | } | 4310 | } |
| 3969 | | 4311 | |
| 3970 | 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) { |
| 3971 | Error err; | 4313 | Error err; |
| 3972 | assert(node->type == NodeTypeSymbol); | 4314 | assert(node->type == NodeTypeSymbol); |
| 3973 | | 4315 | |
| ... | @@ -4001,7 +4343,7 @@ static IrInstruction *ir_gen_symbol(IrBuilder *irb, Scope *scope, AstNode *node, | ... | @@ -4001,7 +4343,7 @@ static IrInstruction *ir_gen_symbol(IrBuilder *irb, Scope *scope, AstNode *node, |
| 4001 | if (lval == LValPtr) { | 4343 | if (lval == LValPtr) { |
| 4002 | return ir_build_ref(irb, scope, node, value, false, false); | 4344 | return ir_build_ref(irb, scope, node, value, false, false); |
| 4003 | } else { | 4345 | } else { |
| 4004 | return value; | 4346 | return ir_expr_wrap(irb, scope, value, result_loc); |
| 4005 | } | 4347 | } |
| 4006 | } | 4348 | } |
| 4007 | | 4349 | |
| ... | @@ -4009,15 +4351,22 @@ static IrInstruction *ir_gen_symbol(IrBuilder *irb, Scope *scope, AstNode *node, | ... | @@ -4009,15 +4351,22 @@ static IrInstruction *ir_gen_symbol(IrBuilder *irb, Scope *scope, AstNode *node, |
| 4009 | 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); |
| 4010 | if (var) { | 4352 | if (var) { |
| 4011 | 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); |
| 4012 | if (lval == LValPtr) | 4354 | if (lval == LValPtr) { |
| 4013 | return var_ptr; | 4355 | return var_ptr; |
| 4014 | else | 4356 | } else { |
| 4015 | 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 | } |
| 4016 | } | 4359 | } |
| 4017 | | 4360 | |
| 4018 | Tld *tld = find_decl(irb->codegen, scope, variable_name); | 4361 | Tld *tld = find_decl(irb->codegen, scope, variable_name); |
| 4019 | if (tld) | 4362 | if (tld) { |
| 4020 | 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 | } |
| 4021 | | 4370 | |
| 4022 | if (get_container_scope(node->owner)->any_imports_failed) { | 4371 | if (get_container_scope(node->owner)->any_imports_failed) { |
| 4023 | // 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 |
| ... | @@ -4028,11 +4377,13 @@ static IrInstruction *ir_gen_symbol(IrBuilder *irb, Scope *scope, AstNode *node, | ... | @@ -4028,11 +4377,13 @@ static IrInstruction *ir_gen_symbol(IrBuilder *irb, Scope *scope, AstNode *node, |
| 4028 | return ir_build_undeclared_identifier(irb, scope, node, variable_name); | 4377 | return ir_build_undeclared_identifier(irb, scope, node, variable_name); |
| 4029 | } | 4378 | } |
| 4030 | | 4379 | |
| 4031 | 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 | { |
| 4032 | assert(node->type == NodeTypeArrayAccessExpr); | 4383 | assert(node->type == NodeTypeArrayAccessExpr); |
| 4033 | | 4384 | |
| 4034 | 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; |
| 4035 | 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); |
| 4036 | if (array_ref_instruction == irb->codegen->invalid_instruction) | 4387 | if (array_ref_instruction == irb->codegen->invalid_instruction) |
| 4037 | return array_ref_instruction; | 4388 | return array_ref_instruction; |
| 4038 | | 4389 | |
| ... | @@ -4042,11 +4393,12 @@ static IrInstruction *ir_gen_array_access(IrBuilder *irb, Scope *scope, AstNode | ... | @@ -4042,11 +4393,12 @@ static IrInstruction *ir_gen_array_access(IrBuilder *irb, Scope *scope, AstNode |
| 4042 | return subscript_instruction; | 4393 | return subscript_instruction; |
| 4043 | | 4394 | |
| 4044 | 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, |
| 4045 | subscript_instruction, true, PtrLenSingle); | 4396 | subscript_instruction, true, PtrLenSingle, nullptr); |
| 4046 | if (lval == LValPtr) | 4397 | if (lval == LValPtr) |
| 4047 | return ptr_instruction; | 4398 | return ptr_instruction; |
| 4048 | | 4399 | |
| 4049 | 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); |
| 4050 | } | 4402 | } |
| 4051 | | 4403 | |
| 4052 | 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) { |
| ... | @@ -4055,11 +4407,11 @@ static IrInstruction *ir_gen_field_access(IrBuilder *irb, Scope *scope, AstNode | ... | @@ -4055,11 +4407,11 @@ static IrInstruction *ir_gen_field_access(IrBuilder *irb, Scope *scope, AstNode |
| 4055 | AstNode *container_ref_node = node->data.field_access_expr.struct_expr; | 4407 | AstNode *container_ref_node = node->data.field_access_expr.struct_expr; |
| 4056 | Buf *field_name = node->data.field_access_expr.field_name; | 4408 | Buf *field_name = node->data.field_access_expr.field_name; |
| 4057 | | 4409 | |
| 4058 | 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); |
| 4059 | if (container_ref_instruction == irb->codegen->invalid_instruction) | 4411 | if (container_ref_instruction == irb->codegen->invalid_instruction) |
| 4060 | return container_ref_instruction; | 4412 | return container_ref_instruction; |
| 4061 | | 4413 | |
| 4062 | 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); |
| 4063 | } | 4415 | } |
| 4064 | | 4416 | |
| 4065 | 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) { |
| ... | @@ -4132,7 +4484,9 @@ static IrInstruction *ir_gen_this(IrBuilder *irb, Scope *orig_scope, AstNode *no | ... | @@ -4132,7 +4484,9 @@ static IrInstruction *ir_gen_this(IrBuilder *irb, Scope *orig_scope, AstNode *no |
| 4132 | zig_unreachable(); | 4484 | zig_unreachable(); |
| 4133 | } | 4485 | } |
| 4134 | | 4486 | |
| 4135 | 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 | { |
| 4136 | assert(node->type == NodeTypeFnCallExpr); | 4490 | assert(node->type == NodeTypeFnCallExpr); |
| 4137 | | 4491 | |
| 4138 | 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; |
| ... | @@ -4168,7 +4522,7 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo | ... | @@ -4168,7 +4522,7 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo |
| 4168 | return arg; | 4522 | return arg; |
| 4169 | | 4523 | |
| 4170 | IrInstruction *type_of = ir_build_typeof(irb, scope, node, arg); | 4524 | IrInstruction *type_of = ir_build_typeof(irb, scope, node, arg); |
| 4171 | return ir_lval_wrap(irb, scope, type_of, lval); | 4525 | return ir_lval_wrap(irb, scope, type_of, lval, result_loc); |
| 4172 | } | 4526 | } |
| 4173 | case BuiltinFnIdSetCold: | 4527 | case BuiltinFnIdSetCold: |
| 4174 | { | 4528 | { |
| ... | @@ -4178,7 +4532,7 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo | ... | @@ -4178,7 +4532,7 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo |
| 4178 | return arg0_value; | 4532 | return arg0_value; |
| 4179 | | 4533 | |
| 4180 | 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); |
| 4181 | return ir_lval_wrap(irb, scope, set_cold, lval); | 4535 | return ir_lval_wrap(irb, scope, set_cold, lval, result_loc); |
| 4182 | } | 4536 | } |
| 4183 | case BuiltinFnIdSetRuntimeSafety: | 4537 | case BuiltinFnIdSetRuntimeSafety: |
| 4184 | { | 4538 | { |
| ... | @@ -4188,7 +4542,7 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo | ... | @@ -4188,7 +4542,7 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo |
| 4188 | return arg0_value; | 4542 | return arg0_value; |
| 4189 | | 4543 | |
| 4190 | 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); |
| 4191 | return ir_lval_wrap(irb, scope, set_safety, lval); | 4545 | return ir_lval_wrap(irb, scope, set_safety, lval, result_loc); |
| 4192 | } | 4546 | } |
| 4193 | case BuiltinFnIdSetFloatMode: | 4547 | case BuiltinFnIdSetFloatMode: |
| 4194 | { | 4548 | { |
| ... | @@ -4198,7 +4552,7 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo | ... | @@ -4198,7 +4552,7 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo |
| 4198 | return arg0_value; | 4552 | return arg0_value; |
| 4199 | | 4553 | |
| 4200 | 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); |
| 4201 | return ir_lval_wrap(irb, scope, set_float_mode, lval); | 4555 | return ir_lval_wrap(irb, scope, set_float_mode, lval, result_loc); |
| 4202 | } | 4556 | } |
| 4203 | case BuiltinFnIdSizeof: | 4557 | case BuiltinFnIdSizeof: |
| 4204 | { | 4558 | { |
| ... | @@ -4208,7 +4562,7 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo | ... | @@ -4208,7 +4562,7 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo |
| 4208 | return arg0_value; | 4562 | return arg0_value; |
| 4209 | | 4563 | |
| 4210 | 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); |
| 4211 | return ir_lval_wrap(irb, scope, size_of, lval); | 4565 | return ir_lval_wrap(irb, scope, size_of, lval, result_loc); |
| 4212 | } | 4566 | } |
| 4213 | case BuiltinFnIdImport: | 4567 | case BuiltinFnIdImport: |
| 4214 | { | 4568 | { |
| ... | @@ -4218,12 +4572,12 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo | ... | @@ -4218,12 +4572,12 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo |
| 4218 | return arg0_value; | 4572 | return arg0_value; |
| 4219 | | 4573 | |
| 4220 | IrInstruction *import = ir_build_import(irb, scope, node, arg0_value); | 4574 | IrInstruction *import = ir_build_import(irb, scope, node, arg0_value); |
| 4221 | return ir_lval_wrap(irb, scope, import, lval); | 4575 | return ir_lval_wrap(irb, scope, import, lval, result_loc); |
| 4222 | } | 4576 | } |
| 4223 | case BuiltinFnIdCImport: | 4577 | case BuiltinFnIdCImport: |
| 4224 | { | 4578 | { |
| 4225 | IrInstruction *c_import = ir_build_c_import(irb, scope, node); | 4579 | IrInstruction *c_import = ir_build_c_import(irb, scope, node); |
| 4226 | return ir_lval_wrap(irb, scope, c_import, lval); | 4580 | return ir_lval_wrap(irb, scope, c_import, lval, result_loc); |
| 4227 | } | 4581 | } |
| 4228 | case BuiltinFnIdCInclude: | 4582 | case BuiltinFnIdCInclude: |
| 4229 | { | 4583 | { |
| ... | @@ -4238,7 +4592,7 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo | ... | @@ -4238,7 +4592,7 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo |
| 4238 | } | 4592 | } |
| 4239 | | 4593 | |
| 4240 | 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); |
| 4241 | return ir_lval_wrap(irb, scope, c_include, lval); | 4595 | return ir_lval_wrap(irb, scope, c_include, lval, result_loc); |
| 4242 | } | 4596 | } |
| 4243 | case BuiltinFnIdCDefine: | 4597 | case BuiltinFnIdCDefine: |
| 4244 | { | 4598 | { |
| ... | @@ -4258,7 +4612,7 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo | ... | @@ -4258,7 +4612,7 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo |
| 4258 | } | 4612 | } |
| 4259 | | 4613 | |
| 4260 | 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); |
| 4261 | return ir_lval_wrap(irb, scope, c_define, lval); | 4615 | return ir_lval_wrap(irb, scope, c_define, lval, result_loc); |
| 4262 | } | 4616 | } |
| 4263 | case BuiltinFnIdCUndef: | 4617 | case BuiltinFnIdCUndef: |
| 4264 | { | 4618 | { |
| ... | @@ -4273,7 +4627,7 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo | ... | @@ -4273,7 +4627,7 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo |
| 4273 | } | 4627 | } |
| 4274 | | 4628 | |
| 4275 | 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); |
| 4276 | return ir_lval_wrap(irb, scope, c_undef, lval); | 4630 | return ir_lval_wrap(irb, scope, c_undef, lval, result_loc); |
| 4277 | } | 4631 | } |
| 4278 | case BuiltinFnIdCompileErr: | 4632 | case BuiltinFnIdCompileErr: |
| 4279 | { | 4633 | { |
| ... | @@ -4283,7 +4637,7 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo | ... | @@ -4283,7 +4637,7 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo |
| 4283 | return arg0_value; | 4637 | return arg0_value; |
| 4284 | | 4638 | |
| 4285 | 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); |
| 4286 | return ir_lval_wrap(irb, scope, compile_err, lval); | 4640 | return ir_lval_wrap(irb, scope, compile_err, lval, result_loc); |
| 4287 | } | 4641 | } |
| 4288 | case BuiltinFnIdCompileLog: | 4642 | case BuiltinFnIdCompileLog: |
| 4289 | { | 4643 | { |
| ... | @@ -4297,7 +4651,7 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo | ... | @@ -4297,7 +4651,7 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo |
| 4297 | } | 4651 | } |
| 4298 | | 4652 | |
| 4299 | 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); |
| 4300 | return ir_lval_wrap(irb, scope, compile_log, lval); | 4654 | return ir_lval_wrap(irb, scope, compile_log, lval, result_loc); |
| 4301 | } | 4655 | } |
| 4302 | case BuiltinFnIdErrName: | 4656 | case BuiltinFnIdErrName: |
| 4303 | { | 4657 | { |
| ... | @@ -4307,7 +4661,7 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo | ... | @@ -4307,7 +4661,7 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo |
| 4307 | return arg0_value; | 4661 | return arg0_value; |
| 4308 | | 4662 | |
| 4309 | 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); |
| 4310 | return ir_lval_wrap(irb, scope, err_name, lval); | 4664 | return ir_lval_wrap(irb, scope, err_name, lval, result_loc); |
| 4311 | } | 4665 | } |
| 4312 | case BuiltinFnIdEmbedFile: | 4666 | case BuiltinFnIdEmbedFile: |
| 4313 | { | 4667 | { |
| ... | @@ -4317,7 +4671,7 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo | ... | @@ -4317,7 +4671,7 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo |
| 4317 | return arg0_value; | 4671 | return arg0_value; |
| 4318 | | 4672 | |
| 4319 | 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); |
| 4320 | return ir_lval_wrap(irb, scope, embed_file, lval); | 4674 | return ir_lval_wrap(irb, scope, embed_file, lval, result_loc); |
| 4321 | } | 4675 | } |
| 4322 | case BuiltinFnIdCmpxchgWeak: | 4676 | case BuiltinFnIdCmpxchgWeak: |
| 4323 | case BuiltinFnIdCmpxchgStrong: | 4677 | case BuiltinFnIdCmpxchgStrong: |
| ... | @@ -4353,8 +4707,9 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo | ... | @@ -4353,8 +4707,9 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo |
| 4353 | return arg5_value; | 4707 | return arg5_value; |
| 4354 | | 4708 | |
| 4355 | 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, |
| 4356 | 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), |
| 4357 | return ir_lval_wrap(irb, scope, cmpxchg, lval); | 4711 | result_loc); |
| | 4712 | return ir_lval_wrap(irb, scope, cmpxchg, lval, result_loc); |
| 4358 | } | 4713 | } |
| 4359 | case BuiltinFnIdFence: | 4714 | case BuiltinFnIdFence: |
| 4360 | { | 4715 | { |
| ... | @@ -4364,7 +4719,7 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo | ... | @@ -4364,7 +4719,7 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo |
| 4364 | return arg0_value; | 4719 | return arg0_value; |
| 4365 | | 4720 | |
| 4366 | IrInstruction *fence = ir_build_fence(irb, scope, node, arg0_value, AtomicOrderUnordered); | 4721 | IrInstruction *fence = ir_build_fence(irb, scope, node, arg0_value, AtomicOrderUnordered); |
| 4367 | return ir_lval_wrap(irb, scope, fence, lval); | 4722 | return ir_lval_wrap(irb, scope, fence, lval, result_loc); |
| 4368 | } | 4723 | } |
| 4369 | case BuiltinFnIdDivExact: | 4724 | case BuiltinFnIdDivExact: |
| 4370 | { | 4725 | { |
| ... | @@ -4379,7 +4734,7 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo | ... | @@ -4379,7 +4734,7 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo |
| 4379 | return arg1_value; | 4734 | return arg1_value; |
| 4380 | | 4735 | |
| 4381 | 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); |
| 4382 | return ir_lval_wrap(irb, scope, bin_op, lval); | 4737 | return ir_lval_wrap(irb, scope, bin_op, lval, result_loc); |
| 4383 | } | 4738 | } |
| 4384 | case BuiltinFnIdDivTrunc: | 4739 | case BuiltinFnIdDivTrunc: |
| 4385 | { | 4740 | { |
| ... | @@ -4394,7 +4749,7 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo | ... | @@ -4394,7 +4749,7 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo |
| 4394 | return arg1_value; | 4749 | return arg1_value; |
| 4395 | | 4750 | |
| 4396 | 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); |
| 4397 | return ir_lval_wrap(irb, scope, bin_op, lval); | 4752 | return ir_lval_wrap(irb, scope, bin_op, lval, result_loc); |
| 4398 | } | 4753 | } |
| 4399 | case BuiltinFnIdDivFloor: | 4754 | case BuiltinFnIdDivFloor: |
| 4400 | { | 4755 | { |
| ... | @@ -4409,7 +4764,7 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo | ... | @@ -4409,7 +4764,7 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo |
| 4409 | return arg1_value; | 4764 | return arg1_value; |
| 4410 | | 4765 | |
| 4411 | 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); |
| 4412 | return ir_lval_wrap(irb, scope, bin_op, lval); | 4767 | return ir_lval_wrap(irb, scope, bin_op, lval, result_loc); |
| 4413 | } | 4768 | } |
| 4414 | case BuiltinFnIdRem: | 4769 | case BuiltinFnIdRem: |
| 4415 | { | 4770 | { |
| ... | @@ -4424,7 +4779,7 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo | ... | @@ -4424,7 +4779,7 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo |
| 4424 | return arg1_value; | 4779 | return arg1_value; |
| 4425 | | 4780 | |
| 4426 | 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); |
| 4427 | return ir_lval_wrap(irb, scope, bin_op, lval); | 4782 | return ir_lval_wrap(irb, scope, bin_op, lval, result_loc); |
| 4428 | } | 4783 | } |
| 4429 | case BuiltinFnIdMod: | 4784 | case BuiltinFnIdMod: |
| 4430 | { | 4785 | { |
| ... | @@ -4439,7 +4794,7 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo | ... | @@ -4439,7 +4794,7 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo |
| 4439 | return arg1_value; | 4794 | return arg1_value; |
| 4440 | | 4795 | |
| 4441 | 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); |
| 4442 | return ir_lval_wrap(irb, scope, bin_op, lval); | 4797 | return ir_lval_wrap(irb, scope, bin_op, lval, result_loc); |
| 4443 | } | 4798 | } |
| 4444 | case BuiltinFnIdSqrt: | 4799 | case BuiltinFnIdSqrt: |
| 4445 | case BuiltinFnIdSin: | 4800 | case BuiltinFnIdSin: |
| ... | @@ -4467,7 +4822,7 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo | ... | @@ -4467,7 +4822,7 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo |
| 4467 | return arg1_value; | 4822 | return arg1_value; |
| 4468 | | 4823 | |
| 4469 | IrInstruction *ir_sqrt = ir_build_float_op(irb, scope, node, arg0_value, arg1_value, builtin_fn->id); | 4824 | IrInstruction *ir_sqrt = ir_build_float_op(irb, scope, node, arg0_value, arg1_value, builtin_fn->id); |
| 4470 | return ir_lval_wrap(irb, scope, ir_sqrt, lval); | 4825 | return ir_lval_wrap(irb, scope, ir_sqrt, lval, result_loc); |
| 4471 | } | 4826 | } |
| 4472 | case BuiltinFnIdTruncate: | 4827 | case BuiltinFnIdTruncate: |
| 4473 | { | 4828 | { |
| ... | @@ -4482,7 +4837,7 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo | ... | @@ -4482,7 +4837,7 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo |
| 4482 | return arg1_value; | 4837 | return arg1_value; |
| 4483 | | 4838 | |
| 4484 | 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); |
| 4485 | return ir_lval_wrap(irb, scope, truncate, lval); | 4840 | return ir_lval_wrap(irb, scope, truncate, lval, result_loc); |
| 4486 | } | 4841 | } |
| 4487 | case BuiltinFnIdIntCast: | 4842 | case BuiltinFnIdIntCast: |
| 4488 | { | 4843 | { |
| ... | @@ -4497,7 +4852,7 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo | ... | @@ -4497,7 +4852,7 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo |
| 4497 | return arg1_value; | 4852 | return arg1_value; |
| 4498 | | 4853 | |
| 4499 | 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); |
| 4500 | return ir_lval_wrap(irb, scope, result, lval); | 4855 | return ir_lval_wrap(irb, scope, result, lval, result_loc); |
| 4501 | } | 4856 | } |
| 4502 | case BuiltinFnIdFloatCast: | 4857 | case BuiltinFnIdFloatCast: |
| 4503 | { | 4858 | { |
| ... | @@ -4512,7 +4867,7 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo | ... | @@ -4512,7 +4867,7 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo |
| 4512 | return arg1_value; | 4867 | return arg1_value; |
| 4513 | | 4868 | |
| 4514 | 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); |
| 4515 | return ir_lval_wrap(irb, scope, result, lval); | 4870 | return ir_lval_wrap(irb, scope, result, lval, result_loc); |
| 4516 | } | 4871 | } |
| 4517 | case BuiltinFnIdErrSetCast: | 4872 | case BuiltinFnIdErrSetCast: |
| 4518 | { | 4873 | { |
| ... | @@ -4527,7 +4882,7 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo | ... | @@ -4527,7 +4882,7 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo |
| 4527 | return arg1_value; | 4882 | return arg1_value; |
| 4528 | | 4883 | |
| 4529 | 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); |
| 4530 | return ir_lval_wrap(irb, scope, result, lval); | 4885 | return ir_lval_wrap(irb, scope, result, lval, result_loc); |
| 4531 | } | 4886 | } |
| 4532 | case BuiltinFnIdFromBytes: | 4887 | case BuiltinFnIdFromBytes: |
| 4533 | { | 4888 | { |
| ... | @@ -4541,8 +4896,8 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo | ... | @@ -4541,8 +4896,8 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo |
| 4541 | if (arg1_value == irb->codegen->invalid_instruction) | 4896 | if (arg1_value == irb->codegen->invalid_instruction) |
| 4542 | return arg1_value; | 4897 | return arg1_value; |
| 4543 | | 4898 | |
| 4544 | 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); |
| 4545 | return ir_lval_wrap(irb, scope, result, lval); | 4900 | return ir_lval_wrap(irb, scope, result, lval, result_loc); |
| 4546 | } | 4901 | } |
| 4547 | case BuiltinFnIdToBytes: | 4902 | case BuiltinFnIdToBytes: |
| 4548 | { | 4903 | { |
| ... | @@ -4551,8 +4906,8 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo | ... | @@ -4551,8 +4906,8 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo |
| 4551 | if (arg0_value == irb->codegen->invalid_instruction) | 4906 | if (arg0_value == irb->codegen->invalid_instruction) |
| 4552 | return arg0_value; | 4907 | return arg0_value; |
| 4553 | | 4908 | |
| 4554 | 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); |
| 4555 | return ir_lval_wrap(irb, scope, result, lval); | 4910 | return ir_lval_wrap(irb, scope, result, lval, result_loc); |
| 4556 | } | 4911 | } |
| 4557 | case BuiltinFnIdIntToFloat: | 4912 | case BuiltinFnIdIntToFloat: |
| 4558 | { | 4913 | { |
| ... | @@ -4567,7 +4922,7 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo | ... | @@ -4567,7 +4922,7 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo |
| 4567 | return arg1_value; | 4922 | return arg1_value; |
| 4568 | | 4923 | |
| 4569 | 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); |
| 4570 | return ir_lval_wrap(irb, scope, result, lval); | 4925 | return ir_lval_wrap(irb, scope, result, lval, result_loc); |
| 4571 | } | 4926 | } |
| 4572 | case BuiltinFnIdFloatToInt: | 4927 | case BuiltinFnIdFloatToInt: |
| 4573 | { | 4928 | { |
| ... | @@ -4582,7 +4937,7 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo | ... | @@ -4582,7 +4937,7 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo |
| 4582 | return arg1_value; | 4937 | return arg1_value; |
| 4583 | | 4938 | |
| 4584 | 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); |
| 4585 | return ir_lval_wrap(irb, scope, result, lval); | 4940 | return ir_lval_wrap(irb, scope, result, lval, result_loc); |
| 4586 | } | 4941 | } |
| 4587 | case BuiltinFnIdErrToInt: | 4942 | case BuiltinFnIdErrToInt: |
| 4588 | { | 4943 | { |
| ... | @@ -4592,7 +4947,7 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo | ... | @@ -4592,7 +4947,7 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo |
| 4592 | return arg0_value; | 4947 | return arg0_value; |
| 4593 | | 4948 | |
| 4594 | 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); |
| 4595 | return ir_lval_wrap(irb, scope, result, lval); | 4950 | return ir_lval_wrap(irb, scope, result, lval, result_loc); |
| 4596 | } | 4951 | } |
| 4597 | case BuiltinFnIdIntToErr: | 4952 | case BuiltinFnIdIntToErr: |
| 4598 | { | 4953 | { |
| ... | @@ -4602,7 +4957,7 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo | ... | @@ -4602,7 +4957,7 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo |
| 4602 | return arg0_value; | 4957 | return arg0_value; |
| 4603 | | 4958 | |
| 4604 | 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); |
| 4605 | return ir_lval_wrap(irb, scope, result, lval); | 4960 | return ir_lval_wrap(irb, scope, result, lval, result_loc); |
| 4606 | } | 4961 | } |
| 4607 | case BuiltinFnIdBoolToInt: | 4962 | case BuiltinFnIdBoolToInt: |
| 4608 | { | 4963 | { |
| ... | @@ -4612,7 +4967,7 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo | ... | @@ -4612,7 +4967,7 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo |
| 4612 | return arg0_value; | 4967 | return arg0_value; |
| 4613 | | 4968 | |
| 4614 | 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); |
| 4615 | return ir_lval_wrap(irb, scope, result, lval); | 4970 | return ir_lval_wrap(irb, scope, result, lval, result_loc); |
| 4616 | } | 4971 | } |
| 4617 | case BuiltinFnIdIntType: | 4972 | case BuiltinFnIdIntType: |
| 4618 | { | 4973 | { |
| ... | @@ -4627,7 +4982,7 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo | ... | @@ -4627,7 +4982,7 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo |
| 4627 | return arg1_value; | 4982 | return arg1_value; |
| 4628 | | 4983 | |
| 4629 | 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); |
| 4630 | return ir_lval_wrap(irb, scope, int_type, lval); | 4985 | return ir_lval_wrap(irb, scope, int_type, lval, result_loc); |
| 4631 | } | 4986 | } |
| 4632 | case BuiltinFnIdVectorType: | 4987 | case BuiltinFnIdVectorType: |
| 4633 | { | 4988 | { |
| ... | @@ -4642,7 +4997,7 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo | ... | @@ -4642,7 +4997,7 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo |
| 4642 | return arg1_value; | 4997 | return arg1_value; |
| 4643 | | 4998 | |
| 4644 | 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); |
| 4645 | return ir_lval_wrap(irb, scope, vector_type, lval); | 5000 | return ir_lval_wrap(irb, scope, vector_type, lval, result_loc); |
| 4646 | } | 5001 | } |
| 4647 | case BuiltinFnIdMemcpy: | 5002 | case BuiltinFnIdMemcpy: |
| 4648 | { | 5003 | { |
| ... | @@ -4662,7 +5017,7 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo | ... | @@ -4662,7 +5017,7 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo |
| 4662 | return arg2_value; | 5017 | return arg2_value; |
| 4663 | | 5018 | |
| 4664 | 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); |
| 4665 | return ir_lval_wrap(irb, scope, ir_memcpy, lval); | 5020 | return ir_lval_wrap(irb, scope, ir_memcpy, lval, result_loc); |
| 4666 | } | 5021 | } |
| 4667 | case BuiltinFnIdMemset: | 5022 | case BuiltinFnIdMemset: |
| 4668 | { | 5023 | { |
| ... | @@ -4682,7 +5037,7 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo | ... | @@ -4682,7 +5037,7 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo |
| 4682 | return arg2_value; | 5037 | return arg2_value; |
| 4683 | | 5038 | |
| 4684 | 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); |
| 4685 | return ir_lval_wrap(irb, scope, ir_memset, lval); | 5040 | return ir_lval_wrap(irb, scope, ir_memset, lval, result_loc); |
| 4686 | } | 5041 | } |
| 4687 | case BuiltinFnIdMemberCount: | 5042 | case BuiltinFnIdMemberCount: |
| 4688 | { | 5043 | { |
| ... | @@ -4692,7 +5047,7 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo | ... | @@ -4692,7 +5047,7 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo |
| 4692 | return arg0_value; | 5047 | return arg0_value; |
| 4693 | | 5048 | |
| 4694 | 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); |
| 4695 | return ir_lval_wrap(irb, scope, member_count, lval); | 5050 | return ir_lval_wrap(irb, scope, member_count, lval, result_loc); |
| 4696 | } | 5051 | } |
| 4697 | case BuiltinFnIdMemberType: | 5052 | case BuiltinFnIdMemberType: |
| 4698 | { | 5053 | { |
| ... | @@ -4708,7 +5063,7 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo | ... | @@ -4708,7 +5063,7 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo |
| 4708 | | 5063 | |
| 4709 | | 5064 | |
| 4710 | 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); |
| 4711 | return ir_lval_wrap(irb, scope, member_type, lval); | 5066 | return ir_lval_wrap(irb, scope, member_type, lval, result_loc); |
| 4712 | } | 5067 | } |
| 4713 | case BuiltinFnIdMemberName: | 5068 | case BuiltinFnIdMemberName: |
| 4714 | { | 5069 | { |
| ... | @@ -4724,12 +5079,12 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo | ... | @@ -4724,12 +5079,12 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo |
| 4724 | | 5079 | |
| 4725 | | 5080 | |
| 4726 | 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); |
| 4727 | return ir_lval_wrap(irb, scope, member_name, lval); | 5082 | return ir_lval_wrap(irb, scope, member_name, lval, result_loc); |
| 4728 | } | 5083 | } |
| 4729 | case BuiltinFnIdField: | 5084 | case BuiltinFnIdField: |
| 4730 | { | 5085 | { |
| 4731 | AstNode *arg0_node = node->data.fn_call_expr.params.at(0); | 5086 | AstNode *arg0_node = node->data.fn_call_expr.params.at(0); |
| 4732 | 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); |
| 4733 | if (arg0_value == irb->codegen->invalid_instruction) | 5088 | if (arg0_value == irb->codegen->invalid_instruction) |
| 4734 | return arg0_value; | 5089 | return arg0_value; |
| 4735 | | 5090 | |
| ... | @@ -4743,7 +5098,8 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo | ... | @@ -4743,7 +5098,8 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo |
| 4743 | if (lval == LValPtr) | 5098 | if (lval == LValPtr) |
| 4744 | return ptr_instruction; | 5099 | return ptr_instruction; |
| 4745 | | 5100 | |
| 4746 | 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); |
| 4747 | } | 5103 | } |
| 4748 | case BuiltinFnIdTypeInfo: | 5104 | case BuiltinFnIdTypeInfo: |
| 4749 | { | 5105 | { |
| ... | @@ -4753,14 +5109,14 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo | ... | @@ -4753,14 +5109,14 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo |
| 4753 | return arg0_value; | 5109 | return arg0_value; |
| 4754 | | 5110 | |
| 4755 | 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); |
| 4756 | return ir_lval_wrap(irb, scope, type_info, lval); | 5112 | return ir_lval_wrap(irb, scope, type_info, lval, result_loc); |
| 4757 | } | 5113 | } |
| 4758 | case BuiltinFnIdBreakpoint: | 5114 | case BuiltinFnIdBreakpoint: |
| 4759 | 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); |
| 4760 | case BuiltinFnIdReturnAddress: | 5116 | case BuiltinFnIdReturnAddress: |
| 4761 | 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); |
| 4762 | case BuiltinFnIdFrameAddress: | 5118 | case BuiltinFnIdFrameAddress: |
| 4763 | 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); |
| 4764 | case BuiltinFnIdHandle: | 5120 | case BuiltinFnIdHandle: |
| 4765 | if (!irb->exec->fn_entry) { | 5121 | if (!irb->exec->fn_entry) { |
| 4766 | 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")); |
| ... | @@ -4770,7 +5126,7 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo | ... | @@ -4770,7 +5126,7 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo |
| 4770 | 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")); |
| 4771 | return irb->codegen->invalid_instruction; | 5127 | return irb->codegen->invalid_instruction; |
| 4772 | } | 5128 | } |
| 4773 | 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); |
| 4774 | case BuiltinFnIdAlignOf: | 5130 | case BuiltinFnIdAlignOf: |
| 4775 | { | 5131 | { |
| 4776 | AstNode *arg0_node = node->data.fn_call_expr.params.at(0); | 5132 | AstNode *arg0_node = node->data.fn_call_expr.params.at(0); |
| ... | @@ -4779,18 +5135,18 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo | ... | @@ -4779,18 +5135,18 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo |
| 4779 | return arg0_value; | 5135 | return arg0_value; |
| 4780 | | 5136 | |
| 4781 | 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); |
| 4782 | return ir_lval_wrap(irb, scope, align_of, lval); | 5138 | return ir_lval_wrap(irb, scope, align_of, lval, result_loc); |
| 4783 | } | 5139 | } |
| 4784 | case BuiltinFnIdAddWithOverflow: | 5140 | case BuiltinFnIdAddWithOverflow: |
| 4785 | 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); |
| 4786 | case BuiltinFnIdSubWithOverflow: | 5142 | case BuiltinFnIdSubWithOverflow: |
| 4787 | 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); |
| 4788 | case BuiltinFnIdMulWithOverflow: | 5144 | case BuiltinFnIdMulWithOverflow: |
| 4789 | 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); |
| 4790 | case BuiltinFnIdShlWithOverflow: | 5146 | case BuiltinFnIdShlWithOverflow: |
| 4791 | 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); |
| 4792 | case BuiltinFnIdMulAdd: | 5148 | case BuiltinFnIdMulAdd: |
| 4793 | return ir_lval_wrap(irb, scope, ir_gen_mul_add(irb, scope, node), lval); | 5149 | return ir_lval_wrap(irb, scope, ir_gen_mul_add(irb, scope, node), lval, result_loc); |
| 4794 | case BuiltinFnIdTypeName: | 5150 | case BuiltinFnIdTypeName: |
| 4795 | { | 5151 | { |
| 4796 | AstNode *arg0_node = node->data.fn_call_expr.params.at(0); | 5152 | AstNode *arg0_node = node->data.fn_call_expr.params.at(0); |
| ... | @@ -4799,7 +5155,7 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo | ... | @@ -4799,7 +5155,7 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo |
| 4799 | return arg0_value; | 5155 | return arg0_value; |
| 4800 | | 5156 | |
| 4801 | 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); |
| 4802 | return ir_lval_wrap(irb, scope, type_name, lval); | 5158 | return ir_lval_wrap(irb, scope, type_name, lval, result_loc); |
| 4803 | } | 5159 | } |
| 4804 | case BuiltinFnIdPanic: | 5160 | case BuiltinFnIdPanic: |
| 4805 | { | 5161 | { |
| ... | @@ -4809,7 +5165,7 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo | ... | @@ -4809,7 +5165,7 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo |
| 4809 | return arg0_value; | 5165 | return arg0_value; |
| 4810 | | 5166 | |
| 4811 | IrInstruction *panic = ir_build_panic(irb, scope, node, arg0_value); | 5167 | IrInstruction *panic = ir_build_panic(irb, scope, node, arg0_value); |
| 4812 | return ir_lval_wrap(irb, scope, panic, lval); | 5168 | return ir_lval_wrap(irb, scope, panic, lval, result_loc); |
| 4813 | } | 5169 | } |
| 4814 | case BuiltinFnIdPtrCast: | 5170 | case BuiltinFnIdPtrCast: |
| 4815 | { | 5171 | { |
| ... | @@ -4824,22 +5180,31 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo | ... | @@ -4824,22 +5180,31 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo |
| 4824 | return arg1_value; | 5180 | return arg1_value; |
| 4825 | | 5181 | |
| 4826 | 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); |
| 4827 | return ir_lval_wrap(irb, scope, ptr_cast, lval); | 5183 | return ir_lval_wrap(irb, scope, ptr_cast, lval, result_loc); |
| 4828 | } | 5184 | } |
| 4829 | case BuiltinFnIdBitCast: | 5185 | case BuiltinFnIdBitCast: |
| 4830 | { | 5186 | { |
| 4831 | AstNode *arg0_node = node->data.fn_call_expr.params.at(0); | 5187 | AstNode *dest_type_node = node->data.fn_call_expr.params.at(0); |
| 4832 | IrInstruction *arg0_value = ir_gen_node(irb, arg0_node, scope); | 5188 | IrInstruction *dest_type = ir_gen_node(irb, dest_type_node, scope); |
| 4833 | if (arg0_value == irb->codegen->invalid_instruction) | 5189 | if (dest_type == irb->codegen->invalid_instruction) |
| 4834 | 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); |
| 4835 | | 5199 | |
| 4836 | AstNode *arg1_node = node->data.fn_call_expr.params.at(1); | 5200 | AstNode *arg1_node = node->data.fn_call_expr.params.at(1); |
| 4837 | 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); |
| 4838 | if (arg1_value == irb->codegen->invalid_instruction) | 5203 | if (arg1_value == irb->codegen->invalid_instruction) |
| 4839 | return arg1_value; | 5204 | return arg1_value; |
| 4840 | | 5205 | |
| 4841 | 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); |
| 4842 | return ir_lval_wrap(irb, scope, bit_cast, lval); | 5207 | return ir_lval_wrap(irb, scope, bitcast, lval, result_loc); |
| 4843 | } | 5208 | } |
| 4844 | case BuiltinFnIdIntToPtr: | 5209 | case BuiltinFnIdIntToPtr: |
| 4845 | { | 5210 | { |
| ... | @@ -4854,7 +5219,7 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo | ... | @@ -4854,7 +5219,7 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo |
| 4854 | return arg1_value; | 5219 | return arg1_value; |
| 4855 | | 5220 | |
| 4856 | 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); |
| 4857 | return ir_lval_wrap(irb, scope, int_to_ptr, lval); | 5222 | return ir_lval_wrap(irb, scope, int_to_ptr, lval, result_loc); |
| 4858 | } | 5223 | } |
| 4859 | case BuiltinFnIdPtrToInt: | 5224 | case BuiltinFnIdPtrToInt: |
| 4860 | { | 5225 | { |
| ... | @@ -4864,7 +5229,7 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo | ... | @@ -4864,7 +5229,7 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo |
| 4864 | return arg0_value; | 5229 | return arg0_value; |
| 4865 | | 5230 | |
| 4866 | 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); |
| 4867 | return ir_lval_wrap(irb, scope, ptr_to_int, lval); | 5232 | return ir_lval_wrap(irb, scope, ptr_to_int, lval, result_loc); |
| 4868 | } | 5233 | } |
| 4869 | case BuiltinFnIdTagName: | 5234 | case BuiltinFnIdTagName: |
| 4870 | { | 5235 | { |
| ... | @@ -4875,7 +5240,7 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo | ... | @@ -4875,7 +5240,7 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo |
| 4875 | | 5240 | |
| 4876 | 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); |
| 4877 | 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); |
| 4878 | return ir_lval_wrap(irb, scope, tag_name, lval); | 5243 | return ir_lval_wrap(irb, scope, tag_name, lval, result_loc); |
| 4879 | } | 5244 | } |
| 4880 | case BuiltinFnIdTagType: | 5245 | case BuiltinFnIdTagType: |
| 4881 | { | 5246 | { |
| ... | @@ -4885,7 +5250,7 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo | ... | @@ -4885,7 +5250,7 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo |
| 4885 | return arg0_value; | 5250 | return arg0_value; |
| 4886 | | 5251 | |
| 4887 | 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); |
| 4888 | return ir_lval_wrap(irb, scope, tag_type, lval); | 5253 | return ir_lval_wrap(irb, scope, tag_type, lval, result_loc); |
| 4889 | } | 5254 | } |
| 4890 | case BuiltinFnIdFieldParentPtr: | 5255 | case BuiltinFnIdFieldParentPtr: |
| 4891 | { | 5256 | { |
| ... | @@ -4905,7 +5270,7 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo | ... | @@ -4905,7 +5270,7 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo |
| 4905 | return arg2_value; | 5270 | return arg2_value; |
| 4906 | | 5271 | |
| 4907 | 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); |
| 4908 | return ir_lval_wrap(irb, scope, field_parent_ptr, lval); | 5273 | return ir_lval_wrap(irb, scope, field_parent_ptr, lval, result_loc); |
| 4909 | } | 5274 | } |
| 4910 | case BuiltinFnIdByteOffsetOf: | 5275 | case BuiltinFnIdByteOffsetOf: |
| 4911 | { | 5276 | { |
| ... | @@ -4920,7 +5285,7 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo | ... | @@ -4920,7 +5285,7 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo |
| 4920 | return arg1_value; | 5285 | return arg1_value; |
| 4921 | | 5286 | |
| 4922 | 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); |
| 4923 | return ir_lval_wrap(irb, scope, offset_of, lval); | 5288 | return ir_lval_wrap(irb, scope, offset_of, lval, result_loc); |
| 4924 | } | 5289 | } |
| 4925 | case BuiltinFnIdBitOffsetOf: | 5290 | case BuiltinFnIdBitOffsetOf: |
| 4926 | { | 5291 | { |
| ... | @@ -4935,7 +5300,7 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo | ... | @@ -4935,7 +5300,7 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo |
| 4935 | return arg1_value; | 5300 | return arg1_value; |
| 4936 | | 5301 | |
| 4937 | 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); |
| 4938 | return ir_lval_wrap(irb, scope, offset_of, lval); | 5303 | return ir_lval_wrap(irb, scope, offset_of, lval, result_loc); |
| 4939 | } | 5304 | } |
| 4940 | case BuiltinFnIdInlineCall: | 5305 | case BuiltinFnIdInlineCall: |
| 4941 | case BuiltinFnIdNoInlineCall: | 5306 | case BuiltinFnIdNoInlineCall: |
| ... | @@ -4961,8 +5326,9 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo | ... | @@ -4961,8 +5326,9 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo |
| 4961 | } | 5326 | } |
| 4962 | FnInline fn_inline = (builtin_fn->id == BuiltinFnIdInlineCall) ? FnInlineAlways : FnInlineNever; | 5327 | FnInline fn_inline = (builtin_fn->id == BuiltinFnIdInlineCall) ? FnInlineAlways : FnInlineNever; |
| 4963 | | 5328 | |
| 4964 | 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, |
| 4965 | 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); |
| 4966 | } | 5332 | } |
| 4967 | case BuiltinFnIdNewStackCall: | 5333 | case BuiltinFnIdNewStackCall: |
| 4968 | { | 5334 | { |
| ... | @@ -4991,8 +5357,9 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo | ... | @@ -4991,8 +5357,9 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo |
| 4991 | return args[i]; | 5357 | return args[i]; |
| 4992 | } | 5358 | } |
| 4993 | | 5359 | |
| 4994 | 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, |
| 4995 | 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); |
| 4996 | } | 5363 | } |
| 4997 | case BuiltinFnIdTypeId: | 5364 | case BuiltinFnIdTypeId: |
| 4998 | { | 5365 | { |
| ... | @@ -5002,7 +5369,7 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo | ... | @@ -5002,7 +5369,7 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo |
| 5002 | return arg0_value; | 5369 | return arg0_value; |
| 5003 | | 5370 | |
| 5004 | 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); |
| 5005 | return ir_lval_wrap(irb, scope, type_id, lval); | 5372 | return ir_lval_wrap(irb, scope, type_id, lval, result_loc); |
| 5006 | } | 5373 | } |
| 5007 | case BuiltinFnIdShlExact: | 5374 | case BuiltinFnIdShlExact: |
| 5008 | { | 5375 | { |
| ... | @@ -5017,7 +5384,7 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo | ... | @@ -5017,7 +5384,7 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo |
| 5017 | return arg1_value; | 5384 | return arg1_value; |
| 5018 | | 5385 | |
| 5019 | 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); |
| 5020 | return ir_lval_wrap(irb, scope, bin_op, lval); | 5387 | return ir_lval_wrap(irb, scope, bin_op, lval, result_loc); |
| 5021 | } | 5388 | } |
| 5022 | case BuiltinFnIdShrExact: | 5389 | case BuiltinFnIdShrExact: |
| 5023 | { | 5390 | { |
| ... | @@ -5032,7 +5399,7 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo | ... | @@ -5032,7 +5399,7 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo |
| 5032 | return arg1_value; | 5399 | return arg1_value; |
| 5033 | | 5400 | |
| 5034 | 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); |
| 5035 | return ir_lval_wrap(irb, scope, bin_op, lval); | 5402 | return ir_lval_wrap(irb, scope, bin_op, lval, result_loc); |
| 5036 | } | 5403 | } |
| 5037 | case BuiltinFnIdSetEvalBranchQuota: | 5404 | case BuiltinFnIdSetEvalBranchQuota: |
| 5038 | { | 5405 | { |
| ... | @@ -5042,7 +5409,7 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo | ... | @@ -5042,7 +5409,7 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo |
| 5042 | return arg0_value; | 5409 | return arg0_value; |
| 5043 | | 5410 | |
| 5044 | 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); |
| 5045 | 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); |
| 5046 | } | 5413 | } |
| 5047 | case BuiltinFnIdAlignCast: | 5414 | case BuiltinFnIdAlignCast: |
| 5048 | { | 5415 | { |
| ... | @@ -5057,17 +5424,17 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo | ... | @@ -5057,17 +5424,17 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo |
| 5057 | return arg1_value; | 5424 | return arg1_value; |
| 5058 | | 5425 | |
| 5059 | 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); |
| 5060 | return ir_lval_wrap(irb, scope, align_cast, lval); | 5427 | return ir_lval_wrap(irb, scope, align_cast, lval, result_loc); |
| 5061 | } | 5428 | } |
| 5062 | case BuiltinFnIdOpaqueType: | 5429 | case BuiltinFnIdOpaqueType: |
| 5063 | { | 5430 | { |
| 5064 | IrInstruction *opaque_type = ir_build_opaque_type(irb, scope, node); | 5431 | IrInstruction *opaque_type = ir_build_opaque_type(irb, scope, node); |
| 5065 | return ir_lval_wrap(irb, scope, opaque_type, lval); | 5432 | return ir_lval_wrap(irb, scope, opaque_type, lval, result_loc); |
| 5066 | } | 5433 | } |
| 5067 | case BuiltinFnIdThis: | 5434 | case BuiltinFnIdThis: |
| 5068 | { | 5435 | { |
| 5069 | IrInstruction *this_inst = ir_gen_this(irb, scope, node); | 5436 | IrInstruction *this_inst = ir_gen_this(irb, scope, node); |
| 5070 | return ir_lval_wrap(irb, scope, this_inst, lval); | 5437 | return ir_lval_wrap(irb, scope, this_inst, lval, result_loc); |
| 5071 | } | 5438 | } |
| 5072 | case BuiltinFnIdSetAlignStack: | 5439 | case BuiltinFnIdSetAlignStack: |
| 5073 | { | 5440 | { |
| ... | @@ -5077,7 +5444,7 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo | ... | @@ -5077,7 +5444,7 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo |
| 5077 | return arg0_value; | 5444 | return arg0_value; |
| 5078 | | 5445 | |
| 5079 | 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); |
| 5080 | return ir_lval_wrap(irb, scope, set_align_stack, lval); | 5447 | return ir_lval_wrap(irb, scope, set_align_stack, lval, result_loc); |
| 5081 | } | 5448 | } |
| 5082 | case BuiltinFnIdArgType: | 5449 | case BuiltinFnIdArgType: |
| 5083 | { | 5450 | { |
| ... | @@ -5092,7 +5459,7 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo | ... | @@ -5092,7 +5459,7 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo |
| 5092 | return arg1_value; | 5459 | return arg1_value; |
| 5093 | | 5460 | |
| 5094 | 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); |
| 5095 | return ir_lval_wrap(irb, scope, arg_type, lval); | 5462 | return ir_lval_wrap(irb, scope, arg_type, lval, result_loc); |
| 5096 | } | 5463 | } |
| 5097 | case BuiltinFnIdExport: | 5464 | case BuiltinFnIdExport: |
| 5098 | { | 5465 | { |
| ... | @@ -5112,12 +5479,12 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo | ... | @@ -5112,12 +5479,12 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo |
| 5112 | return arg2_value; | 5479 | return arg2_value; |
| 5113 | | 5480 | |
| 5114 | 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); |
| 5115 | return ir_lval_wrap(irb, scope, ir_export, lval); | 5482 | return ir_lval_wrap(irb, scope, ir_export, lval, result_loc); |
| 5116 | } | 5483 | } |
| 5117 | case BuiltinFnIdErrorReturnTrace: | 5484 | case BuiltinFnIdErrorReturnTrace: |
| 5118 | { | 5485 | { |
| 5119 | 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); |
| 5120 | return ir_lval_wrap(irb, scope, error_return_trace, lval); | 5487 | return ir_lval_wrap(irb, scope, error_return_trace, lval, result_loc); |
| 5121 | } | 5488 | } |
| 5122 | case BuiltinFnIdAtomicRmw: | 5489 | case BuiltinFnIdAtomicRmw: |
| 5123 | { | 5490 | { |
| ... | @@ -5146,10 +5513,11 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo | ... | @@ -5146,10 +5513,11 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo |
| 5146 | if (arg4_value == irb->codegen->invalid_instruction) | 5513 | if (arg4_value == irb->codegen->invalid_instruction) |
| 5147 | return arg4_value; | 5514 | return arg4_value; |
| 5148 | | 5515 | |
| 5149 | 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, |
| 5150 | arg4_value, | 5517 | arg4_value, |
| 5151 | // 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 |
| 5152 | AtomicRmwOp_xchg, AtomicOrderMonotonic); | 5519 | AtomicRmwOp_xchg, AtomicOrderMonotonic); |
| | 5520 | return ir_lval_wrap(irb, scope, inst, lval, result_loc); |
| 5153 | } | 5521 | } |
| 5154 | case BuiltinFnIdAtomicLoad: | 5522 | case BuiltinFnIdAtomicLoad: |
| 5155 | { | 5523 | { |
| ... | @@ -5168,9 +5536,10 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo | ... | @@ -5168,9 +5536,10 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo |
| 5168 | if (arg2_value == irb->codegen->invalid_instruction) | 5536 | if (arg2_value == irb->codegen->invalid_instruction) |
| 5169 | return arg2_value; | 5537 | return arg2_value; |
| 5170 | | 5538 | |
| 5171 | 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, |
| 5172 | // 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 |
| 5173 | AtomicOrderMonotonic); | 5541 | AtomicOrderMonotonic); |
| | 5542 | return ir_lval_wrap(irb, scope, inst, lval, result_loc); |
| 5174 | } | 5543 | } |
| 5175 | case BuiltinFnIdIntToEnum: | 5544 | case BuiltinFnIdIntToEnum: |
| 5176 | { | 5545 | { |
| ... | @@ -5185,7 +5554,7 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo | ... | @@ -5185,7 +5554,7 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo |
| 5185 | return arg1_value; | 5554 | return arg1_value; |
| 5186 | | 5555 | |
| 5187 | 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); |
| 5188 | return ir_lval_wrap(irb, scope, result, lval); | 5557 | return ir_lval_wrap(irb, scope, result, lval, result_loc); |
| 5189 | } | 5558 | } |
| 5190 | case BuiltinFnIdEnumToInt: | 5559 | case BuiltinFnIdEnumToInt: |
| 5191 | { | 5560 | { |
| ... | @@ -5195,7 +5564,7 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo | ... | @@ -5195,7 +5564,7 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo |
| 5195 | return arg0_value; | 5564 | return arg0_value; |
| 5196 | | 5565 | |
| 5197 | 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); |
| 5198 | return ir_lval_wrap(irb, scope, result, lval); | 5567 | return ir_lval_wrap(irb, scope, result, lval, result_loc); |
| 5199 | } | 5568 | } |
| 5200 | case BuiltinFnIdCtz: | 5569 | case BuiltinFnIdCtz: |
| 5201 | case BuiltinFnIdPopCount: | 5570 | case BuiltinFnIdPopCount: |
| ... | @@ -5233,7 +5602,7 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo | ... | @@ -5233,7 +5602,7 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo |
| 5233 | default: | 5602 | default: |
| 5234 | zig_unreachable(); | 5603 | zig_unreachable(); |
| 5235 | } | 5604 | } |
| 5236 | return ir_lval_wrap(irb, scope, result, lval); | 5605 | return ir_lval_wrap(irb, scope, result, lval, result_loc); |
| 5237 | } | 5606 | } |
| 5238 | case BuiltinFnIdHasDecl: | 5607 | case BuiltinFnIdHasDecl: |
| 5239 | { | 5608 | { |
| ... | @@ -5248,17 +5617,19 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo | ... | @@ -5248,17 +5617,19 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo |
| 5248 | return arg1_value; | 5617 | return arg1_value; |
| 5249 | | 5618 | |
| 5250 | 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); |
| 5251 | return ir_lval_wrap(irb, scope, has_decl, lval); | 5620 | return ir_lval_wrap(irb, scope, has_decl, lval, result_loc); |
| 5252 | } | 5621 | } |
| 5253 | } | 5622 | } |
| 5254 | zig_unreachable(); | 5623 | zig_unreachable(); |
| 5255 | } | 5624 | } |
| 5256 | | 5625 | |
| 5257 | 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 | { |
| 5258 | assert(node->type == NodeTypeFnCallExpr); | 5629 | assert(node->type == NodeTypeFnCallExpr); |
| 5259 | | 5630 | |
| 5260 | if (node->data.fn_call_expr.is_builtin) | 5631 | if (node->data.fn_call_expr.is_builtin) |
| 5261 | return ir_gen_builtin_fn_call(irb, scope, node, lval); | 5632 | return ir_gen_builtin_fn_call(irb, scope, node, lval, result_loc); |
| 5262 | | 5633 | |
| 5263 | 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; |
| 5264 | IrInstruction *fn_ref = ir_gen_node(irb, fn_ref_node, scope); | 5635 | IrInstruction *fn_ref = ir_gen_node(irb, fn_ref_node, scope); |
| ... | @@ -5284,12 +5655,14 @@ static IrInstruction *ir_gen_fn_call(IrBuilder *irb, Scope *scope, AstNode *node | ... | @@ -5284,12 +5655,14 @@ static IrInstruction *ir_gen_fn_call(IrBuilder *irb, Scope *scope, AstNode *node |
| 5284 | } | 5655 | } |
| 5285 | } | 5656 | } |
| 5286 | | 5657 | |
| 5287 | 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, |
| 5288 | is_async, async_allocator, nullptr); | 5659 | is_async, async_allocator, nullptr, result_loc); |
| 5289 | return ir_lval_wrap(irb, scope, fn_call, lval); | 5660 | return ir_lval_wrap(irb, scope, fn_call, lval, result_loc); |
| 5290 | } | 5661 | } |
| 5291 | | 5662 | |
| 5292 | 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 | { |
| 5293 | assert(node->type == NodeTypeIfBoolExpr); | 5666 | assert(node->type == NodeTypeIfBoolExpr); |
| 5294 | | 5667 | |
| 5295 | 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); |
| ... | @@ -5310,12 +5683,16 @@ static IrInstruction *ir_gen_if_bool_expr(IrBuilder *irb, Scope *scope, AstNode | ... | @@ -5310,12 +5683,16 @@ static IrInstruction *ir_gen_if_bool_expr(IrBuilder *irb, Scope *scope, AstNode |
| 5310 | IrBasicBlock *else_block = ir_create_basic_block(irb, scope, "Else"); | 5683 | IrBasicBlock *else_block = ir_create_basic_block(irb, scope, "Else"); |
| 5311 | IrBasicBlock *endif_block = ir_create_basic_block(irb, scope, "EndIf"); | 5684 | IrBasicBlock *endif_block = ir_create_basic_block(irb, scope, "EndIf"); |
| 5312 | | 5685 | |
| 5313 | 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); |
| 5314 | | 5690 | |
| 5315 | ir_set_cursor_at_end_and_append_block(irb, then_block); | 5691 | ir_set_cursor_at_end_and_append_block(irb, then_block); |
| 5316 | | 5692 | |
| 5317 | 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); |
| 5318 | 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); |
| 5319 | if (then_expr_result == irb->codegen->invalid_instruction) | 5696 | if (then_expr_result == irb->codegen->invalid_instruction) |
| 5320 | return irb->codegen->invalid_instruction; | 5697 | return irb->codegen->invalid_instruction; |
| 5321 | IrBasicBlock *after_then_block = irb->current_basic_block; | 5698 | IrBasicBlock *after_then_block = irb->current_basic_block; |
| ... | @@ -5325,11 +5702,12 @@ static IrInstruction *ir_gen_if_bool_expr(IrBuilder *irb, Scope *scope, AstNode | ... | @@ -5325,11 +5702,12 @@ static IrInstruction *ir_gen_if_bool_expr(IrBuilder *irb, Scope *scope, AstNode |
| 5325 | ir_set_cursor_at_end_and_append_block(irb, else_block); | 5702 | ir_set_cursor_at_end_and_append_block(irb, else_block); |
| 5326 | IrInstruction *else_expr_result; | 5703 | IrInstruction *else_expr_result; |
| 5327 | if (else_node) { | 5704 | if (else_node) { |
| 5328 | 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); |
| 5329 | if (else_expr_result == irb->codegen->invalid_instruction) | 5706 | if (else_expr_result == irb->codegen->invalid_instruction) |
| 5330 | return irb->codegen->invalid_instruction; | 5707 | return irb->codegen->invalid_instruction; |
| 5331 | } else { | 5708 | } else { |
| 5332 | 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); |
| 5333 | } | 5711 | } |
| 5334 | IrBasicBlock *after_else_block = irb->current_basic_block; | 5712 | IrBasicBlock *after_else_block = irb->current_basic_block; |
| 5335 | if (!instr_is_unreachable(else_expr_result)) | 5713 | if (!instr_is_unreachable(else_expr_result)) |
| ... | @@ -5343,14 +5721,15 @@ static IrInstruction *ir_gen_if_bool_expr(IrBuilder *irb, Scope *scope, AstNode | ... | @@ -5343,14 +5721,15 @@ static IrInstruction *ir_gen_if_bool_expr(IrBuilder *irb, Scope *scope, AstNode |
| 5343 | incoming_blocks[0] = after_then_block; | 5721 | incoming_blocks[0] = after_then_block; |
| 5344 | incoming_blocks[1] = after_else_block; | 5722 | incoming_blocks[1] = after_else_block; |
| 5345 | | 5723 | |
| 5346 | 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); |
| 5347 | } | 5726 | } |
| 5348 | | 5727 | |
| 5349 | 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) { |
| 5350 | assert(node->type == NodeTypePrefixOpExpr); | 5729 | assert(node->type == NodeTypePrefixOpExpr); |
| 5351 | AstNode *expr_node = node->data.prefix_op_expr.primary_expr; | 5730 | AstNode *expr_node = node->data.prefix_op_expr.primary_expr; |
| 5352 | | 5731 | |
| 5353 | IrInstruction *value = ir_gen_node_extra(irb, expr_node, scope, lval); | 5732 | IrInstruction *value = ir_gen_node_extra(irb, expr_node, scope, lval, nullptr); |
| 5354 | if (value == irb->codegen->invalid_instruction) | 5733 | if (value == irb->codegen->invalid_instruction) |
| 5355 | return value; | 5734 | return value; |
| 5356 | | 5735 | |
| ... | @@ -5361,15 +5740,34 @@ static IrInstruction *ir_gen_prefix_op_id(IrBuilder *irb, Scope *scope, AstNode | ... | @@ -5361,15 +5740,34 @@ static IrInstruction *ir_gen_prefix_op_id(IrBuilder *irb, Scope *scope, AstNode |
| 5361 | 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); |
| 5362 | } | 5741 | } |
| 5363 | | 5742 | |
| 5364 | 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) { |
| 5365 | 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 | { |
| 5366 | return value; | 5758 | return value; |
| 5367 | 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 { |
| 5368 | return value; | 5768 | return value; |
| | 5769 | } |
| 5369 | | 5770 | |
| 5370 | // We needed a pointer to a value, but we got a value. So we create | | |
| 5371 | // an instruction which just makes a const pointer of it. | | |
| 5372 | return ir_build_ref(irb, scope, value->source_node, value, false, false); | | |
| 5373 | } | 5771 | } |
| 5374 | | 5772 | |
| 5375 | static PtrLen star_token_to_ptr_len(TokenId token_id) { | 5773 | static PtrLen star_token_to_ptr_len(TokenId token_id) { |
| ... | @@ -5442,21 +5840,22 @@ static IrInstruction *ir_gen_pointer_type(IrBuilder *irb, Scope *scope, AstNode | ... | @@ -5442,21 +5840,22 @@ static IrInstruction *ir_gen_pointer_type(IrBuilder *irb, Scope *scope, AstNode |
| 5442 | 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); |
| 5443 | } | 5841 | } |
| 5444 | | 5842 | |
| 5445 | 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, |
| 5446 | LVal lval) | 5844 | AstNode *expr_node, LVal lval, ResultLoc *result_loc) |
| 5447 | { | 5845 | { |
| 5448 | 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); |
| 5449 | if (err_union_ptr == irb->codegen->invalid_instruction) | 5847 | if (err_union_ptr == irb->codegen->invalid_instruction) |
| 5450 | return irb->codegen->invalid_instruction; | 5848 | return irb->codegen->invalid_instruction; |
| 5451 | | 5849 | |
| 5452 | 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); |
| 5453 | if (payload_ptr == irb->codegen->invalid_instruction) | 5851 | if (payload_ptr == irb->codegen->invalid_instruction) |
| 5454 | return irb->codegen->invalid_instruction; | 5852 | return irb->codegen->invalid_instruction; |
| 5455 | | 5853 | |
| 5456 | if (lval == LValPtr) | 5854 | if (lval == LValPtr) |
| 5457 | return payload_ptr; | 5855 | return payload_ptr; |
| 5458 | | 5856 | |
| 5459 | 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); |
| 5460 | } | 5859 | } |
| 5461 | | 5860 | |
| 5462 | 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) { |
| ... | @@ -5470,7 +5869,9 @@ static IrInstruction *ir_gen_bool_not(IrBuilder *irb, Scope *scope, AstNode *nod | ... | @@ -5470,7 +5869,9 @@ static IrInstruction *ir_gen_bool_not(IrBuilder *irb, Scope *scope, AstNode *nod |
| 5470 | return ir_build_bool_not(irb, scope, node, value); | 5869 | return ir_build_bool_not(irb, scope, node, value); |
| 5471 | } | 5870 | } |
| 5472 | | 5871 | |
| 5473 | 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 | { |
| 5474 | assert(node->type == NodeTypePrefixOpExpr); | 5875 | assert(node->type == NodeTypePrefixOpExpr); |
| 5475 | | 5876 | |
| 5476 | PrefixOp prefix_op = node->data.prefix_op_expr.prefix_op; | 5877 | PrefixOp prefix_op = node->data.prefix_op_expr.prefix_op; |
| ... | @@ -5479,24 +5880,26 @@ static IrInstruction *ir_gen_prefix_op_expr(IrBuilder *irb, Scope *scope, AstNod | ... | @@ -5479,24 +5880,26 @@ static IrInstruction *ir_gen_prefix_op_expr(IrBuilder *irb, Scope *scope, AstNod |
| 5479 | case PrefixOpInvalid: | 5880 | case PrefixOpInvalid: |
| 5480 | zig_unreachable(); | 5881 | zig_unreachable(); |
| 5481 | case PrefixOpBoolNot: | 5882 | case PrefixOpBoolNot: |
| 5482 | 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); |
| 5483 | case PrefixOpBinNot: | 5884 | case PrefixOpBinNot: |
| 5484 | 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); |
| 5485 | case PrefixOpNegation: | 5886 | case PrefixOpNegation: |
| 5486 | 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); |
| 5487 | case PrefixOpNegationWrap: | 5888 | case PrefixOpNegationWrap: |
| 5488 | 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); |
| 5489 | case PrefixOpOptional: | 5890 | case PrefixOpOptional: |
| 5490 | 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); |
| 5491 | case PrefixOpAddrOf: { | 5892 | case PrefixOpAddrOf: { |
| 5492 | AstNode *expr_node = node->data.prefix_op_expr.primary_expr; | 5893 | AstNode *expr_node = node->data.prefix_op_expr.primary_expr; |
| 5493 | 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); |
| 5494 | } | 5895 | } |
| 5495 | } | 5896 | } |
| 5496 | zig_unreachable(); | 5897 | zig_unreachable(); |
| 5497 | } | 5898 | } |
| 5498 | | 5899 | |
| 5499 | 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 | { |
| 5500 | assert(node->type == NodeTypeContainerInitExpr); | 5903 | assert(node->type == NodeTypeContainerInitExpr); |
| 5501 | | 5904 | |
| 5502 | AstNodeContainerInitExpr *container_init_expr = &node->data.container_init_expr; | 5905 | AstNodeContainerInitExpr *container_init_expr = &node->data.container_init_expr; |
| ... | @@ -5514,45 +5917,104 @@ static IrInstruction *ir_gen_container_init_expr(IrBuilder *irb, Scope *scope, A | ... | @@ -5514,45 +5917,104 @@ static IrInstruction *ir_gen_container_init_expr(IrBuilder *irb, Scope *scope, A |
| 5514 | return container_type; | 5917 | return container_type; |
| 5515 | } | 5918 | } |
| 5516 | | 5919 | |
| 5517 | if (kind == ContainerInitKindStruct) { | 5920 | switch (kind) { |
| 5518 | if (elem_type != nullptr) { | 5921 | case ContainerInitKindStruct: { |
| 5519 | add_node_error(irb->codegen, container_init_expr->type, | 5922 | if (elem_type != nullptr) { |
| 5520 | buf_sprintf("initializing array with struct syntax")); | 5923 | add_node_error(irb->codegen, container_init_expr->type, |
| 5521 | return irb->codegen->invalid_instruction; | 5924 | buf_sprintf("initializing array with struct syntax")); |
| 5522 | } | 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); |
| | 5936 | |
| | 5937 | Buf *name = entry_node->data.struct_val_field.name; |
| | 5938 | AstNode *expr_node = entry_node->data.struct_val_field.expr; |
| 5523 | | 5939 | |
| 5524 | size_t field_count = container_init_expr->entries.length; | 5940 | IrInstruction *field_ptr = ir_build_field_ptr(irb, scope, entry_node, container_ptr, name, true); |
| 5525 | IrInstructionContainerInitFieldsField *fields = allocate<IrInstructionContainerInitFieldsField>(field_count); | 5941 | ResultLocInstruction *result_loc_inst = allocate<ResultLocInstruction>(1); |
| 5526 | for (size_t i = 0; i < field_count; i += 1) { | 5942 | result_loc_inst->base.id = ResultLocIdInstruction; |
| 5527 | AstNode *entry_node = container_init_expr->entries.at(i); | 5943 | result_loc_inst->base.source_instruction = field_ptr; |
| 5528 | assert(entry_node->type == NodeTypeStructValueField); | 5944 | ir_ref_instruction(field_ptr, irb->current_basic_block); |
| | 5945 | ir_build_reset_result(irb, scope, expr_node, &result_loc_inst->base); |
| 5529 | | 5946 | |
| 5530 | Buf *name = entry_node->data.struct_val_field.name; | 5947 | IrInstruction *expr_value = ir_gen_node_extra(irb, expr_node, scope, LValNone, |
| 5531 | AstNode *expr_node = entry_node->data.struct_val_field.expr; | 5948 | &result_loc_inst->base); |
| 5532 | IrInstruction *expr_value = ir_gen_node(irb, expr_node, scope); | 5949 | if (expr_value == irb->codegen->invalid_instruction) |
| 5533 | if (expr_value == irb->codegen->invalid_instruction) | 5950 | return expr_value; |
| 5534 | return expr_value; | | |
| 5535 | | 5951 | |
| 5536 | fields[i].name = name; | 5952 | fields[i].name = name; |
| 5537 | fields[i].value = expr_value; | 5953 | fields[i].source_node = entry_node; |
| 5538 | 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); |
| 5539 | } | 5960 | } |
| 5540 | return ir_build_container_init_fields(irb, scope, node, container_type, field_count, fields); | 5961 | case ContainerInitKindArray: { |
| 5541 | } else if (kind == ContainerInitKindArray) { | 5962 | size_t item_count = container_init_expr->entries.length; |
| 5542 | size_t item_count = container_init_expr->entries.length; | 5963 | |
| 5543 | IrInstruction **values = allocate<IrInstruction *>(item_count); | 5964 | if (container_type == nullptr) { |
| 5544 | for (size_t i = 0; i < item_count; i += 1) { | 5965 | IrInstruction *item_count_inst = ir_build_const_usize(irb, scope, node, item_count); |
| 5545 | AstNode *expr_node = container_init_expr->entries.at(i); | 5966 | container_type = ir_build_array_type(irb, scope, node, item_count_inst, elem_type); |
| 5546 | IrInstruction *expr_value = ir_gen_node(irb, expr_node, scope); | 5967 | } |
| 5547 | if (expr_value == irb->codegen->invalid_instruction) | | |
| 5548 | return expr_value; | | |
| 5549 | | 5968 | |
| 5550 | values[i] = 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); |
| | 5984 | |
| | 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); |
| 5551 | } | 5995 | } |
| 5552 | return ir_build_container_init_list(irb, scope, node, container_type, elem_type, item_count, values); | | |
| 5553 | } else { | | |
| 5554 | zig_unreachable(); | | |
| 5555 | } | 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); |
| 5556 | } | 6018 | } |
| 5557 | | 6019 | |
| 5558 | 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) { |
| ... | @@ -5565,9 +6027,12 @@ static IrInstruction *ir_gen_var_decl(IrBuilder *irb, Scope *scope, AstNode *nod | ... | @@ -5565,9 +6027,12 @@ static IrInstruction *ir_gen_var_decl(IrBuilder *irb, Scope *scope, AstNode *nod |
| 5565 | return irb->codegen->invalid_instruction; | 6027 | return irb->codegen->invalid_instruction; |
| 5566 | } | 6028 | } |
| 5567 | | 6029 | |
| | 6030 | // Used for the type expr and the align expr |
| | 6031 | Scope *comptime_scope = create_comptime_scope(irb->codegen, node, scope); |
| | 6032 | |
| 5568 | IrInstruction *type_instruction; | 6033 | IrInstruction *type_instruction; |
| 5569 | if (variable_declaration->type != nullptr) { | 6034 | if (variable_declaration->type != nullptr) { |
| 5570 | type_instruction = ir_gen_node(irb, variable_declaration->type, scope); | 6035 | type_instruction = ir_gen_node(irb, variable_declaration->type, comptime_scope); |
| 5571 | if (type_instruction == irb->codegen->invalid_instruction) | 6036 | if (type_instruction == irb->codegen->invalid_instruction) |
| 5572 | return type_instruction; | 6037 | return type_instruction; |
| 5573 | } else { | 6038 | } else { |
| ... | @@ -5578,8 +6043,8 @@ static IrInstruction *ir_gen_var_decl(IrBuilder *irb, Scope *scope, AstNode *nod | ... | @@ -5578,8 +6043,8 @@ static IrInstruction *ir_gen_var_decl(IrBuilder *irb, Scope *scope, AstNode *nod |
| 5578 | bool is_const = variable_declaration->is_const; | 6043 | bool is_const = variable_declaration->is_const; |
| 5579 | bool is_extern = variable_declaration->is_extern; | 6044 | bool is_extern = variable_declaration->is_extern; |
| 5580 | | 6045 | |
| 5581 | 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; |
| 5582 | ir_should_inline(irb->exec, scope) || variable_declaration->is_comptime); | 6047 | IrInstruction *is_comptime = ir_build_const_bool(irb, scope, node, is_comptime_scalar); |
| 5583 | ZigVar *var = ir_create_var(irb, node, scope, variable_declaration->symbol, | 6048 | ZigVar *var = ir_create_var(irb, node, scope, variable_declaration->symbol, |
| 5584 | is_const, is_const, is_shadowable, is_comptime); | 6049 | is_const, is_const, is_shadowable, is_comptime); |
| 5585 | // 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 |
| ... | @@ -5593,7 +6058,7 @@ static IrInstruction *ir_gen_var_decl(IrBuilder *irb, Scope *scope, AstNode *nod | ... | @@ -5593,7 +6058,7 @@ static IrInstruction *ir_gen_var_decl(IrBuilder *irb, Scope *scope, AstNode *nod |
| 5593 | | 6058 | |
| 5594 | IrInstruction *align_value = nullptr; | 6059 | IrInstruction *align_value = nullptr; |
| 5595 | if (variable_declaration->align_expr != nullptr) { | 6060 | if (variable_declaration->align_expr != nullptr) { |
| 5596 | align_value = ir_gen_node(irb, variable_declaration->align_expr, scope); | 6061 | align_value = ir_gen_node(irb, variable_declaration->align_expr, comptime_scope); |
| 5597 | if (align_value == irb->codegen->invalid_instruction) | 6062 | if (align_value == irb->codegen->invalid_instruction) |
| 5598 | return align_value; | 6063 | return align_value; |
| 5599 | } | 6064 | } |
| ... | @@ -5606,20 +6071,39 @@ static IrInstruction *ir_gen_var_decl(IrBuilder *irb, Scope *scope, AstNode *nod | ... | @@ -5606,20 +6071,39 @@ static IrInstruction *ir_gen_var_decl(IrBuilder *irb, Scope *scope, AstNode *nod |
| 5606 | // Parser should ensure that this never happens | 6071 | // Parser should ensure that this never happens |
| 5607 | assert(variable_declaration->threadlocal_tok == nullptr); | 6072 | assert(variable_declaration->threadlocal_tok == nullptr); |
| 5608 | | 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 | |
| 5609 | // Temporarily set the name of the IrExecutable to the VariableDeclaration | 6084 | // Temporarily set the name of the IrExecutable to the VariableDeclaration |
| 5610 | // 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. |
| 5611 | Buf *old_exec_name = irb->exec->name; | 6086 | Buf *old_exec_name = irb->exec->name; |
| 5612 | irb->exec->name = variable_declaration->symbol; | 6087 | irb->exec->name = variable_declaration->symbol; |
| 5613 | 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); |
| 5614 | irb->exec->name = old_exec_name; | 6090 | irb->exec->name = old_exec_name; |
| 5615 | | 6091 | |
| 5616 | if (init_value == irb->codegen->invalid_instruction) | 6092 | if (init_value == irb->codegen->invalid_instruction) |
| 5617 | 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 | } |
| 5618 | | 6100 | |
| 5619 | 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); |
| 5620 | } | 6102 | } |
| 5621 | | 6103 | |
| 5622 | 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 | { |
| 5623 | assert(node->type == NodeTypeWhileExpr); | 6107 | assert(node->type == NodeTypeWhileExpr); |
| 5624 | | 6108 | |
| 5625 | AstNode *continue_expr_node = node->data.while_expr.continue_expr; | 6109 | AstNode *continue_expr_node = node->data.while_expr.continue_expr; |
| ... | @@ -5654,25 +6138,33 @@ static IrInstruction *ir_gen_while_expr(IrBuilder *irb, Scope *scope, AstNode *n | ... | @@ -5654,25 +6138,33 @@ static IrInstruction *ir_gen_while_expr(IrBuilder *irb, Scope *scope, AstNode *n |
| 5654 | } else { | 6138 | } else { |
| 5655 | payload_scope = subexpr_scope; | 6139 | payload_scope = subexpr_scope; |
| 5656 | } | 6140 | } |
| 5657 | 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); |
| 5658 | if (err_val_ptr == irb->codegen->invalid_instruction) | 6143 | if (err_val_ptr == irb->codegen->invalid_instruction) |
| 5659 | return err_val_ptr; | 6144 | return err_val_ptr; |
| 5660 | 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); |
| 5661 | IrInstruction *is_err = ir_build_test_err(irb, scope, node->data.while_expr.condition, err_val); | | |
| 5662 | IrBasicBlock *after_cond_block = irb->current_basic_block; | 6146 | IrBasicBlock *after_cond_block = irb->current_basic_block; |
| 5663 | 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; |
| 5664 | if (!instr_is_unreachable(is_err)) { | 6149 | if (!instr_is_unreachable(is_err)) { |
| 5665 | 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, |
| 5666 | 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(); |
| 5667 | } | 6156 | } |
| 5668 | | 6157 | |
| | 6158 | ResultLocPeerParent *peer_parent = ir_build_result_peers(irb, cond_br_inst, end_block, result_loc, |
| | 6159 | is_comptime); |
| | 6160 | |
| 5669 | ir_set_cursor_at_end_and_append_block(irb, body_block); | 6161 | ir_set_cursor_at_end_and_append_block(irb, body_block); |
| 5670 | if (var_symbol) { | 6162 | if (var_symbol) { |
| 5671 | 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, |
| 5672 | err_val_ptr, false); | 6164 | err_val_ptr, false, false); |
| 5673 | IrInstruction *var_value = node->data.while_expr.var_is_ptr ? | 6165 | IrInstruction *var_ptr = node->data.while_expr.var_is_ptr ? |
| 5674 | 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; |
| 5675 | 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); |
| 5676 | } | 6168 | } |
| 5677 | | 6169 | |
| 5678 | ZigList<IrInstruction *> incoming_values = {0}; | 6170 | ZigList<IrInstruction *> incoming_values = {0}; |
| ... | @@ -5684,7 +6176,12 @@ static IrInstruction *ir_gen_while_expr(IrBuilder *irb, Scope *scope, AstNode *n | ... | @@ -5684,7 +6176,12 @@ static IrInstruction *ir_gen_while_expr(IrBuilder *irb, Scope *scope, AstNode *n |
| 5684 | loop_scope->is_comptime = is_comptime; | 6176 | loop_scope->is_comptime = is_comptime; |
| 5685 | loop_scope->incoming_blocks = &incoming_blocks; | 6177 | loop_scope->incoming_blocks = &incoming_blocks; |
| 5686 | 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; |
| 5687 | | 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. |
| 5688 | 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); |
| 5689 | if (body_result == irb->codegen->invalid_instruction) | 6186 | if (body_result == irb->codegen->invalid_instruction) |
| 5690 | return body_result; | 6187 | return body_result; |
| ... | @@ -5713,10 +6210,15 @@ static IrInstruction *ir_gen_while_expr(IrBuilder *irb, Scope *scope, AstNode *n | ... | @@ -5713,10 +6210,15 @@ static IrInstruction *ir_gen_while_expr(IrBuilder *irb, Scope *scope, AstNode *n |
| 5713 | 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, |
| 5714 | true, false, false, is_comptime); | 6211 | true, false, false, is_comptime); |
| 5715 | Scope *err_scope = err_var->child_scope; | 6212 | Scope *err_scope = err_var->child_scope; |
| 5716 | 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); |
| 5717 | 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); |
| 5718 | | 6215 | |
| 5719 | 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); |
| 5720 | if (else_result == irb->codegen->invalid_instruction) | 6222 | if (else_result == irb->codegen->invalid_instruction) |
| 5721 | return else_result; | 6223 | return else_result; |
| 5722 | if (!instr_is_unreachable(else_result)) | 6224 | if (!instr_is_unreachable(else_result)) |
| ... | @@ -5730,8 +6232,13 @@ static IrInstruction *ir_gen_while_expr(IrBuilder *irb, Scope *scope, AstNode *n | ... | @@ -5730,8 +6232,13 @@ static IrInstruction *ir_gen_while_expr(IrBuilder *irb, Scope *scope, AstNode *n |
| 5730 | incoming_blocks.append(after_cond_block); | 6232 | incoming_blocks.append(after_cond_block); |
| 5731 | incoming_values.append(void_else_result); | 6233 | incoming_values.append(void_else_result); |
| 5732 | } | 6234 | } |
| | 6235 | if (peer_parent->peers.length != 0) { |
| | 6236 | peer_parent->peers.last()->next_bb = end_block; |
| | 6237 | } |
| 5733 | | 6238 | |
| 5734 | 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); |
| 5735 | } else if (var_symbol != nullptr) { | 6242 | } else if (var_symbol != nullptr) { |
| 5736 | ir_set_cursor_at_end_and_append_block(irb, cond_block); | 6243 | ir_set_cursor_at_end_and_append_block(irb, cond_block); |
| 5737 | 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); |
| ... | @@ -5741,23 +6248,32 @@ static IrInstruction *ir_gen_while_expr(IrBuilder *irb, Scope *scope, AstNode *n | ... | @@ -5741,23 +6248,32 @@ static IrInstruction *ir_gen_while_expr(IrBuilder *irb, Scope *scope, AstNode *n |
| 5741 | 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, |
| 5742 | true, false, false, is_comptime); | 6249 | true, false, false, is_comptime); |
| 5743 | Scope *child_scope = payload_var->child_scope; | 6250 | Scope *child_scope = payload_var->child_scope; |
| 5744 | 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); |
| 5745 | if (maybe_val_ptr == irb->codegen->invalid_instruction) | 6253 | if (maybe_val_ptr == irb->codegen->invalid_instruction) |
| 5746 | return maybe_val_ptr; | 6254 | return maybe_val_ptr; |
| 5747 | 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); |
| 5748 | 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); |
| 5749 | IrBasicBlock *after_cond_block = irb->current_basic_block; | 6257 | IrBasicBlock *after_cond_block = irb->current_basic_block; |
| 5750 | 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; |
| 5751 | if (!instr_is_unreachable(is_non_null)) { | 6260 | if (!instr_is_unreachable(is_non_null)) { |
| 5752 | 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, |
| 5753 | 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(); |
| 5754 | } | 6267 | } |
| 5755 | | 6268 | |
| | 6269 | ResultLocPeerParent *peer_parent = ir_build_result_peers(irb, cond_br_inst, end_block, result_loc, |
| | 6270 | is_comptime); |
| | 6271 | |
| 5756 | ir_set_cursor_at_end_and_append_block(irb, body_block); | 6272 | ir_set_cursor_at_end_and_append_block(irb, body_block); |
| 5757 | 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); |
| 5758 | IrInstruction *var_value = node->data.while_expr.var_is_ptr ? | 6274 | IrInstruction *var_ptr = node->data.while_expr.var_is_ptr ? |
| 5759 | 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; |
| 5760 | 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); |
| 5761 | | 6277 | |
| 5762 | ZigList<IrInstruction *> incoming_values = {0}; | 6278 | ZigList<IrInstruction *> incoming_values = {0}; |
| 5763 | ZigList<IrBasicBlock *> incoming_blocks = {0}; | 6279 | ZigList<IrBasicBlock *> incoming_blocks = {0}; |
| ... | @@ -5768,7 +6284,12 @@ static IrInstruction *ir_gen_while_expr(IrBuilder *irb, Scope *scope, AstNode *n | ... | @@ -5768,7 +6284,12 @@ static IrInstruction *ir_gen_while_expr(IrBuilder *irb, Scope *scope, AstNode *n |
| 5768 | loop_scope->is_comptime = is_comptime; | 6284 | loop_scope->is_comptime = is_comptime; |
| 5769 | loop_scope->incoming_blocks = &incoming_blocks; | 6285 | loop_scope->incoming_blocks = &incoming_blocks; |
| 5770 | 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; |
| 5771 | | 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. |
| 5772 | 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); |
| 5773 | if (body_result == irb->codegen->invalid_instruction) | 6294 | if (body_result == irb->codegen->invalid_instruction) |
| 5774 | return body_result; | 6295 | return body_result; |
| ... | @@ -5793,7 +6314,12 @@ static IrInstruction *ir_gen_while_expr(IrBuilder *irb, Scope *scope, AstNode *n | ... | @@ -5793,7 +6314,12 @@ static IrInstruction *ir_gen_while_expr(IrBuilder *irb, Scope *scope, AstNode *n |
| 5793 | if (else_node) { | 6314 | if (else_node) { |
| 5794 | ir_set_cursor_at_end_and_append_block(irb, else_block); | 6315 | ir_set_cursor_at_end_and_append_block(irb, else_block); |
| 5795 | | 6316 | |
| 5796 | 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); |
| 5797 | if (else_result == irb->codegen->invalid_instruction) | 6323 | if (else_result == irb->codegen->invalid_instruction) |
| 5798 | return else_result; | 6324 | return else_result; |
| 5799 | if (!instr_is_unreachable(else_result)) | 6325 | if (!instr_is_unreachable(else_result)) |
| ... | @@ -5808,8 +6334,13 @@ static IrInstruction *ir_gen_while_expr(IrBuilder *irb, Scope *scope, AstNode *n | ... | @@ -5808,8 +6334,13 @@ static IrInstruction *ir_gen_while_expr(IrBuilder *irb, Scope *scope, AstNode *n |
| 5808 | incoming_blocks.append(after_cond_block); | 6334 | incoming_blocks.append(after_cond_block); |
| 5809 | incoming_values.append(void_else_result); | 6335 | incoming_values.append(void_else_result); |
| 5810 | } | 6336 | } |
| | 6337 | if (peer_parent->peers.length != 0) { |
| | 6338 | peer_parent->peers.last()->next_bb = end_block; |
| | 6339 | } |
| 5811 | | 6340 | |
| 5812 | 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); |
| 5813 | } else { | 6344 | } else { |
| 5814 | ir_set_cursor_at_end_and_append_block(irb, cond_block); | 6345 | ir_set_cursor_at_end_and_append_block(irb, cond_block); |
| 5815 | 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); |
| ... | @@ -5817,11 +6348,18 @@ static IrInstruction *ir_gen_while_expr(IrBuilder *irb, Scope *scope, AstNode *n | ... | @@ -5817,11 +6348,18 @@ static IrInstruction *ir_gen_while_expr(IrBuilder *irb, Scope *scope, AstNode *n |
| 5817 | return cond_val; | 6348 | return cond_val; |
| 5818 | IrBasicBlock *after_cond_block = irb->current_basic_block; | 6349 | IrBasicBlock *after_cond_block = irb->current_basic_block; |
| 5819 | 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; |
| 5820 | if (!instr_is_unreachable(cond_val)) { | 6352 | if (!instr_is_unreachable(cond_val)) { |
| 5821 | 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, |
| 5822 | 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(); |
| 5823 | } | 6359 | } |
| 5824 | | 6360 | |
| | 6361 | ResultLocPeerParent *peer_parent = ir_build_result_peers(irb, cond_br_inst, end_block, result_loc, |
| | 6362 | is_comptime); |
| 5825 | ir_set_cursor_at_end_and_append_block(irb, body_block); | 6363 | ir_set_cursor_at_end_and_append_block(irb, body_block); |
| 5826 | | 6364 | |
| 5827 | ZigList<IrInstruction *> incoming_values = {0}; | 6365 | ZigList<IrInstruction *> incoming_values = {0}; |
| ... | @@ -5835,7 +6373,12 @@ static IrInstruction *ir_gen_while_expr(IrBuilder *irb, Scope *scope, AstNode *n | ... | @@ -5835,7 +6373,12 @@ static IrInstruction *ir_gen_while_expr(IrBuilder *irb, Scope *scope, AstNode *n |
| 5835 | loop_scope->is_comptime = is_comptime; | 6373 | loop_scope->is_comptime = is_comptime; |
| 5836 | loop_scope->incoming_blocks = &incoming_blocks; | 6374 | loop_scope->incoming_blocks = &incoming_blocks; |
| 5837 | 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; |
| 5838 | | 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. |
| 5839 | 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); |
| 5840 | if (body_result == irb->codegen->invalid_instruction) | 6383 | if (body_result == irb->codegen->invalid_instruction) |
| 5841 | return body_result; | 6384 | return body_result; |
| ... | @@ -5860,7 +6403,13 @@ static IrInstruction *ir_gen_while_expr(IrBuilder *irb, Scope *scope, AstNode *n | ... | @@ -5860,7 +6403,13 @@ static IrInstruction *ir_gen_while_expr(IrBuilder *irb, Scope *scope, AstNode *n |
| 5860 | if (else_node) { | 6403 | if (else_node) { |
| 5861 | ir_set_cursor_at_end_and_append_block(irb, else_block); | 6404 | ir_set_cursor_at_end_and_append_block(irb, else_block); |
| 5862 | | 6405 | |
| 5863 | 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); |
| 5864 | if (else_result == irb->codegen->invalid_instruction) | 6413 | if (else_result == irb->codegen->invalid_instruction) |
| 5865 | return else_result; | 6414 | return else_result; |
| 5866 | if (!instr_is_unreachable(else_result)) | 6415 | if (!instr_is_unreachable(else_result)) |
| ... | @@ -5875,12 +6424,19 @@ static IrInstruction *ir_gen_while_expr(IrBuilder *irb, Scope *scope, AstNode *n | ... | @@ -5875,12 +6424,19 @@ static IrInstruction *ir_gen_while_expr(IrBuilder *irb, Scope *scope, AstNode *n |
| 5875 | incoming_blocks.append(after_cond_block); | 6424 | incoming_blocks.append(after_cond_block); |
| 5876 | incoming_values.append(void_else_result); | 6425 | incoming_values.append(void_else_result); |
| 5877 | } | 6426 | } |
| | 6427 | if (peer_parent->peers.length != 0) { |
| | 6428 | peer_parent->peers.last()->next_bb = end_block; |
| | 6429 | } |
| 5878 | | 6430 | |
| 5879 | 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); |
| 5880 | } | 6434 | } |
| 5881 | } | 6435 | } |
| 5882 | | 6436 | |
| 5883 | 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 | { |
| 5884 | assert(node->type == NodeTypeForExpr); | 6440 | assert(node->type == NodeTypeForExpr); |
| 5885 | | 6441 | |
| 5886 | AstNode *array_node = node->data.for_expr.array_expr; | 6442 | AstNode *array_node = node->data.for_expr.array_expr; |
| ... | @@ -5895,76 +6451,67 @@ static IrInstruction *ir_gen_for_expr(IrBuilder *irb, Scope *parent_scope, AstNo | ... | @@ -5895,76 +6451,67 @@ static IrInstruction *ir_gen_for_expr(IrBuilder *irb, Scope *parent_scope, AstNo |
| 5895 | } | 6451 | } |
| 5896 | assert(elem_node->type == NodeTypeSymbol); | 6452 | assert(elem_node->type == NodeTypeSymbol); |
| 5897 | | 6453 | |
| 5898 | 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); |
| 5899 | if (array_val_ptr == irb->codegen->invalid_instruction) | 6455 | if (array_val_ptr == irb->codegen->invalid_instruction) |
| 5900 | return array_val_ptr; | 6456 | return array_val_ptr; |
| 5901 | | 6457 | |
| 5902 | IrInstruction *pointer_type = ir_build_to_ptr_type(irb, parent_scope, array_node, array_val_ptr); | | |
| 5903 | IrInstruction *elem_var_type; | | |
| 5904 | if (node->data.for_expr.elem_is_ptr) { | | |
| 5905 | elem_var_type = pointer_type; | | |
| 5906 | } else { | | |
| 5907 | elem_var_type = ir_build_ptr_type_child(irb, parent_scope, elem_node, pointer_type); | | |
| 5908 | } | | |
| 5909 | | | |
| 5910 | IrInstruction *is_comptime = ir_build_const_bool(irb, parent_scope, node, | 6458 | IrInstruction *is_comptime = ir_build_const_bool(irb, parent_scope, node, |
| 5911 | 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); |
| 5912 | | 6460 | |
| 5913 | // TODO make it an error to write to element variable or i variable. | | |
| 5914 | Buf *elem_var_name = elem_node->data.symbol_expr.symbol; | | |
| 5915 | ZigVar *elem_var = ir_create_var(irb, elem_node, parent_scope, elem_var_name, true, false, false, is_comptime); | | |
| 5916 | Scope *child_scope = elem_var->child_scope; | | |
| 5917 | | | |
| 5918 | IrInstruction *undefined_value = ir_build_const_undefined(irb, child_scope, elem_node); | | |
| 5919 | ir_build_var_decl_src(irb, child_scope, elem_node, elem_var, elem_var_type, nullptr, undefined_value); | | |
| 5920 | IrInstruction *elem_var_ptr = ir_build_var_ptr(irb, child_scope, node, elem_var); | | |
| 5921 | | | |
| 5922 | AstNode *index_var_source_node; | 6461 | AstNode *index_var_source_node; |
| 5923 | ZigVar *index_var; | 6462 | ZigVar *index_var; |
| | 6463 | const char *index_var_name; |
| 5924 | if (index_node) { | 6464 | if (index_node) { |
| 5925 | index_var_source_node = index_node; | 6465 | index_var_source_node = index_node; |
| 5926 | Buf *index_var_name = index_node->data.symbol_expr.symbol; | 6466 | Buf *index_var_name_buf = index_node->data.symbol_expr.symbol; |
| 5927 | 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); |
| 5928 | } else { | 6469 | } else { |
| 5929 | index_var_source_node = node; | 6470 | index_var_source_node = node; |
| 5930 | 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"; |
| 5931 | } | 6473 | } |
| 5932 | child_scope = index_var->child_scope; | | |
| 5933 | | 6474 | |
| 5934 | 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); |
| 5935 | 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); |
| 5936 | IrInstruction *one = ir_build_const_usize(irb, child_scope, node, 1); | 6477 | parent_scope = index_var->child_scope; |
| 5937 | ir_build_var_decl_src(irb, child_scope, index_var_source_node, index_var, usize, nullptr, zero); | 6478 | |
| 5938 | 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); |
| 5939 | | 6481 | |
| 5940 | | 6482 | |
| 5941 | IrBasicBlock *cond_block = ir_create_basic_block(irb, child_scope, "ForCond"); | 6483 | IrBasicBlock *cond_block = ir_create_basic_block(irb, parent_scope, "ForCond"); |
| 5942 | IrBasicBlock *body_block = ir_create_basic_block(irb, child_scope, "ForBody"); | 6484 | IrBasicBlock *body_block = ir_create_basic_block(irb, parent_scope, "ForBody"); |
| 5943 | IrBasicBlock *end_block = ir_create_basic_block(irb, child_scope, "ForEnd"); | 6485 | IrBasicBlock *end_block = ir_create_basic_block(irb, parent_scope, "ForEnd"); |
| 5944 | 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; |
| 5945 | IrBasicBlock *continue_block = ir_create_basic_block(irb, child_scope, "ForContinue"); | 6487 | IrBasicBlock *continue_block = ir_create_basic_block(irb, parent_scope, "ForContinue"); |
| 5946 | | 6488 | |
| 5947 | Buf *len_field_name = buf_create_from_str("len"); | 6489 | Buf *len_field_name = buf_create_from_str("len"); |
| 5948 | 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); |
| 5949 | 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); |
| 5950 | ir_build_br(irb, child_scope, node, cond_block, is_comptime); | 6492 | ir_build_br(irb, parent_scope, node, cond_block, is_comptime); |
| 5951 | | 6493 | |
| 5952 | ir_set_cursor_at_end_and_append_block(irb, cond_block); | 6494 | ir_set_cursor_at_end_and_append_block(irb, cond_block); |
| 5953 | 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); |
| 5954 | 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); |
| 5955 | IrBasicBlock *after_cond_block = irb->current_basic_block; | 6497 | IrBasicBlock *after_cond_block = irb->current_basic_block; |
| 5956 | 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)); |
| 5957 | 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); |
| 5958 | | 6503 | |
| 5959 | ir_set_cursor_at_end_and_append_block(irb, body_block); | 6504 | ir_set_cursor_at_end_and_append_block(irb, body_block); |
| 5960 | 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, |
| 5961 | IrInstruction *elem_val; | 6506 | PtrLenSingle, nullptr); |
| 5962 | if (node->data.for_expr.elem_is_ptr) { | 6507 | // TODO make it an error to write to element variable or i variable. |
| 5963 | elem_val = elem_ptr; | 6508 | Buf *elem_var_name = elem_node->data.symbol_expr.symbol; |
| 5964 | } else { | 6509 | ZigVar *elem_var = ir_create_var(irb, elem_node, parent_scope, elem_var_name, true, false, false, is_comptime); |
| 5965 | elem_val = ir_build_load_ptr(irb, child_scope, node, elem_ptr); | 6510 | Scope *child_scope = elem_var->child_scope; |
| 5966 | } | 6511 | |
| 5967 | 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); |
| 5968 | | 6515 | |
| 5969 | ZigList<IrInstruction *> incoming_values = {0}; | 6516 | ZigList<IrInstruction *> incoming_values = {0}; |
| 5970 | ZigList<IrBasicBlock *> incoming_blocks = {0}; | 6517 | ZigList<IrBasicBlock *> incoming_blocks = {0}; |
| ... | @@ -5974,7 +6521,12 @@ static IrInstruction *ir_gen_for_expr(IrBuilder *irb, Scope *parent_scope, AstNo | ... | @@ -5974,7 +6521,12 @@ static IrInstruction *ir_gen_for_expr(IrBuilder *irb, Scope *parent_scope, AstNo |
| 5974 | loop_scope->is_comptime = is_comptime; | 6521 | loop_scope->is_comptime = is_comptime; |
| 5975 | loop_scope->incoming_blocks = &incoming_blocks; | 6522 | loop_scope->incoming_blocks = &incoming_blocks; |
| 5976 | loop_scope->incoming_values = &incoming_values; | 6523 | loop_scope->incoming_values = &incoming_values; |
| | 6524 | loop_scope->lval = lval; |
| | 6525 | loop_scope->peer_parent = peer_parent; |
| 5977 | | 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. |
| 5978 | 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); |
| 5979 | | 6531 | |
| 5980 | if (!instr_is_unreachable(body_result)) { | 6532 | if (!instr_is_unreachable(body_result)) { |
| ... | @@ -5991,7 +6543,12 @@ static IrInstruction *ir_gen_for_expr(IrBuilder *irb, Scope *parent_scope, AstNo | ... | @@ -5991,7 +6543,12 @@ static IrInstruction *ir_gen_for_expr(IrBuilder *irb, Scope *parent_scope, AstNo |
| 5991 | if (else_node) { | 6543 | if (else_node) { |
| 5992 | ir_set_cursor_at_end_and_append_block(irb, else_block); | 6544 | ir_set_cursor_at_end_and_append_block(irb, else_block); |
| 5993 | | 6545 | |
| 5994 | 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, lval, &peer_result->base); |
| 5995 | if (else_result == irb->codegen->invalid_instruction) | 6552 | if (else_result == irb->codegen->invalid_instruction) |
| 5996 | return else_result; | 6553 | return else_result; |
| 5997 | if (!instr_is_unreachable(else_result)) | 6554 | if (!instr_is_unreachable(else_result)) |
| ... | @@ -6007,8 +6564,13 @@ static IrInstruction *ir_gen_for_expr(IrBuilder *irb, Scope *parent_scope, AstNo | ... | @@ -6007,8 +6564,13 @@ static IrInstruction *ir_gen_for_expr(IrBuilder *irb, Scope *parent_scope, AstNo |
| 6007 | incoming_blocks.append(after_cond_block); | 6564 | incoming_blocks.append(after_cond_block); |
| 6008 | incoming_values.append(void_else_value); | 6565 | incoming_values.append(void_else_value); |
| 6009 | } | 6566 | } |
| | 6567 | if (peer_parent->peers.length != 0) { |
| | 6568 | peer_parent->peers.last()->next_bb = end_block; |
| | 6569 | } |
| 6010 | | 6570 | |
| 6011 | 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_expr_wrap(irb, parent_scope, phi, result_loc); |
| 6012 | } | 6574 | } |
| 6013 | | 6575 | |
| 6014 | 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) { |
| ... | @@ -6293,7 +6855,9 @@ static IrInstruction *ir_gen_asm_expr(IrBuilder *irb, Scope *scope, AstNode *nod | ... | @@ -6293,7 +6855,9 @@ static IrInstruction *ir_gen_asm_expr(IrBuilder *irb, Scope *scope, AstNode *nod |
| 6293 | input_list, output_types, output_vars, return_count, is_volatile); | 6855 | input_list, output_types, output_vars, return_count, is_volatile); |
| 6294 | } | 6856 | } |
| 6295 | | 6857 | |
| 6296 | 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 | { |
| 6297 | assert(node->type == NodeTypeIfOptional); | 6861 | assert(node->type == NodeTypeIfOptional); |
| 6298 | | 6862 | |
| 6299 | Buf *var_symbol = node->data.test_expr.var_symbol; | 6863 | Buf *var_symbol = node->data.test_expr.var_symbol; |
| ... | @@ -6302,7 +6866,7 @@ static IrInstruction *ir_gen_if_optional_expr(IrBuilder *irb, Scope *scope, AstN | ... | @@ -6302,7 +6866,7 @@ static IrInstruction *ir_gen_if_optional_expr(IrBuilder *irb, Scope *scope, AstN |
| 6302 | AstNode *else_node = node->data.test_expr.else_node; | 6866 | AstNode *else_node = node->data.test_expr.else_node; |
| 6303 | bool var_is_ptr = node->data.test_expr.var_is_ptr; | 6867 | bool var_is_ptr = node->data.test_expr.var_is_ptr; |
| 6304 | | 6868 | |
| 6305 | 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); |
| 6306 | if (maybe_val_ptr == irb->codegen->invalid_instruction) | 6870 | if (maybe_val_ptr == irb->codegen->invalid_instruction) |
| 6307 | return maybe_val_ptr; | 6871 | return maybe_val_ptr; |
| 6308 | | 6872 | |
| ... | @@ -6319,27 +6883,31 @@ static IrInstruction *ir_gen_if_optional_expr(IrBuilder *irb, Scope *scope, AstN | ... | @@ -6319,27 +6883,31 @@ static IrInstruction *ir_gen_if_optional_expr(IrBuilder *irb, Scope *scope, AstN |
| 6319 | } else { | 6883 | } else { |
| 6320 | 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); |
| 6321 | } | 6885 | } |
| 6322 | 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); |
| 6323 | | 6891 | |
| 6324 | ir_set_cursor_at_end_and_append_block(irb, then_block); | 6892 | ir_set_cursor_at_end_and_append_block(irb, then_block); |
| 6325 | | 6893 | |
| 6326 | 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); |
| 6327 | Scope *var_scope; | 6895 | Scope *var_scope; |
| 6328 | if (var_symbol) { | 6896 | if (var_symbol) { |
| 6329 | IrInstruction *var_type = nullptr; | | |
| 6330 | bool is_shadowable = false; | 6897 | bool is_shadowable = false; |
| 6331 | bool is_const = true; | 6898 | bool is_const = true; |
| 6332 | ZigVar *var = ir_create_var(irb, node, subexpr_scope, | 6899 | ZigVar *var = ir_create_var(irb, node, subexpr_scope, |
| 6333 | var_symbol, is_const, is_const, is_shadowable, is_comptime); | 6900 | var_symbol, is_const, is_const, is_shadowable, is_comptime); |
| 6334 | | 6901 | |
| 6335 | 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); |
| 6336 | 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; |
| 6337 | 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); |
| 6338 | var_scope = var->child_scope; | 6905 | var_scope = var->child_scope; |
| 6339 | } else { | 6906 | } else { |
| 6340 | var_scope = subexpr_scope; | 6907 | var_scope = subexpr_scope; |
| 6341 | } | 6908 | } |
| 6342 | 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); |
| 6343 | if (then_expr_result == irb->codegen->invalid_instruction) | 6911 | if (then_expr_result == irb->codegen->invalid_instruction) |
| 6344 | return then_expr_result; | 6912 | return then_expr_result; |
| 6345 | IrBasicBlock *after_then_block = irb->current_basic_block; | 6913 | IrBasicBlock *after_then_block = irb->current_basic_block; |
| ... | @@ -6349,11 +6917,12 @@ static IrInstruction *ir_gen_if_optional_expr(IrBuilder *irb, Scope *scope, AstN | ... | @@ -6349,11 +6917,12 @@ static IrInstruction *ir_gen_if_optional_expr(IrBuilder *irb, Scope *scope, AstN |
| 6349 | ir_set_cursor_at_end_and_append_block(irb, else_block); | 6917 | ir_set_cursor_at_end_and_append_block(irb, else_block); |
| 6350 | IrInstruction *else_expr_result; | 6918 | IrInstruction *else_expr_result; |
| 6351 | if (else_node) { | 6919 | if (else_node) { |
| 6352 | 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); |
| 6353 | if (else_expr_result == irb->codegen->invalid_instruction) | 6921 | if (else_expr_result == irb->codegen->invalid_instruction) |
| 6354 | return else_expr_result; | 6922 | return else_expr_result; |
| 6355 | } else { | 6923 | } else { |
| 6356 | 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); |
| 6357 | } | 6926 | } |
| 6358 | IrBasicBlock *after_else_block = irb->current_basic_block; | 6927 | IrBasicBlock *after_else_block = irb->current_basic_block; |
| 6359 | if (!instr_is_unreachable(else_expr_result)) | 6928 | if (!instr_is_unreachable(else_expr_result)) |
| ... | @@ -6367,10 +6936,13 @@ static IrInstruction *ir_gen_if_optional_expr(IrBuilder *irb, Scope *scope, AstN | ... | @@ -6367,10 +6936,13 @@ static IrInstruction *ir_gen_if_optional_expr(IrBuilder *irb, Scope *scope, AstN |
| 6367 | incoming_blocks[0] = after_then_block; | 6936 | incoming_blocks[0] = after_then_block; |
| 6368 | incoming_blocks[1] = after_else_block; | 6937 | incoming_blocks[1] = after_else_block; |
| 6369 | | 6938 | |
| 6370 | 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); |
| 6371 | } | 6941 | } |
| 6372 | | 6942 | |
| 6373 | 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 | { |
| 6374 | assert(node->type == NodeTypeIfErrorExpr); | 6946 | assert(node->type == NodeTypeIfErrorExpr); |
| 6375 | | 6947 | |
| 6376 | AstNode *target_node = node->data.if_err_expr.target_node; | 6948 | AstNode *target_node = node->data.if_err_expr.target_node; |
| ... | @@ -6381,12 +6953,12 @@ static IrInstruction *ir_gen_if_err_expr(IrBuilder *irb, Scope *scope, AstNode * | ... | @@ -6381,12 +6953,12 @@ static IrInstruction *ir_gen_if_err_expr(IrBuilder *irb, Scope *scope, AstNode * |
| 6381 | Buf *var_symbol = node->data.if_err_expr.var_symbol; | 6953 | Buf *var_symbol = node->data.if_err_expr.var_symbol; |
| 6382 | Buf *err_symbol = node->data.if_err_expr.err_symbol; | 6954 | Buf *err_symbol = node->data.if_err_expr.err_symbol; |
| 6383 | | 6955 | |
| 6384 | 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); |
| 6385 | if (err_val_ptr == irb->codegen->invalid_instruction) | 6957 | if (err_val_ptr == irb->codegen->invalid_instruction) |
| 6386 | return err_val_ptr; | 6958 | return err_val_ptr; |
| 6387 | | 6959 | |
| 6388 | 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); |
| 6389 | 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); |
| 6390 | | 6962 | |
| 6391 | IrBasicBlock *ok_block = ir_create_basic_block(irb, scope, "TryOk"); | 6963 | IrBasicBlock *ok_block = ir_create_basic_block(irb, scope, "TryOk"); |
| 6392 | IrBasicBlock *else_block = ir_create_basic_block(irb, scope, "TryElse"); | 6964 | IrBasicBlock *else_block = ir_create_basic_block(irb, scope, "TryElse"); |
| ... | @@ -6394,27 +6966,31 @@ static IrInstruction *ir_gen_if_err_expr(IrBuilder *irb, Scope *scope, AstNode * | ... | @@ -6394,27 +6966,31 @@ static IrInstruction *ir_gen_if_err_expr(IrBuilder *irb, Scope *scope, AstNode * |
| 6394 | | 6966 | |
| 6395 | bool force_comptime = ir_should_inline(irb->exec, scope); | 6967 | bool force_comptime = ir_should_inline(irb->exec, scope); |
| 6396 | 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); |
| 6397 | 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); |
| 6398 | | 6973 | |
| 6399 | ir_set_cursor_at_end_and_append_block(irb, ok_block); | 6974 | ir_set_cursor_at_end_and_append_block(irb, ok_block); |
| 6400 | | 6975 | |
| 6401 | 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); |
| 6402 | Scope *var_scope; | 6977 | Scope *var_scope; |
| 6403 | if (var_symbol) { | 6978 | if (var_symbol) { |
| 6404 | IrInstruction *var_type = nullptr; | | |
| 6405 | bool is_shadowable = false; | 6979 | bool is_shadowable = false; |
| 6406 | 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); |
| 6407 | ZigVar *var = ir_create_var(irb, node, subexpr_scope, | 6981 | ZigVar *var = ir_create_var(irb, node, subexpr_scope, |
| 6408 | 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); |
| 6409 | | 6983 | |
| 6410 | 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); |
| 6411 | 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 ? |
| 6412 | 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); |
| 6413 | var_scope = var->child_scope; | 6988 | var_scope = var->child_scope; |
| 6414 | } else { | 6989 | } else { |
| 6415 | var_scope = subexpr_scope; | 6990 | var_scope = subexpr_scope; |
| 6416 | } | 6991 | } |
| 6417 | 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); |
| 6418 | if (then_expr_result == irb->codegen->invalid_instruction) | 6994 | if (then_expr_result == irb->codegen->invalid_instruction) |
| 6419 | return then_expr_result; | 6995 | return then_expr_result; |
| 6420 | IrBasicBlock *after_then_block = irb->current_basic_block; | 6996 | IrBasicBlock *after_then_block = irb->current_basic_block; |
| ... | @@ -6427,23 +7003,23 @@ static IrInstruction *ir_gen_if_err_expr(IrBuilder *irb, Scope *scope, AstNode * | ... | @@ -6427,23 +7003,23 @@ static IrInstruction *ir_gen_if_err_expr(IrBuilder *irb, Scope *scope, AstNode * |
| 6427 | if (else_node) { | 7003 | if (else_node) { |
| 6428 | Scope *err_var_scope; | 7004 | Scope *err_var_scope; |
| 6429 | if (err_symbol) { | 7005 | if (err_symbol) { |
| 6430 | IrInstruction *var_type = nullptr; | | |
| 6431 | bool is_shadowable = false; | 7006 | bool is_shadowable = false; |
| 6432 | bool is_const = true; | 7007 | bool is_const = true; |
| 6433 | ZigVar *var = ir_create_var(irb, node, subexpr_scope, | 7008 | ZigVar *var = ir_create_var(irb, node, subexpr_scope, |
| 6434 | err_symbol, is_const, is_const, is_shadowable, is_comptime); | 7009 | err_symbol, is_const, is_const, is_shadowable, is_comptime); |
| 6435 | | 7010 | |
| 6436 | 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); |
| 6437 | 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); |
| 6438 | err_var_scope = var->child_scope; | 7013 | err_var_scope = var->child_scope; |
| 6439 | } else { | 7014 | } else { |
| 6440 | err_var_scope = subexpr_scope; | 7015 | err_var_scope = subexpr_scope; |
| 6441 | } | 7016 | } |
| 6442 | 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); |
| 6443 | if (else_expr_result == irb->codegen->invalid_instruction) | 7018 | if (else_expr_result == irb->codegen->invalid_instruction) |
| 6444 | return else_expr_result; | 7019 | return else_expr_result; |
| 6445 | } else { | 7020 | } else { |
| 6446 | 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); |
| 6447 | } | 7023 | } |
| 6448 | IrBasicBlock *after_else_block = irb->current_basic_block; | 7024 | IrBasicBlock *after_else_block = irb->current_basic_block; |
| 6449 | if (!instr_is_unreachable(else_expr_result)) | 7025 | if (!instr_is_unreachable(else_expr_result)) |
| ... | @@ -6457,14 +7033,15 @@ static IrInstruction *ir_gen_if_err_expr(IrBuilder *irb, Scope *scope, AstNode * | ... | @@ -6457,14 +7033,15 @@ static IrInstruction *ir_gen_if_err_expr(IrBuilder *irb, Scope *scope, AstNode * |
| 6457 | incoming_blocks[0] = after_then_block; | 7033 | incoming_blocks[0] = after_then_block; |
| 6458 | incoming_blocks[1] = after_else_block; | 7034 | incoming_blocks[1] = after_else_block; |
| 6459 | | 7035 | |
| 6460 | 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); |
| 6461 | } | 7038 | } |
| 6462 | | 7039 | |
| 6463 | 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, |
| 6464 | IrBasicBlock *end_block, IrInstruction *is_comptime, IrInstruction *var_is_comptime, | 7041 | IrBasicBlock *end_block, IrInstruction *is_comptime, IrInstruction *var_is_comptime, |
| 6465 | 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, |
| 6466 | ZigList<IrBasicBlock *> *incoming_blocks, ZigList<IrInstruction *> *incoming_values, | 7043 | ZigList<IrBasicBlock *> *incoming_blocks, ZigList<IrInstruction *> *incoming_values, |
| 6467 | IrInstructionSwitchElseVar **out_switch_else_var) | 7044 | IrInstructionSwitchElseVar **out_switch_else_var, LVal lval, ResultLoc *result_loc) |
| 6468 | { | 7045 | { |
| 6469 | assert(switch_node->type == NodeTypeSwitchExpr); | 7046 | assert(switch_node->type == NodeTypeSwitchExpr); |
| 6470 | assert(prong_node->type == NodeTypeSwitchProng); | 7047 | assert(prong_node->type == NodeTypeSwitchProng); |
| ... | @@ -6482,28 +7059,27 @@ static bool ir_gen_switch_prong_expr(IrBuilder *irb, Scope *scope, AstNode *swit | ... | @@ -6482,28 +7059,27 @@ static bool ir_gen_switch_prong_expr(IrBuilder *irb, Scope *scope, AstNode *swit |
| 6482 | ZigVar *var = ir_create_var(irb, var_symbol_node, scope, | 7059 | ZigVar *var = ir_create_var(irb, var_symbol_node, scope, |
| 6483 | var_name, is_const, is_const, is_shadowable, var_is_comptime); | 7060 | var_name, is_const, is_const, is_shadowable, var_is_comptime); |
| 6484 | child_scope = var->child_scope; | 7061 | child_scope = var->child_scope; |
| 6485 | IrInstruction *var_value; | 7062 | IrInstruction *var_ptr; |
| 6486 | if (out_switch_else_var != nullptr) { | 7063 | if (out_switch_else_var != nullptr) { |
| 6487 | 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, |
| 6488 | target_value_ptr); | 7065 | target_value_ptr); |
| 6489 | *out_switch_else_var = switch_else_var; | 7066 | *out_switch_else_var = switch_else_var; |
| 6490 | IrInstruction *var_ptr_value = &switch_else_var->base; | 7067 | IrInstruction *payload_ptr = &switch_else_var->base; |
| 6491 | 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; |
| 6492 | } else if (prong_values != nullptr) { | 7069 | } else if (prong_values != nullptr) { |
| 6493 | 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, |
| 6494 | prong_values, prong_values_len); | 7071 | prong_values, prong_values_len); |
| 6495 | 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; |
| 6496 | } else { | 7073 | } else { |
| 6497 | var_value = var_is_ptr ? target_value_ptr : ir_build_load_ptr(irb, scope, var_symbol_node, | 7074 | var_ptr = var_is_ptr ? |
| 6498 | target_value_ptr); | 7075 | ir_build_ref(irb, scope, var_symbol_node, target_value_ptr, true, false) : target_value_ptr; |
| 6499 | } | 7076 | } |
| 6500 | IrInstruction *var_type = nullptr; // infer the type | 7077 | ir_build_var_decl_src(irb, scope, var_symbol_node, var, nullptr, var_ptr); |
| 6501 | ir_build_var_decl_src(irb, scope, var_symbol_node, var, var_type, nullptr, var_value); | | |
| 6502 | } else { | 7078 | } else { |
| 6503 | child_scope = scope; | 7079 | child_scope = scope; |
| 6504 | } | 7080 | } |
| 6505 | | 7081 | |
| 6506 | 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); |
| 6507 | if (expr_result == irb->codegen->invalid_instruction) | 7083 | if (expr_result == irb->codegen->invalid_instruction) |
| 6508 | return false; | 7084 | return false; |
| 6509 | if (!instr_is_unreachable(expr_result)) | 7085 | if (!instr_is_unreachable(expr_result)) |
| ... | @@ -6513,11 +7089,13 @@ target_value_ptr); | ... | @@ -6513,11 +7089,13 @@ target_value_ptr); |
| 6513 | return true; | 7089 | return true; |
| 6514 | } | 7090 | } |
| 6515 | | 7091 | |
| 6516 | 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 | { |
| 6517 | assert(node->type == NodeTypeSwitchExpr); | 7095 | assert(node->type == NodeTypeSwitchExpr); |
| 6518 | | 7096 | |
| 6519 | AstNode *target_node = node->data.switch_expr.expr; | 7097 | AstNode *target_node = node->data.switch_expr.expr; |
| 6520 | 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); |
| 6521 | if (target_value_ptr == irb->codegen->invalid_instruction) | 7099 | if (target_value_ptr == irb->codegen->invalid_instruction) |
| 6522 | return target_value_ptr; | 7100 | return target_value_ptr; |
| 6523 | 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); |
| ... | @@ -6544,6 +7122,14 @@ static IrInstruction *ir_gen_switch_expr(IrBuilder *irb, Scope *scope, AstNode * | ... | @@ -6544,6 +7122,14 @@ static IrInstruction *ir_gen_switch_expr(IrBuilder *irb, Scope *scope, AstNode * |
| 6544 | | 7122 | |
| 6545 | IrInstructionSwitchElseVar *switch_else_var = nullptr; | 7123 | IrInstructionSwitchElseVar *switch_else_var = nullptr; |
| 6546 | | 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 | |
| 6547 | // First do the else and the ranges | 7133 | // First do the else and the ranges |
| 6548 | 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); |
| 6549 | Scope *comptime_scope = create_comptime_scope(irb->codegen, node, scope); | 7135 | Scope *comptime_scope = create_comptime_scope(irb->codegen, node, scope); |
| ... | @@ -6552,6 +7138,7 @@ static IrInstruction *ir_gen_switch_expr(IrBuilder *irb, Scope *scope, AstNode * | ... | @@ -6552,6 +7138,7 @@ static IrInstruction *ir_gen_switch_expr(IrBuilder *irb, Scope *scope, AstNode * |
| 6552 | AstNode *prong_node = node->data.switch_expr.prongs.at(prong_i); | 7138 | AstNode *prong_node = node->data.switch_expr.prongs.at(prong_i); |
| 6553 | 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; |
| 6554 | if (prong_item_count == 0) { | 7140 | if (prong_item_count == 0) { |
| | 7141 | ResultLocPeer *this_peer_result_loc = create_peer_result(peer_parent); |
| 6555 | if (else_prong) { | 7142 | if (else_prong) { |
| 6556 | ErrorMsg *msg = add_node_error(irb->codegen, prong_node, | 7143 | ErrorMsg *msg = add_node_error(irb->codegen, prong_node, |
| 6557 | buf_sprintf("multiple else prongs in switch expression")); | 7144 | buf_sprintf("multiple else prongs in switch expression")); |
| ... | @@ -6562,15 +7149,21 @@ static IrInstruction *ir_gen_switch_expr(IrBuilder *irb, Scope *scope, AstNode * | ... | @@ -6562,15 +7149,21 @@ static IrInstruction *ir_gen_switch_expr(IrBuilder *irb, Scope *scope, AstNode * |
| 6562 | else_prong = prong_node; | 7149 | else_prong = prong_node; |
| 6563 | | 7150 | |
| 6564 | 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); |
| 6565 | ir_set_cursor_at_end_and_append_block(irb, else_block); | 7156 | ir_set_cursor_at_end_and_append_block(irb, else_block); |
| 6566 | 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, |
| 6567 | 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, |
| 6568 | &switch_else_var)) | 7159 | &switch_else_var, lval, &this_peer_result_loc->base)) |
| 6569 | { | 7160 | { |
| 6570 | return irb->codegen->invalid_instruction; | 7161 | return irb->codegen->invalid_instruction; |
| 6571 | } | 7162 | } |
| 6572 | ir_set_cursor_at_end(irb, prev_block); | 7163 | ir_set_cursor_at_end(irb, prev_block); |
| 6573 | } 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 | |
| 6574 | IrInstruction *ok_bit = nullptr; | 7167 | IrInstruction *ok_bit = nullptr; |
| 6575 | AstNode *last_item_node = nullptr; | 7168 | AstNode *last_item_node = nullptr; |
| 6576 | 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) { |
| ... | @@ -6627,13 +7220,20 @@ static IrInstruction *ir_gen_switch_expr(IrBuilder *irb, Scope *scope, AstNode * | ... | @@ -6627,13 +7220,20 @@ static IrInstruction *ir_gen_switch_expr(IrBuilder *irb, Scope *scope, AstNode * |
| 6627 | | 7220 | |
| 6628 | assert(ok_bit); | 7221 | assert(ok_bit); |
| 6629 | assert(last_item_node); | 7222 | assert(last_item_node); |
| 6630 | 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, |
| 6631 | 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 | } |
| 6632 | | 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); |
| 6633 | 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); |
| 6634 | 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, |
| 6635 | is_comptime, var_is_comptime, target_value_ptr, nullptr, 0, | 7235 | is_comptime, var_is_comptime, target_value_ptr, nullptr, 0, |
| 6636 | &incoming_blocks, &incoming_values, nullptr)) | 7236 | &incoming_blocks, &incoming_values, nullptr, lval, &this_peer_result_loc->base)) |
| 6637 | { | 7237 | { |
| 6638 | return irb->codegen->invalid_instruction; | 7238 | return irb->codegen->invalid_instruction; |
| 6639 | } | 7239 | } |
| ... | @@ -6651,6 +7251,8 @@ static IrInstruction *ir_gen_switch_expr(IrBuilder *irb, Scope *scope, AstNode * | ... | @@ -6651,6 +7251,8 @@ static IrInstruction *ir_gen_switch_expr(IrBuilder *irb, Scope *scope, AstNode * |
| 6651 | if (prong_node->data.switch_prong.any_items_are_range) | 7251 | if (prong_node->data.switch_prong.any_items_are_range) |
| 6652 | continue; | 7252 | continue; |
| 6653 | | 7253 | |
| | 7254 | ResultLocPeer *this_peer_result_loc = create_peer_result(peer_parent); |
| | 7255 | |
| 6654 | IrBasicBlock *prong_block = ir_create_basic_block(irb, scope, "SwitchProng"); | 7256 | IrBasicBlock *prong_block = ir_create_basic_block(irb, scope, "SwitchProng"); |
| 6655 | IrInstruction **items = allocate<IrInstruction *>(prong_item_count); | 7257 | IrInstruction **items = allocate<IrInstruction *>(prong_item_count); |
| 6656 | | 7258 | |
| ... | @@ -6674,10 +7276,14 @@ static IrInstruction *ir_gen_switch_expr(IrBuilder *irb, Scope *scope, AstNode * | ... | @@ -6674,10 +7276,14 @@ static IrInstruction *ir_gen_switch_expr(IrBuilder *irb, Scope *scope, AstNode * |
| 6674 | } | 7276 | } |
| 6675 | | 7277 | |
| 6676 | 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); |
| 6677 | ir_set_cursor_at_end_and_append_block(irb, prong_block); | 7283 | ir_set_cursor_at_end_and_append_block(irb, prong_block); |
| 6678 | 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, |
| 6679 | 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, |
| 6680 | &incoming_blocks, &incoming_values, nullptr)) | 7286 | &incoming_blocks, &incoming_values, nullptr, lval, &this_peer_result_loc->base)) |
| 6681 | { | 7287 | { |
| 6682 | return irb->codegen->invalid_instruction; | 7288 | return irb->codegen->invalid_instruction; |
| 6683 | } | 7289 | } |
| ... | @@ -6686,38 +7292,57 @@ static IrInstruction *ir_gen_switch_expr(IrBuilder *irb, Scope *scope, AstNode * | ... | @@ -6686,38 +7292,57 @@ static IrInstruction *ir_gen_switch_expr(IrBuilder *irb, Scope *scope, AstNode * |
| 6686 | | 7292 | |
| 6687 | } | 7293 | } |
| 6688 | | 7294 | |
| 6689 | 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, |
| 6690 | else_prong != nullptr); | 7296 | check_ranges.items, check_ranges.length, else_prong != nullptr); |
| 6691 | | 7297 | |
| | 7298 | IrInstruction *br_instruction; |
| 6692 | if (cases.length == 0) { | 7299 | if (cases.length == 0) { |
| 6693 | ir_build_br(irb, scope, node, else_block, is_comptime); | 7300 | br_instruction = ir_build_br(irb, scope, node, else_block, is_comptime); |
| 6694 | } else { | 7301 | } else { |
| 6695 | 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, |
| 6696 | cases.length, cases.items, is_comptime, switch_prongs_void); | 7303 | cases.length, cases.items, is_comptime, switch_prongs_void); |
| 6697 | if (switch_else_var != nullptr) { | 7304 | if (switch_else_var != nullptr) { |
| 6698 | switch_else_var->switch_br = switch_br; | 7305 | switch_else_var->switch_br = switch_br; |
| 6699 | } | 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; |
| 6700 | } | 7314 | } |
| 6701 | | 7315 | |
| 6702 | if (!else_prong) { | 7316 | if (!else_prong) { |
| | 7317 | if (peer_parent->peers.length != 0) { |
| | 7318 | peer_parent->peers.last()->next_bb = else_block; |
| | 7319 | } |
| 6703 | ir_set_cursor_at_end_and_append_block(irb, else_block); | 7320 | ir_set_cursor_at_end_and_append_block(irb, else_block); |
| 6704 | 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 | } |
| 6705 | } | 7326 | } |
| 6706 | | 7327 | |
| 6707 | ir_set_cursor_at_end_and_append_block(irb, end_block); | 7328 | ir_set_cursor_at_end_and_append_block(irb, end_block); |
| 6708 | assert(incoming_blocks.length == incoming_values.length); | 7329 | assert(incoming_blocks.length == incoming_values.length); |
| | 7330 | IrInstruction *result_instruction; |
| 6709 | if (incoming_blocks.length == 0) { | 7331 | if (incoming_blocks.length == 0) { |
| 6710 | return ir_build_const_void(irb, scope, node); | 7332 | result_instruction = ir_build_const_void(irb, scope, node); |
| 6711 | } else { | 7333 | } else { |
| 6712 | 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); |
| 6713 | } | 7336 | } |
| | 7337 | return ir_expr_wrap(irb, scope, result_instruction, result_loc); |
| 6714 | } | 7338 | } |
| 6715 | | 7339 | |
| 6716 | 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) { |
| 6717 | assert(node->type == NodeTypeCompTime); | 7341 | assert(node->type == NodeTypeCompTime); |
| 6718 | | 7342 | |
| 6719 | Scope *child_scope = create_comptime_scope(irb->codegen, node, parent_scope); | 7343 | Scope *child_scope = create_comptime_scope(irb->codegen, node, parent_scope); |
| 6720 | 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); |
| 6721 | } | 7346 | } |
| 6722 | | 7347 | |
| 6723 | 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) { |
| ... | @@ -6730,7 +7355,11 @@ static IrInstruction *ir_gen_return_from_block(IrBuilder *irb, Scope *break_scop | ... | @@ -6730,7 +7355,11 @@ static IrInstruction *ir_gen_return_from_block(IrBuilder *irb, Scope *break_scop |
| 6730 | | 7355 | |
| 6731 | IrInstruction *result_value; | 7356 | IrInstruction *result_value; |
| 6732 | if (node->data.break_expr.expr) { | 7357 | if (node->data.break_expr.expr) { |
| 6733 | 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); |
| 6734 | if (result_value == irb->codegen->invalid_instruction) | 7363 | if (result_value == irb->codegen->invalid_instruction) |
| 6735 | return irb->codegen->invalid_instruction; | 7364 | return irb->codegen->invalid_instruction; |
| 6736 | } else { | 7365 | } else { |
| ... | @@ -6800,7 +7429,11 @@ static IrInstruction *ir_gen_break(IrBuilder *irb, Scope *break_scope, AstNode * | ... | @@ -6800,7 +7429,11 @@ static IrInstruction *ir_gen_break(IrBuilder *irb, Scope *break_scope, AstNode * |
| 6800 | | 7429 | |
| 6801 | IrInstruction *result_value; | 7430 | IrInstruction *result_value; |
| 6802 | if (node->data.break_expr.expr) { | 7431 | if (node->data.break_expr.expr) { |
| 6803 | 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); |
| 6804 | if (result_value == irb->codegen->invalid_instruction) | 7437 | if (result_value == irb->codegen->invalid_instruction) |
| 6805 | return irb->codegen->invalid_instruction; | 7438 | return irb->codegen->invalid_instruction; |
| 6806 | } else { | 7439 | } else { |
| ... | @@ -6888,7 +7521,7 @@ static IrInstruction *ir_gen_defer(IrBuilder *irb, Scope *parent_scope, AstNode | ... | @@ -6888,7 +7521,7 @@ static IrInstruction *ir_gen_defer(IrBuilder *irb, Scope *parent_scope, AstNode |
| 6888 | return ir_build_const_void(irb, parent_scope, node); | 7521 | return ir_build_const_void(irb, parent_scope, node); |
| 6889 | } | 7522 | } |
| 6890 | | 7523 | |
| 6891 | 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) { |
| 6892 | assert(node->type == NodeTypeSliceExpr); | 7525 | assert(node->type == NodeTypeSliceExpr); |
| 6893 | | 7526 | |
| 6894 | AstNodeSliceExpr *slice_expr = &node->data.slice_expr; | 7527 | AstNodeSliceExpr *slice_expr = &node->data.slice_expr; |
| ... | @@ -6896,7 +7529,7 @@ static IrInstruction *ir_gen_slice(IrBuilder *irb, Scope *scope, AstNode *node) | ... | @@ -6896,7 +7529,7 @@ static IrInstruction *ir_gen_slice(IrBuilder *irb, Scope *scope, AstNode *node) |
| 6896 | AstNode *start_node = slice_expr->start; | 7529 | AstNode *start_node = slice_expr->start; |
| 6897 | AstNode *end_node = slice_expr->end; | 7530 | AstNode *end_node = slice_expr->end; |
| 6898 | | 7531 | |
| 6899 | 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); |
| 6900 | if (ptr_value == irb->codegen->invalid_instruction) | 7533 | if (ptr_value == irb->codegen->invalid_instruction) |
| 6901 | return irb->codegen->invalid_instruction; | 7534 | return irb->codegen->invalid_instruction; |
| 6902 | | 7535 | |
| ... | @@ -6913,11 +7546,14 @@ static IrInstruction *ir_gen_slice(IrBuilder *irb, Scope *scope, AstNode *node) | ... | @@ -6913,11 +7546,14 @@ static IrInstruction *ir_gen_slice(IrBuilder *irb, Scope *scope, AstNode *node) |
| 6913 | end_value = nullptr; | 7546 | end_value = nullptr; |
| 6914 | } | 7547 | } |
| 6915 | | 7548 | |
| 6916 | 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); |
| 6917 | } | 7551 | } |
| 6918 | | 7552 | |
| 6919 | 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, |
| 6920 | assert(node->type == NodeTypeUnwrapErrorExpr); | 7554 | ResultLoc *result_loc) |
| | 7555 | { |
| | 7556 | assert(node->type == NodeTypeCatchExpr); |
| 6921 | | 7557 | |
| 6922 | AstNode *op1_node = node->data.unwrap_err_expr.op1; | 7558 | AstNode *op1_node = node->data.unwrap_err_expr.op1; |
| 6923 | AstNode *op2_node = node->data.unwrap_err_expr.op2; | 7559 | AstNode *op2_node = node->data.unwrap_err_expr.op2; |
| ... | @@ -6930,16 +7566,15 @@ static IrInstruction *ir_gen_catch(IrBuilder *irb, Scope *parent_scope, AstNode | ... | @@ -6930,16 +7566,15 @@ static IrInstruction *ir_gen_catch(IrBuilder *irb, Scope *parent_scope, AstNode |
| 6930 | 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))); |
| 6931 | return irb->codegen->invalid_instruction; | 7567 | return irb->codegen->invalid_instruction; |
| 6932 | } | 7568 | } |
| 6933 | 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); |
| 6934 | } | 7570 | } |
| 6935 | | 7571 | |
| 6936 | | 7572 | |
| 6937 | 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); |
| 6938 | if (err_union_ptr == irb->codegen->invalid_instruction) | 7574 | if (err_union_ptr == irb->codegen->invalid_instruction) |
| 6939 | return irb->codegen->invalid_instruction; | 7575 | return irb->codegen->invalid_instruction; |
| 6940 | | 7576 | |
| 6941 | 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); |
| 6942 | IrInstruction *is_err = ir_build_test_err(irb, parent_scope, node, err_union_val); | | |
| 6943 | | 7578 | |
| 6944 | IrInstruction *is_comptime; | 7579 | IrInstruction *is_comptime; |
| 6945 | if (ir_should_inline(irb->exec, parent_scope)) { | 7580 | if (ir_should_inline(irb->exec, parent_scope)) { |
| ... | @@ -6951,7 +7586,10 @@ static IrInstruction *ir_gen_catch(IrBuilder *irb, Scope *parent_scope, AstNode | ... | @@ -6951,7 +7586,10 @@ static IrInstruction *ir_gen_catch(IrBuilder *irb, Scope *parent_scope, AstNode |
| 6951 | IrBasicBlock *ok_block = ir_create_basic_block(irb, parent_scope, "UnwrapErrOk"); | 7586 | IrBasicBlock *ok_block = ir_create_basic_block(irb, parent_scope, "UnwrapErrOk"); |
| 6952 | IrBasicBlock *err_block = ir_create_basic_block(irb, parent_scope, "UnwrapErrError"); | 7587 | IrBasicBlock *err_block = ir_create_basic_block(irb, parent_scope, "UnwrapErrError"); |
| 6953 | IrBasicBlock *end_block = ir_create_basic_block(irb, parent_scope, "UnwrapErrEnd"); | 7588 | IrBasicBlock *end_block = ir_create_basic_block(irb, parent_scope, "UnwrapErrEnd"); |
| 6954 | 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); |
| 6955 | | 7593 | |
| 6956 | ir_set_cursor_at_end_and_append_block(irb, err_block); | 7594 | ir_set_cursor_at_end_and_append_block(irb, err_block); |
| 6957 | Scope *err_scope; | 7595 | Scope *err_scope; |
| ... | @@ -6963,12 +7601,12 @@ static IrInstruction *ir_gen_catch(IrBuilder *irb, Scope *parent_scope, AstNode | ... | @@ -6963,12 +7601,12 @@ static IrInstruction *ir_gen_catch(IrBuilder *irb, Scope *parent_scope, AstNode |
| 6963 | ZigVar *var = ir_create_var(irb, node, parent_scope, var_name, | 7601 | ZigVar *var = ir_create_var(irb, node, parent_scope, var_name, |
| 6964 | is_const, is_const, is_shadowable, is_comptime); | 7602 | is_const, is_const, is_shadowable, is_comptime); |
| 6965 | err_scope = var->child_scope; | 7603 | err_scope = var->child_scope; |
| 6966 | 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); |
| 6967 | 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); |
| 6968 | } else { | 7606 | } else { |
| 6969 | err_scope = parent_scope; | 7607 | err_scope = parent_scope; |
| 6970 | } | 7608 | } |
| 6971 | 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); |
| 6972 | if (err_result == irb->codegen->invalid_instruction) | 7610 | if (err_result == irb->codegen->invalid_instruction) |
| 6973 | return irb->codegen->invalid_instruction; | 7611 | return irb->codegen->invalid_instruction; |
| 6974 | IrBasicBlock *after_err_block = irb->current_basic_block; | 7612 | IrBasicBlock *after_err_block = irb->current_basic_block; |
| ... | @@ -6976,8 +7614,9 @@ static IrInstruction *ir_gen_catch(IrBuilder *irb, Scope *parent_scope, AstNode | ... | @@ -6976,8 +7614,9 @@ static IrInstruction *ir_gen_catch(IrBuilder *irb, Scope *parent_scope, AstNode |
| 6976 | 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)); |
| 6977 | | 7615 | |
| 6978 | ir_set_cursor_at_end_and_append_block(irb, ok_block); | 7616 | ir_set_cursor_at_end_and_append_block(irb, ok_block); |
| 6979 | 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); |
| 6980 | 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); |
| 6981 | IrBasicBlock *after_ok_block = irb->current_basic_block; | 7620 | IrBasicBlock *after_ok_block = irb->current_basic_block; |
| 6982 | ir_build_br(irb, parent_scope, node, end_block, is_comptime); | 7621 | ir_build_br(irb, parent_scope, node, end_block, is_comptime); |
| 6983 | | 7622 | |
| ... | @@ -6988,7 +7627,8 @@ static IrInstruction *ir_gen_catch(IrBuilder *irb, Scope *parent_scope, AstNode | ... | @@ -6988,7 +7627,8 @@ static IrInstruction *ir_gen_catch(IrBuilder *irb, Scope *parent_scope, AstNode |
| 6988 | IrBasicBlock **incoming_blocks = allocate<IrBasicBlock *>(2); | 7627 | IrBasicBlock **incoming_blocks = allocate<IrBasicBlock *>(2); |
| 6989 | incoming_blocks[0] = after_err_block; | 7628 | incoming_blocks[0] = after_err_block; |
| 6990 | incoming_blocks[1] = after_ok_block; | 7629 | incoming_blocks[1] = after_ok_block; |
| 6991 | 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); |
| 6992 | } | 7632 | } |
| 6993 | | 7633 | |
| 6994 | 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) { |
| ... | @@ -7264,7 +7904,7 @@ static IrInstruction *ir_gen_cancel_target(IrBuilder *irb, Scope *scope, AstNode | ... | @@ -7264,7 +7904,7 @@ static IrInstruction *ir_gen_cancel_target(IrBuilder *irb, Scope *scope, AstNode |
| 7264 | 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); |
| 7265 | 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); |
| 7266 | 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, |
| 7267 | atomic_state_field_name); | 7907 | atomic_state_field_name, false); |
| 7268 | | 7908 | |
| 7269 | // set the is_canceled bit | 7909 | // set the is_canceled bit |
| 7270 | IrInstruction *prev_atomic_value = ir_build_atomic_rmw(irb, scope, node, | 7910 | IrInstruction *prev_atomic_value = ir_build_atomic_rmw(irb, scope, node, |
| ... | @@ -7343,7 +7983,7 @@ static IrInstruction *ir_gen_resume_target(IrBuilder *irb, Scope *scope, AstNode | ... | @@ -7343,7 +7983,7 @@ static IrInstruction *ir_gen_resume_target(IrBuilder *irb, Scope *scope, AstNode |
| 7343 | 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); |
| 7344 | 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); |
| 7345 | 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, |
| 7346 | atomic_state_field_name); | 7986 | atomic_state_field_name, false); |
| 7347 | | 7987 | |
| 7348 | // clear the is_suspended bit | 7988 | // clear the is_suspended bit |
| 7349 | IrInstruction *prev_atomic_value = ir_build_atomic_rmw(irb, scope, node, | 7989 | IrInstruction *prev_atomic_value = ir_build_atomic_rmw(irb, scope, node, |
| ... | @@ -7410,12 +8050,12 @@ static IrInstruction *ir_gen_await_expr(IrBuilder *irb, Scope *scope, AstNode *n | ... | @@ -7410,12 +8050,12 @@ static IrInstruction *ir_gen_await_expr(IrBuilder *irb, Scope *scope, AstNode *n |
| 7410 | | 8050 | |
| 7411 | 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); |
| 7412 | 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); |
| 7413 | 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); |
| 7414 | | 8054 | |
| 7415 | if (irb->codegen->have_err_ret_tracing) { | 8055 | if (irb->codegen->have_err_ret_tracing) { |
| 7416 | 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); |
| 7417 | 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); |
| 7418 | 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); |
| 7419 | 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); |
| 7420 | } | 8060 | } |
| 7421 | | 8061 | |
| ... | @@ -7437,11 +8077,11 @@ static IrInstruction *ir_gen_await_expr(IrBuilder *irb, Scope *scope, AstNode *n | ... | @@ -7437,11 +8077,11 @@ static IrInstruction *ir_gen_await_expr(IrBuilder *irb, Scope *scope, AstNode *n |
| 7437 | | 8077 | |
| 7438 | 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); |
| 7439 | 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, |
| 7440 | atomic_state_field_name); | 8080 | atomic_state_field_name, false); |
| 7441 | | 8081 | |
| 7442 | 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); |
| 7443 | 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); |
| 7444 | IrInstruction *undefined_value = ir_build_const_undefined(irb, scope, node); | 8084 | IrInstruction *undef = ir_build_const_undefined(irb, scope, node); |
| 7445 | 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); |
| 7446 | IrInstruction *zero = ir_build_const_usize(irb, scope, node, 0); | 8086 | IrInstruction *zero = ir_build_const_usize(irb, scope, node, 0); |
| 7447 | 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 |
| ... | @@ -7455,7 +8095,8 @@ static IrInstruction *ir_gen_await_expr(IrBuilder *irb, Scope *scope, AstNode *n | ... | @@ -7455,7 +8095,8 @@ static IrInstruction *ir_gen_await_expr(IrBuilder *irb, Scope *scope, AstNode *n |
| 7455 | 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); |
| 7456 | 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); |
| 7457 | ir_build_await_bookkeeping(irb, scope, node, promise_result_type); | 8097 | ir_build_await_bookkeeping(irb, scope, node, promise_result_type); |
| 7458 | 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); |
| 7459 | 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); |
| 7460 | 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); |
| 7461 | 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); |
| ... | @@ -7490,12 +8131,12 @@ static IrInstruction *ir_gen_await_expr(IrBuilder *irb, Scope *scope, AstNode *n | ... | @@ -7490,12 +8131,12 @@ static IrInstruction *ir_gen_await_expr(IrBuilder *irb, Scope *scope, AstNode *n |
| 7490 | 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); |
| 7491 | if (irb->codegen->have_err_ret_tracing) { | 8132 | if (irb->codegen->have_err_ret_tracing) { |
| 7492 | 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); |
| 7493 | 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); |
| 7494 | 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); |
| 7495 | 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); |
| 7496 | } | 8137 | } |
| 7497 | Buf *result_field_name = buf_create_from_str(RESULT_FIELD_NAME); | 8138 | Buf *result_field_name = buf_create_from_str(RESULT_FIELD_NAME); |
| 7498 | 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); |
| 7499 | // 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, |
| 7500 | // 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. |
| 7501 | 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); |
| ... | @@ -7671,7 +8312,8 @@ static IrInstruction *ir_gen_suspend(IrBuilder *irb, Scope *parent_scope, AstNod | ... | @@ -7671,7 +8312,8 @@ static IrInstruction *ir_gen_suspend(IrBuilder *irb, Scope *parent_scope, AstNod |
| 7671 | incoming_values[0] = const_bool_true; | 8312 | incoming_values[0] = const_bool_true; |
| 7672 | incoming_blocks[1] = post_cancel_awaiter_block; | 8313 | incoming_blocks[1] = post_cancel_awaiter_block; |
| 7673 | incoming_values[1] = const_bool_false; | 8314 | incoming_values[1] = const_bool_false; |
| 7674 | 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); |
| 7675 | ir_gen_defers_for_block(irb, parent_scope, outer_scope, true); | 8317 | ir_gen_defers_for_block(irb, parent_scope, outer_scope, true); |
| 7676 | 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)); |
| 7677 | | 8319 | |
| ... | @@ -7680,7 +8322,7 @@ static IrInstruction *ir_gen_suspend(IrBuilder *irb, Scope *parent_scope, AstNod | ... | @@ -7680,7 +8322,7 @@ static IrInstruction *ir_gen_suspend(IrBuilder *irb, Scope *parent_scope, AstNod |
| 7680 | } | 8322 | } |
| 7681 | | 8323 | |
| 7682 | 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, |
| 7683 | LVal lval) | 8325 | LVal lval, ResultLoc *result_loc) |
| 7684 | { | 8326 | { |
| 7685 | assert(scope); | 8327 | assert(scope); |
| 7686 | switch (node->type) { | 8328 | switch (node->type) { |
| ... | @@ -7694,37 +8336,37 @@ static IrInstruction *ir_gen_node_raw(IrBuilder *irb, AstNode *node, Scope *scop | ... | @@ -7694,37 +8336,37 @@ static IrInstruction *ir_gen_node_raw(IrBuilder *irb, AstNode *node, Scope *scop |
| 7694 | case NodeTypeTestDecl: | 8336 | case NodeTypeTestDecl: |
| 7695 | zig_unreachable(); | 8337 | zig_unreachable(); |
| 7696 | case NodeTypeBlock: | 8338 | case NodeTypeBlock: |
| 7697 | return ir_lval_wrap(irb, scope, ir_gen_block(irb, scope, node), lval); | 8339 | return ir_gen_block(irb, scope, node, lval, result_loc); |
| 7698 | case NodeTypeGroupedExpr: | 8340 | case NodeTypeGroupedExpr: |
| 7699 | 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); |
| 7700 | case NodeTypeBinOpExpr: | 8342 | case NodeTypeBinOpExpr: |
| 7701 | 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); |
| 7702 | case NodeTypeIntLiteral: | 8344 | case NodeTypeIntLiteral: |
| 7703 | 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); |
| 7704 | case NodeTypeFloatLiteral: | 8346 | case NodeTypeFloatLiteral: |
| 7705 | 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); |
| 7706 | case NodeTypeCharLiteral: | 8348 | case NodeTypeCharLiteral: |
| 7707 | 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); |
| 7708 | case NodeTypeSymbol: | 8350 | case NodeTypeSymbol: |
| 7709 | return ir_gen_symbol(irb, scope, node, lval); | 8351 | return ir_gen_symbol(irb, scope, node, lval, result_loc); |
| 7710 | case NodeTypeFnCallExpr: | 8352 | case NodeTypeFnCallExpr: |
| 7711 | return ir_gen_fn_call(irb, scope, node, lval); | 8353 | return ir_gen_fn_call(irb, scope, node, lval, result_loc); |
| 7712 | case NodeTypeIfBoolExpr: | 8354 | case NodeTypeIfBoolExpr: |
| 7713 | 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); |
| 7714 | case NodeTypePrefixOpExpr: | 8356 | case NodeTypePrefixOpExpr: |
| 7715 | return ir_gen_prefix_op_expr(irb, scope, node, lval); | 8357 | return ir_gen_prefix_op_expr(irb, scope, node, lval, result_loc); |
| 7716 | case NodeTypeContainerInitExpr: | 8358 | case NodeTypeContainerInitExpr: |
| 7717 | 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); |
| 7718 | case NodeTypeVariableDeclaration: | 8360 | case NodeTypeVariableDeclaration: |
| 7719 | return ir_lval_wrap(irb, scope, ir_gen_var_decl(irb, scope, node), lval); | 8361 | return ir_gen_var_decl(irb, scope, node); |
| 7720 | case NodeTypeWhileExpr: | 8362 | case NodeTypeWhileExpr: |
| 7721 | 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); |
| 7722 | case NodeTypeForExpr: | 8364 | case NodeTypeForExpr: |
| 7723 | 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); |
| 7724 | case NodeTypeArrayAccessExpr: | 8366 | case NodeTypeArrayAccessExpr: |
| 7725 | return ir_gen_array_access(irb, scope, node, lval); | 8367 | return ir_gen_array_access(irb, scope, node, lval, result_loc); |
| 7726 | case NodeTypeReturnExpr: | 8368 | case NodeTypeReturnExpr: |
| 7727 | return ir_gen_return(irb, scope, node, lval); | 8369 | return ir_gen_return(irb, scope, node, lval, result_loc); |
| 7728 | case NodeTypeFieldAccessExpr: | 8370 | case NodeTypeFieldAccessExpr: |
| 7729 | { | 8371 | { |
| 7730 | IrInstruction *ptr_instruction = ir_gen_field_access(irb, scope, node); | 8372 | IrInstruction *ptr_instruction = ir_gen_field_access(irb, scope, node); |
| ... | @@ -7733,86 +8375,89 @@ static IrInstruction *ir_gen_node_raw(IrBuilder *irb, AstNode *node, Scope *scop | ... | @@ -7733,86 +8375,89 @@ static IrInstruction *ir_gen_node_raw(IrBuilder *irb, AstNode *node, Scope *scop |
| 7733 | if (lval == LValPtr) | 8375 | if (lval == LValPtr) |
| 7734 | return ptr_instruction; | 8376 | return ptr_instruction; |
| 7735 | | 8377 | |
| 7736 | 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); |
| 7737 | } | 8380 | } |
| 7738 | case NodeTypePtrDeref: { | 8381 | case NodeTypePtrDeref: { |
| 7739 | AstNode *expr_node = node->data.ptr_deref_expr.target; | 8382 | AstNode *expr_node = node->data.ptr_deref_expr.target; |
| 7740 | IrInstruction *value = ir_gen_node_extra(irb, expr_node, scope, lval); | 8383 | IrInstruction *value = ir_gen_node_extra(irb, expr_node, scope, lval, nullptr); |
| 7741 | if (value == irb->codegen->invalid_instruction) | 8384 | if (value == irb->codegen->invalid_instruction) |
| 7742 | return value; | 8385 | return value; |
| 7743 | | 8386 | |
| 7744 | // We essentially just converted any lvalue from &(x.*) to (&x).*; | 8387 | // We essentially just converted any lvalue from &(x.*) to (&x).*; |
| 7745 | // 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 |
| 7746 | // record whether the pointer check is needed | 8389 | // record whether the pointer check is needed |
| 7747 | 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); |
| 7748 | } | 8392 | } |
| 7749 | case NodeTypeUnwrapOptional: { | 8393 | case NodeTypeUnwrapOptional: { |
| 7750 | AstNode *expr_node = node->data.unwrap_optional.expr; | 8394 | AstNode *expr_node = node->data.unwrap_optional.expr; |
| 7751 | | 8395 | |
| 7752 | 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); |
| 7753 | if (maybe_ptr == irb->codegen->invalid_instruction) | 8397 | if (maybe_ptr == irb->codegen->invalid_instruction) |
| 7754 | return irb->codegen->invalid_instruction; | 8398 | return irb->codegen->invalid_instruction; |
| 7755 | | 8399 | |
| 7756 | 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); |
| 7757 | if (lval == LValPtr) | 8401 | if (lval == LValPtr) |
| 7758 | return unwrapped_ptr; | 8402 | return unwrapped_ptr; |
| 7759 | | 8403 | |
| 7760 | 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); |
| 7761 | } | 8406 | } |
| 7762 | case NodeTypeBoolLiteral: | 8407 | case NodeTypeBoolLiteral: |
| 7763 | 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); |
| 7764 | case NodeTypeArrayType: | 8409 | case NodeTypeArrayType: |
| 7765 | 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); |
| 7766 | case NodeTypePointerType: | 8411 | case NodeTypePointerType: |
| 7767 | 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); |
| 7768 | case NodeTypePromiseType: | 8413 | case NodeTypePromiseType: |
| 7769 | 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); |
| 7770 | case NodeTypeStringLiteral: | 8415 | case NodeTypeStringLiteral: |
| 7771 | 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); |
| 7772 | case NodeTypeUndefinedLiteral: | 8417 | case NodeTypeUndefinedLiteral: |
| 7773 | 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); |
| 7774 | case NodeTypeAsmExpr: | 8419 | case NodeTypeAsmExpr: |
| 7775 | 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); |
| 7776 | case NodeTypeNullLiteral: | 8421 | case NodeTypeNullLiteral: |
| 7777 | 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); |
| 7778 | case NodeTypeIfErrorExpr: | 8423 | case NodeTypeIfErrorExpr: |
| 7779 | 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); |
| 7780 | case NodeTypeIfOptional: | 8425 | case NodeTypeIfOptional: |
| 7781 | 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); |
| 7782 | case NodeTypeSwitchExpr: | 8427 | case NodeTypeSwitchExpr: |
| 7783 | 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); |
| 7784 | case NodeTypeCompTime: | 8429 | case NodeTypeCompTime: |
| 7785 | return ir_gen_comptime(irb, scope, node, lval); | 8430 | return ir_expr_wrap(irb, scope, ir_gen_comptime(irb, scope, node, lval), result_loc); |
| 7786 | case NodeTypeErrorType: | 8431 | case NodeTypeErrorType: |
| 7787 | 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); |
| 7788 | case NodeTypeBreak: | 8433 | case NodeTypeBreak: |
| 7789 | 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); |
| 7790 | case NodeTypeContinue: | 8435 | case NodeTypeContinue: |
| 7791 | 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); |
| 7792 | case NodeTypeUnreachable: | 8437 | case NodeTypeUnreachable: |
| 7793 | return ir_lval_wrap(irb, scope, ir_build_unreachable(irb, scope, node), lval); | 8438 | return ir_build_unreachable(irb, scope, node); |
| 7794 | case NodeTypeDefer: | 8439 | case NodeTypeDefer: |
| 7795 | 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); |
| 7796 | case NodeTypeSliceExpr: | 8441 | case NodeTypeSliceExpr: |
| 7797 | return ir_lval_wrap(irb, scope, ir_gen_slice(irb, scope, node), lval); | 8442 | return ir_gen_slice(irb, scope, node, lval, result_loc); |
| 7798 | case NodeTypeUnwrapErrorExpr: | 8443 | case NodeTypeCatchExpr: |
| 7799 | return ir_lval_wrap(irb, scope, ir_gen_catch(irb, scope, node), lval); | 8444 | return ir_gen_catch(irb, scope, node, lval, result_loc); |
| 7800 | case NodeTypeContainerDecl: | 8445 | case NodeTypeContainerDecl: |
| 7801 | 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); |
| 7802 | case NodeTypeFnProto: | 8447 | case NodeTypeFnProto: |
| 7803 | 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); |
| 7804 | case NodeTypeErrorSetDecl: | 8449 | case NodeTypeErrorSetDecl: |
| 7805 | 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); |
| 7806 | case NodeTypeCancel: | 8451 | case NodeTypeCancel: |
| 7807 | 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); |
| 7808 | case NodeTypeResume: | 8453 | case NodeTypeResume: |
| 7809 | 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); |
| 7810 | case NodeTypeAwaitExpr: | 8455 | case NodeTypeAwaitExpr: |
| 7811 | 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); |
| 7812 | case NodeTypeSuspend: | 8457 | case NodeTypeSuspend: |
| 7813 | 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); |
| 7814 | case NodeTypeEnumLiteral: | 8459 | case NodeTypeEnumLiteral: |
| 7815 | 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); |
| 7816 | case NodeTypeInferredArrayType: | 8461 | case NodeTypeInferredArrayType: |
| 7817 | add_node_error(irb->codegen, node, | 8462 | add_node_error(irb->codegen, node, |
| 7818 | buf_sprintf("inferred array size invalid here")); | 8463 | buf_sprintf("inferred array size invalid here")); |
| ... | @@ -7821,14 +8466,28 @@ static IrInstruction *ir_gen_node_raw(IrBuilder *irb, AstNode *node, Scope *scop | ... | @@ -7821,14 +8466,28 @@ static IrInstruction *ir_gen_node_raw(IrBuilder *irb, AstNode *node, Scope *scop |
| 7821 | zig_unreachable(); | 8466 | zig_unreachable(); |
| 7822 | } | 8467 | } |
| 7823 | | 8468 | |
| 7824 | static IrInstruction *ir_gen_node_extra(IrBuilder *irb, AstNode *node, Scope *scope, LVal lval) { | 8469 | static ResultLoc *no_result_loc(void) { |
| 7825 | 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); |
| 7826 | irb->exec->invalid = irb->exec->invalid || (result == irb->codegen->invalid_instruction); | 8485 | irb->exec->invalid = irb->exec->invalid || (result == irb->codegen->invalid_instruction); |
| 7827 | return result; | 8486 | return result; |
| 7828 | } | 8487 | } |
| 7829 | | 8488 | |
| 7830 | static IrInstruction *ir_gen_node(IrBuilder *irb, AstNode *node, Scope *scope) { | 8489 | static IrInstruction *ir_gen_node(IrBuilder *irb, AstNode *node, Scope *scope) { |
| 7831 | return ir_gen_node_extra(irb, node, scope, LValNone); | 8490 | return ir_gen_node_extra(irb, node, scope, LValNone, nullptr); |
| 7832 | } | 8491 | } |
| 7833 | | 8492 | |
| 7834 | static void invalidate_exec(IrExecutable *exec) { | 8493 | static void invalidate_exec(IrExecutable *exec) { |
| ... | @@ -7879,17 +8538,19 @@ bool ir_gen(CodeGen *codegen, AstNode *node, Scope *scope, IrExecutable *ir_exec | ... | @@ -7879,17 +8538,19 @@ bool ir_gen(CodeGen *codegen, AstNode *node, Scope *scope, IrExecutable *ir_exec |
| 7879 | | 8538 | |
| 7880 | 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; |
| 7881 | 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 |
| 7882 | 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); |
| 7883 | 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); |
| 7884 | // 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); |
| 7885 | 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); |
| 7886 | 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); |
| 7887 | | 8547 | |
| 7888 | 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); |
| 7889 | IrInstruction *null_value = ir_build_const_null(irb, coro_scope, node); | 8549 | IrInstruction *null_value = ir_build_const_null(irb, coro_scope, node); |
| 7890 | 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, |
| 7891 | get_optional_type(irb->codegen, irb->codegen->builtin_types.entry_promise)); | 8551 | get_optional_type(irb->codegen, irb->codegen->builtin_types.entry_promise)); |
| 7892 | 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); |
| 7893 | 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); |
| 7894 | | 8555 | |
| 7895 | u8_ptr_type = ir_build_const_type(irb, coro_scope, node, | 8556 | u8_ptr_type = ir_build_const_type(irb, coro_scope, node, |
| ... | @@ -7899,13 +8560,14 @@ bool ir_gen(CodeGen *codegen, AstNode *node, Scope *scope, IrExecutable *ir_exec | ... | @@ -7899,13 +8560,14 @@ bool ir_gen(CodeGen *codegen, AstNode *node, Scope *scope, IrExecutable *ir_exec |
| 7899 | 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); |
| 7900 | 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); |
| 7901 | IrInstruction *coro_size = ir_build_coro_size(irb, coro_scope, node); | 8562 | IrInstruction *coro_size = ir_build_coro_size(irb, coro_scope, node); |
| 7902 | 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); |
| 7903 | 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, |
| 7904 | ImplicitAllocatorIdArg); | 8565 | ImplicitAllocatorIdArg); |
| 7905 | 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); |
| 7906 | 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); |
| 7907 | 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); |
| 7908 | 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); |
| 7909 | 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); |
| 7910 | 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); |
| 7911 | 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); |
| ... | @@ -7925,32 +8587,32 @@ bool ir_gen(CodeGen *codegen, AstNode *node, Scope *scope, IrExecutable *ir_exec | ... | @@ -7925,32 +8587,32 @@ bool ir_gen(CodeGen *codegen, AstNode *node, Scope *scope, IrExecutable *ir_exec |
| 7925 | | 8587 | |
| 7926 | 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); |
| 7927 | 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, |
| 7928 | atomic_state_field_name); | 8590 | atomic_state_field_name, false); |
| 7929 | IrInstruction *zero = ir_build_const_usize(irb, scope, node, 0); | 8591 | IrInstruction *zero = ir_build_const_usize(irb, scope, node, 0); |
| 7930 | 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); |
| 7931 | Buf *result_field_name = buf_create_from_str(RESULT_FIELD_NAME); | 8593 | Buf *result_field_name = buf_create_from_str(RESULT_FIELD_NAME); |
| 7932 | 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); |
| 7933 | 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); |
| 7934 | 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); |
| 7935 | 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); |
| 7936 | if (irb->codegen->have_err_ret_tracing) { | 8598 | if (irb->codegen->have_err_ret_tracing) { |
| 7937 | // initialize the error return trace | 8599 | // initialize the error return trace |
| 7938 | 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); |
| 7939 | 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); |
| 7940 | | 8602 | |
| 7941 | 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); |
| 7942 | 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); |
| 7943 | 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); |
| 7944 | | 8606 | |
| 7945 | // coordinate with builtin.zig | 8607 | // coordinate with builtin.zig |
| 7946 | Buf *index_name = buf_create_from_str("index"); | 8608 | Buf *index_name = buf_create_from_str("index"); |
| 7947 | 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); |
| 7948 | ir_build_store_ptr(irb, scope, node, index_ptr, zero); | 8610 | ir_build_store_ptr(irb, scope, node, index_ptr, zero); |
| 7949 | | 8611 | |
| 7950 | Buf *instruction_addresses_name = buf_create_from_str("instruction_addresses"); | 8612 | Buf *instruction_addresses_name = buf_create_from_str("instruction_addresses"); |
| 7951 | 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); |
| 7952 | | 8614 | |
| 7953 | 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()); |
| 7954 | 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); |
| 7955 | } | 8617 | } |
| 7956 | | 8618 | |
| ... | @@ -7961,7 +8623,7 @@ bool ir_gen(CodeGen *codegen, AstNode *node, Scope *scope, IrExecutable *ir_exec | ... | @@ -7961,7 +8623,7 @@ bool ir_gen(CodeGen *codegen, AstNode *node, Scope *scope, IrExecutable *ir_exec |
| 7961 | 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"); |
| 7962 | } | 8624 | } |
| 7963 | | 8625 | |
| 7964 | IrInstruction *result = ir_gen_node_extra(irb, node, scope, LValNone); | 8626 | IrInstruction *result = ir_gen_node_extra(irb, node, scope, LValNone, nullptr); |
| 7965 | assert(result); | 8627 | assert(result); |
| 7966 | if (irb->exec->invalid) | 8628 | if (irb->exec->invalid) |
| 7967 | return false; | 8629 | return false; |
| ... | @@ -8009,7 +8671,7 @@ bool ir_gen(CodeGen *codegen, AstNode *node, Scope *scope, IrExecutable *ir_exec | ... | @@ -8009,7 +8671,7 @@ bool ir_gen(CodeGen *codegen, AstNode *node, Scope *scope, IrExecutable *ir_exec |
| 8009 | } | 8671 | } |
| 8010 | if (irb->codegen->have_err_ret_tracing) { | 8672 | if (irb->codegen->have_err_ret_tracing) { |
| 8011 | 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); |
| 8012 | 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); |
| 8013 | 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); |
| 8014 | 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); |
| 8015 | } | 8677 | } |
| ... | @@ -8017,7 +8679,7 @@ bool ir_gen(CodeGen *codegen, AstNode *node, Scope *scope, IrExecutable *ir_exec | ... | @@ -8017,7 +8679,7 @@ bool ir_gen(CodeGen *codegen, AstNode *node, Scope *scope, IrExecutable *ir_exec |
| 8017 | // 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, |
| 8018 | // otherwise llvm tries to access memory inside the destroyed frame. | 8680 | // otherwise llvm tries to access memory inside the destroyed frame. |
| 8019 | 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, |
| 8020 | irb->exec->await_handle_var_ptr, false); | 8682 | irb->exec->await_handle_var_ptr, false, false); |
| 8021 | 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); |
| 8022 | 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); |
| 8023 | | 8685 | |
| ... | @@ -8031,7 +8693,7 @@ bool ir_gen(CodeGen *codegen, AstNode *node, Scope *scope, IrExecutable *ir_exec | ... | @@ -8031,7 +8693,7 @@ bool ir_gen(CodeGen *codegen, AstNode *node, Scope *scope, IrExecutable *ir_exec |
| 8031 | incoming_values[0] = const_bool_false; | 8693 | incoming_values[0] = const_bool_false; |
| 8032 | incoming_blocks[1] = irb->exec->coro_normal_final; | 8694 | incoming_blocks[1] = irb->exec->coro_normal_final; |
| 8033 | incoming_values[1] = const_bool_true; | 8695 | incoming_values[1] = const_bool_true; |
| 8034 | 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); |
| 8035 | | 8697 | |
| 8036 | IrBasicBlock **merge_incoming_blocks = allocate<IrBasicBlock *>(2); | 8698 | IrBasicBlock **merge_incoming_blocks = allocate<IrBasicBlock *>(2); |
| 8037 | IrInstruction **merge_incoming_values = allocate<IrInstruction *>(2); | 8699 | IrInstruction **merge_incoming_values = allocate<IrInstruction *>(2); |
| ... | @@ -8039,12 +8701,12 @@ bool ir_gen(CodeGen *codegen, AstNode *node, Scope *scope, IrExecutable *ir_exec | ... | @@ -8039,12 +8701,12 @@ bool ir_gen(CodeGen *codegen, AstNode *node, Scope *scope, IrExecutable *ir_exec |
| 8039 | merge_incoming_values[0] = ir_build_const_undefined(irb, scope, node); | 8701 | merge_incoming_values[0] = ir_build_const_undefined(irb, scope, node); |
| 8040 | merge_incoming_blocks[1] = irb->exec->coro_normal_final; | 8702 | merge_incoming_blocks[1] = irb->exec->coro_normal_final; |
| 8041 | merge_incoming_values[1] = await_handle_in_block; | 8703 | merge_incoming_values[1] = await_handle_in_block; |
| 8042 | 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); |
| 8043 | | 8705 | |
| 8044 | 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); |
| 8045 | 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, |
| 8046 | ImplicitAllocatorIdLocalVar); | 8708 | ImplicitAllocatorIdLocalVar); |
| 8047 | 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); |
| 8048 | 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); |
| 8049 | IrInstruction *zero = ir_build_const_usize(irb, scope, node, 0); | 8711 | IrInstruction *zero = ir_build_const_usize(irb, scope, node, 0); |
| 8050 | 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); |
| ... | @@ -8056,7 +8718,8 @@ bool ir_gen(CodeGen *codegen, AstNode *node, Scope *scope, IrExecutable *ir_exec | ... | @@ -8056,7 +8718,8 @@ bool ir_gen(CodeGen *codegen, AstNode *node, Scope *scope, IrExecutable *ir_exec |
| 8056 | 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); |
| 8057 | 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); |
| 8058 | 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); |
| 8059 | 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()); |
| 8060 | size_t arg_count = 5; | 8723 | size_t arg_count = 5; |
| 8061 | IrInstruction **args = allocate<IrInstruction *>(arg_count); | 8724 | IrInstruction **args = allocate<IrInstruction *>(arg_count); |
| 8062 | args[0] = implicit_allocator_ptr; // self | 8725 | args[0] = implicit_allocator_ptr; // self |
| ... | @@ -8070,7 +8733,8 @@ bool ir_gen(CodeGen *codegen, AstNode *node, Scope *scope, IrExecutable *ir_exec | ... | @@ -8070,7 +8733,8 @@ bool ir_gen(CodeGen *codegen, AstNode *node, Scope *scope, IrExecutable *ir_exec |
| 8070 | // 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. |
| 8071 | 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 |
| 8072 | 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 |
| 8073 | 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()); |
| 8074 | | 8738 | |
| 8075 | IrBasicBlock *resume_block = ir_create_basic_block(irb, scope, "Resume"); | 8739 | IrBasicBlock *resume_block = ir_create_basic_block(irb, scope, "Resume"); |
| 8076 | 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); |
| ... | @@ -8177,6 +8841,15 @@ static ConstExprValue *ir_exec_const_result(CodeGen *codegen, IrExecutable *exec | ... | @@ -8177,6 +8841,15 @@ static ConstExprValue *ir_exec_const_result(CodeGen *codegen, IrExecutable *exec |
| 8177 | } | 8841 | } |
| 8178 | return &value->value; | 8842 | return &value->value; |
| 8179 | } 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 | } |
| 8180 | exec_add_error_node(codegen, exec, instruction->source_node, | 8853 | exec_add_error_node(codegen, exec, instruction->source_node, |
| 8181 | buf_sprintf("unable to evaluate constant expression")); | 8854 | buf_sprintf("unable to evaluate constant expression")); |
| 8182 | return &codegen->invalid_instruction->value; | 8855 | return &codegen->invalid_instruction->value; |
| ... | @@ -9154,15 +9827,6 @@ static bool ir_num_lit_fits_in_other_type(IrAnalyze *ira, IrInstruction *instruc | ... | @@ -9154,15 +9827,6 @@ static bool ir_num_lit_fits_in_other_type(IrAnalyze *ira, IrInstruction *instruc |
| 9154 | return false; | 9827 | return false; |
| 9155 | } | 9828 | } |
| 9156 | | 9829 | |
| 9157 | static bool is_slice(ZigType *type) { | | |
| 9158 | return type->id == ZigTypeIdStruct && type->data.structure.is_slice; | | |
| 9159 | } | | |
| 9160 | | | |
| 9161 | static bool slice_is_const(ZigType *type) { | | |
| 9162 | assert(is_slice(type)); | | |
| 9163 | return type->data.structure.fields[slice_ptr_index].type_entry->data.pointer.is_const; | | |
| 9164 | } | | |
| 9165 | | | |
| 9166 | static bool is_tagged_union(ZigType *type) { | 9830 | static bool is_tagged_union(ZigType *type) { |
| 9167 | if (type->id != ZigTypeIdUnion) | 9831 | if (type->id != ZigTypeIdUnion) |
| 9168 | return false; | 9832 | return false; |
| ... | @@ -9533,9 +10197,21 @@ static ZigType *ir_resolve_peer_types(IrAnalyze *ira, AstNode *source_node, ZigT | ... | @@ -9533,9 +10197,21 @@ static ZigType *ir_resolve_peer_types(IrAnalyze *ira, AstNode *source_node, ZigT |
| 9533 | { | 10197 | { |
| 9534 | Error err; | 10198 | Error err; |
| 9535 | assert(instruction_count >= 1); | 10199 | assert(instruction_count >= 1); |
| 9536 | IrInstruction *prev_inst = instructions[0]; | 10200 | IrInstruction *prev_inst; |
| 9537 | if (type_is_invalid(prev_inst->value.type)) { | 10201 | size_t i = 0; |
| 9538 | 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; |
| 9539 | } | 10215 | } |
| 9540 | ErrorTableEntry **errors = nullptr; | 10216 | ErrorTableEntry **errors = nullptr; |
| 9541 | size_t errors_count = 0; | 10217 | size_t errors_count = 0; |
| ... | @@ -9560,7 +10236,7 @@ static ZigType *ir_resolve_peer_types(IrAnalyze *ira, AstNode *source_node, ZigT | ... | @@ -9560,7 +10236,7 @@ static ZigType *ir_resolve_peer_types(IrAnalyze *ira, AstNode *source_node, ZigT |
| 9560 | | 10236 | |
| 9561 | bool any_are_null = (prev_inst->value.type->id == ZigTypeIdNull); | 10237 | bool any_are_null = (prev_inst->value.type->id == ZigTypeIdNull); |
| 9562 | bool convert_to_const_slice = false; | 10238 | bool convert_to_const_slice = false; |
| 9563 | for (size_t i = 1; i < instruction_count; i += 1) { | 10239 | for (; i < instruction_count; i += 1) { |
| 9564 | IrInstruction *cur_inst = instructions[i]; | 10240 | IrInstruction *cur_inst = instructions[i]; |
| 9565 | ZigType *cur_type = cur_inst->value.type; | 10241 | ZigType *cur_type = cur_inst->value.type; |
| 9566 | ZigType *prev_type = prev_inst->value.type; | 10242 | ZigType *prev_type = prev_inst->value.type; |
| ... | @@ -9579,7 +10255,7 @@ static ZigType *ir_resolve_peer_types(IrAnalyze *ira, AstNode *source_node, ZigT | ... | @@ -9579,7 +10255,7 @@ static ZigType *ir_resolve_peer_types(IrAnalyze *ira, AstNode *source_node, ZigT |
| 9579 | } | 10255 | } |
| 9580 | | 10256 | |
| 9581 | if (prev_type->id == ZigTypeIdErrorSet) { | 10257 | if (prev_type->id == ZigTypeIdErrorSet) { |
| 9582 | assert(err_set_type != nullptr); | 10258 | ir_assert(err_set_type != nullptr, prev_inst); |
| 9583 | if (cur_type->id == ZigTypeIdErrorSet) { | 10259 | if (cur_type->id == ZigTypeIdErrorSet) { |
| 9584 | if (type_is_global_error_set(err_set_type)) { | 10260 | if (type_is_global_error_set(err_set_type)) { |
| 9585 | continue; | 10261 | continue; |
| ... | @@ -9839,6 +10515,7 @@ static ZigType *ir_resolve_peer_types(IrAnalyze *ira, AstNode *source_node, ZigT | ... | @@ -9839,6 +10515,7 @@ static ZigType *ir_resolve_peer_types(IrAnalyze *ira, AstNode *source_node, ZigT |
| 9839 | | 10515 | |
| 9840 | if (prev_type->id == ZigTypeIdNull) { | 10516 | if (prev_type->id == ZigTypeIdNull) { |
| 9841 | prev_inst = cur_inst; | 10517 | prev_inst = cur_inst; |
| | 10518 | any_are_null = true; |
| 9842 | continue; | 10519 | continue; |
| 9843 | } | 10520 | } |
| 9844 | | 10521 | |
| ... | @@ -10153,6 +10830,8 @@ static ZigType *ir_resolve_peer_types(IrAnalyze *ira, AstNode *source_node, ZigT | ... | @@ -10153,6 +10830,8 @@ static ZigType *ir_resolve_peer_types(IrAnalyze *ira, AstNode *source_node, ZigT |
| 10153 | } else if (prev_inst->value.type->id == ZigTypeIdOptional) { | 10830 | } else if (prev_inst->value.type->id == ZigTypeIdOptional) { |
| 10154 | return prev_inst->value.type; | 10831 | return prev_inst->value.type; |
| 10155 | } else { | 10832 | } else { |
| | 10833 | if ((err = type_resolve(ira->codegen, prev_inst->value.type, ResolveStatusSizeKnown))) |
| | 10834 | return ira->codegen->builtin_types.entry_invalid; |
| 10156 | return get_optional_type(ira->codegen, prev_inst->value.type); | 10835 | return get_optional_type(ira->codegen, prev_inst->value.type); |
| 10157 | } | 10836 | } |
| 10158 | } else { | 10837 | } else { |
| ... | @@ -10160,24 +10839,18 @@ static ZigType *ir_resolve_peer_types(IrAnalyze *ira, AstNode *source_node, ZigT | ... | @@ -10160,24 +10839,18 @@ static ZigType *ir_resolve_peer_types(IrAnalyze *ira, AstNode *source_node, ZigT |
| 10160 | } | 10839 | } |
| 10161 | } | 10840 | } |
| 10162 | | 10841 | |
| 10163 | static void ir_add_alloca(IrAnalyze *ira, IrInstruction *instruction, ZigType *type_entry) { | | |
| 10164 | if (type_has_bits(type_entry) && handle_is_ptr(type_entry)) { | | |
| 10165 | ZigFn *fn_entry = exec_fn_entry(ira->new_irb.exec); | | |
| 10166 | if (fn_entry != nullptr) { | | |
| 10167 | fn_entry->alloca_list.append(instruction); | | |
| 10168 | } | | |
| 10169 | } | | |
| 10170 | } | | |
| 10171 | | | |
| 10172 | 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) { |
| 10173 | ConstGlobalRefs *global_refs = dest->global_refs; | 10843 | ConstGlobalRefs *global_refs = dest->global_refs; |
| 10174 | assert(!same_global_refs || src->global_refs != nullptr); | 10844 | memcpy(dest, src, sizeof(ConstExprValue)); |
| 10175 | *dest = *src; | | |
| 10176 | if (!same_global_refs) { | 10845 | if (!same_global_refs) { |
| 10177 | dest->global_refs = global_refs; | 10846 | dest->global_refs = global_refs; |
| | 10847 | if (src->special == ConstValSpecialUndef) |
| | 10848 | return; |
| 10178 | if (dest->type->id == ZigTypeIdStruct) { | 10849 | if (dest->type->id == ZigTypeIdStruct) { |
| 10179 | 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); |
| 10180 | 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 | } |
| 10181 | } | 10854 | } |
| 10182 | } | 10855 | } |
| 10183 | } | 10856 | } |
| ... | @@ -10195,7 +10868,6 @@ static bool eval_const_expr_implicit_cast(IrAnalyze *ira, IrInstruction *source_ | ... | @@ -10195,7 +10868,6 @@ static bool eval_const_expr_implicit_cast(IrAnalyze *ira, IrInstruction *source_ |
| 10195 | zig_unreachable(); | 10868 | zig_unreachable(); |
| 10196 | case CastOpErrSet: | 10869 | case CastOpErrSet: |
| 10197 | case CastOpBitCast: | 10870 | case CastOpBitCast: |
| 10198 | case CastOpPtrOfArrayToSlice: | | |
| 10199 | zig_panic("TODO"); | 10871 | zig_panic("TODO"); |
| 10200 | case CastOpNoop: | 10872 | case CastOpNoop: |
| 10201 | { | 10873 | { |
| ... | @@ -10295,7 +10967,7 @@ static IrInstruction *ir_const(IrAnalyze *ira, IrInstruction *old_instruction, Z | ... | @@ -10295,7 +10967,7 @@ static IrInstruction *ir_const(IrAnalyze *ira, IrInstruction *old_instruction, Z |
| 10295 | } | 10967 | } |
| 10296 | | 10968 | |
| 10297 | 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, |
| 10298 | ZigType *wanted_type, CastOp cast_op, bool need_alloca) | 10970 | ZigType *wanted_type, CastOp cast_op) |
| 10299 | { | 10971 | { |
| 10300 | if (instr_is_comptime(value) || !type_has_bits(wanted_type)) { | 10972 | if (instr_is_comptime(value) || !type_has_bits(wanted_type)) { |
| 10301 | IrInstruction *result = ir_const(ira, source_instr, wanted_type); | 10973 | IrInstruction *result = ir_const(ira, source_instr, wanted_type); |
| ... | @@ -10308,9 +10980,6 @@ static IrInstruction *ir_resolve_cast(IrAnalyze *ira, IrInstruction *source_inst | ... | @@ -10308,9 +10980,6 @@ static IrInstruction *ir_resolve_cast(IrAnalyze *ira, IrInstruction *source_inst |
| 10308 | } else { | 10980 | } else { |
| 10309 | 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); |
| 10310 | result->value.type = wanted_type; | 10982 | result->value.type = wanted_type; |
| 10311 | if (need_alloca) { | | |
| 10312 | ir_add_alloca(ira, result, wanted_type); | | |
| 10313 | } | | |
| 10314 | return result; | 10983 | return result; |
| 10315 | } | 10984 | } |
| 10316 | } | 10985 | } |
| ... | @@ -10352,7 +11021,7 @@ static IrInstruction *ir_resolve_ptr_of_array_to_unknown_len_ptr(IrAnalyze *ira, | ... | @@ -10352,7 +11021,7 @@ static IrInstruction *ir_resolve_ptr_of_array_to_unknown_len_ptr(IrAnalyze *ira, |
| 10352 | } | 11021 | } |
| 10353 | | 11022 | |
| 10354 | 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, |
| 10355 | IrInstruction *value, ZigType *wanted_type) | 11024 | IrInstruction *value, ZigType *wanted_type, ResultLoc *result_loc) |
| 10356 | { | 11025 | { |
| 10357 | Error err; | 11026 | Error err; |
| 10358 | | 11027 | |
| ... | @@ -10383,11 +11052,12 @@ static IrInstruction *ir_resolve_ptr_of_array_to_slice(IrAnalyze *ira, IrInstruc | ... | @@ -10383,11 +11052,12 @@ static IrInstruction *ir_resolve_ptr_of_array_to_slice(IrAnalyze *ira, IrInstruc |
| 10383 | } | 11052 | } |
| 10384 | } | 11053 | } |
| 10385 | | 11054 | |
| 10386 | 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(); |
| 10387 | wanted_type, value, CastOpPtrOfArrayToSlice); | 11056 | IrInstruction *result_loc_inst = ir_resolve_result(ira, source_instr, result_loc, wanted_type, nullptr, true, false); |
| 10388 | result->value.type = wanted_type; | 11057 | if (type_is_invalid(result_loc_inst->value.type) || instr_is_unreachable(result_loc_inst)) { |
| 10389 | ir_add_alloca(ira, result, wanted_type); | 11058 | return result_loc_inst; |
| 10390 | return result; | 11059 | } |
| | 11060 | return ir_build_ptr_of_array_to_slice(ira, source_instr, wanted_type, value, result_loc_inst); |
| 10391 | } | 11061 | } |
| 10392 | | 11062 | |
| 10393 | 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) { |
| ... | @@ -10419,51 +11089,136 @@ static IrBasicBlock *ir_get_new_bb_runtime(IrAnalyze *ira, IrBasicBlock *old_bb, | ... | @@ -10419,51 +11089,136 @@ static IrBasicBlock *ir_get_new_bb_runtime(IrAnalyze *ira, IrBasicBlock *old_bb, |
| 10419 | } | 11089 | } |
| 10420 | | 11090 | |
| 10421 | 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); |
| 10422 | ira->instruction_index = 0; | 11093 | ira->instruction_index = 0; |
| 10423 | ira->old_irb.current_basic_block = old_bb; | 11094 | ira->old_irb.current_basic_block = old_bb; |
| 10424 | ira->const_predecessor_bb = const_predecessor_bb; | 11095 | ira->const_predecessor_bb = const_predecessor_bb; |
| | 11096 | ira->old_bb_index = old_bb->index; |
| 10425 | } | 11097 | } |
| 10426 | | 11098 | |
| 10427 | static void ir_finish_bb(IrAnalyze *ira) { | 11099 | static IrInstruction *ira_suspend(IrAnalyze *ira, IrInstruction *old_instruction, IrBasicBlock *next_bb, |
| 10428 | ira->new_irb.exec->basic_block_list.append(ira->new_irb.current_basic_block); | 11100 | IrSuspendPosition *suspend_pos) |
| 10429 | ira->instruction_index += 1; | 11101 | { |
| 10430 | while (ira->instruction_index < ira->old_irb.current_basic_block->instruction_list.length) { | 11102 | if (ira->codegen->verbose_ir) { |
| 10431 | 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, |
| 10432 | if (!next_instruction->is_gen) { | 11104 | ira->old_irb.current_basic_block->debug_id, |
| 10433 | 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, |
| 10434 | break; | 11106 | ira->old_irb.exec->basic_block_list.at(ira->old_bb_index)->debug_id, |
| 10435 | } | 11107 | ira->old_irb.current_basic_block->instruction_list.at(ira->instruction_index)->debug_id, |
| 10436 | 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; |
| 10437 | } | 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 | } |
| 10438 | | 11150 | |
| 10439 | size_t my_old_bb_index = ira->old_bb_index; | 11151 | static void ir_start_next_bb(IrAnalyze *ira) { |
| 10440 | ira->old_bb_index += 1; | 11152 | ira->old_bb_index += 1; |
| 10441 | | 11153 | |
| 10442 | bool need_repeat = true; | 11154 | bool need_repeat = true; |
| 10443 | for (;;) { | 11155 | for (;;) { |
| 10444 | 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) { |
| 10445 | 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); |
| 10446 | if (old_bb->other == nullptr) { | 11158 | if (old_bb->other == nullptr && old_bb->suspend_instruction_ref == nullptr) { |
| 10447 | ira->old_bb_index += 1; | 11159 | ira->old_bb_index += 1; |
| 10448 | continue; | 11160 | continue; |
| 10449 | } | 11161 | } |
| 10450 | 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 | { |
| 10451 | ira->old_bb_index += 1; | 11169 | ira->old_bb_index += 1; |
| 10452 | continue; | 11170 | continue; |
| 10453 | } | 11171 | } |
| 10454 | ira->new_irb.current_basic_block = old_bb->other; | | |
| 10455 | | 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; |
| 10456 | ir_start_bb(ira, old_bb, nullptr); | 11185 | ir_start_bb(ira, old_bb, nullptr); |
| 10457 | return; | 11186 | return; |
| 10458 | } | 11187 | } |
| 10459 | if (!need_repeat) | 11188 | if (!need_repeat) { |
| | 11189 | if (ira->resume_stack.length != 0) { |
| | 11190 | ira_resume(ira); |
| | 11191 | } |
| 10460 | return; | 11192 | return; |
| | 11193 | } |
| 10461 | need_repeat = false; | 11194 | need_repeat = false; |
| 10462 | ira->old_bb_index = 0; | 11195 | ira->old_bb_index = 0; |
| 10463 | continue; | 11196 | continue; |
| 10464 | } | 11197 | } |
| 10465 | } | 11198 | } |
| 10466 | | 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 | |
| 10467 | static IrInstruction *ir_unreach_error(IrAnalyze *ira) { | 11222 | static IrInstruction *ir_unreach_error(IrAnalyze *ira) { |
| 10468 | ira->old_bb_index = SIZE_MAX; | 11223 | ira->old_bb_index = SIZE_MAX; |
| 10469 | ira->new_irb.exec->invalid = true; | 11224 | ira->new_irb.exec->invalid = true; |
| ... | @@ -10524,6 +11279,12 @@ static IrInstruction *ir_const_undef(IrAnalyze *ira, IrInstruction *source_instr | ... | @@ -10524,6 +11279,12 @@ static IrInstruction *ir_const_undef(IrAnalyze *ira, IrInstruction *source_instr |
| 10524 | return result; | 11279 | return result; |
| 10525 | } | 11280 | } |
| 10526 | | 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 | |
| 10527 | static IrInstruction *ir_const_void(IrAnalyze *ira, IrInstruction *source_instruction) { | 11288 | static IrInstruction *ir_const_void(IrAnalyze *ira, IrInstruction *source_instruction) { |
| 10528 | 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); |
| 10529 | } | 11290 | } |
| ... | @@ -10721,7 +11482,7 @@ static ZigFn *ir_resolve_fn(IrAnalyze *ira, IrInstruction *fn_value) { | ... | @@ -10721,7 +11482,7 @@ static ZigFn *ir_resolve_fn(IrAnalyze *ira, IrInstruction *fn_value) { |
| 10721 | } | 11482 | } |
| 10722 | | 11483 | |
| 10723 | 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, |
| 10724 | ZigType *wanted_type) | 11485 | ZigType *wanted_type, ResultLoc *result_loc) |
| 10725 | { | 11486 | { |
| 10726 | assert(wanted_type->id == ZigTypeIdOptional); | 11487 | assert(wanted_type->id == ZigTypeIdOptional); |
| 10727 | | 11488 | |
| ... | @@ -10747,20 +11508,29 @@ static IrInstruction *ir_analyze_optional_wrap(IrAnalyze *ira, IrInstruction *so | ... | @@ -10747,20 +11508,29 @@ static IrInstruction *ir_analyze_optional_wrap(IrAnalyze *ira, IrInstruction *so |
| 10747 | return &const_instruction->base; | 11508 | return &const_instruction->base; |
| 10748 | } | 11509 | } |
| 10749 | | 11510 | |
| 10750 | 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)) { |
| 10751 | 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); |
| 10752 | result->value.data.rh_maybe = RuntimeHintOptionalNonNull; | 11522 | result->value.data.rh_maybe = RuntimeHintOptionalNonNull; |
| 10753 | ir_add_alloca(ira, result, wanted_type); | | |
| 10754 | return result; | 11523 | return result; |
| 10755 | } | 11524 | } |
| 10756 | | 11525 | |
| 10757 | 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, |
| 10758 | IrInstruction *value, ZigType *wanted_type) | 11527 | IrInstruction *value, ZigType *wanted_type, ResultLoc *result_loc) |
| 10759 | { | 11528 | { |
| 10760 | assert(wanted_type->id == ZigTypeIdErrorUnion); | 11529 | assert(wanted_type->id == ZigTypeIdErrorUnion); |
| 10761 | | 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; |
| 10762 | if (instr_is_comptime(value)) { | 11533 | if (instr_is_comptime(value)) { |
| 10763 | ZigType *payload_type = wanted_type->data.error_union.payload_type; | | |
| 10764 | IrInstruction *casted_payload = ir_implicit_cast(ira, value, payload_type); | 11534 | IrInstruction *casted_payload = ir_implicit_cast(ira, value, payload_type); |
| 10765 | if (type_is_invalid(casted_payload->value.type)) | 11535 | if (type_is_invalid(casted_payload->value.type)) |
| 10766 | return ira->codegen->invalid_instruction; | 11536 | return ira->codegen->invalid_instruction; |
| ... | @@ -10770,7 +11540,7 @@ static IrInstruction *ir_analyze_err_wrap_payload(IrAnalyze *ira, IrInstruction | ... | @@ -10770,7 +11540,7 @@ static IrInstruction *ir_analyze_err_wrap_payload(IrAnalyze *ira, IrInstruction |
| 10770 | return ira->codegen->invalid_instruction; | 11540 | return ira->codegen->invalid_instruction; |
| 10771 | | 11541 | |
| 10772 | ConstExprValue *err_set_val = create_const_vals(1); | 11542 | ConstExprValue *err_set_val = create_const_vals(1); |
| 10773 | err_set_val->type = wanted_type->data.error_union.err_set_type; | 11543 | err_set_val->type = err_set_type; |
| 10774 | err_set_val->special = ConstValSpecialStatic; | 11544 | err_set_val->special = ConstValSpecialStatic; |
| 10775 | err_set_val->data.x_err_set = nullptr; | 11545 | err_set_val->data.x_err_set = nullptr; |
| 10776 | | 11546 | |
| ... | @@ -10783,10 +11553,19 @@ static IrInstruction *ir_analyze_err_wrap_payload(IrAnalyze *ira, IrInstruction | ... | @@ -10783,10 +11553,19 @@ static IrInstruction *ir_analyze_err_wrap_payload(IrAnalyze *ira, IrInstruction |
| 10783 | return &const_instruction->base; | 11553 | return &const_instruction->base; |
| 10784 | } | 11554 | } |
| 10785 | | 11555 | |
| 10786 | IrInstruction *result = ir_build_err_wrap_payload(&ira->new_irb, source_instr->scope, source_instr->source_node, value); | 11556 | IrInstruction *result_loc_inst; |
| 10787 | 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); |
| 10788 | result->value.data.rh_error_union = RuntimeHintErrorUnionNonError; | 11568 | result->value.data.rh_error_union = RuntimeHintErrorUnionNonError; |
| 10789 | ir_add_alloca(ira, result, wanted_type); | | |
| 10790 | return result; | 11569 | return result; |
| 10791 | } | 11570 | } |
| 10792 | | 11571 | |
| ... | @@ -10833,7 +11612,9 @@ static IrInstruction *ir_analyze_err_set_cast(IrAnalyze *ira, IrInstruction *sou | ... | @@ -10833,7 +11612,9 @@ static IrInstruction *ir_analyze_err_set_cast(IrAnalyze *ira, IrInstruction *sou |
| 10833 | return result; | 11612 | return result; |
| 10834 | } | 11613 | } |
| 10835 | | 11614 | |
| 10836 | 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 | { |
| 10837 | assert(wanted_type->id == ZigTypeIdErrorUnion); | 11618 | assert(wanted_type->id == ZigTypeIdErrorUnion); |
| 10838 | | 11619 | |
| 10839 | 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); |
| ... | @@ -10857,10 +11638,20 @@ static IrInstruction *ir_analyze_err_wrap_code(IrAnalyze *ira, IrInstruction *so | ... | @@ -10857,10 +11638,20 @@ static IrInstruction *ir_analyze_err_wrap_code(IrAnalyze *ira, IrInstruction *so |
| 10857 | return &const_instruction->base; | 11638 | return &const_instruction->base; |
| 10858 | } | 11639 | } |
| 10859 | | 11640 | |
| 10860 | IrInstruction *result = ir_build_err_wrap_code(&ira->new_irb, source_instr->scope, source_instr->source_node, value); | 11641 | IrInstruction *result_loc_inst; |
| 10861 | 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); |
| 10862 | result->value.data.rh_error_union = RuntimeHintErrorUnionError; | 11654 | result->value.data.rh_error_union = RuntimeHintErrorUnionError; |
| 10863 | ir_add_alloca(ira, result, wanted_type); | | |
| 10864 | return result; | 11655 | return result; |
| 10865 | } | 11656 | } |
| 10866 | | 11657 | |
| ... | @@ -10920,20 +11711,21 @@ static IrInstruction *ir_get_ref(IrAnalyze *ira, IrInstruction *source_instructi | ... | @@ -10920,20 +11711,21 @@ static IrInstruction *ir_get_ref(IrAnalyze *ira, IrInstruction *source_instructi |
| 10920 | | 11711 | |
| 10921 | 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, |
| 10922 | is_const, is_volatile, PtrLenSingle, 0, 0, 0, false); | 11713 | is_const, is_volatile, PtrLenSingle, 0, 0, 0, false); |
| 10923 | IrInstruction *new_instruction = ir_build_ref(&ira->new_irb, source_instruction->scope, | 11714 | |
| 10924 | source_instruction->source_node, value, is_const, is_volatile); | 11715 | IrInstruction *result_loc; |
| 10925 | new_instruction->value.type = ptr_type; | | |
| 10926 | new_instruction->value.data.rh_ptr = RuntimeHintPtrStack; | | |
| 10927 | 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)) { |
| 10928 | 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); |
| 10929 | assert(fn_entry); | 11718 | } else { |
| 10930 | fn_entry->alloca_list.append(new_instruction); | 11719 | result_loc = nullptr; |
| 10931 | } | 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; |
| 10932 | return new_instruction; | 11724 | return new_instruction; |
| 10933 | } | 11725 | } |
| 10934 | | 11726 | |
| 10935 | 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, |
| 10936 | IrInstruction *array_arg, ZigType *wanted_type) | 11728 | IrInstruction *array_arg, ZigType *wanted_type, ResultLoc *result_loc) |
| 10937 | { | 11729 | { |
| 10938 | assert(is_slice(wanted_type)); | 11730 | assert(is_slice(wanted_type)); |
| 10939 | // 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 |
| ... | @@ -10942,7 +11734,7 @@ static IrInstruction *ir_analyze_array_to_slice(IrAnalyze *ira, IrInstruction *s | ... | @@ -10942,7 +11734,7 @@ static IrInstruction *ir_analyze_array_to_slice(IrAnalyze *ira, IrInstruction *s |
| 10942 | IrInstruction *array_ptr = nullptr; | 11734 | IrInstruction *array_ptr = nullptr; |
| 10943 | IrInstruction *array; | 11735 | IrInstruction *array; |
| 10944 | if (array_arg->value.type->id == ZigTypeIdPointer) { | 11736 | if (array_arg->value.type->id == ZigTypeIdPointer) { |
| 10945 | array = ir_get_deref(ira, source_instr, array_arg); | 11737 | array = ir_get_deref(ira, source_instr, array_arg, nullptr); |
| 10946 | array_ptr = array_arg; | 11738 | array_ptr = array_arg; |
| 10947 | } else { | 11739 | } else { |
| 10948 | array = array_arg; | 11740 | array = array_arg; |
| ... | @@ -10965,12 +11757,14 @@ static IrInstruction *ir_analyze_array_to_slice(IrAnalyze *ira, IrInstruction *s | ... | @@ -10965,12 +11757,14 @@ static IrInstruction *ir_analyze_array_to_slice(IrAnalyze *ira, IrInstruction *s |
| 10965 | | 11757 | |
| 10966 | 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); |
| 10967 | | 11759 | |
| 10968 | IrInstruction *result = ir_build_slice(&ira->new_irb, source_instr->scope, | 11760 | if (result_loc == nullptr) result_loc = no_result_loc(); |
| 10969 | 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); |
| 10970 | 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); |
| 10971 | result->value.data.rh_slice.id = RuntimeHintSliceIdLen; | 11766 | result->value.data.rh_slice.id = RuntimeHintSliceIdLen; |
| 10972 | result->value.data.rh_slice.len = array_type->data.array.len; | 11767 | result->value.data.rh_slice.len = array_type->data.array.len; |
| 10973 | ir_add_alloca(ira, result, result->value.type); | | |
| 10974 | | 11768 | |
| 10975 | return result; | 11769 | return result; |
| 10976 | } | 11770 | } |
| ... | @@ -11608,7 +12402,7 @@ static IrInstruction *ir_analyze_array_to_vector(IrAnalyze *ira, IrInstruction * | ... | @@ -11608,7 +12402,7 @@ static IrInstruction *ir_analyze_array_to_vector(IrAnalyze *ira, IrInstruction * |
| 11608 | } | 12402 | } |
| 11609 | | 12403 | |
| 11610 | 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, |
| 11611 | IrInstruction *vector, ZigType *array_type) | 12405 | IrInstruction *vector, ZigType *array_type, ResultLoc *result_loc) |
| 11612 | { | 12406 | { |
| 11613 | if (instr_is_comptime(vector)) { | 12407 | if (instr_is_comptime(vector)) { |
| 11614 | // arrays and vectors have the same ConstExprValue representation | 12408 | // arrays and vectors have the same ConstExprValue representation |
| ... | @@ -11617,7 +12411,14 @@ static IrInstruction *ir_analyze_vector_to_array(IrAnalyze *ira, IrInstruction * | ... | @@ -11617,7 +12411,14 @@ static IrInstruction *ir_analyze_vector_to_array(IrAnalyze *ira, IrInstruction * |
| 11617 | result->value.type = array_type; | 12411 | result->value.type = array_type; |
| 11618 | return result; | 12412 | return result; |
| 11619 | } | 12413 | } |
| 11620 | 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); |
| 11621 | } | 12422 | } |
| 11622 | | 12423 | |
| 11623 | 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, |
| ... | @@ -11667,7 +12468,7 @@ static bool is_pointery_and_elem_is_not_pointery(ZigType *ty) { | ... | @@ -11667,7 +12468,7 @@ static bool is_pointery_and_elem_is_not_pointery(ZigType *ty) { |
| 11667 | } | 12468 | } |
| 11668 | | 12469 | |
| 11669 | static IrInstruction *ir_analyze_cast(IrAnalyze *ira, IrInstruction *source_instr, | 12470 | static IrInstruction *ir_analyze_cast(IrAnalyze *ira, IrInstruction *source_instr, |
| 11670 | ZigType *wanted_type, IrInstruction *value) | 12471 | ZigType *wanted_type, IrInstruction *value, ResultLoc *result_loc) |
| 11671 | { | 12472 | { |
| 11672 | Error err; | 12473 | Error err; |
| 11673 | ZigType *actual_type = value->value.type; | 12474 | ZigType *actual_type = value->value.type; |
| ... | @@ -11683,7 +12484,7 @@ static IrInstruction *ir_analyze_cast(IrAnalyze *ira, IrInstruction *source_inst | ... | @@ -11683,7 +12484,7 @@ static IrInstruction *ir_analyze_cast(IrAnalyze *ira, IrInstruction *source_inst |
| 11683 | if (const_cast_result.id == ConstCastResultIdInvalid) | 12484 | if (const_cast_result.id == ConstCastResultIdInvalid) |
| 11684 | return ira->codegen->invalid_instruction; | 12485 | return ira->codegen->invalid_instruction; |
| 11685 | if (const_cast_result.id == ConstCastResultIdOk) { | 12486 | if (const_cast_result.id == ConstCastResultIdOk) { |
| 11686 | return ir_resolve_cast(ira, source_instr, value, wanted_type, CastOpNoop, false); | 12487 | return ir_resolve_cast(ira, source_instr, value, wanted_type, CastOpNoop); |
| 11687 | } | 12488 | } |
| 11688 | | 12489 | |
| 11689 | // cast from T to ?T | 12490 | // cast from T to ?T |
| ... | @@ -11693,12 +12494,12 @@ static IrInstruction *ir_analyze_cast(IrAnalyze *ira, IrInstruction *source_inst | ... | @@ -11693,12 +12494,12 @@ static IrInstruction *ir_analyze_cast(IrAnalyze *ira, IrInstruction *source_inst |
| 11693 | 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, |
| 11694 | false).id == ConstCastResultIdOk) | 12495 | false).id == ConstCastResultIdOk) |
| 11695 | { | 12496 | { |
| 11696 | 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); |
| 11697 | } else if (actual_type->id == ZigTypeIdComptimeInt || | 12498 | } else if (actual_type->id == ZigTypeIdComptimeInt || |
| 11698 | actual_type->id == ZigTypeIdComptimeFloat) | 12499 | actual_type->id == ZigTypeIdComptimeFloat) |
| 11699 | { | 12500 | { |
| 11700 | 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)) { |
| 11701 | 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); |
| 11702 | } else { | 12503 | } else { |
| 11703 | return ira->codegen->invalid_instruction; | 12504 | return ira->codegen->invalid_instruction; |
| 11704 | } | 12505 | } |
| ... | @@ -11722,7 +12523,7 @@ static IrInstruction *ir_analyze_cast(IrAnalyze *ira, IrInstruction *source_inst | ... | @@ -11722,7 +12523,7 @@ static IrInstruction *ir_analyze_cast(IrAnalyze *ira, IrInstruction *source_inst |
| 11722 | wanted_child_type); | 12523 | wanted_child_type); |
| 11723 | if (type_is_invalid(cast1->value.type)) | 12524 | if (type_is_invalid(cast1->value.type)) |
| 11724 | return ira->codegen->invalid_instruction; | 12525 | return ira->codegen->invalid_instruction; |
| 11725 | 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); |
| 11726 | } | 12527 | } |
| 11727 | } | 12528 | } |
| 11728 | } | 12529 | } |
| ... | @@ -11732,12 +12533,12 @@ static IrInstruction *ir_analyze_cast(IrAnalyze *ira, IrInstruction *source_inst | ... | @@ -11732,12 +12533,12 @@ static IrInstruction *ir_analyze_cast(IrAnalyze *ira, IrInstruction *source_inst |
| 11732 | 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, |
| 11733 | source_node, false).id == ConstCastResultIdOk) | 12534 | source_node, false).id == ConstCastResultIdOk) |
| 11734 | { | 12535 | { |
| 11735 | 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); |
| 11736 | } else if (actual_type->id == ZigTypeIdComptimeInt || | 12537 | } else if (actual_type->id == ZigTypeIdComptimeInt || |
| 11737 | actual_type->id == ZigTypeIdComptimeFloat) | 12538 | actual_type->id == ZigTypeIdComptimeFloat) |
| 11738 | { | 12539 | { |
| 11739 | 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)) { |
| 11740 | 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); |
| 11741 | } else { | 12542 | } else { |
| 11742 | return ira->codegen->invalid_instruction; | 12543 | return ira->codegen->invalid_instruction; |
| 11743 | } | 12544 | } |
| ... | @@ -11755,11 +12556,11 @@ static IrInstruction *ir_analyze_cast(IrAnalyze *ira, IrInstruction *source_inst | ... | @@ -11755,11 +12556,11 @@ static IrInstruction *ir_analyze_cast(IrAnalyze *ira, IrInstruction *source_inst |
| 11755 | actual_type->id == ZigTypeIdComptimeInt || | 12556 | actual_type->id == ZigTypeIdComptimeInt || |
| 11756 | actual_type->id == ZigTypeIdComptimeFloat) | 12557 | actual_type->id == ZigTypeIdComptimeFloat) |
| 11757 | { | 12558 | { |
| 11758 | 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); |
| 11759 | if (type_is_invalid(cast1->value.type)) | 12560 | if (type_is_invalid(cast1->value.type)) |
| 11760 | return ira->codegen->invalid_instruction; | 12561 | return ira->codegen->invalid_instruction; |
| 11761 | | 12562 | |
| 11762 | 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); |
| 11763 | if (type_is_invalid(cast2->value.type)) | 12564 | if (type_is_invalid(cast2->value.type)) |
| 11764 | return ira->codegen->invalid_instruction; | 12565 | return ira->codegen->invalid_instruction; |
| 11765 | | 12566 | |
| ... | @@ -11841,7 +12642,7 @@ static IrInstruction *ir_analyze_cast(IrAnalyze *ira, IrInstruction *source_inst | ... | @@ -11841,7 +12642,7 @@ static IrInstruction *ir_analyze_cast(IrAnalyze *ira, IrInstruction *source_inst |
| 11841 | 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, |
| 11842 | source_node, false).id == ConstCastResultIdOk) | 12643 | source_node, false).id == ConstCastResultIdOk) |
| 11843 | { | 12644 | { |
| 11844 | 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); |
| 11845 | } | 12646 | } |
| 11846 | } | 12647 | } |
| 11847 | | 12648 | |
| ... | @@ -11858,11 +12659,11 @@ static IrInstruction *ir_analyze_cast(IrAnalyze *ira, IrInstruction *source_inst | ... | @@ -11858,11 +12659,11 @@ static IrInstruction *ir_analyze_cast(IrAnalyze *ira, IrInstruction *source_inst |
| 11858 | 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, |
| 11859 | source_node, false).id == ConstCastResultIdOk) | 12660 | source_node, false).id == ConstCastResultIdOk) |
| 11860 | { | 12661 | { |
| 11861 | 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); |
| 11862 | if (type_is_invalid(cast1->value.type)) | 12663 | if (type_is_invalid(cast1->value.type)) |
| 11863 | return ira->codegen->invalid_instruction; | 12664 | return ira->codegen->invalid_instruction; |
| 11864 | | 12665 | |
| 11865 | 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); |
| 11866 | if (type_is_invalid(cast2->value.type)) | 12667 | if (type_is_invalid(cast2->value.type)) |
| 11867 | return ira->codegen->invalid_instruction; | 12668 | return ira->codegen->invalid_instruction; |
| 11868 | | 12669 | |
| ... | @@ -11905,7 +12706,7 @@ static IrInstruction *ir_analyze_cast(IrAnalyze *ira, IrInstruction *source_inst | ... | @@ -11905,7 +12706,7 @@ static IrInstruction *ir_analyze_cast(IrAnalyze *ira, IrInstruction *source_inst |
| 11905 | array_type->data.array.child_type, source_node, | 12706 | array_type->data.array.child_type, source_node, |
| 11906 | !slice_ptr_type->data.pointer.is_const).id == ConstCastResultIdOk) | 12707 | !slice_ptr_type->data.pointer.is_const).id == ConstCastResultIdOk) |
| 11907 | { | 12708 | { |
| 11908 | 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); |
| 11909 | } | 12710 | } |
| 11910 | } | 12711 | } |
| 11911 | | 12712 | |
| ... | @@ -11936,11 +12737,11 @@ static IrInstruction *ir_analyze_cast(IrAnalyze *ira, IrInstruction *source_inst | ... | @@ -11936,11 +12737,11 @@ static IrInstruction *ir_analyze_cast(IrAnalyze *ira, IrInstruction *source_inst |
| 11936 | 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, |
| 11937 | source_node, false).id == ConstCastResultIdOk) | 12738 | source_node, false).id == ConstCastResultIdOk) |
| 11938 | { | 12739 | { |
| 11939 | 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); |
| 11940 | if (type_is_invalid(cast1->value.type)) | 12741 | if (type_is_invalid(cast1->value.type)) |
| 11941 | return ira->codegen->invalid_instruction; | 12742 | return ira->codegen->invalid_instruction; |
| 11942 | | 12743 | |
| 11943 | 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); |
| 11944 | if (type_is_invalid(cast2->value.type)) | 12745 | if (type_is_invalid(cast2->value.type)) |
| 11945 | return ira->codegen->invalid_instruction; | 12746 | return ira->codegen->invalid_instruction; |
| 11946 | | 12747 | |
| ... | @@ -11952,7 +12753,7 @@ static IrInstruction *ir_analyze_cast(IrAnalyze *ira, IrInstruction *source_inst | ... | @@ -11952,7 +12753,7 @@ static IrInstruction *ir_analyze_cast(IrAnalyze *ira, IrInstruction *source_inst |
| 11952 | if (wanted_type->id == ZigTypeIdErrorUnion && | 12753 | if (wanted_type->id == ZigTypeIdErrorUnion && |
| 11953 | actual_type->id == ZigTypeIdErrorSet) | 12754 | actual_type->id == ZigTypeIdErrorSet) |
| 11954 | { | 12755 | { |
| 11955 | 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); |
| 11956 | } | 12757 | } |
| 11957 | | 12758 | |
| 11958 | // cast from typed number to integer or float literal. | 12759 | // cast from typed number to integer or float literal. |
| ... | @@ -12076,7 +12877,7 @@ static IrInstruction *ir_analyze_cast(IrAnalyze *ira, IrInstruction *source_inst | ... | @@ -12076,7 +12877,7 @@ static IrInstruction *ir_analyze_cast(IrAnalyze *ira, IrInstruction *source_inst |
| 12076 | 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, |
| 12077 | actual_type->data.vector.elem_type, source_node, false).id == ConstCastResultIdOk) | 12878 | actual_type->data.vector.elem_type, source_node, false).id == ConstCastResultIdOk) |
| 12078 | { | 12879 | { |
| 12079 | 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); |
| 12080 | } | 12881 | } |
| 12081 | | 12882 | |
| 12082 | // cast from [N]T to @Vector(N, T) | 12883 | // cast from [N]T to @Vector(N, T) |
| ... | @@ -12118,7 +12919,9 @@ static IrInstruction *ir_analyze_cast(IrAnalyze *ira, IrInstruction *source_inst | ... | @@ -12118,7 +12919,9 @@ static IrInstruction *ir_analyze_cast(IrAnalyze *ira, IrInstruction *source_inst |
| 12118 | return ira->codegen->invalid_instruction; | 12919 | return ira->codegen->invalid_instruction; |
| 12119 | } | 12920 | } |
| 12120 | | 12921 | |
| 12121 | 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 | { |
| 12122 | assert(value); | 12925 | assert(value); |
| 12123 | assert(value != ira->codegen->invalid_instruction); | 12926 | assert(value != ira->codegen->invalid_instruction); |
| 12124 | assert(!expected_type || !type_is_invalid(expected_type)); | 12927 | assert(!expected_type || !type_is_invalid(expected_type)); |
| ... | @@ -12131,63 +12934,76 @@ static IrInstruction *ir_implicit_cast(IrAnalyze *ira, IrInstruction *value, Zig | ... | @@ -12131,63 +12934,76 @@ static IrInstruction *ir_implicit_cast(IrAnalyze *ira, IrInstruction *value, Zig |
| 12131 | if (value->value.type->id == ZigTypeIdUnreachable) | 12934 | if (value->value.type->id == ZigTypeIdUnreachable) |
| 12132 | return value; | 12935 | return value; |
| 12133 | | 12936 | |
| 12134 | 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); |
| 12135 | } | 12942 | } |
| 12136 | | 12943 | |
| 12137 | 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 | { |
| 12138 | Error err; | 12947 | Error err; |
| 12139 | ZigType *type_entry = ptr->value.type; | 12948 | ZigType *type_entry = ptr->value.type; |
| 12140 | if (type_is_invalid(type_entry)) { | 12949 | if (type_is_invalid(type_entry)) |
| 12141 | return ira->codegen->invalid_instruction; | 12950 | return ira->codegen->invalid_instruction; |
| 12142 | } else if (type_entry->id == ZigTypeIdPointer) { | | |
| 12143 | ZigType *child_type = type_entry->data.pointer.child_type; | | |
| 12144 | // if the child type has one possible value, the deref is comptime | | |
| 12145 | switch (type_has_one_possible_value(ira->codegen, child_type)) { | | |
| 12146 | case OnePossibleValueInvalid: | | |
| 12147 | return ira->codegen->invalid_instruction; | | |
| 12148 | case OnePossibleValueYes: | | |
| 12149 | return ir_const(ira, source_instruction, child_type); | | |
| 12150 | case OnePossibleValueNo: | | |
| 12151 | break; | | |
| 12152 | } | | |
| 12153 | if (instr_is_comptime(ptr)) { | | |
| 12154 | if (ptr->value.special == ConstValSpecialUndef) { | | |
| 12155 | ir_add_error(ira, ptr, buf_sprintf("attempt to dereference undefined value")); | | |
| 12156 | return ira->codegen->invalid_instruction; | | |
| 12157 | } | | |
| 12158 | if (ptr->value.data.x_ptr.mut == ConstPtrMutComptimeConst || | | |
| 12159 | ptr->value.data.x_ptr.mut == ConstPtrMutComptimeVar) | | |
| 12160 | { | | |
| 12161 | ConstExprValue *pointee = const_ptr_pointee_unchecked(ira->codegen, &ptr->value); | | |
| 12162 | if (pointee->special != ConstValSpecialRuntime) { | | |
| 12163 | IrInstruction *result = ir_const(ira, source_instruction, child_type); | | |
| 12164 | | 12951 | |
| 12165 | if ((err = ir_read_const_ptr(ira, ira->codegen, source_instruction->source_node, &result->value, | 12952 | if (type_entry->id != ZigTypeIdPointer) { |
| 12166 | &ptr->value))) | 12953 | ir_add_error_node(ira, source_instruction->source_node, |
| 12167 | { | 12954 | buf_sprintf("attempt to dereference non-pointer type '%s'", |
| 12168 | return ira->codegen->invalid_instruction; | 12955 | buf_ptr(&type_entry->name))); |
| 12169 | } | 12956 | return ira->codegen->invalid_instruction; |
| 12170 | result->value.type = child_type; | 12957 | } |
| 12171 | return result; | 12958 | |
| | 12959 | ZigType *child_type = type_entry->data.pointer.child_type; |
| | 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; |
| | 12973 | } |
| | 12974 | if (ptr->value.data.x_ptr.mut != ConstPtrMutRuntimeVar) { |
| | 12975 | ConstExprValue *pointee = const_ptr_pointee_unchecked(ira->codegen, &ptr->value); |
| | 12976 | if (pointee->special != ConstValSpecialRuntime) { |
| | 12977 | IrInstruction *result = ir_const(ira, source_instruction, child_type); |
| | 12978 | |
| | 12979 | if ((err = ir_read_const_ptr(ira, ira->codegen, source_instruction->source_node, &result->value, |
| | 12980 | &ptr->value))) |
| | 12981 | { |
| | 12982 | return ira->codegen->invalid_instruction; |
| 12172 | } | 12983 | } |
| | 12984 | result->value.type = child_type; |
| | 12985 | return result; |
| 12173 | } | 12986 | } |
| 12174 | } | 12987 | } |
| 12175 | // if the instruction is a const ref instruction we can skip it | 12988 | } |
| 12176 | if (ptr->id == IrInstructionIdRef) { | 12989 | // if the instruction is a const ref instruction we can skip it |
| 12177 | IrInstructionRef *ref_inst = reinterpret_cast<IrInstructionRef *>(ptr); | 12990 | if (ptr->id == IrInstructionIdRef) { |
| 12178 | return ref_inst->value; | 12991 | IrInstructionRef *ref_inst = reinterpret_cast<IrInstructionRef *>(ptr); |
| 12179 | } | 12992 | return ref_inst->value; |
| 12180 | IrInstruction *result = ir_build_load_ptr_gen(ira, source_instruction, ptr, child_type); | 12993 | } |
| 12181 | if (type_entry->data.pointer.host_int_bytes != 0 && handle_is_ptr(child_type)) { | 12994 | |
| 12182 | 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; |
| 12183 | } | 13001 | } |
| 12184 | return result; | | |
| 12185 | } else { | 13002 | } else { |
| 12186 | ir_add_error_node(ira, source_instruction->source_node, | 13003 | result_loc_inst = nullptr; |
| 12187 | buf_sprintf("attempt to dereference non-pointer type '%s'", | | |
| 12188 | buf_ptr(&type_entry->name))); | | |
| 12189 | return ira->codegen->invalid_instruction; | | |
| 12190 | } | 13004 | } |
| | 13005 | |
| | 13006 | return ir_build_load_ptr_gen(ira, source_instruction, ptr, child_type, result_loc_inst); |
| 12191 | } | 13007 | } |
| 12192 | | 13008 | |
| 12193 | 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) { |
| ... | @@ -12401,6 +13217,14 @@ static IrInstruction *ir_analyze_instruction_return(IrAnalyze *ira, IrInstructio | ... | @@ -12401,6 +13217,14 @@ static IrInstruction *ir_analyze_instruction_return(IrAnalyze *ira, IrInstructio |
| 12401 | if (type_is_invalid(value->value.type)) | 13217 | if (type_is_invalid(value->value.type)) |
| 12402 | return ir_unreach_error(ira); | 13218 | return ir_unreach_error(ira); |
| 12403 | | 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 | |
| 12404 | 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); |
| 12405 | if (type_is_invalid(casted_value->value.type)) { | 13229 | if (type_is_invalid(casted_value->value.type)) { |
| 12406 | AstNode *source_node = ira->explicit_return_type_source_node; | 13230 | AstNode *source_node = ira->explicit_return_type_source_node; |
| ... | @@ -12563,7 +13387,7 @@ static IrInstruction *ir_analyze_bin_op_cmp(IrAnalyze *ira, IrInstructionBinOp * | ... | @@ -12563,7 +13387,7 @@ static IrInstruction *ir_analyze_bin_op_cmp(IrAnalyze *ira, IrInstructionBinOp * |
| 12563 | } else { | 13387 | } else { |
| 12564 | return is_non_null; | 13388 | return is_non_null; |
| 12565 | } | 13389 | } |
| 12566 | } else if (is_equality_cmp && | 13390 | } else if (is_equality_cmp && |
| 12567 | ((op1->value.type->id == ZigTypeIdNull && op2->value.type->id == ZigTypeIdPointer && | 13391 | ((op1->value.type->id == ZigTypeIdNull && op2->value.type->id == ZigTypeIdPointer && |
| 12568 | op2->value.type->data.pointer.ptr_len == PtrLenC) || | 13392 | op2->value.type->data.pointer.ptr_len == PtrLenC) || |
| 12569 | (op2->value.type->id == ZigTypeIdNull && op1->value.type->id == ZigTypeIdPointer && | 13393 | (op2->value.type->id == ZigTypeIdNull && op1->value.type->id == ZigTypeIdPointer && |
| ... | @@ -13005,7 +13829,7 @@ static ErrorMsg *ir_eval_math_op_scalar(IrAnalyze *ira, IrInstruction *source_in | ... | @@ -13005,7 +13829,7 @@ static ErrorMsg *ir_eval_math_op_scalar(IrAnalyze *ira, IrInstruction *source_in |
| 13005 | } | 13829 | } |
| 13006 | } else { | 13830 | } else { |
| 13007 | float_div_trunc(out_val, op1_val, op2_val); | 13831 | float_div_trunc(out_val, op1_val, op2_val); |
| 13008 | ConstExprValue remainder; | 13832 | ConstExprValue remainder = {}; |
| 13009 | float_rem(&remainder, op1_val, op2_val); | 13833 | float_rem(&remainder, op1_val, op2_val); |
| 13010 | if (float_cmp_zero(&remainder) != CmpEQ) { | 13834 | if (float_cmp_zero(&remainder) != CmpEQ) { |
| 13011 | 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")); |
| ... | @@ -13380,8 +14204,8 @@ static IrInstruction *ir_analyze_bin_op_math(IrAnalyze *ira, IrInstructionBinOp | ... | @@ -13380,8 +14204,8 @@ static IrInstruction *ir_analyze_bin_op_math(IrAnalyze *ira, IrInstructionBinOp |
| 13380 | // have a remainder function ambiguity problem | 14204 | // have a remainder function ambiguity problem |
| 13381 | ok = true; | 14205 | ok = true; |
| 13382 | } else { | 14206 | } else { |
| 13383 | ConstExprValue rem_result; | 14207 | ConstExprValue rem_result = {}; |
| 13384 | ConstExprValue mod_result; | 14208 | ConstExprValue mod_result = {}; |
| 13385 | float_rem(&rem_result, op1_val, op2_val); | 14209 | float_rem(&rem_result, op1_val, op2_val); |
| 13386 | float_mod(&mod_result, op1_val, op2_val); | 14210 | float_mod(&mod_result, op1_val, op2_val); |
| 13387 | ok = float_cmp(&rem_result, &mod_result) == CmpEQ; | 14211 | ok = float_cmp(&rem_result, &mod_result) == CmpEQ; |
| ... | @@ -13604,10 +14428,12 @@ static IrInstruction *ir_analyze_array_cat(IrAnalyze *ira, IrInstructionBinOp *i | ... | @@ -13604,10 +14428,12 @@ static IrInstruction *ir_analyze_array_cat(IrAnalyze *ira, IrInstructionBinOp *i |
| 13604 | | 14428 | |
| 13605 | size_t next_index = 0; | 14429 | size_t next_index = 0; |
| 13606 | 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) { |
| 13607 | 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); |
| 13608 | } | 14433 | } |
| 13609 | 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) { |
| 13610 | 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); |
| 13611 | } | 14437 | } |
| 13612 | if (next_index < new_len) { | 14438 | if (next_index < new_len) { |
| 13613 | 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]; |
| ... | @@ -13668,7 +14494,8 @@ static IrInstruction *ir_analyze_array_mult(IrAnalyze *ira, IrInstructionBinOp * | ... | @@ -13668,7 +14494,8 @@ static IrInstruction *ir_analyze_array_mult(IrAnalyze *ira, IrInstructionBinOp * |
| 13668 | uint64_t i = 0; | 14494 | uint64_t i = 0; |
| 13669 | for (uint64_t x = 0; x < mult_amt; x += 1) { | 14495 | for (uint64_t x = 0; x < mult_amt; x += 1) { |
| 13670 | for (uint64_t y = 0; y < old_array_len; y += 1) { | 14496 | for (uint64_t y = 0; y < old_array_len; y += 1) { |
| 13671 | 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); |
| 13672 | i += 1; | 14499 | i += 1; |
| 13673 | } | 14500 | } |
| 13674 | } | 14501 | } |
| ... | @@ -13765,12 +14592,6 @@ static IrInstruction *ir_analyze_instruction_decl_var(IrAnalyze *ira, | ... | @@ -13765,12 +14592,6 @@ static IrInstruction *ir_analyze_instruction_decl_var(IrAnalyze *ira, |
| 13765 | Error err; | 14592 | Error err; |
| 13766 | ZigVar *var = decl_var_instruction->var; | 14593 | ZigVar *var = decl_var_instruction->var; |
| 13767 | | 14594 | |
| 13768 | IrInstruction *init_value = decl_var_instruction->init_value->child; | | |
| 13769 | if (type_is_invalid(init_value->value.type)) { | | |
| 13770 | var->var_type = ira->codegen->builtin_types.entry_invalid; | | |
| 13771 | return ira->codegen->invalid_instruction; | | |
| 13772 | } | | |
| 13773 | | | |
| 13774 | ZigType *explicit_type = nullptr; | 14595 | ZigType *explicit_type = nullptr; |
| 13775 | IrInstruction *var_type = nullptr; | 14596 | IrInstruction *var_type = nullptr; |
| 13776 | if (decl_var_instruction->var_type != nullptr) { | 14597 | if (decl_var_instruction->var_type != nullptr) { |
| ... | @@ -13785,18 +14606,40 @@ static IrInstruction *ir_analyze_instruction_decl_var(IrAnalyze *ira, | ... | @@ -13785,18 +14606,40 @@ static IrInstruction *ir_analyze_instruction_decl_var(IrAnalyze *ira, |
| 13785 | | 14606 | |
| 13786 | AstNode *source_node = decl_var_instruction->base.source_node; | 14607 | AstNode *source_node = decl_var_instruction->base.source_node; |
| 13787 | | 14608 | |
| 13788 | IrInstruction *casted_init_value = ir_implicit_cast(ira, init_value, explicit_type); | | |
| 13789 | bool is_comptime_var = ir_get_var_is_comptime(var); | 14609 | bool is_comptime_var = ir_get_var_is_comptime(var); |
| 13790 | | 14610 | |
| 13791 | bool var_class_requires_const = false; | 14611 | bool var_class_requires_const = false; |
| 13792 | | 14612 | |
| 13793 | 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; |
| 13794 | if (type_is_invalid(result_type)) { | 14626 | if (type_is_invalid(result_type)) { |
| 13795 | result_type = ira->codegen->builtin_types.entry_invalid; | 14627 | result_type = ira->codegen->builtin_types.entry_invalid; |
| 13796 | } else if (result_type->id == ZigTypeIdUnreachable || result_type->id == ZigTypeIdOpaque) { | 14628 | } else if (result_type->id == ZigTypeIdUnreachable || result_type->id == ZigTypeIdOpaque) { |
| 13797 | ir_add_error_node(ira, source_node, | 14629 | zig_unreachable(); |
| 13798 | buf_sprintf("variable of type '%s' not allowed", buf_ptr(&result_type->name))); | 14630 | } |
| 13799 | 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 | } |
| 13800 | } | 14643 | } |
| 13801 | | 14644 | |
| 13802 | switch (type_requires_comptime(ira->codegen, result_type)) { | 14645 | switch (type_requires_comptime(ira->codegen, result_type)) { |
| ... | @@ -13813,18 +14656,20 @@ static IrInstruction *ir_analyze_instruction_decl_var(IrAnalyze *ira, | ... | @@ -13813,18 +14656,20 @@ static IrInstruction *ir_analyze_instruction_decl_var(IrAnalyze *ira, |
| 13813 | } | 14656 | } |
| 13814 | break; | 14657 | break; |
| 13815 | case ReqCompTimeNo: | 14658 | case ReqCompTimeNo: |
| 13816 | if (casted_init_value->value.special == ConstValSpecialStatic && | 14659 | if (init_val != nullptr) { |
| 13817 | casted_init_value->value.type->id == ZigTypeIdFn && | 14660 | if (init_val->special == ConstValSpecialStatic && |
| 13818 | casted_init_value->value.data.x_ptr.special != ConstPtrSpecialHardCodedAddr && | 14661 | init_val->type->id == ZigTypeIdFn && |
| 13819 | casted_init_value->value.data.x_ptr.data.fn.fn_entry->fn_inline == FnInlineAlways) | 14662 | init_val->data.x_ptr.special != ConstPtrSpecialHardCodedAddr && |
| 13820 | { | 14663 | init_val->data.x_ptr.data.fn.fn_entry->fn_inline == FnInlineAlways) |
| 13821 | var_class_requires_const = true; | 14664 | { |
| 13822 | if (!var->src_is_const && !is_comptime_var) { | 14665 | var_class_requires_const = true; |
| 13823 | ErrorMsg *msg = ir_add_error_node(ira, source_node, | 14666 | if (!var->src_is_const && !is_comptime_var) { |
| 13824 | buf_sprintf("functions marked inline must be stored in const or comptime var")); | 14667 | ErrorMsg *msg = ir_add_error_node(ira, source_node, |
| 13825 | 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")); |
| 13826 | 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; |
| 13827 | 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 | } |
| 13828 | } | 14673 | } |
| 13829 | } | 14674 | } |
| 13830 | break; | 14675 | break; |
| ... | @@ -13871,11 +14716,29 @@ static IrInstruction *ir_analyze_instruction_decl_var(IrAnalyze *ira, | ... | @@ -13871,11 +14716,29 @@ static IrInstruction *ir_analyze_instruction_decl_var(IrAnalyze *ira, |
| 13871 | } | 14716 | } |
| 13872 | } | 14717 | } |
| 13873 | | 14718 | |
| 13874 | if (casted_init_value->value.special != ConstValSpecialRuntime) { | 14719 | if (init_val != nullptr && init_val->special != ConstValSpecialRuntime) { |
| 13875 | 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) { |
| 13876 | 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); |
| 13877 | 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); |
| 13878 | 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); |
| 13879 | | 14742 | |
| 13880 | 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)) { |
| 13881 | return ir_const_void(ira, &decl_var_instruction->base); | 14744 | return ir_const_void(ira, &decl_var_instruction->base); |
| ... | @@ -13892,7 +14755,7 @@ static IrInstruction *ir_analyze_instruction_decl_var(IrAnalyze *ira, | ... | @@ -13892,7 +14755,7 @@ static IrInstruction *ir_analyze_instruction_decl_var(IrAnalyze *ira, |
| 13892 | if (fn_entry) | 14755 | if (fn_entry) |
| 13893 | fn_entry->variable_list.append(var); | 14756 | fn_entry->variable_list.append(var); |
| 13894 | | 14757 | |
| 13895 | 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); |
| 13896 | } | 14759 | } |
| 13897 | | 14760 | |
| 13898 | static IrInstruction *ir_analyze_instruction_export(IrAnalyze *ira, IrInstructionExport *instruction) { | 14761 | static IrInstruction *ir_analyze_instruction_export(IrAnalyze *ira, IrInstructionExport *instruction) { |
| ... | @@ -14186,7 +15049,7 @@ IrInstruction *ir_get_implicit_allocator(IrAnalyze *ira, IrInstruction *source_i | ... | @@ -14186,7 +15049,7 @@ IrInstruction *ir_get_implicit_allocator(IrAnalyze *ira, IrInstruction *source_i |
| 14186 | ZigVar *coro_allocator_var = ira->old_irb.exec->coro_allocator_var; | 15049 | ZigVar *coro_allocator_var = ira->old_irb.exec->coro_allocator_var; |
| 14187 | assert(coro_allocator_var != nullptr); | 15050 | assert(coro_allocator_var != nullptr); |
| 14188 | 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); |
| 14189 | IrInstruction *result = ir_get_deref(ira, source_instr, var_ptr_inst); | 15052 | IrInstruction *result = ir_get_deref(ira, source_instr, var_ptr_inst, nullptr); |
| 14190 | assert(result->value.type != nullptr); | 15053 | assert(result->value.type != nullptr); |
| 14191 | return result; | 15054 | return result; |
| 14192 | } | 15055 | } |
| ... | @@ -14194,7 +15057,436 @@ IrInstruction *ir_get_implicit_allocator(IrAnalyze *ira, IrInstruction *source_i | ... | @@ -14194,7 +15057,436 @@ IrInstruction *ir_get_implicit_allocator(IrAnalyze *ira, IrInstruction *source_i |
| 14194 | zig_unreachable(); | 15057 | zig_unreachable(); |
| 14195 | } | 15058 | } |
| 14196 | | 15059 | |
| 14197 | 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, |
| | 15061 | uint32_t align, const char *name_hint, bool force_comptime) |
| | 15062 | { |
| | 15063 | Error err; |
| | 15064 | |
| | 15065 | ConstExprValue *pointee = create_const_vals(1); |
| | 15066 | pointee->special = ConstValSpecialUndef; |
| | 15067 | |
| | 15068 | IrInstructionAllocaGen *result = ir_create_alloca_gen(ira, source_inst, align, name_hint); |
| | 15069 | result->base.value.special = ConstValSpecialStatic; |
| | 15070 | result->base.value.data.x_ptr.special = ConstPtrSpecialRef; |
| | 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))) |
| | 15075 | return ira->codegen->invalid_instruction; |
| | 15076 | assert(result->base.value.data.x_ptr.special != ConstPtrSpecialInvalid); |
| | 15077 | |
| | 15078 | pointee->type = var_type; |
| | 15079 | result->base.value.type = get_pointer_to_type_extra(ira->codegen, var_type, false, false, |
| | 15080 | PtrLenSingle, align, 0, 0, false); |
| | 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; |
| | 15088 | } |
| | 15089 | |
| | 15090 | static ZigType *ir_result_loc_expected_type(IrAnalyze *ira, IrInstruction *suspend_source_instr, |
| | 15091 | ResultLoc *result_loc) |
| | 15092 | { |
| | 15093 | switch (result_loc->id) { |
| | 15094 | case ResultLocIdInvalid: |
| | 15095 | case ResultLocIdPeerParent: |
| | 15096 | zig_unreachable(); |
| | 15097 | case ResultLocIdNone: |
| | 15098 | case ResultLocIdVar: |
| | 15099 | case ResultLocIdBitCast: |
| | 15100 | return nullptr; |
| | 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 | } |
| | 15110 | |
| | 15111 | static bool type_can_bit_cast(ZigType *t) { |
| | 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: |
| | 15126 | return false; |
| | 15127 | default: |
| | 15128 | // TODO list these types out explicitly, there are probably some other invalid ones here |
| | 15129 | return true; |
| | 15130 | } |
| | 15131 | } |
| | 15132 | |
| | 15133 | static void set_up_result_loc_for_inferred_comptime(IrInstruction *ptr) { |
| | 15134 | ConstExprValue *undef_child = create_const_vals(1); |
| | 15135 | undef_child->type = ptr->value.type->data.pointer.child_type; |
| | 15136 | undef_child->special = ConstValSpecialUndef; |
| | 15137 | ptr->value.special = ConstValSpecialStatic; |
| | 15138 | ptr->value.data.x_ptr.mut = ConstPtrMutInfer; |
| | 15139 | ptr->value.data.x_ptr.special = ConstPtrSpecialRef; |
| | 15140 | ptr->value.data.x_ptr.data.ref.pointee = undef_child; |
| | 15141 | } |
| | 15142 | |
| | 15143 | // when calling this function, at the callsite must check for result type noreturn and propagate it up |
| | 15144 | static IrInstruction *ir_resolve_result_raw(IrAnalyze *ira, IrInstruction *suspend_source_instr, |
| | 15145 | ResultLoc *result_loc, ZigType *value_type, IrInstruction *value, bool force_runtime, bool non_null_comptime) |
| | 15146 | { |
| | 15147 | Error err; |
| | 15148 | if (result_loc->resolved_loc != nullptr) { |
| | 15149 | // allow to redo the result location if the value is known and comptime and the previous one isn't |
| | 15150 | if (value == nullptr || !instr_is_comptime(value) || instr_is_comptime(result_loc->resolved_loc)) { |
| | 15151 | return result_loc->resolved_loc; |
| | 15152 | } |
| | 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 | } |
| | 15188 | |
| | 15189 | IrInstructionAllocaSrc *alloca_src = |
| | 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, |
| 14198 | ZigType *fn_type, IrInstruction *fn_ref, IrInstruction **casted_args, size_t arg_count, | 15490 | ZigType *fn_type, IrInstruction *fn_ref, IrInstruction **casted_args, size_t arg_count, |
| 14199 | IrInstruction *async_allocator_inst) | 15491 | IrInstruction *async_allocator_inst) |
| 14200 | { | 15492 | { |
| ... | @@ -14202,7 +15494,7 @@ static IrInstruction *ir_analyze_async_call(IrAnalyze *ira, IrInstructionCall *c | ... | @@ -14202,7 +15494,7 @@ static IrInstruction *ir_analyze_async_call(IrAnalyze *ira, IrInstructionCall *c |
| 14202 | ir_assert(async_allocator_inst->value.type->id == ZigTypeIdPointer, &call_instruction->base); | 15494 | ir_assert(async_allocator_inst->value.type->id == ZigTypeIdPointer, &call_instruction->base); |
| 14203 | ZigType *container_type = async_allocator_inst->value.type->data.pointer.child_type; | 15495 | ZigType *container_type = async_allocator_inst->value.type->data.pointer.child_type; |
| 14204 | IrInstruction *field_ptr_inst = ir_analyze_container_field_ptr(ira, realloc_field_name, &call_instruction->base, | 15496 | IrInstruction *field_ptr_inst = ir_analyze_container_field_ptr(ira, realloc_field_name, &call_instruction->base, |
| 14205 | async_allocator_inst, container_type); | 15497 | async_allocator_inst, container_type, false); |
| 14206 | if (type_is_invalid(field_ptr_inst->value.type)) { | 15498 | if (type_is_invalid(field_ptr_inst->value.type)) { |
| 14207 | return ira->codegen->invalid_instruction; | 15499 | return ira->codegen->invalid_instruction; |
| 14208 | } | 15500 | } |
| ... | @@ -14227,10 +15519,15 @@ static IrInstruction *ir_analyze_async_call(IrAnalyze *ira, IrInstructionCall *c | ... | @@ -14227,10 +15519,15 @@ static IrInstruction *ir_analyze_async_call(IrAnalyze *ira, IrInstructionCall *c |
| 14227 | ZigType *promise_type = get_promise_type(ira->codegen, return_type); | 15519 | ZigType *promise_type = get_promise_type(ira->codegen, return_type); |
| 14228 | ZigType *async_return_type = get_error_union_type(ira->codegen, alloc_fn_error_set_type, promise_type); | 15520 | ZigType *async_return_type = get_error_union_type(ira->codegen, alloc_fn_error_set_type, promise_type); |
| 14229 | | 15521 | |
| 14230 | IrInstruction *result = ir_build_call(&ira->new_irb, call_instruction->base.scope, call_instruction->base.source_node, | 15522 | IrInstruction *result_loc = ir_resolve_result(ira, &call_instruction->base, no_result_loc(), |
| 14231 | fn_entry, fn_ref, arg_count, casted_args, false, FnInlineAuto, true, async_allocator_inst, nullptr); | 15523 | async_return_type, nullptr, true, true); |
| 14232 | result->value.type = async_return_type; | 15524 | if (type_is_invalid(result_loc->value.type) || instr_is_unreachable(result_loc)) { |
| 14233 | return result; | 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); |
| 14234 | } | 15531 | } |
| 14235 | | 15532 | |
| 14236 | static bool ir_analyze_fn_call_inline_arg(IrAnalyze *ira, AstNode *fn_proto_node, | 15533 | static bool ir_analyze_fn_call_inline_arg(IrAnalyze *ira, AstNode *fn_proto_node, |
| ... | @@ -14253,7 +15550,7 @@ static bool ir_analyze_fn_call_inline_arg(IrAnalyze *ira, AstNode *fn_proto_node | ... | @@ -14253,7 +15550,7 @@ static bool ir_analyze_fn_call_inline_arg(IrAnalyze *ira, AstNode *fn_proto_node |
| 14253 | casted_arg = arg; | 15550 | casted_arg = arg; |
| 14254 | } | 15551 | } |
| 14255 | | 15552 | |
| 14256 | ConstExprValue *arg_val = ir_resolve_const(ira, casted_arg, UndefBad); | 15553 | ConstExprValue *arg_val = ir_resolve_const(ira, casted_arg, UndefOk); |
| 14257 | if (!arg_val) | 15554 | if (!arg_val) |
| 14258 | return false; | 15555 | return false; |
| 14259 | | 15556 | |
| ... | @@ -14309,7 +15606,7 @@ static bool ir_analyze_fn_call_generic_arg(IrAnalyze *ira, AstNode *fn_proto_nod | ... | @@ -14309,7 +15606,7 @@ static bool ir_analyze_fn_call_generic_arg(IrAnalyze *ira, AstNode *fn_proto_nod |
| 14309 | arg_val = create_const_runtime(casted_arg->value.type); | 15606 | arg_val = create_const_runtime(casted_arg->value.type); |
| 14310 | } | 15607 | } |
| 14311 | if (arg_part_of_generic_id) { | 15608 | if (arg_part_of_generic_id) { |
| 14312 | generic_id->params[generic_id->param_count] = *arg_val; | 15609 | copy_const_val(&generic_id->params[generic_id->param_count], arg_val, true); |
| 14313 | generic_id->param_count += 1; | 15610 | generic_id->param_count += 1; |
| 14314 | } | 15611 | } |
| 14315 | | 15612 | |
| ... | @@ -14480,7 +15777,9 @@ static IrInstruction *ir_analyze_store_ptr(IrAnalyze *ira, IrInstruction *source | ... | @@ -14480,7 +15777,9 @@ static IrInstruction *ir_analyze_store_ptr(IrAnalyze *ira, IrInstruction *source |
| 14480 | 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")); |
| 14481 | return ira->codegen->invalid_instruction; | 15778 | return ira->codegen->invalid_instruction; |
| 14482 | } | 15779 | } |
| 14483 | 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 | { |
| 14484 | if (instr_is_comptime(value)) { | 15783 | if (instr_is_comptime(value)) { |
| 14485 | 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); |
| 14486 | if (dest_val == nullptr) | 15785 | if (dest_val == nullptr) |
| ... | @@ -14494,18 +15793,24 @@ static IrInstruction *ir_analyze_store_ptr(IrAnalyze *ira, IrInstruction *source | ... | @@ -14494,18 +15793,24 @@ static IrInstruction *ir_analyze_store_ptr(IrAnalyze *ira, IrInstruction *source |
| 14494 | // ConstPtrMutComptimeVar, thus defeating the logic below. | 15793 | // ConstPtrMutComptimeVar, thus defeating the logic below. |
| 14495 | bool same_global_refs = ptr->value.data.x_ptr.mut != ConstPtrMutComptimeVar; | 15794 | bool same_global_refs = ptr->value.data.x_ptr.mut != ConstPtrMutComptimeVar; |
| 14496 | copy_const_val(dest_val, &value->value, same_global_refs); | 15795 | copy_const_val(dest_val, &value->value, same_global_refs); |
| 14497 | 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 | { |
| 14498 | 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; |
| 14499 | } | 15800 | } |
| 14500 | return ir_const_void(ira, source_instr); | 15801 | return ir_const_void(ira, source_instr); |
| 14501 | } | 15802 | } |
| 14502 | } | 15803 | } |
| 14503 | ir_add_error(ira, source_instr, | 15804 | if (ptr->value.data.x_ptr.mut == ConstPtrMutInfer) { |
| 14504 | buf_sprintf("cannot store runtime value in compile time variable")); | 15805 | ptr->value.special = ConstValSpecialRuntime; |
| 14505 | ConstExprValue *dest_val = const_ptr_pointee_unchecked(ira->codegen, &ptr->value); | 15806 | } else { |
| 14506 | 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; |
| 14507 | | 15811 | |
| 14508 | return ira->codegen->invalid_instruction; | 15812 | return ira->codegen->invalid_instruction; |
| | 15813 | } |
| 14509 | } | 15814 | } |
| 14510 | } | 15815 | } |
| 14511 | | 15816 | |
| ... | @@ -14534,7 +15839,7 @@ static IrInstruction *ir_analyze_store_ptr(IrAnalyze *ira, IrInstruction *source | ... | @@ -14534,7 +15839,7 @@ static IrInstruction *ir_analyze_store_ptr(IrAnalyze *ira, IrInstruction *source |
| 14534 | return result; | 15839 | return result; |
| 14535 | } | 15840 | } |
| 14536 | | 15841 | |
| 14537 | static IrInstruction *ir_analyze_fn_call(IrAnalyze *ira, IrInstructionCall *call_instruction, | 15842 | static IrInstruction *ir_analyze_fn_call(IrAnalyze *ira, IrInstructionCallSrc *call_instruction, |
| 14538 | ZigFn *fn_entry, ZigType *fn_type, IrInstruction *fn_ref, | 15843 | ZigFn *fn_entry, ZigType *fn_type, IrInstruction *fn_ref, |
| 14539 | IrInstruction *first_arg_ptr, bool comptime_fn_call, FnInline fn_inline) | 15844 | IrInstruction *first_arg_ptr, bool comptime_fn_call, FnInline fn_inline) |
| 14540 | { | 15845 | { |
| ... | @@ -14637,7 +15942,7 @@ static IrInstruction *ir_analyze_fn_call(IrAnalyze *ira, IrInstructionCall *call | ... | @@ -14637,7 +15942,7 @@ static IrInstruction *ir_analyze_fn_call(IrAnalyze *ira, IrInstructionCall *call |
| 14637 | 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)) { |
| 14638 | first_arg = first_arg_ptr; | 15943 | first_arg = first_arg_ptr; |
| 14639 | } else { | 15944 | } else { |
| 14640 | 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); |
| 14641 | if (type_is_invalid(first_arg->value.type)) | 15946 | if (type_is_invalid(first_arg->value.type)) |
| 14642 | return ira->codegen->invalid_instruction; | 15947 | return ira->codegen->invalid_instruction; |
| 14643 | } | 15948 | } |
| ... | @@ -14796,7 +16101,7 @@ static IrInstruction *ir_analyze_fn_call(IrAnalyze *ira, IrInstructionCall *call | ... | @@ -14796,7 +16101,7 @@ static IrInstruction *ir_analyze_fn_call(IrAnalyze *ira, IrInstructionCall *call |
| 14796 | 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)) { |
| 14797 | first_arg = first_arg_ptr; | 16102 | first_arg = first_arg_ptr; |
| 14798 | } else { | 16103 | } else { |
| 14799 | 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); |
| 14800 | if (type_is_invalid(first_arg->value.type)) | 16105 | if (type_is_invalid(first_arg->value.type)) |
| 14801 | return ira->codegen->invalid_instruction; | 16106 | return ira->codegen->invalid_instruction; |
| 14802 | } | 16107 | } |
| ... | @@ -14840,7 +16145,7 @@ static IrInstruction *ir_analyze_fn_call(IrAnalyze *ira, IrInstructionCall *call | ... | @@ -14840,7 +16145,7 @@ static IrInstruction *ir_analyze_fn_call(IrAnalyze *ira, IrInstructionCall *call |
| 14840 | if (type_is_invalid(arg_var_ptr_inst->value.type)) | 16145 | if (type_is_invalid(arg_var_ptr_inst->value.type)) |
| 14841 | return ira->codegen->invalid_instruction; | 16146 | return ira->codegen->invalid_instruction; |
| 14842 | | 16147 | |
| 14843 | 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); |
| 14844 | if (type_is_invalid(arg_tuple_arg->value.type)) | 16149 | if (type_is_invalid(arg_tuple_arg->value.type)) |
| 14845 | return ira->codegen->invalid_instruction; | 16150 | return ira->codegen->invalid_instruction; |
| 14846 | | 16151 | |
| ... | @@ -14889,7 +16194,7 @@ static IrInstruction *ir_analyze_fn_call(IrAnalyze *ira, IrInstructionCall *call | ... | @@ -14889,7 +16194,7 @@ static IrInstruction *ir_analyze_fn_call(IrAnalyze *ira, IrInstructionCall *call |
| 14889 | 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); |
| 14890 | IrInstructionConst *const_instruction = ir_create_instruction<IrInstructionConst>(&ira->new_irb, | 16195 | IrInstructionConst *const_instruction = ir_create_instruction<IrInstructionConst>(&ira->new_irb, |
| 14891 | 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); |
| 14892 | const_instruction->base.value = *align_result; | 16197 | copy_const_val(&const_instruction->base.value, align_result, true); |
| 14893 | | 16198 | |
| 14894 | uint32_t align_bytes = 0; | 16199 | uint32_t align_bytes = 0; |
| 14895 | ir_resolve_align(ira, &const_instruction->base, &align_bytes); | 16200 | ir_resolve_align(ira, &const_instruction->base, &align_bytes); |
| ... | @@ -14971,6 +16276,19 @@ static IrInstruction *ir_analyze_fn_call(IrAnalyze *ira, IrInstructionCall *call | ... | @@ -14971,6 +16276,19 @@ static IrInstruction *ir_analyze_fn_call(IrAnalyze *ira, IrInstructionCall *call |
| 14971 | } | 16276 | } |
| 14972 | | 16277 | |
| 14973 | 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 | |
| 14974 | if (fn_type_can_fail(impl_fn_type_id)) { | 16292 | if (fn_type_can_fail(impl_fn_type_id)) { |
| 14975 | parent_fn_entry->calls_or_awaits_errorable_fn = true; | 16293 | parent_fn_entry->calls_or_awaits_errorable_fn = true; |
| 14976 | } | 16294 | } |
| ... | @@ -14979,18 +16297,14 @@ static IrInstruction *ir_analyze_fn_call(IrAnalyze *ira, IrInstructionCall *call | ... | @@ -14979,18 +16297,14 @@ static IrInstruction *ir_analyze_fn_call(IrAnalyze *ira, IrInstructionCall *call |
| 14979 | if (call_instruction->is_async) { | 16297 | if (call_instruction->is_async) { |
| 14980 | 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, |
| 14981 | fn_ref, casted_args, impl_param_count, async_allocator_inst); | 16299 | fn_ref, casted_args, impl_param_count, async_allocator_inst); |
| 14982 | ir_add_alloca(ira, result, result->value.type); | | |
| 14983 | return ir_finish_anal(ira, result); | 16300 | return ir_finish_anal(ira, result); |
| 14984 | } | 16301 | } |
| 14985 | | 16302 | |
| 14986 | assert(async_allocator_inst == nullptr); | 16303 | assert(async_allocator_inst == nullptr); |
| 14987 | IrInstruction *new_call_instruction = ir_build_call(&ira->new_irb, | 16304 | IrInstruction *new_call_instruction = ir_build_call_gen(ira, &call_instruction->base, |
| 14988 | call_instruction->base.scope, call_instruction->base.source_node, | 16305 | impl_fn, nullptr, impl_param_count, casted_args, fn_inline, |
| 14989 | impl_fn, nullptr, impl_param_count, casted_args, false, fn_inline, | 16306 | call_instruction->is_async, nullptr, casted_new_stack, result_loc, |
| 14990 | call_instruction->is_async, nullptr, casted_new_stack); | 16307 | impl_fn_type_id->return_type); |
| 14991 | new_call_instruction->value.type = impl_fn_type_id->return_type; | | |
| 14992 | | | |
| 14993 | ir_add_alloca(ira, new_call_instruction, impl_fn_type_id->return_type); | | |
| 14994 | | 16308 | |
| 14995 | return ir_finish_anal(ira, new_call_instruction); | 16309 | return ir_finish_anal(ira, new_call_instruction); |
| 14996 | } | 16310 | } |
| ... | @@ -15018,7 +16332,7 @@ static IrInstruction *ir_analyze_fn_call(IrAnalyze *ira, IrInstructionCall *call | ... | @@ -15018,7 +16332,7 @@ static IrInstruction *ir_analyze_fn_call(IrAnalyze *ira, IrInstructionCall *call |
| 15018 | { | 16332 | { |
| 15019 | first_arg = first_arg_ptr; | 16333 | first_arg = first_arg_ptr; |
| 15020 | } else { | 16334 | } else { |
| 15021 | 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); |
| 15022 | if (type_is_invalid(first_arg->value.type)) | 16336 | if (type_is_invalid(first_arg->value.type)) |
| 15023 | return ira->codegen->invalid_instruction; | 16337 | return ira->codegen->invalid_instruction; |
| 15024 | } | 16338 | } |
| ... | @@ -15075,7 +16389,6 @@ static IrInstruction *ir_analyze_fn_call(IrAnalyze *ira, IrInstructionCall *call | ... | @@ -15075,7 +16389,6 @@ static IrInstruction *ir_analyze_fn_call(IrAnalyze *ira, IrInstructionCall *call |
| 15075 | | 16389 | |
| 15076 | 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, |
| 15077 | casted_args, call_param_count, async_allocator_inst); | 16391 | casted_args, call_param_count, async_allocator_inst); |
| 15078 | ir_add_alloca(ira, result, result->value.type); | | |
| 15079 | return ir_finish_anal(ira, result); | 16392 | return ir_finish_anal(ira, result); |
| 15080 | } | 16393 | } |
| 15081 | | 16394 | |
| ... | @@ -15085,15 +16398,24 @@ static IrInstruction *ir_analyze_fn_call(IrAnalyze *ira, IrInstructionCall *call | ... | @@ -15085,15 +16398,24 @@ static IrInstruction *ir_analyze_fn_call(IrAnalyze *ira, IrInstructionCall *call |
| 15085 | return ira->codegen->invalid_instruction; | 16398 | return ira->codegen->invalid_instruction; |
| 15086 | } | 16399 | } |
| 15087 | | 16400 | |
| 15088 | IrInstruction *new_call_instruction = ir_build_call(&ira->new_irb, | 16401 | IrInstruction *result_loc; |
| 15089 | call_instruction->base.scope, call_instruction->base.source_node, | 16402 | if (handle_is_ptr(return_type)) { |
| 15090 | 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, |
| 15091 | new_call_instruction->value.type = return_type; | 16404 | return_type, nullptr, true, true); |
| 15092 | 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); |
| 15093 | return ir_finish_anal(ira, new_call_instruction); | 16415 | return ir_finish_anal(ira, new_call_instruction); |
| 15094 | } | 16416 | } |
| 15095 | | 16417 | |
| 15096 | static IrInstruction *ir_analyze_instruction_call(IrAnalyze *ira, IrInstructionCall *call_instruction) { | 16418 | static IrInstruction *ir_analyze_instruction_call(IrAnalyze *ira, IrInstructionCallSrc *call_instruction) { |
| 15097 | IrInstruction *fn_ref = call_instruction->fn_ref->child; | 16419 | IrInstruction *fn_ref = call_instruction->fn_ref->child; |
| 15098 | if (type_is_invalid(fn_ref->value.type)) | 16420 | if (type_is_invalid(fn_ref->value.type)) |
| 15099 | return ira->codegen->invalid_instruction; | 16421 | return ira->codegen->invalid_instruction; |
| ... | @@ -15117,7 +16439,8 @@ static IrInstruction *ir_analyze_instruction_call(IrAnalyze *ira, IrInstructionC | ... | @@ -15117,7 +16439,8 @@ static IrInstruction *ir_analyze_instruction_call(IrAnalyze *ira, IrInstructionC |
| 15117 | | 16439 | |
| 15118 | IrInstruction *arg = call_instruction->args[0]->child; | 16440 | IrInstruction *arg = call_instruction->args[0]->child; |
| 15119 | | 16441 | |
| 15120 | 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); |
| 15121 | if (type_is_invalid(cast_instruction->value.type)) | 16444 | if (type_is_invalid(cast_instruction->value.type)) |
| 15122 | return ira->codegen->invalid_instruction; | 16445 | return ira->codegen->invalid_instruction; |
| 15123 | return ir_finish_anal(ira, cast_instruction); | 16446 | return ir_finish_anal(ira, cast_instruction); |
| ... | @@ -15170,7 +16493,7 @@ static Error ir_read_const_ptr(IrAnalyze *ira, CodeGen *codegen, AstNode *source | ... | @@ -15170,7 +16493,7 @@ static Error ir_read_const_ptr(IrAnalyze *ira, CodeGen *codegen, AstNode *source |
| 15170 | | 16493 | |
| 15171 | if (dst_size <= src_size) { | 16494 | if (dst_size <= src_size) { |
| 15172 | 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)) { |
| 15173 | 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); |
| 15174 | return ErrorNone; | 16497 | return ErrorNone; |
| 15175 | } | 16498 | } |
| 15176 | Buf buf = BUF_INIT; | 16499 | Buf buf = BUF_INIT; |
| ... | @@ -15419,7 +16742,7 @@ static IrInstruction *ir_analyze_instruction_un_op(IrAnalyze *ira, IrInstruction | ... | @@ -15419,7 +16742,7 @@ static IrInstruction *ir_analyze_instruction_un_op(IrAnalyze *ira, IrInstruction |
| 15419 | return ira->codegen->invalid_instruction; | 16742 | return ira->codegen->invalid_instruction; |
| 15420 | } | 16743 | } |
| 15421 | | 16744 | |
| 15422 | IrInstruction *result = ir_get_deref(ira, &instruction->base, ptr); | 16745 | IrInstruction *result = ir_get_deref(ira, &instruction->base, ptr, instruction->result_loc); |
| 15423 | if (result == ira->codegen->invalid_instruction) | 16746 | if (result == ira->codegen->invalid_instruction) |
| 15424 | return ira->codegen->invalid_instruction; | 16747 | return ira->codegen->invalid_instruction; |
| 15425 | | 16748 | |
| ... | @@ -15438,6 +16761,19 @@ static IrInstruction *ir_analyze_instruction_un_op(IrAnalyze *ira, IrInstruction | ... | @@ -15438,6 +16761,19 @@ static IrInstruction *ir_analyze_instruction_un_op(IrAnalyze *ira, IrInstruction |
| 15438 | zig_unreachable(); | 16761 | zig_unreachable(); |
| 15439 | } | 16762 | } |
| 15440 | | 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 | |
| 15441 | static IrInstruction *ir_analyze_instruction_br(IrAnalyze *ira, IrInstructionBr *br_instruction) { | 16777 | static IrInstruction *ir_analyze_instruction_br(IrAnalyze *ira, IrInstructionBr *br_instruction) { |
| 15442 | IrBasicBlock *old_dest_block = br_instruction->dest_block; | 16778 | IrBasicBlock *old_dest_block = br_instruction->dest_block; |
| 15443 | | 16779 | |
| ... | @@ -15445,13 +16781,15 @@ static IrInstruction *ir_analyze_instruction_br(IrAnalyze *ira, IrInstructionBr | ... | @@ -15445,13 +16781,15 @@ static IrInstruction *ir_analyze_instruction_br(IrAnalyze *ira, IrInstructionBr |
| 15445 | 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)) |
| 15446 | return ir_unreach_error(ira); | 16782 | return ir_unreach_error(ira); |
| 15447 | | 16783 | |
| 15448 | 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)) |
| 15449 | return ir_inline_bb(ira, &br_instruction->base, old_dest_block); | 16785 | return ir_inline_bb(ira, &br_instruction->base, old_dest_block); |
| 15450 | | 16786 | |
| 15451 | 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); |
| 15452 | if (new_bb == nullptr) | 16788 | if (new_bb == nullptr) |
| 15453 | return ir_unreach_error(ira); | 16789 | return ir_unreach_error(ira); |
| 15454 | | 16790 | |
| | 16791 | ir_push_resume_block(ira, old_dest_block); |
| | 16792 | |
| 15455 | IrInstruction *result = ir_build_br(&ira->new_irb, | 16793 | IrInstruction *result = ir_build_br(&ira->new_irb, |
| 15456 | 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); |
| 15457 | result->value.type = ira->codegen->builtin_types.entry_unreachable; | 16795 | result->value.type = ira->codegen->builtin_types.entry_unreachable; |
| ... | @@ -15480,13 +16818,15 @@ static IrInstruction *ir_analyze_instruction_cond_br(IrAnalyze *ira, IrInstructi | ... | @@ -15480,13 +16818,15 @@ static IrInstruction *ir_analyze_instruction_cond_br(IrAnalyze *ira, IrInstructi |
| 15480 | IrBasicBlock *old_dest_block = cond_is_true ? | 16818 | IrBasicBlock *old_dest_block = cond_is_true ? |
| 15481 | cond_br_instruction->then_block : cond_br_instruction->else_block; | 16819 | cond_br_instruction->then_block : cond_br_instruction->else_block; |
| 15482 | | 16820 | |
| 15483 | 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)) |
| 15484 | 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); |
| 15485 | | 16823 | |
| 15486 | 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); |
| 15487 | if (new_dest_block == nullptr) | 16825 | if (new_dest_block == nullptr) |
| 15488 | return ir_unreach_error(ira); | 16826 | return ir_unreach_error(ira); |
| 15489 | | 16827 | |
| | 16828 | ir_push_resume_block(ira, old_dest_block); |
| | 16829 | |
| 15490 | IrInstruction *result = ir_build_br(&ira->new_irb, | 16830 | IrInstruction *result = ir_build_br(&ira->new_irb, |
| 15491 | 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); |
| 15492 | result->value.type = ira->codegen->builtin_types.entry_unreachable; | 16832 | result->value.type = ira->codegen->builtin_types.entry_unreachable; |
| ... | @@ -15502,6 +16842,9 @@ static IrInstruction *ir_analyze_instruction_cond_br(IrAnalyze *ira, IrInstructi | ... | @@ -15502,6 +16842,9 @@ static IrInstruction *ir_analyze_instruction_cond_br(IrAnalyze *ira, IrInstructi |
| 15502 | if (new_else_block == nullptr) | 16842 | if (new_else_block == nullptr) |
| 15503 | return ir_unreach_error(ira); | 16843 | return ir_unreach_error(ira); |
| 15504 | | 16844 | |
| | 16845 | ir_push_resume_block(ira, cond_br_instruction->else_block); |
| | 16846 | ir_push_resume_block(ira, cond_br_instruction->then_block); |
| | 16847 | |
| 15505 | IrInstruction *result = ir_build_cond_br(&ira->new_irb, | 16848 | IrInstruction *result = ir_build_cond_br(&ira->new_irb, |
| 15506 | cond_br_instruction->base.scope, cond_br_instruction->base.source_node, | 16849 | cond_br_instruction->base.scope, cond_br_instruction->base.source_node, |
| 15507 | casted_condition, new_then_block, new_else_block, nullptr); | 16850 | casted_condition, new_then_block, new_else_block, nullptr); |
| ... | @@ -15540,11 +16883,85 @@ static IrInstruction *ir_analyze_instruction_phi(IrAnalyze *ira, IrInstructionPh | ... | @@ -15540,11 +16883,85 @@ static IrInstruction *ir_analyze_instruction_phi(IrAnalyze *ira, IrInstructionPh |
| 15540 | zig_unreachable(); | 16883 | zig_unreachable(); |
| 15541 | } | 16884 | } |
| 15542 | | 16885 | |
| 15543 | ZigList<IrBasicBlock*> new_incoming_blocks = {0}; | 16886 | ResultLocPeerParent *peer_parent = phi_instruction->peer_parent; |
| 15544 | ZigList<IrInstruction*> new_incoming_values = {0}; | 16887 | if (peer_parent != nullptr && !peer_parent->skipped && !peer_parent->done_resuming && |
| 15545 | | 16888 | peer_parent->peers.length >= 2) |
| 15546 | for (size_t i = 0; i < phi_instruction->incoming_count; i += 1) { | 16889 | { |
| 15547 | IrBasicBlock *predecessor = phi_instruction->incoming_blocks[i]; | 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 | |
| | 16960 | ZigList<IrBasicBlock*> new_incoming_blocks = {0}; |
| | 16961 | ZigList<IrInstruction*> new_incoming_values = {0}; |
| | 16962 | |
| | 16963 | for (size_t i = 0; i < phi_instruction->incoming_count; i += 1) { |
| | 16964 | IrBasicBlock *predecessor = phi_instruction->incoming_blocks[i]; |
| 15548 | if (predecessor->ref_count == 0) | 16965 | if (predecessor->ref_count == 0) |
| 15549 | continue; | 16966 | continue; |
| 15550 | | 16967 | |
| ... | @@ -15612,7 +17029,7 @@ static IrInstruction *ir_analyze_instruction_phi(IrAnalyze *ira, IrInstructionPh | ... | @@ -15612,7 +17029,7 @@ static IrInstruction *ir_analyze_instruction_phi(IrAnalyze *ira, IrInstructionPh |
| 15612 | IrInstruction *branch_instruction = predecessor->instruction_list.pop(); | 17029 | IrInstruction *branch_instruction = predecessor->instruction_list.pop(); |
| 15613 | ir_set_cursor_at_end(&ira->new_irb, predecessor); | 17030 | ir_set_cursor_at_end(&ira->new_irb, predecessor); |
| 15614 | IrInstruction *casted_value = ir_implicit_cast(ira, new_value, resolved_type); | 17031 | IrInstruction *casted_value = ir_implicit_cast(ira, new_value, resolved_type); |
| 15615 | if (casted_value == ira->codegen->invalid_instruction) { | 17032 | if (type_is_invalid(casted_value->value.type)) { |
| 15616 | return ira->codegen->invalid_instruction; | 17033 | return ira->codegen->invalid_instruction; |
| 15617 | } | 17034 | } |
| 15618 | new_incoming_values.items[i] = casted_value; | 17035 | new_incoming_values.items[i] = casted_value; |
| ... | @@ -15628,7 +17045,7 @@ static IrInstruction *ir_analyze_instruction_phi(IrAnalyze *ira, IrInstructionPh | ... | @@ -15628,7 +17045,7 @@ static IrInstruction *ir_analyze_instruction_phi(IrAnalyze *ira, IrInstructionPh |
| 15628 | | 17045 | |
| 15629 | IrInstruction *result = ir_build_phi(&ira->new_irb, | 17046 | IrInstruction *result = ir_build_phi(&ira->new_irb, |
| 15630 | phi_instruction->base.scope, phi_instruction->base.source_node, | 17047 | phi_instruction->base.scope, phi_instruction->base.source_node, |
| 15631 | 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); |
| 15632 | result->value.type = resolved_type; | 17049 | result->value.type = resolved_type; |
| 15633 | | 17050 | |
| 15634 | if (all_stack_ptrs) { | 17051 | if (all_stack_ptrs) { |
| ... | @@ -15846,6 +17263,48 @@ static IrInstruction *ir_analyze_instruction_elem_ptr(IrAnalyze *ira, IrInstruct | ... | @@ -15846,6 +17263,48 @@ static IrInstruction *ir_analyze_instruction_elem_ptr(IrAnalyze *ira, IrInstruct |
| 15846 | if (array_ptr_val == nullptr) | 17263 | if (array_ptr_val == nullptr) |
| 15847 | return ira->codegen->invalid_instruction; | 17264 | return ira->codegen->invalid_instruction; |
| 15848 | | 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 | assert(actual_array_type->id == ZigTypeIdArray); |
| | 17284 | |
| | 17285 | ConstExprValue *array_init_val = create_const_vals(1); |
| | 17286 | array_init_val->special = ConstValSpecialStatic; |
| | 17287 | array_init_val->type = actual_array_type; |
| | 17288 | array_init_val->data.x_array.special = ConstArraySpecialNone; |
| | 17289 | array_init_val->data.x_array.data.s_none.elements = create_const_vals(actual_array_type->data.array.len); |
| | 17290 | array_init_val->special = ConstValSpecialStatic; |
| | 17291 | for (size_t i = 0; i < actual_array_type->data.array.len; i += 1) { |
| | 17292 | ConstExprValue *elem_val = &array_init_val->data.x_array.data.s_none.elements[i]; |
| | 17293 | elem_val->special = ConstValSpecialUndef; |
| | 17294 | elem_val->type = actual_array_type->data.array.child_type; |
| | 17295 | elem_val->parent.id = ConstParentIdArray; |
| | 17296 | elem_val->parent.data.p_array.array_val = array_init_val; |
| | 17297 | elem_val->parent.data.p_array.elem_index = i; |
| | 17298 | } |
| | 17299 | |
| | 17300 | init_const_slice(ira->codegen, array_ptr_val, array_init_val, 0, actual_array_type->data.array.len, |
| | 17301 | false); |
| | 17302 | array_ptr_val->data.x_struct.fields[slice_ptr_index].data.x_ptr.mut = ConstPtrMutInfer; |
| | 17303 | } else { |
| | 17304 | zig_unreachable(); |
| | 17305 | } |
| | 17306 | } |
| | 17307 | |
| 15849 | if (array_ptr_val->special != ConstValSpecialRuntime && | 17308 | if (array_ptr_val->special != ConstValSpecialRuntime && |
| 15850 | (array_type->id != ZigTypeIdPointer || | 17309 | (array_type->id != ZigTypeIdPointer || |
| 15851 | array_ptr_val->data.x_ptr.special != ConstPtrSpecialHardCodedAddr)) | 17310 | array_ptr_val->data.x_ptr.special != ConstPtrSpecialHardCodedAddr)) |
| ... | @@ -15911,8 +17370,9 @@ static IrInstruction *ir_analyze_instruction_elem_ptr(IrAnalyze *ira, IrInstruct | ... | @@ -15911,8 +17370,9 @@ static IrInstruction *ir_analyze_instruction_elem_ptr(IrAnalyze *ira, IrInstruct |
| 15911 | } else if (is_slice(array_type)) { | 17370 | } else if (is_slice(array_type)) { |
| 15912 | ConstExprValue *ptr_field = &array_ptr_val->data.x_struct.fields[slice_ptr_index]; | 17371 | ConstExprValue *ptr_field = &array_ptr_val->data.x_struct.fields[slice_ptr_index]; |
| 15913 | if (ptr_field->data.x_ptr.special == ConstPtrSpecialHardCodedAddr) { | 17372 | if (ptr_field->data.x_ptr.special == ConstPtrSpecialHardCodedAddr) { |
| 15914 | IrInstruction *result = ir_build_elem_ptr(&ira->new_irb, elem_ptr_instruction->base.scope, elem_ptr_instruction->base.source_node, | 17373 | IrInstruction *result = ir_build_elem_ptr(&ira->new_irb, elem_ptr_instruction->base.scope, |
| 15915 | array_ptr, casted_elem_index, false, elem_ptr_instruction->ptr_len); | 17374 | elem_ptr_instruction->base.source_node, array_ptr, casted_elem_index, false, |
| | 17375 | elem_ptr_instruction->ptr_len, nullptr); |
| 15916 | result->value.type = return_type; | 17376 | result->value.type = return_type; |
| 15917 | return result; | 17377 | return result; |
| 15918 | } | 17378 | } |
| ... | @@ -15965,7 +17425,16 @@ static IrInstruction *ir_analyze_instruction_elem_ptr(IrAnalyze *ira, IrInstruct | ... | @@ -15965,7 +17425,16 @@ static IrInstruction *ir_analyze_instruction_elem_ptr(IrAnalyze *ira, IrInstruct |
| 15965 | } | 17425 | } |
| 15966 | return result; | 17426 | return result; |
| 15967 | } else if (array_type->id == ZigTypeIdArray) { | 17427 | } else if (array_type->id == ZigTypeIdArray) { |
| 15968 | IrInstruction *result = ir_const(ira, &elem_ptr_instruction->base, return_type); | 17428 | IrInstruction *result; |
| | 17429 | if (orig_array_ptr_val->data.x_ptr.mut == ConstPtrMutInfer) { |
| | 17430 | result = ir_build_elem_ptr(&ira->new_irb, elem_ptr_instruction->base.scope, |
| | 17431 | elem_ptr_instruction->base.source_node, array_ptr, casted_elem_index, |
| | 17432 | false, elem_ptr_instruction->ptr_len, elem_ptr_instruction->init_array_type); |
| | 17433 | result->value.type = return_type; |
| | 17434 | result->value.special = ConstValSpecialStatic; |
| | 17435 | } else { |
| | 17436 | result = ir_const(ira, &elem_ptr_instruction->base, return_type); |
| | 17437 | } |
| 15969 | ConstExprValue *out_val = &result->value; | 17438 | ConstExprValue *out_val = &result->value; |
| 15970 | out_val->data.x_ptr.special = ConstPtrSpecialBaseArray; | 17439 | out_val->data.x_ptr.special = ConstPtrSpecialBaseArray; |
| 15971 | out_val->data.x_ptr.mut = orig_array_ptr_val->data.x_ptr.mut; | 17440 | out_val->data.x_ptr.mut = orig_array_ptr_val->data.x_ptr.mut; |
| ... | @@ -15977,7 +17446,6 @@ static IrInstruction *ir_analyze_instruction_elem_ptr(IrAnalyze *ira, IrInstruct | ... | @@ -15977,7 +17446,6 @@ static IrInstruction *ir_analyze_instruction_elem_ptr(IrAnalyze *ira, IrInstruct |
| 15977 | } | 17446 | } |
| 15978 | } | 17447 | } |
| 15979 | } | 17448 | } |
| 15980 | | | |
| 15981 | } else { | 17449 | } else { |
| 15982 | // runtime known element index | 17450 | // runtime known element index |
| 15983 | switch (type_requires_comptime(ira->codegen, return_type)) { | 17451 | switch (type_requires_comptime(ira->codegen, return_type)) { |
| ... | @@ -16003,8 +17471,9 @@ static IrInstruction *ir_analyze_instruction_elem_ptr(IrAnalyze *ira, IrInstruct | ... | @@ -16003,8 +17471,9 @@ static IrInstruction *ir_analyze_instruction_elem_ptr(IrAnalyze *ira, IrInstruct |
| 16003 | } | 17471 | } |
| 16004 | } | 17472 | } |
| 16005 | | 17473 | |
| 16006 | IrInstruction *result = ir_build_elem_ptr(&ira->new_irb, elem_ptr_instruction->base.scope, elem_ptr_instruction->base.source_node, | 17474 | IrInstruction *result = ir_build_elem_ptr(&ira->new_irb, elem_ptr_instruction->base.scope, |
| 16007 | array_ptr, casted_elem_index, safety_check_on, elem_ptr_instruction->ptr_len); | 17475 | elem_ptr_instruction->base.source_node, array_ptr, casted_elem_index, safety_check_on, |
| | 17476 | elem_ptr_instruction->ptr_len, elem_ptr_instruction->init_array_type); |
| 16008 | result->value.type = return_type; | 17477 | result->value.type = return_type; |
| 16009 | return result; | 17478 | return result; |
| 16010 | } | 17479 | } |
| ... | @@ -16049,8 +17518,80 @@ static IrInstruction *ir_analyze_container_member_access_inner(IrAnalyze *ira, | ... | @@ -16049,8 +17518,80 @@ static IrInstruction *ir_analyze_container_member_access_inner(IrAnalyze *ira, |
| 16049 | return ira->codegen->invalid_instruction; | 17518 | return ira->codegen->invalid_instruction; |
| 16050 | } | 17519 | } |
| 16051 | | 17520 | |
| | 17521 | static IrInstruction *ir_analyze_struct_field_ptr(IrAnalyze *ira, IrInstruction *source_instr, |
| | 17522 | TypeStructField *field, IrInstruction *struct_ptr, ZigType *struct_type, bool initializing) |
| | 17523 | { |
| | 17524 | switch (type_has_one_possible_value(ira->codegen, field->type_entry)) { |
| | 17525 | case OnePossibleValueInvalid: |
| | 17526 | return ira->codegen->invalid_instruction; |
| | 17527 | case OnePossibleValueYes: { |
| | 17528 | IrInstruction *elem = ir_const(ira, source_instr, field->type_entry); |
| | 17529 | return ir_get_ref(ira, source_instr, elem, false, false); |
| | 17530 | } |
| | 17531 | case OnePossibleValueNo: |
| | 17532 | break; |
| | 17533 | } |
| | 17534 | assert(struct_ptr->value.type->id == ZigTypeIdPointer); |
| | 17535 | bool is_packed = (struct_type->data.structure.layout == ContainerLayoutPacked); |
| | 17536 | uint32_t align_bytes = is_packed ? 1 : get_abi_alignment(ira->codegen, field->type_entry); |
| | 17537 | uint32_t ptr_bit_offset = struct_ptr->value.type->data.pointer.bit_offset_in_host; |
| | 17538 | uint32_t ptr_host_int_bytes = struct_ptr->value.type->data.pointer.host_int_bytes; |
| | 17539 | uint32_t host_int_bytes_for_result_type = (ptr_host_int_bytes == 0) ? |
| | 17540 | get_host_int_bytes(ira->codegen, struct_type, field) : ptr_host_int_bytes; |
| | 17541 | bool is_const = struct_ptr->value.type->data.pointer.is_const; |
| | 17542 | bool is_volatile = struct_ptr->value.type->data.pointer.is_volatile; |
| | 17543 | ZigType *ptr_type = get_pointer_to_type_extra(ira->codegen, field->type_entry, |
| | 17544 | is_const, is_volatile, PtrLenSingle, align_bytes, |
| | 17545 | (uint32_t)(ptr_bit_offset + field->bit_offset_in_host), |
| | 17546 | (uint32_t)host_int_bytes_for_result_type, false); |
| | 17547 | if (instr_is_comptime(struct_ptr)) { |
| | 17548 | ConstExprValue *ptr_val = ir_resolve_const(ira, struct_ptr, UndefBad); |
| | 17549 | if (!ptr_val) |
| | 17550 | return ira->codegen->invalid_instruction; |
| | 17551 | |
| | 17552 | if (ptr_val->data.x_ptr.special != ConstPtrSpecialHardCodedAddr) { |
| | 17553 | ConstExprValue *struct_val = const_ptr_pointee(ira, ira->codegen, ptr_val, source_instr->source_node); |
| | 17554 | if (struct_val == nullptr) |
| | 17555 | return ira->codegen->invalid_instruction; |
| | 17556 | if (type_is_invalid(struct_val->type)) |
| | 17557 | return ira->codegen->invalid_instruction; |
| | 17558 | if (struct_val->special == ConstValSpecialUndef && initializing) { |
| | 17559 | struct_val->data.x_struct.fields = create_const_vals(struct_type->data.structure.src_field_count); |
| | 17560 | struct_val->special = ConstValSpecialStatic; |
| | 17561 | for (size_t i = 0; i < struct_type->data.structure.src_field_count; i += 1) { |
| | 17562 | ConstExprValue *field_val = &struct_val->data.x_struct.fields[i]; |
| | 17563 | field_val->special = ConstValSpecialUndef; |
| | 17564 | field_val->type = struct_type->data.structure.fields[i].type_entry; |
| | 17565 | field_val->parent.id = ConstParentIdStruct; |
| | 17566 | field_val->parent.data.p_struct.struct_val = struct_val; |
| | 17567 | field_val->parent.data.p_struct.field_index = i; |
| | 17568 | } |
| | 17569 | } |
| | 17570 | IrInstruction *result; |
| | 17571 | if (ptr_val->data.x_ptr.mut == ConstPtrMutInfer) { |
| | 17572 | result = ir_build_struct_field_ptr(&ira->new_irb, source_instr->scope, |
| | 17573 | source_instr->source_node, struct_ptr, field); |
| | 17574 | result->value.type = ptr_type; |
| | 17575 | result->value.special = ConstValSpecialStatic; |
| | 17576 | } else { |
| | 17577 | result = ir_const(ira, source_instr, ptr_type); |
| | 17578 | } |
| | 17579 | ConstExprValue *const_val = &result->value; |
| | 17580 | const_val->data.x_ptr.special = ConstPtrSpecialBaseStruct; |
| | 17581 | const_val->data.x_ptr.mut = ptr_val->data.x_ptr.mut; |
| | 17582 | const_val->data.x_ptr.data.base_struct.struct_val = struct_val; |
| | 17583 | const_val->data.x_ptr.data.base_struct.field_index = field->src_index; |
| | 17584 | return result; |
| | 17585 | } |
| | 17586 | } |
| | 17587 | IrInstruction *result = ir_build_struct_field_ptr(&ira->new_irb, source_instr->scope, source_instr->source_node, |
| | 17588 | struct_ptr, field); |
| | 17589 | result->value.type = ptr_type; |
| | 17590 | return result; |
| | 17591 | } |
| | 17592 | |
| 16052 | static IrInstruction *ir_analyze_container_field_ptr(IrAnalyze *ira, Buf *field_name, | 17593 | static IrInstruction *ir_analyze_container_field_ptr(IrAnalyze *ira, Buf *field_name, |
| 16053 | IrInstruction *source_instr, IrInstruction *container_ptr, ZigType *container_type) | 17594 | IrInstruction *source_instr, IrInstruction *container_ptr, ZigType *container_type, bool initializing) |
| 16054 | { | 17595 | { |
| 16055 | Error err; | 17596 | Error err; |
| 16056 | | 17597 | |
| ... | @@ -16059,81 +17600,55 @@ static IrInstruction *ir_analyze_container_field_ptr(IrAnalyze *ira, Buf *field_ | ... | @@ -16059,81 +17600,55 @@ static IrInstruction *ir_analyze_container_field_ptr(IrAnalyze *ira, Buf *field_ |
| 16059 | return ira->codegen->invalid_instruction; | 17600 | return ira->codegen->invalid_instruction; |
| 16060 | | 17601 | |
| 16061 | assert(container_ptr->value.type->id == ZigTypeIdPointer); | 17602 | assert(container_ptr->value.type->id == ZigTypeIdPointer); |
| 16062 | bool is_const = container_ptr->value.type->data.pointer.is_const; | | |
| 16063 | bool is_volatile = container_ptr->value.type->data.pointer.is_volatile; | | |
| 16064 | if (bare_type->id == ZigTypeIdStruct) { | 17603 | if (bare_type->id == ZigTypeIdStruct) { |
| 16065 | TypeStructField *field = find_struct_type_field(bare_type, field_name); | 17604 | TypeStructField *field = find_struct_type_field(bare_type, field_name); |
| 16066 | if (field) { | 17605 | if (field != nullptr) { |
| 16067 | switch (type_has_one_possible_value(ira->codegen, field->type_entry)) { | 17606 | return ir_analyze_struct_field_ptr(ira, source_instr, field, container_ptr, bare_type, initializing); |
| 16068 | case OnePossibleValueInvalid: | | |
| 16069 | return ira->codegen->invalid_instruction; | | |
| 16070 | case OnePossibleValueYes: { | | |
| 16071 | IrInstruction *elem = ir_const(ira, source_instr, field->type_entry); | | |
| 16072 | return ir_get_ref(ira, source_instr, elem, false, false); | | |
| 16073 | } | | |
| 16074 | case OnePossibleValueNo: | | |
| 16075 | break; | | |
| 16076 | } | | |
| 16077 | bool is_packed = (bare_type->data.structure.layout == ContainerLayoutPacked); | | |
| 16078 | uint32_t align_bytes = is_packed ? 1 : get_abi_alignment(ira->codegen, field->type_entry); | | |
| 16079 | uint32_t ptr_bit_offset = container_ptr->value.type->data.pointer.bit_offset_in_host; | | |
| 16080 | uint32_t ptr_host_int_bytes = container_ptr->value.type->data.pointer.host_int_bytes; | | |
| 16081 | uint32_t host_int_bytes_for_result_type = (ptr_host_int_bytes == 0) ? | | |
| 16082 | get_host_int_bytes(ira->codegen, bare_type, field) : ptr_host_int_bytes; | | |
| 16083 | if (instr_is_comptime(container_ptr)) { | | |
| 16084 | ConstExprValue *ptr_val = ir_resolve_const(ira, container_ptr, UndefBad); | | |
| 16085 | if (!ptr_val) | | |
| 16086 | return ira->codegen->invalid_instruction; | | |
| 16087 | | | |
| 16088 | if (ptr_val->data.x_ptr.special != ConstPtrSpecialHardCodedAddr) { | | |
| 16089 | ConstExprValue *struct_val = const_ptr_pointee(ira, ira->codegen, ptr_val, source_instr->source_node); | | |
| 16090 | if (struct_val == nullptr) | | |
| 16091 | return ira->codegen->invalid_instruction; | | |
| 16092 | if (type_is_invalid(struct_val->type)) | | |
| 16093 | return ira->codegen->invalid_instruction; | | |
| 16094 | ZigType *ptr_type = get_pointer_to_type_extra(ira->codegen, field->type_entry, | | |
| 16095 | is_const, is_volatile, PtrLenSingle, align_bytes, | | |
| 16096 | (uint32_t)(ptr_bit_offset + field->bit_offset_in_host), | | |
| 16097 | (uint32_t)host_int_bytes_for_result_type, false); | | |
| 16098 | IrInstruction *result = ir_const(ira, source_instr, ptr_type); | | |
| 16099 | ConstExprValue *const_val = &result->value; | | |
| 16100 | const_val->data.x_ptr.special = ConstPtrSpecialBaseStruct; | | |
| 16101 | const_val->data.x_ptr.mut = container_ptr->value.data.x_ptr.mut; | | |
| 16102 | const_val->data.x_ptr.data.base_struct.struct_val = struct_val; | | |
| 16103 | const_val->data.x_ptr.data.base_struct.field_index = field->src_index; | | |
| 16104 | return result; | | |
| 16105 | } | | |
| 16106 | } | | |
| 16107 | IrInstruction *result = ir_build_struct_field_ptr(&ira->new_irb, source_instr->scope, source_instr->source_node, | | |
| 16108 | container_ptr, field); | | |
| 16109 | result->value.type = get_pointer_to_type_extra(ira->codegen, field->type_entry, is_const, is_volatile, | | |
| 16110 | PtrLenSingle, | | |
| 16111 | align_bytes, | | |
| 16112 | (uint32_t)(ptr_bit_offset + field->bit_offset_in_host), | | |
| 16113 | host_int_bytes_for_result_type, false); | | |
| 16114 | return result; | | |
| 16115 | } else { | 17607 | } else { |
| 16116 | return ir_analyze_container_member_access_inner(ira, bare_type, field_name, | 17608 | return ir_analyze_container_member_access_inner(ira, bare_type, field_name, |
| 16117 | source_instr, container_ptr, container_type); | 17609 | source_instr, container_ptr, container_type); |
| 16118 | } | 17610 | } |
| 16119 | } else if (bare_type->id == ZigTypeIdEnum) { | 17611 | } |
| | 17612 | |
| | 17613 | if (bare_type->id == ZigTypeIdEnum) { |
| 16120 | return ir_analyze_container_member_access_inner(ira, bare_type, field_name, | 17614 | return ir_analyze_container_member_access_inner(ira, bare_type, field_name, |
| 16121 | source_instr, container_ptr, container_type); | 17615 | source_instr, container_ptr, container_type); |
| 16122 | } else if (bare_type->id == ZigTypeIdUnion) { | 17616 | } |
| | 17617 | |
| | 17618 | if (bare_type->id == ZigTypeIdUnion) { |
| | 17619 | bool is_const = container_ptr->value.type->data.pointer.is_const; |
| | 17620 | bool is_volatile = container_ptr->value.type->data.pointer.is_volatile; |
| | 17621 | |
| 16123 | TypeUnionField *field = find_union_type_field(bare_type, field_name); | 17622 | TypeUnionField *field = find_union_type_field(bare_type, field_name); |
| 16124 | if (field) { | 17623 | if (field == nullptr) { |
| 16125 | if (instr_is_comptime(container_ptr)) { | 17624 | return ir_analyze_container_member_access_inner(ira, bare_type, field_name, |
| 16126 | ConstExprValue *ptr_val = ir_resolve_const(ira, container_ptr, UndefBad); | 17625 | source_instr, container_ptr, container_type); |
| 16127 | if (!ptr_val) | 17626 | } |
| | 17627 | ZigType *ptr_type = get_pointer_to_type_extra(ira->codegen, field->type_entry, |
| | 17628 | is_const, is_volatile, PtrLenSingle, 0, 0, 0, false); |
| | 17629 | if (instr_is_comptime(container_ptr)) { |
| | 17630 | ConstExprValue *ptr_val = ir_resolve_const(ira, container_ptr, UndefBad); |
| | 17631 | if (!ptr_val) |
| | 17632 | return ira->codegen->invalid_instruction; |
| | 17633 | |
| | 17634 | if (ptr_val->data.x_ptr.special != ConstPtrSpecialHardCodedAddr) { |
| | 17635 | ConstExprValue *union_val = const_ptr_pointee(ira, ira->codegen, ptr_val, source_instr->source_node); |
| | 17636 | if (union_val == nullptr) |
| | 17637 | return ira->codegen->invalid_instruction; |
| | 17638 | if (type_is_invalid(union_val->type)) |
| 16128 | return ira->codegen->invalid_instruction; | 17639 | return ira->codegen->invalid_instruction; |
| 16129 | | 17640 | |
| 16130 | if (ptr_val->data.x_ptr.special != ConstPtrSpecialHardCodedAddr) { | 17641 | if (initializing) { |
| 16131 | ConstExprValue *union_val = const_ptr_pointee(ira, ira->codegen, ptr_val, source_instr->source_node); | 17642 | ConstExprValue *payload_val = create_const_vals(1); |
| 16132 | if (union_val == nullptr) | 17643 | payload_val->special = ConstValSpecialUndef; |
| 16133 | return ira->codegen->invalid_instruction; | 17644 | payload_val->type = field->type_entry; |
| 16134 | if (type_is_invalid(union_val->type)) | 17645 | payload_val->parent.id = ConstParentIdUnion; |
| 16135 | return ira->codegen->invalid_instruction; | 17646 | payload_val->parent.data.p_union.union_val = union_val; |
| 16136 | | 17647 | |
| | 17648 | union_val->special = ConstValSpecialStatic; |
| | 17649 | bigint_init_bigint(&union_val->data.x_union.tag, &field->enum_field->value); |
| | 17650 | union_val->data.x_union.payload = payload_val; |
| | 17651 | } else { |
| 16137 | TypeUnionField *actual_field = find_union_field_by_tag(bare_type, &union_val->data.x_union.tag); | 17652 | TypeUnionField *actual_field = find_union_field_by_tag(bare_type, &union_val->data.x_union.tag); |
| 16138 | if (actual_field == nullptr) | 17653 | if (actual_field == nullptr) |
| 16139 | zig_unreachable(); | 17654 | zig_unreachable(); |
| ... | @@ -16144,33 +17659,35 @@ static IrInstruction *ir_analyze_container_field_ptr(IrAnalyze *ira, Buf *field_ | ... | @@ -16144,33 +17659,35 @@ static IrInstruction *ir_analyze_container_field_ptr(IrAnalyze *ira, Buf *field_ |
| 16144 | buf_ptr(actual_field->name))); | 17659 | buf_ptr(actual_field->name))); |
| 16145 | return ira->codegen->invalid_instruction; | 17660 | return ira->codegen->invalid_instruction; |
| 16146 | } | 17661 | } |
| | 17662 | } |
| 16147 | | 17663 | |
| 16148 | ConstExprValue *payload_val = union_val->data.x_union.payload; | 17664 | ConstExprValue *payload_val = union_val->data.x_union.payload; |
| 16149 | | 17665 | |
| 16150 | ZigType *field_type = field->type_entry; | | |
| 16151 | ZigType *ptr_type = get_pointer_to_type_extra(ira->codegen, field_type, | | |
| 16152 | is_const, is_volatile, PtrLenSingle, 0, 0, 0, false); | | |
| 16153 | | 17666 | |
| 16154 | IrInstruction *result = ir_const(ira, source_instr, ptr_type); | 17667 | IrInstruction *result; |
| 16155 | ConstExprValue *const_val = &result->value; | 17668 | if (ptr_val->data.x_ptr.mut == ConstPtrMutInfer) { |
| 16156 | const_val->data.x_ptr.special = ConstPtrSpecialRef; | 17669 | result = ir_build_union_field_ptr(&ira->new_irb, source_instr->scope, |
| 16157 | const_val->data.x_ptr.mut = container_ptr->value.data.x_ptr.mut; | 17670 | source_instr->source_node, container_ptr, field, true, initializing); |
| 16158 | const_val->data.x_ptr.data.ref.pointee = payload_val; | 17671 | result->value.type = ptr_type; |
| 16159 | return result; | 17672 | result->value.special = ConstValSpecialStatic; |
| | 17673 | } else { |
| | 17674 | result = ir_const(ira, source_instr, ptr_type); |
| 16160 | } | 17675 | } |
| | 17676 | ConstExprValue *const_val = &result->value; |
| | 17677 | const_val->data.x_ptr.special = ConstPtrSpecialRef; |
| | 17678 | const_val->data.x_ptr.mut = container_ptr->value.data.x_ptr.mut; |
| | 17679 | const_val->data.x_ptr.data.ref.pointee = payload_val; |
| | 17680 | return result; |
| 16161 | } | 17681 | } |
| 16162 | | | |
| 16163 | IrInstruction *result = ir_build_union_field_ptr(&ira->new_irb, source_instr->scope, source_instr->source_node, container_ptr, field); | | |
| 16164 | result->value.type = get_pointer_to_type_extra(ira->codegen, field->type_entry, is_const, is_volatile, | | |
| 16165 | PtrLenSingle, 0, 0, 0, false); | | |
| 16166 | return result; | | |
| 16167 | } else { | | |
| 16168 | return ir_analyze_container_member_access_inner(ira, bare_type, field_name, | | |
| 16169 | source_instr, container_ptr, container_type); | | |
| 16170 | } | 17682 | } |
| 16171 | } else { | 17683 | |
| 16172 | zig_unreachable(); | 17684 | IrInstruction *result = ir_build_union_field_ptr(&ira->new_irb, source_instr->scope, |
| | 17685 | source_instr->source_node, container_ptr, field, true, initializing); |
| | 17686 | result->value.type = ptr_type; |
| | 17687 | return result; |
| 16173 | } | 17688 | } |
| | 17689 | |
| | 17690 | zig_unreachable(); |
| 16174 | } | 17691 | } |
| 16175 | | 17692 | |
| 16176 | static void add_link_lib_symbol(IrAnalyze *ira, Buf *lib_name, Buf *symbol_name, AstNode *source_node) { | 17693 | static void add_link_lib_symbol(IrAnalyze *ira, Buf *lib_name, Buf *symbol_name, AstNode *source_node) { |
| ... | @@ -16208,6 +17725,11 @@ static void add_link_lib_symbol(IrAnalyze *ira, Buf *lib_name, Buf *symbol_name, | ... | @@ -16208,6 +17725,11 @@ static void add_link_lib_symbol(IrAnalyze *ira, Buf *lib_name, Buf *symbol_name, |
| 16208 | link_lib->symbols.append(symbol_name); | 17725 | link_lib->symbols.append(symbol_name); |
| 16209 | } | 17726 | } |
| 16210 | | 17727 | |
| | 17728 | static IrInstruction *ir_error_dependency_loop(IrAnalyze *ira, IrInstruction *source_instr) { |
| | 17729 | ErrorMsg *msg = ir_add_error(ira, source_instr, buf_sprintf("dependency loop detected")); |
| | 17730 | emit_error_notes_for_ref_stack(ira->codegen, msg); |
| | 17731 | return ira->codegen->invalid_instruction; |
| | 17732 | } |
| 16211 | | 17733 | |
| 16212 | static IrInstruction *ir_analyze_decl_ref(IrAnalyze *ira, IrInstruction *source_instruction, Tld *tld) { | 17734 | static IrInstruction *ir_analyze_decl_ref(IrAnalyze *ira, IrInstruction *source_instruction, Tld *tld) { |
| 16213 | resolve_top_level_decl(ira->codegen, tld, source_instruction->source_node); | 17735 | resolve_top_level_decl(ira->codegen, tld, source_instruction->source_node); |
| ... | @@ -16222,6 +17744,9 @@ static IrInstruction *ir_analyze_decl_ref(IrAnalyze *ira, IrInstruction *source_ | ... | @@ -16222,6 +17744,9 @@ static IrInstruction *ir_analyze_decl_ref(IrAnalyze *ira, IrInstruction *source_ |
| 16222 | { | 17744 | { |
| 16223 | TldVar *tld_var = (TldVar *)tld; | 17745 | TldVar *tld_var = (TldVar *)tld; |
| 16224 | ZigVar *var = tld_var->var; | 17746 | ZigVar *var = tld_var->var; |
| | 17747 | if (var == nullptr) { |
| | 17748 | return ir_error_dependency_loop(ira, source_instruction); |
| | 17749 | } |
| 16225 | if (tld_var->extern_lib_name != nullptr) { | 17750 | if (tld_var->extern_lib_name != nullptr) { |
| 16226 | add_link_lib_symbol(ira, tld_var->extern_lib_name, &var->name, source_instruction->source_node); | 17751 | add_link_lib_symbol(ira, tld_var->extern_lib_name, &var->name, source_instruction->source_node); |
| 16227 | } | 17752 | } |
| ... | @@ -16237,23 +17762,13 @@ static IrInstruction *ir_analyze_decl_ref(IrAnalyze *ira, IrInstruction *source_ | ... | @@ -16237,23 +17762,13 @@ static IrInstruction *ir_analyze_decl_ref(IrAnalyze *ira, IrInstruction *source_ |
| 16237 | if (type_is_invalid(fn_entry->type_entry)) | 17762 | if (type_is_invalid(fn_entry->type_entry)) |
| 16238 | return ira->codegen->invalid_instruction; | 17763 | return ira->codegen->invalid_instruction; |
| 16239 | | 17764 | |
| 16240 | // TODO instead of allocating this every time, put it in the tld value and we can reference | | |
| 16241 | // the same one every time | | |
| 16242 | ConstExprValue *const_val = create_const_vals(1); | | |
| 16243 | const_val->special = ConstValSpecialStatic; | | |
| 16244 | const_val->type = fn_entry->type_entry; | | |
| 16245 | const_val->data.x_ptr.data.fn.fn_entry = fn_entry; | | |
| 16246 | const_val->data.x_ptr.special = ConstPtrSpecialFunction; | | |
| 16247 | const_val->data.x_ptr.mut = ConstPtrMutComptimeConst; | | |
| 16248 | | | |
| 16249 | if (tld_fn->extern_lib_name != nullptr) { | 17765 | if (tld_fn->extern_lib_name != nullptr) { |
| 16250 | add_link_lib_symbol(ira, tld_fn->extern_lib_name, &fn_entry->symbol_name, source_instruction->source_node); | 17766 | add_link_lib_symbol(ira, tld_fn->extern_lib_name, &fn_entry->symbol_name, source_instruction->source_node); |
| 16251 | } | 17767 | } |
| 16252 | | 17768 | |
| 16253 | bool ptr_is_const = true; | 17769 | IrInstruction *fn_inst = ir_create_const_fn(&ira->new_irb, source_instruction->scope, |
| 16254 | bool ptr_is_volatile = false; | 17770 | source_instruction->source_node, fn_entry); |
| 16255 | return ir_get_const_ptr(ira, source_instruction, const_val, fn_entry->type_entry, | 17771 | return ir_get_ref(ira, source_instruction, fn_inst, true, false); |
| 16256 | ConstPtrMutComptimeConst, ptr_is_const, ptr_is_volatile, 0); | | |
| 16257 | } | 17772 | } |
| 16258 | } | 17773 | } |
| 16259 | zig_unreachable(); | 17774 | zig_unreachable(); |
| ... | @@ -16295,14 +17810,14 @@ static IrInstruction *ir_analyze_instruction_field_ptr(IrAnalyze *ira, IrInstruc | ... | @@ -16295,14 +17810,14 @@ static IrInstruction *ir_analyze_instruction_field_ptr(IrAnalyze *ira, IrInstruc |
| 16295 | assert(container_ptr->value.type->id == ZigTypeIdPointer); | 17810 | assert(container_ptr->value.type->id == ZigTypeIdPointer); |
| 16296 | if (container_type->id == ZigTypeIdPointer) { | 17811 | if (container_type->id == ZigTypeIdPointer) { |
| 16297 | ZigType *bare_type = container_ref_type(container_type); | 17812 | ZigType *bare_type = container_ref_type(container_type); |
| 16298 | IrInstruction *container_child = ir_get_deref(ira, &field_ptr_instruction->base, container_ptr); | 17813 | IrInstruction *container_child = ir_get_deref(ira, &field_ptr_instruction->base, container_ptr, nullptr); |
| 16299 | IrInstruction *result = ir_analyze_container_field_ptr(ira, field_name, &field_ptr_instruction->base, container_child, bare_type); | 17814 | IrInstruction *result = ir_analyze_container_field_ptr(ira, field_name, &field_ptr_instruction->base, container_child, bare_type, field_ptr_instruction->initializing); |
| 16300 | return result; | 17815 | return result; |
| 16301 | } else { | 17816 | } else { |
| 16302 | IrInstruction *result = ir_analyze_container_field_ptr(ira, field_name, &field_ptr_instruction->base, container_ptr, container_type); | 17817 | IrInstruction *result = ir_analyze_container_field_ptr(ira, field_name, &field_ptr_instruction->base, container_ptr, container_type, field_ptr_instruction->initializing); |
| 16303 | return result; | 17818 | return result; |
| 16304 | } | 17819 | } |
| 16305 | } else if (is_array_ref(container_type)) { | 17820 | } else if (is_array_ref(container_type) && !field_ptr_instruction->initializing) { |
| 16306 | if (buf_eql_str(field_name, "len")) { | 17821 | if (buf_eql_str(field_name, "len")) { |
| 16307 | ConstExprValue *len_val = create_const_vals(1); | 17822 | ConstExprValue *len_val = create_const_vals(1); |
| 16308 | if (container_type->id == ZigTypeIdPointer) { | 17823 | if (container_type->id == ZigTypeIdPointer) { |
| ... | @@ -16617,6 +18132,10 @@ static IrInstruction *ir_analyze_instruction_field_ptr(IrAnalyze *ira, IrInstruc | ... | @@ -16617,6 +18132,10 @@ static IrInstruction *ir_analyze_instruction_field_ptr(IrAnalyze *ira, IrInstruc |
| 16617 | buf_sprintf("type '%s' does not support field access", buf_ptr(&child_type->name))); | 18132 | buf_sprintf("type '%s' does not support field access", buf_ptr(&child_type->name))); |
| 16618 | return ira->codegen->invalid_instruction; | 18133 | return ira->codegen->invalid_instruction; |
| 16619 | } | 18134 | } |
| | 18135 | } else if (field_ptr_instruction->initializing) { |
| | 18136 | ir_add_error(ira, &field_ptr_instruction->base, |
| | 18137 | buf_sprintf("type '%s' does not support struct initialization syntax", buf_ptr(&container_type->name))); |
| | 18138 | return ira->codegen->invalid_instruction; |
| 16620 | } else { | 18139 | } else { |
| 16621 | ir_add_error_node(ira, field_ptr_instruction->base.source_node, | 18140 | ir_add_error_node(ira, field_ptr_instruction->base.source_node, |
| 16622 | buf_sprintf("type '%s' does not support field access", buf_ptr(&container_type->name))); | 18141 | buf_sprintf("type '%s' does not support field access", buf_ptr(&container_type->name))); |
| ... | @@ -16640,7 +18159,7 @@ static IrInstruction *ir_analyze_instruction_load_ptr(IrAnalyze *ira, IrInstruct | ... | @@ -16640,7 +18159,7 @@ static IrInstruction *ir_analyze_instruction_load_ptr(IrAnalyze *ira, IrInstruct |
| 16640 | IrInstruction *ptr = instruction->ptr->child; | 18159 | IrInstruction *ptr = instruction->ptr->child; |
| 16641 | if (type_is_invalid(ptr->value.type)) | 18160 | if (type_is_invalid(ptr->value.type)) |
| 16642 | return ira->codegen->invalid_instruction; | 18161 | return ira->codegen->invalid_instruction; |
| 16643 | return ir_get_deref(ira, &instruction->base, ptr); | 18162 | return ir_get_deref(ira, &instruction->base, ptr, nullptr); |
| 16644 | } | 18163 | } |
| 16645 | | 18164 | |
| 16646 | static IrInstruction *ir_analyze_instruction_typeof(IrAnalyze *ira, IrInstructionTypeOf *typeof_instruction) { | 18165 | static IrInstruction *ir_analyze_instruction_typeof(IrAnalyze *ira, IrInstructionTypeOf *typeof_instruction) { |
| ... | @@ -16651,64 +18170,6 @@ static IrInstruction *ir_analyze_instruction_typeof(IrAnalyze *ira, IrInstructio | ... | @@ -16651,64 +18170,6 @@ static IrInstruction *ir_analyze_instruction_typeof(IrAnalyze *ira, IrInstructio |
| 16651 | return ir_const_type(ira, &typeof_instruction->base, type_entry); | 18170 | return ir_const_type(ira, &typeof_instruction->base, type_entry); |
| 16652 | } | 18171 | } |
| 16653 | | 18172 | |
| 16654 | static IrInstruction *ir_analyze_instruction_to_ptr_type(IrAnalyze *ira, | | |
| 16655 | IrInstructionToPtrType *to_ptr_type_instruction) | | |
| 16656 | { | | |
| 16657 | Error err; | | |
| 16658 | IrInstruction *ptr_ptr = to_ptr_type_instruction->ptr->child; | | |
| 16659 | if (type_is_invalid(ptr_ptr->value.type)) | | |
| 16660 | return ira->codegen->invalid_instruction; | | |
| 16661 | | | |
| 16662 | ZigType *ptr_ptr_type = ptr_ptr->value.type; | | |
| 16663 | assert(ptr_ptr_type->id == ZigTypeIdPointer); | | |
| 16664 | ZigType *type_entry = ptr_ptr_type->data.pointer.child_type; | | |
| 16665 | | | |
| 16666 | ZigType *ptr_type; | | |
| 16667 | if (type_entry->id == ZigTypeIdArray) { | | |
| 16668 | ptr_type = get_pointer_to_type(ira->codegen, type_entry->data.array.child_type, ptr_ptr_type->data.pointer.is_const); | | |
| 16669 | } else if (is_array_ref(type_entry)) { | | |
| 16670 | ptr_type = get_pointer_to_type(ira->codegen, | | |
| 16671 | type_entry->data.pointer.child_type->data.array.child_type, type_entry->data.pointer.is_const); | | |
| 16672 | } else if (is_slice(type_entry)) { | | |
| 16673 | ZigType *slice_ptr_type = type_entry->data.structure.fields[0].type_entry; | | |
| 16674 | ptr_type = adjust_ptr_len(ira->codegen, slice_ptr_type, PtrLenSingle); | | |
| 16675 | // If the pointer is over-aligned, we may have to reduce it based on the alignment of the element type. | | |
| 16676 | if (slice_ptr_type->data.pointer.explicit_alignment != 0) { | | |
| 16677 | ZigType *elem_type = slice_ptr_type->data.pointer.child_type; | | |
| 16678 | if ((err = type_resolve(ira->codegen, elem_type, ResolveStatusAlignmentKnown))) | | |
| 16679 | return ira->codegen->invalid_instruction; | | |
| 16680 | uint32_t elem_align = get_abi_alignment(ira->codegen, elem_type); | | |
| 16681 | uint32_t reduced_align = min(elem_align, slice_ptr_type->data.pointer.explicit_alignment); | | |
| 16682 | ptr_type = adjust_ptr_align(ira->codegen, ptr_type, reduced_align); | | |
| 16683 | } | | |
| 16684 | } else if (type_entry->id == ZigTypeIdArgTuple) { | | |
| 16685 | zig_panic("TODO for loop on var args"); | | |
| 16686 | } else { | | |
| 16687 | ir_add_error_node(ira, to_ptr_type_instruction->base.source_node, | | |
| 16688 | buf_sprintf("expected array type, found '%s'", buf_ptr(&type_entry->name))); | | |
| 16689 | return ira->codegen->invalid_instruction; | | |
| 16690 | } | | |
| 16691 | | | |
| 16692 | return ir_const_type(ira, &to_ptr_type_instruction->base, ptr_type); | | |
| 16693 | } | | |
| 16694 | | | |
| 16695 | static IrInstruction *ir_analyze_instruction_ptr_type_child(IrAnalyze *ira, | | |
| 16696 | IrInstructionPtrTypeChild *ptr_type_child_instruction) | | |
| 16697 | { | | |
| 16698 | IrInstruction *type_value = ptr_type_child_instruction->value->child; | | |
| 16699 | ZigType *type_entry = ir_resolve_type(ira, type_value); | | |
| 16700 | if (type_is_invalid(type_entry)) | | |
| 16701 | return ira->codegen->invalid_instruction; | | |
| 16702 | | | |
| 16703 | if (type_entry->id != ZigTypeIdPointer) { | | |
| 16704 | ir_add_error_node(ira, ptr_type_child_instruction->base.source_node, | | |
| 16705 | buf_sprintf("expected pointer type, found '%s'", buf_ptr(&type_entry->name))); | | |
| 16706 | return ira->codegen->invalid_instruction; | | |
| 16707 | } | | |
| 16708 | | | |
| 16709 | return ir_const_type(ira, &ptr_type_child_instruction->base, type_entry->data.pointer.child_type); | | |
| 16710 | } | | |
| 16711 | | | |
| 16712 | static IrInstruction *ir_analyze_instruction_set_cold(IrAnalyze *ira, IrInstructionSetCold *instruction) { | 18173 | static IrInstruction *ir_analyze_instruction_set_cold(IrAnalyze *ira, IrInstructionSetCold *instruction) { |
| 16713 | if (ira->new_irb.exec->is_inline) { | 18174 | if (ira->new_irb.exec->is_inline) { |
| 16714 | // ignore setCold when running functions at compile time | 18175 | // ignore setCold when running functions at compile time |
| ... | @@ -17138,7 +18599,7 @@ static IrInstruction *ir_analyze_instruction_test_non_null(IrAnalyze *ira, IrIns | ... | @@ -17138,7 +18599,7 @@ static IrInstruction *ir_analyze_instruction_test_non_null(IrAnalyze *ira, IrIns |
| 17138 | } | 18599 | } |
| 17139 | | 18600 | |
| 17140 | static IrInstruction *ir_analyze_unwrap_optional_payload(IrAnalyze *ira, IrInstruction *source_instr, | 18601 | static IrInstruction *ir_analyze_unwrap_optional_payload(IrAnalyze *ira, IrInstruction *source_instr, |
| 17141 | IrInstruction *base_ptr, bool safety_check_on) | 18602 | IrInstruction *base_ptr, bool safety_check_on, bool initializing) |
| 17142 | { | 18603 | { |
| 17143 | ZigType *ptr_type = base_ptr->value.type; | 18604 | ZigType *ptr_type = base_ptr->value.type; |
| 17144 | assert(ptr_type->id == ZigTypeIdPointer); | 18605 | assert(ptr_type->id == ZigTypeIdPointer); |
| ... | @@ -17168,7 +18629,7 @@ static IrInstruction *ir_analyze_unwrap_optional_payload(IrAnalyze *ira, IrInstr | ... | @@ -17168,7 +18629,7 @@ static IrInstruction *ir_analyze_unwrap_optional_payload(IrAnalyze *ira, IrInstr |
| 17168 | } | 18629 | } |
| 17169 | if (!safety_check_on) | 18630 | if (!safety_check_on) |
| 17170 | return base_ptr; | 18631 | return base_ptr; |
| 17171 | IrInstruction *c_ptr_val = ir_get_deref(ira, source_instr, base_ptr); | 18632 | IrInstruction *c_ptr_val = ir_get_deref(ira, source_instr, base_ptr, nullptr); |
| 17172 | ir_build_assert_non_null(ira, source_instr, c_ptr_val); | 18633 | ir_build_assert_non_null(ira, source_instr, c_ptr_val); |
| 17173 | return base_ptr; | 18634 | return base_ptr; |
| 17174 | } | 18635 | } |
| ... | @@ -17183,34 +18644,84 @@ static IrInstruction *ir_analyze_unwrap_optional_payload(IrAnalyze *ira, IrInstr | ... | @@ -17183,34 +18644,84 @@ static IrInstruction *ir_analyze_unwrap_optional_payload(IrAnalyze *ira, IrInstr |
| 17183 | ZigType *result_type = get_pointer_to_type_extra(ira->codegen, child_type, | 18644 | ZigType *result_type = get_pointer_to_type_extra(ira->codegen, child_type, |
| 17184 | ptr_type->data.pointer.is_const, ptr_type->data.pointer.is_volatile, PtrLenSingle, 0, 0, 0, false); | 18645 | ptr_type->data.pointer.is_const, ptr_type->data.pointer.is_volatile, PtrLenSingle, 0, 0, 0, false); |
| 17185 | | 18646 | |
| | 18647 | bool same_comptime_repr = types_have_same_zig_comptime_repr(type_entry, child_type); |
| | 18648 | |
| 17186 | if (instr_is_comptime(base_ptr)) { | 18649 | if (instr_is_comptime(base_ptr)) { |
| 17187 | ConstExprValue *val = ir_resolve_const(ira, base_ptr, UndefBad); | 18650 | ConstExprValue *ptr_val = ir_resolve_const(ira, base_ptr, UndefBad); |
| 17188 | if (!val) | 18651 | if (!ptr_val) |
| 17189 | return ira->codegen->invalid_instruction; | 18652 | return ira->codegen->invalid_instruction; |
| 17190 | if (val->data.x_ptr.mut != ConstPtrMutRuntimeVar) { | 18653 | if (ptr_val->data.x_ptr.mut != ConstPtrMutRuntimeVar) { |
| 17191 | ConstExprValue *maybe_val = const_ptr_pointee(ira, ira->codegen, val, source_instr->source_node); | 18654 | ConstExprValue *optional_val = const_ptr_pointee(ira, ira->codegen, ptr_val, source_instr->source_node); |
| 17192 | if (maybe_val == nullptr) | 18655 | if (optional_val == nullptr) |
| 17193 | return ira->codegen->invalid_instruction; | 18656 | return ira->codegen->invalid_instruction; |
| 17194 | | 18657 | |
| 17195 | if (optional_value_is_null(maybe_val)) { | 18658 | if (initializing && optional_val->special == ConstValSpecialUndef) { |
| | 18659 | switch (type_has_one_possible_value(ira->codegen, child_type)) { |
| | 18660 | case OnePossibleValueInvalid: |
| | 18661 | return ira->codegen->invalid_instruction; |
| | 18662 | case OnePossibleValueNo: |
| | 18663 | if (!same_comptime_repr) { |
| | 18664 | ConstExprValue *payload_val = create_const_vals(1); |
| | 18665 | payload_val->type = child_type; |
| | 18666 | payload_val->special = ConstValSpecialUndef; |
| | 18667 | payload_val->parent.id = ConstParentIdOptionalPayload; |
| | 18668 | payload_val->parent.data.p_optional_payload.optional_val = optional_val; |
| | 18669 | |
| | 18670 | optional_val->data.x_optional = payload_val; |
| | 18671 | optional_val->special = ConstValSpecialStatic; |
| | 18672 | } |
| | 18673 | break; |
| | 18674 | case OnePossibleValueYes: { |
| | 18675 | ConstExprValue *pointee = create_const_vals(1); |
| | 18676 | pointee->special = ConstValSpecialStatic; |
| | 18677 | pointee->type = child_type; |
| | 18678 | pointee->parent.id = ConstParentIdOptionalPayload; |
| | 18679 | pointee->parent.data.p_optional_payload.optional_val = optional_val; |
| | 18680 | |
| | 18681 | optional_val->special = ConstValSpecialStatic; |
| | 18682 | optional_val->data.x_optional = pointee; |
| | 18683 | break; |
| | 18684 | } |
| | 18685 | } |
| | 18686 | } else if (optional_value_is_null(optional_val)) { |
| 17196 | ir_add_error(ira, source_instr, buf_sprintf("unable to unwrap null")); | 18687 | ir_add_error(ira, source_instr, buf_sprintf("unable to unwrap null")); |
| 17197 | return ira->codegen->invalid_instruction; | 18688 | return ira->codegen->invalid_instruction; |
| 17198 | } | 18689 | } |
| 17199 | IrInstruction *result = ir_const(ira, source_instr, result_type); | 18690 | |
| 17200 | ConstExprValue *out_val = &result->value; | 18691 | IrInstruction *result; |
| 17201 | out_val->data.x_ptr.special = ConstPtrSpecialRef; | 18692 | if (ptr_val->data.x_ptr.mut == ConstPtrMutInfer) { |
| 17202 | out_val->data.x_ptr.mut = val->data.x_ptr.mut; | 18693 | result = ir_build_optional_unwrap_ptr(&ira->new_irb, source_instr->scope, |
| 17203 | if (types_have_same_zig_comptime_repr(type_entry, child_type)) { | 18694 | source_instr->source_node, base_ptr, false, initializing); |
| 17204 | out_val->data.x_ptr.data.ref.pointee = maybe_val; | 18695 | result->value.type = result_type; |
| | 18696 | result->value.special = ConstValSpecialStatic; |
| 17205 | } else { | 18697 | } else { |
| 17206 | out_val->data.x_ptr.data.ref.pointee = maybe_val->data.x_optional; | 18698 | result = ir_const(ira, source_instr, result_type); |
| | 18699 | } |
| | 18700 | ConstExprValue *result_val = &result->value; |
| | 18701 | result_val->data.x_ptr.special = ConstPtrSpecialRef; |
| | 18702 | result_val->data.x_ptr.mut = ptr_val->data.x_ptr.mut; |
| | 18703 | switch (type_has_one_possible_value(ira->codegen, child_type)) { |
| | 18704 | case OnePossibleValueInvalid: |
| | 18705 | return ira->codegen->invalid_instruction; |
| | 18706 | case OnePossibleValueNo: |
| | 18707 | if (same_comptime_repr) { |
| | 18708 | result_val->data.x_ptr.data.ref.pointee = optional_val; |
| | 18709 | } else { |
| | 18710 | assert(optional_val->data.x_optional != nullptr); |
| | 18711 | result_val->data.x_ptr.data.ref.pointee = optional_val->data.x_optional; |
| | 18712 | } |
| | 18713 | break; |
| | 18714 | case OnePossibleValueYes: |
| | 18715 | assert(optional_val->data.x_optional != nullptr); |
| | 18716 | result_val->data.x_ptr.data.ref.pointee = optional_val->data.x_optional; |
| | 18717 | break; |
| 17207 | } | 18718 | } |
| 17208 | return result; | 18719 | return result; |
| 17209 | } | 18720 | } |
| 17210 | } | 18721 | } |
| 17211 | | 18722 | |
| 17212 | IrInstruction *result = ir_build_optional_unwrap_ptr(&ira->new_irb, source_instr->scope, | 18723 | IrInstruction *result = ir_build_optional_unwrap_ptr(&ira->new_irb, source_instr->scope, |
| 17213 | source_instr->source_node, base_ptr, safety_check_on); | 18724 | source_instr->source_node, base_ptr, safety_check_on, initializing); |
| 17214 | result->value.type = result_type; | 18725 | result->value.type = result_type; |
| 17215 | return result; | 18726 | return result; |
| 17216 | } | 18727 | } |
| ... | @@ -17222,7 +18733,8 @@ static IrInstruction *ir_analyze_instruction_optional_unwrap_ptr(IrAnalyze *ira, | ... | @@ -17222,7 +18733,8 @@ static IrInstruction *ir_analyze_instruction_optional_unwrap_ptr(IrAnalyze *ira, |
| 17222 | if (type_is_invalid(base_ptr->value.type)) | 18733 | if (type_is_invalid(base_ptr->value.type)) |
| 17223 | return ira->codegen->invalid_instruction; | 18734 | return ira->codegen->invalid_instruction; |
| 17224 | | 18735 | |
| 17225 | return ir_analyze_unwrap_optional_payload(ira, &instruction->base, base_ptr, instruction->safety_check_on); | 18736 | return ir_analyze_unwrap_optional_payload(ira, &instruction->base, base_ptr, |
| | 18737 | instruction->safety_check_on, false); |
| 17226 | } | 18738 | } |
| 17227 | | 18739 | |
| 17228 | static IrInstruction *ir_analyze_instruction_ctz(IrAnalyze *ira, IrInstructionCtz *instruction) { | 18740 | static IrInstruction *ir_analyze_instruction_ctz(IrAnalyze *ira, IrInstructionCtz *instruction) { |
| ... | @@ -17523,7 +19035,7 @@ static IrInstruction *ir_analyze_instruction_switch_target(IrAnalyze *ira, | ... | @@ -17523,7 +19035,7 @@ static IrInstruction *ir_analyze_instruction_switch_target(IrAnalyze *ira, |
| 17523 | return result; | 19035 | return result; |
| 17524 | } | 19036 | } |
| 17525 | | 19037 | |
| 17526 | IrInstruction *result = ir_get_deref(ira, &switch_target_instruction->base, target_value_ptr); | 19038 | IrInstruction *result = ir_get_deref(ira, &switch_target_instruction->base, target_value_ptr, nullptr); |
| 17527 | result->value.type = target_type; | 19039 | result->value.type = target_type; |
| 17528 | return result; | 19040 | return result; |
| 17529 | } | 19041 | } |
| ... | @@ -17553,7 +19065,7 @@ static IrInstruction *ir_analyze_instruction_switch_target(IrAnalyze *ira, | ... | @@ -17553,7 +19065,7 @@ static IrInstruction *ir_analyze_instruction_switch_target(IrAnalyze *ira, |
| 17553 | return result; | 19065 | return result; |
| 17554 | } | 19066 | } |
| 17555 | | 19067 | |
| 17556 | IrInstruction *union_value = ir_get_deref(ira, &switch_target_instruction->base, target_value_ptr); | 19068 | IrInstruction *union_value = ir_get_deref(ira, &switch_target_instruction->base, target_value_ptr, nullptr); |
| 17557 | union_value->value.type = target_type; | 19069 | union_value->value.type = target_type; |
| 17558 | | 19070 | |
| 17559 | IrInstruction *union_tag_inst = ir_build_union_tag(&ira->new_irb, switch_target_instruction->base.scope, | 19071 | IrInstruction *union_tag_inst = ir_build_union_tag(&ira->new_irb, switch_target_instruction->base.scope, |
| ... | @@ -17577,7 +19089,7 @@ static IrInstruction *ir_analyze_instruction_switch_target(IrAnalyze *ira, | ... | @@ -17577,7 +19089,7 @@ static IrInstruction *ir_analyze_instruction_switch_target(IrAnalyze *ira, |
| 17577 | return result; | 19089 | return result; |
| 17578 | } | 19090 | } |
| 17579 | | 19091 | |
| 17580 | IrInstruction *enum_value = ir_get_deref(ira, &switch_target_instruction->base, target_value_ptr); | 19092 | IrInstruction *enum_value = ir_get_deref(ira, &switch_target_instruction->base, target_value_ptr, nullptr); |
| 17581 | enum_value->value.type = target_type; | 19093 | enum_value->value.type = target_type; |
| 17582 | return enum_value; | 19094 | return enum_value; |
| 17583 | } | 19095 | } |
| ... | @@ -17650,7 +19162,7 @@ static IrInstruction *ir_analyze_instruction_switch_var(IrAnalyze *ira, IrInstru | ... | @@ -17650,7 +19162,7 @@ static IrInstruction *ir_analyze_instruction_switch_var(IrAnalyze *ira, IrInstru |
| 17650 | } | 19162 | } |
| 17651 | | 19163 | |
| 17652 | IrInstruction *result = ir_build_union_field_ptr(&ira->new_irb, | 19164 | IrInstruction *result = ir_build_union_field_ptr(&ira->new_irb, |
| 17653 | instruction->base.scope, instruction->base.source_node, target_value_ptr, field); | 19165 | instruction->base.scope, instruction->base.source_node, target_value_ptr, field, false, false); |
| 17654 | result->value.type = get_pointer_to_type(ira->codegen, field->type_entry, | 19166 | result->value.type = get_pointer_to_type(ira->codegen, field->type_entry, |
| 17655 | target_value_ptr->value.type->data.pointer.is_const); | 19167 | target_value_ptr->value.type->data.pointer.is_const); |
| 17656 | return result; | 19168 | return result; |
| ... | @@ -17860,7 +19372,8 @@ static IrInstruction *ir_analyze_instruction_ref(IrAnalyze *ira, IrInstructionRe | ... | @@ -17860,7 +19372,8 @@ static IrInstruction *ir_analyze_instruction_ref(IrAnalyze *ira, IrInstructionRe |
| 17860 | } | 19372 | } |
| 17861 | | 19373 | |
| 17862 | static IrInstruction *ir_analyze_container_init_fields_union(IrAnalyze *ira, IrInstruction *instruction, | 19374 | static IrInstruction *ir_analyze_container_init_fields_union(IrAnalyze *ira, IrInstruction *instruction, |
| 17863 | ZigType *container_type, size_t instr_field_count, IrInstructionContainerInitFieldsField *fields) | 19375 | ZigType *container_type, size_t instr_field_count, IrInstructionContainerInitFieldsField *fields, |
| | 19376 | IrInstruction *result_loc) |
| 17864 | { | 19377 | { |
| 17865 | Error err; | 19378 | Error err; |
| 17866 | assert(container_type->id == ZigTypeIdUnion); | 19379 | assert(container_type->id == ZigTypeIdUnion); |
| ... | @@ -17875,12 +19388,12 @@ static IrInstruction *ir_analyze_container_init_fields_union(IrAnalyze *ira, IrI | ... | @@ -17875,12 +19388,12 @@ static IrInstruction *ir_analyze_container_init_fields_union(IrAnalyze *ira, IrI |
| 17875 | } | 19388 | } |
| 17876 | | 19389 | |
| 17877 | IrInstructionContainerInitFieldsField *field = &fields[0]; | 19390 | IrInstructionContainerInitFieldsField *field = &fields[0]; |
| 17878 | IrInstruction *field_value = field->value->child; | 19391 | IrInstruction *field_result_loc = field->result_loc->child; |
| 17879 | if (type_is_invalid(field_value->value.type)) | 19392 | if (type_is_invalid(field_result_loc->value.type)) |
| 17880 | return ira->codegen->invalid_instruction; | 19393 | return ira->codegen->invalid_instruction; |
| 17881 | | 19394 | |
| 17882 | TypeUnionField *type_field = find_union_type_field(container_type, field->name); | 19395 | TypeUnionField *type_field = find_union_type_field(container_type, field->name); |
| 17883 | if (!type_field) { | 19396 | if (type_field == nullptr) { |
| 17884 | ir_add_error_node(ira, field->source_node, | 19397 | ir_add_error_node(ira, field->source_node, |
| 17885 | buf_sprintf("no member named '%s' in union '%s'", | 19398 | buf_sprintf("no member named '%s' in union '%s'", |
| 17886 | buf_ptr(field->name), buf_ptr(&container_type->name))); | 19399 | buf_ptr(field->name), buf_ptr(&container_type->name))); |
| ... | @@ -17890,46 +19403,36 @@ static IrInstruction *ir_analyze_container_init_fields_union(IrAnalyze *ira, IrI | ... | @@ -17890,46 +19403,36 @@ static IrInstruction *ir_analyze_container_init_fields_union(IrAnalyze *ira, IrI |
| 17890 | if (type_is_invalid(type_field->type_entry)) | 19403 | if (type_is_invalid(type_field->type_entry)) |
| 17891 | return ira->codegen->invalid_instruction; | 19404 | return ira->codegen->invalid_instruction; |
| 17892 | | 19405 | |
| 17893 | IrInstruction *casted_field_value = ir_implicit_cast(ira, field_value, type_field->type_entry); | 19406 | if (result_loc->value.data.x_ptr.mut == ConstPtrMutInfer) { |
| 17894 | if (casted_field_value == ira->codegen->invalid_instruction) | 19407 | if (instr_is_comptime(field_result_loc) && |
| 17895 | return ira->codegen->invalid_instruction; | 19408 | field_result_loc->value.data.x_ptr.mut != ConstPtrMutRuntimeVar) |
| 17896 | | 19409 | { |
| 17897 | if ((err = type_resolve(ira->codegen, casted_field_value->value.type, ResolveStatusZeroBitsKnown))) | 19410 | // nothing |
| 17898 | return ira->codegen->invalid_instruction; | 19411 | } else { |
| | 19412 | result_loc->value.special = ConstValSpecialRuntime; |
| | 19413 | } |
| | 19414 | } |
| 17899 | | 19415 | |
| 17900 | bool is_comptime = ir_should_inline(ira->new_irb.exec, instruction->scope) | 19416 | bool is_comptime = ir_should_inline(ira->new_irb.exec, instruction->scope) |
| 17901 | || type_requires_comptime(ira->codegen, container_type) == ReqCompTimeYes; | 19417 | || type_requires_comptime(ira->codegen, container_type) == ReqCompTimeYes; |
| 17902 | if (is_comptime || casted_field_value->value.special != ConstValSpecialRuntime || | | |
| 17903 | !type_has_bits(casted_field_value->value.type)) | | |
| 17904 | { | | |
| 17905 | ConstExprValue *field_val = ir_resolve_const(ira, casted_field_value, UndefOk); | | |
| 17906 | if (!field_val) | | |
| 17907 | return ira->codegen->invalid_instruction; | | |
| 17908 | | | |
| 17909 | IrInstruction *result = ir_const(ira, instruction, container_type); | | |
| 17910 | ConstExprValue *out_val = &result->value; | | |
| 17911 | out_val->data.x_union.payload = field_val; | | |
| 17912 | out_val->data.x_union.tag = type_field->enum_field->value; | | |
| 17913 | out_val->parent.id = ConstParentIdUnion; | | |
| 17914 | out_val->parent.data.p_union.union_val = out_val; | | |
| 17915 | | 19418 | |
| 17916 | return result; | 19419 | IrInstruction *result = ir_get_deref(ira, instruction, result_loc, nullptr); |
| | 19420 | if (is_comptime && !instr_is_comptime(result)) { |
| | 19421 | ir_add_error(ira, field->result_loc, |
| | 19422 | buf_sprintf("unable to evaluate constant expression")); |
| | 19423 | return ira->codegen->invalid_instruction; |
| 17917 | } | 19424 | } |
| 17918 | | 19425 | return result; |
| 17919 | IrInstruction *new_instruction = ir_build_union_init(&ira->new_irb, | | |
| 17920 | instruction->scope, instruction->source_node, | | |
| 17921 | container_type, type_field, casted_field_value); | | |
| 17922 | new_instruction->value.type = container_type; | | |
| 17923 | ir_add_alloca(ira, new_instruction, container_type); | | |
| 17924 | return new_instruction; | | |
| 17925 | } | 19426 | } |
| 17926 | | 19427 | |
| 17927 | static IrInstruction *ir_analyze_container_init_fields(IrAnalyze *ira, IrInstruction *instruction, | 19428 | static IrInstruction *ir_analyze_container_init_fields(IrAnalyze *ira, IrInstruction *instruction, |
| 17928 | ZigType *container_type, size_t instr_field_count, IrInstructionContainerInitFieldsField *fields) | 19429 | ZigType *container_type, size_t instr_field_count, IrInstructionContainerInitFieldsField *fields, |
| | 19430 | IrInstruction *result_loc) |
| 17929 | { | 19431 | { |
| 17930 | Error err; | 19432 | Error err; |
| 17931 | if (container_type->id == ZigTypeIdUnion) { | 19433 | if (container_type->id == ZigTypeIdUnion) { |
| 17932 | return ir_analyze_container_init_fields_union(ira, instruction, container_type, instr_field_count, fields); | 19434 | return ir_analyze_container_init_fields_union(ira, instruction, container_type, instr_field_count, |
| | 19435 | fields, result_loc); |
| 17933 | } | 19436 | } |
| 17934 | if (container_type->id != ZigTypeIdStruct || is_slice(container_type)) { | 19437 | if (container_type->id != ZigTypeIdStruct || is_slice(container_type)) { |
| 17935 | ir_add_error(ira, instruction, | 19438 | ir_add_error(ira, instruction, |
| ... | @@ -17946,22 +19449,28 @@ static IrInstruction *ir_analyze_container_init_fields(IrAnalyze *ira, IrInstruc | ... | @@ -17946,22 +19449,28 @@ static IrInstruction *ir_analyze_container_init_fields(IrAnalyze *ira, IrInstruc |
| 17946 | IrInstruction *first_non_const_instruction = nullptr; | 19449 | IrInstruction *first_non_const_instruction = nullptr; |
| 17947 | | 19450 | |
| 17948 | AstNode **field_assign_nodes = allocate<AstNode *>(actual_field_count); | 19451 | AstNode **field_assign_nodes = allocate<AstNode *>(actual_field_count); |
| 17949 | | 19452 | ZigList<IrInstruction *> const_ptrs = {}; |
| 17950 | IrInstructionStructInitField *new_fields = allocate<IrInstructionStructInitField>(actual_field_count); | | |
| 17951 | | 19453 | |
| 17952 | bool is_comptime = ir_should_inline(ira->new_irb.exec, instruction->scope) | 19454 | bool is_comptime = ir_should_inline(ira->new_irb.exec, instruction->scope) |
| 17953 | || type_requires_comptime(ira->codegen, container_type) == ReqCompTimeYes; | 19455 | || type_requires_comptime(ira->codegen, container_type) == ReqCompTimeYes; |
| 17954 | | 19456 | |
| 17955 | ConstExprValue const_val = {}; | 19457 | |
| 17956 | const_val.special = ConstValSpecialStatic; | 19458 | // Here we iterate over the fields that have been initialized, and emit |
| 17957 | const_val.type = container_type; | 19459 | // compile errors for missing fields and duplicate fields. |
| 17958 | // const_val.global_refs = allocate<ConstGlobalRefs>(1); | 19460 | // It is only now that we find out whether the struct initialization can be a comptime |
| 17959 | const_val.data.x_struct.fields = create_const_vals(actual_field_count); | 19461 | // value, but we have already emitted runtime instructions for the fields that |
| | 19462 | // were initialized with runtime values, and have omitted instructions that would have |
| | 19463 | // initialized fields with comptime values. |
| | 19464 | // So now we must clean up this situation. If it turns out the struct initialization can |
| | 19465 | // be a comptime value, overwrite ConstPtrMutInfer with ConstPtrMutComptimeConst. |
| | 19466 | // Otherwise, we must emit instructions to runtime-initialize the fields that have |
| | 19467 | // comptime-known values. |
| | 19468 | |
| 17960 | for (size_t i = 0; i < instr_field_count; i += 1) { | 19469 | for (size_t i = 0; i < instr_field_count; i += 1) { |
| 17961 | IrInstructionContainerInitFieldsField *field = &fields[i]; | 19470 | IrInstructionContainerInitFieldsField *field = &fields[i]; |
| 17962 | | 19471 | |
| 17963 | IrInstruction *field_value = field->value->child; | 19472 | IrInstruction *field_result_loc = field->result_loc->child; |
| 17964 | if (type_is_invalid(field_value->value.type)) | 19473 | if (type_is_invalid(field_result_loc->value.type)) |
| 17965 | return ira->codegen->invalid_instruction; | 19474 | return ira->codegen->invalid_instruction; |
| 17966 | | 19475 | |
| 17967 | TypeStructField *type_field = find_struct_type_field(container_type, field->name); | 19476 | TypeStructField *type_field = find_struct_type_field(container_type, field->name); |
| ... | @@ -17975,10 +19484,6 @@ static IrInstruction *ir_analyze_container_init_fields(IrAnalyze *ira, IrInstruc | ... | @@ -17975,10 +19484,6 @@ static IrInstruction *ir_analyze_container_init_fields(IrAnalyze *ira, IrInstruc |
| 17975 | if (type_is_invalid(type_field->type_entry)) | 19484 | if (type_is_invalid(type_field->type_entry)) |
| 17976 | return ira->codegen->invalid_instruction; | 19485 | return ira->codegen->invalid_instruction; |
| 17977 | | 19486 | |
| 17978 | IrInstruction *casted_field_value = ir_implicit_cast(ira, field_value, type_field->type_entry); | | |
| 17979 | if (casted_field_value == ira->codegen->invalid_instruction) | | |
| 17980 | return ira->codegen->invalid_instruction; | | |
| 17981 | | | |
| 17982 | size_t field_index = type_field->src_index; | 19487 | size_t field_index = type_field->src_index; |
| 17983 | AstNode *existing_assign_node = field_assign_nodes[field_index]; | 19488 | AstNode *existing_assign_node = field_assign_nodes[field_index]; |
| 17984 | if (existing_assign_node) { | 19489 | if (existing_assign_node) { |
| ... | @@ -17988,26 +19493,18 @@ static IrInstruction *ir_analyze_container_init_fields(IrAnalyze *ira, IrInstruc | ... | @@ -17988,26 +19493,18 @@ static IrInstruction *ir_analyze_container_init_fields(IrAnalyze *ira, IrInstruc |
| 17988 | } | 19493 | } |
| 17989 | field_assign_nodes[field_index] = field->source_node; | 19494 | field_assign_nodes[field_index] = field->source_node; |
| 17990 | | 19495 | |
| 17991 | new_fields[field_index].value = casted_field_value; | 19496 | if (instr_is_comptime(field_result_loc) && |
| 17992 | new_fields[field_index].type_struct_field = type_field; | 19497 | field_result_loc->value.data.x_ptr.mut != ConstPtrMutRuntimeVar) |
| 17993 | | 19498 | { |
| 17994 | if (const_val.special == ConstValSpecialStatic) { | 19499 | const_ptrs.append(field_result_loc); |
| 17995 | if (is_comptime || casted_field_value->value.special != ConstValSpecialRuntime) { | 19500 | } else { |
| 17996 | ConstExprValue *field_val = ir_resolve_const(ira, casted_field_value, UndefOk); | 19501 | first_non_const_instruction = field_result_loc; |
| 17997 | if (!field_val) | | |
| 17998 | return ira->codegen->invalid_instruction; | | |
| 17999 | | | |
| 18000 | copy_const_val(&const_val.data.x_struct.fields[field_index], field_val, true); | | |
| 18001 | } else { | | |
| 18002 | first_non_const_instruction = casted_field_value; | | |
| 18003 | const_val.special = ConstValSpecialRuntime; | | |
| 18004 | } | | |
| 18005 | } | 19502 | } |
| 18006 | } | 19503 | } |
| 18007 | | 19504 | |
| 18008 | bool any_missing = false; | 19505 | bool any_missing = false; |
| 18009 | for (size_t i = 0; i < actual_field_count; i += 1) { | 19506 | for (size_t i = 0; i < actual_field_count; i += 1) { |
| 18010 | if (field_assign_nodes[i]) continue; | 19507 | if (field_assign_nodes[i] != nullptr) continue; |
| 18011 | | 19508 | |
| 18012 | // look for a default field value | 19509 | // look for a default field value |
| 18013 | TypeStructField *field = &container_type->data.structure.fields[i]; | 19510 | TypeStructField *field = &container_type->data.structure.fields[i]; |
| ... | @@ -18033,182 +19530,177 @@ static IrInstruction *ir_analyze_container_init_fields(IrAnalyze *ira, IrInstruc | ... | @@ -18033,182 +19530,177 @@ static IrInstruction *ir_analyze_container_init_fields(IrAnalyze *ira, IrInstruc |
| 18033 | IrInstruction *runtime_inst = ir_const(ira, instruction, field->init_val->type); | 19530 | IrInstruction *runtime_inst = ir_const(ira, instruction, field->init_val->type); |
| 18034 | copy_const_val(&runtime_inst->value, field->init_val, true); | 19531 | copy_const_val(&runtime_inst->value, field->init_val, true); |
| 18035 | | 19532 | |
| 18036 | new_fields[i].value = runtime_inst; | 19533 | IrInstruction *field_ptr = ir_analyze_struct_field_ptr(ira, instruction, field, result_loc, |
| 18037 | new_fields[i].type_struct_field = field; | 19534 | container_type, true); |
| 18038 | | 19535 | ir_analyze_store_ptr(ira, instruction, field_ptr, runtime_inst); |
| 18039 | if (const_val.special == ConstValSpecialStatic) { | 19536 | if (instr_is_comptime(field_ptr) && field_ptr->value.data.x_ptr.mut != ConstPtrMutRuntimeVar) { |
| 18040 | copy_const_val(&const_val.data.x_struct.fields[i], field->init_val, true); | 19537 | const_ptrs.append(field_ptr); |
| | 19538 | } else { |
| | 19539 | first_non_const_instruction = result_loc; |
| 18041 | } | 19540 | } |
| 18042 | } | 19541 | } |
| 18043 | if (any_missing) | 19542 | if (any_missing) |
| 18044 | return ira->codegen->invalid_instruction; | 19543 | return ira->codegen->invalid_instruction; |
| 18045 | | 19544 | |
| 18046 | if (const_val.special == ConstValSpecialStatic) { | 19545 | if (result_loc->value.data.x_ptr.mut == ConstPtrMutInfer) { |
| 18047 | IrInstruction *result = ir_const(ira, instruction, nullptr); | 19546 | if (const_ptrs.length != actual_field_count) { |
| 18048 | ConstExprValue *out_val = &result->value; | 19547 | result_loc->value.special = ConstValSpecialRuntime; |
| 18049 | copy_const_val(out_val, &const_val, false); | 19548 | for (size_t i = 0; i < const_ptrs.length; i += 1) { |
| 18050 | out_val->type = container_type; | 19549 | IrInstruction *field_result_loc = const_ptrs.at(i); |
| 18051 | | 19550 | IrInstruction *deref = ir_get_deref(ira, field_result_loc, field_result_loc, nullptr); |
| 18052 | for (size_t i = 0; i < instr_field_count; i += 1) { | 19551 | field_result_loc->value.special = ConstValSpecialRuntime; |
| 18053 | ConstExprValue *field_val = &out_val->data.x_struct.fields[i]; | 19552 | ir_analyze_store_ptr(ira, field_result_loc, field_result_loc, deref); |
| 18054 | ConstParent *parent = get_const_val_parent(ira->codegen, field_val); | | |
| 18055 | if (parent != nullptr) { | | |
| 18056 | parent->id = ConstParentIdStruct; | | |
| 18057 | parent->data.p_struct.field_index = i; | | |
| 18058 | parent->data.p_struct.struct_val = out_val; | | |
| 18059 | } | 19553 | } |
| 18060 | } | 19554 | } |
| 18061 | | | |
| 18062 | return result; | | |
| 18063 | } | 19555 | } |
| 18064 | | 19556 | |
| 18065 | if (is_comptime) { | 19557 | IrInstruction *result = ir_get_deref(ira, instruction, result_loc, nullptr); |
| | 19558 | |
| | 19559 | if (is_comptime && !instr_is_comptime(result)) { |
| 18066 | ir_add_error_node(ira, first_non_const_instruction->source_node, | 19560 | ir_add_error_node(ira, first_non_const_instruction->source_node, |
| 18067 | buf_sprintf("unable to evaluate constant expression")); | 19561 | buf_sprintf("unable to evaluate constant expression")); |
| 18068 | return ira->codegen->invalid_instruction; | 19562 | return ira->codegen->invalid_instruction; |
| 18069 | } | 19563 | } |
| 18070 | | 19564 | |
| 18071 | IrInstruction *new_instruction = ir_build_struct_init(&ira->new_irb, | 19565 | return result; |
| 18072 | instruction->scope, instruction->source_node, | | |
| 18073 | container_type, actual_field_count, new_fields); | | |
| 18074 | new_instruction->value.type = container_type; | | |
| 18075 | ir_add_alloca(ira, new_instruction, container_type); | | |
| 18076 | return new_instruction; | | |
| 18077 | } | 19566 | } |
| 18078 | | 19567 | |
| 18079 | static IrInstruction *ir_analyze_instruction_container_init_list(IrAnalyze *ira, | 19568 | static IrInstruction *ir_analyze_instruction_container_init_list(IrAnalyze *ira, |
| 18080 | IrInstructionContainerInitList *instruction) | 19569 | IrInstructionContainerInitList *instruction) |
| 18081 | { | 19570 | { |
| 18082 | Error err; | 19571 | ZigType *container_type = ir_resolve_type(ira, instruction->container_type->child); |
| | 19572 | if (type_is_invalid(container_type)) |
| | 19573 | return ira->codegen->invalid_instruction; |
| 18083 | | 19574 | |
| 18084 | size_t elem_count = instruction->item_count; | 19575 | size_t elem_count = instruction->item_count; |
| 18085 | | 19576 | |
| 18086 | ZigType *container_type; | | |
| 18087 | if (instruction->container_type != nullptr) { | | |
| 18088 | container_type = ir_resolve_type(ira, instruction->container_type->child); | | |
| 18089 | if (type_is_invalid(container_type)) | | |
| 18090 | return ira->codegen->invalid_instruction; | | |
| 18091 | } else { | | |
| 18092 | ZigType *elem_type = ir_resolve_type(ira, instruction->elem_type->child); | | |
| 18093 | if (type_is_invalid(elem_type)) | | |
| 18094 | return ira->codegen->invalid_instruction; | | |
| 18095 | if ((err = type_resolve(ira->codegen, elem_type, ResolveStatusSizeKnown))) { | | |
| 18096 | return ira->codegen->invalid_instruction; | | |
| 18097 | } | | |
| 18098 | container_type = get_array_type(ira->codegen, elem_type, elem_count); | | |
| 18099 | } | | |
| 18100 | | | |
| 18101 | if (is_slice(container_type)) { | 19577 | if (is_slice(container_type)) { |
| 18102 | ir_add_error(ira, &instruction->base, | 19578 | ir_add_error(ira, &instruction->base, |
| 18103 | buf_sprintf("expected array type or [_], found slice")); | 19579 | buf_sprintf("expected array type or [_], found slice")); |
| 18104 | return ira->codegen->invalid_instruction; | 19580 | return ira->codegen->invalid_instruction; |
| 18105 | } else if (container_type->id == ZigTypeIdStruct && !is_slice(container_type) && elem_count == 0) { | 19581 | } |
| 18106 | return ir_analyze_container_init_fields(ira, &instruction->base, container_type, | | |
| 18107 | 0, nullptr); | | |
| 18108 | } else if (container_type->id == ZigTypeIdArray) { | | |
| 18109 | // array is same as slice init but we make a compile error if the length is wrong | | |
| 18110 | ZigType *child_type; | | |
| 18111 | if (container_type->id == ZigTypeIdArray) { | | |
| 18112 | child_type = container_type->data.array.child_type; | | |
| 18113 | if (container_type->data.array.len != elem_count) { | | |
| 18114 | ZigType *literal_type = get_array_type(ira->codegen, child_type, elem_count); | | |
| 18115 | | | |
| 18116 | ir_add_error(ira, &instruction->base, | | |
| 18117 | buf_sprintf("expected %s literal, found %s literal", | | |
| 18118 | buf_ptr(&container_type->name), buf_ptr(&literal_type->name))); | | |
| 18119 | return ira->codegen->invalid_instruction; | | |
| 18120 | } | | |
| 18121 | } else { | | |
| 18122 | ZigType *pointer_type = container_type->data.structure.fields[slice_ptr_index].type_entry; | | |
| 18123 | assert(pointer_type->id == ZigTypeIdPointer); | | |
| 18124 | child_type = pointer_type->data.pointer.child_type; | | |
| 18125 | } | | |
| 18126 | | 19582 | |
| 18127 | if ((err = type_resolve(ira->codegen, child_type, ResolveStatusSizeKnown))) { | 19583 | if (container_type->id == ZigTypeIdVoid) { |
| | 19584 | if (elem_count != 0) { |
| | 19585 | ir_add_error_node(ira, instruction->base.source_node, |
| | 19586 | buf_sprintf("void expression expects no arguments")); |
| 18128 | return ira->codegen->invalid_instruction; | 19587 | return ira->codegen->invalid_instruction; |
| 18129 | } | 19588 | } |
| | 19589 | return ir_const_void(ira, &instruction->base); |
| | 19590 | } |
| 18130 | | 19591 | |
| 18131 | ZigType *fixed_size_array_type = get_array_type(ira->codegen, child_type, elem_count); | 19592 | if (container_type->id == ZigTypeIdStruct && elem_count == 0) { |
| | 19593 | ir_assert(instruction->result_loc != nullptr, &instruction->base); |
| | 19594 | IrInstruction *result_loc = instruction->result_loc->child; |
| | 19595 | if (type_is_invalid(result_loc->value.type)) |
| | 19596 | return result_loc; |
| | 19597 | return ir_analyze_container_init_fields(ira, &instruction->base, container_type, 0, nullptr, result_loc); |
| | 19598 | } |
| | 19599 | |
| | 19600 | if (container_type->id != ZigTypeIdArray) { |
| | 19601 | ir_add_error_node(ira, instruction->base.source_node, |
| | 19602 | buf_sprintf("type '%s' does not support array initialization", |
| | 19603 | buf_ptr(&container_type->name))); |
| | 19604 | return ira->codegen->invalid_instruction; |
| | 19605 | } |
| 18132 | | 19606 | |
| 18133 | ConstExprValue const_val = {}; | 19607 | ir_assert(instruction->result_loc != nullptr, &instruction->base); |
| 18134 | const_val.special = ConstValSpecialStatic; | 19608 | IrInstruction *result_loc = instruction->result_loc->child; |
| 18135 | const_val.type = fixed_size_array_type; | 19609 | if (type_is_invalid(result_loc->value.type)) |
| 18136 | // const_val.global_refs = allocate<ConstGlobalRefs>(1); | 19610 | return result_loc; |
| 18137 | const_val.data.x_array.data.s_none.elements = create_const_vals(elem_count); | 19611 | ir_assert(result_loc->value.type->id == ZigTypeIdPointer, &instruction->base); |
| 18138 | | 19612 | |
| 18139 | bool is_comptime = ir_should_inline(ira->new_irb.exec, instruction->base.scope); | 19613 | ZigType *child_type = container_type->data.array.child_type; |
| | 19614 | if (container_type->data.array.len != elem_count) { |
| | 19615 | ZigType *literal_type = get_array_type(ira->codegen, child_type, elem_count); |
| 18140 | | 19616 | |
| 18141 | IrInstruction **new_items = allocate<IrInstruction *>(elem_count); | 19617 | ir_add_error(ira, &instruction->base, |
| | 19618 | buf_sprintf("expected %s literal, found %s literal", |
| | 19619 | buf_ptr(&container_type->name), buf_ptr(&literal_type->name))); |
| | 19620 | return ira->codegen->invalid_instruction; |
| | 19621 | } |
| 18142 | | 19622 | |
| 18143 | IrInstruction *first_non_const_instruction = nullptr; | 19623 | switch (type_has_one_possible_value(ira->codegen, container_type)) { |
| | 19624 | case OnePossibleValueInvalid: |
| | 19625 | return ira->codegen->invalid_instruction; |
| | 19626 | case OnePossibleValueYes: |
| | 19627 | return ir_const(ira, &instruction->base, container_type); |
| | 19628 | case OnePossibleValueNo: |
| | 19629 | break; |
| | 19630 | } |
| 18144 | | 19631 | |
| 18145 | for (size_t i = 0; i < elem_count; i += 1) { | 19632 | bool is_comptime; |
| 18146 | IrInstruction *arg_value = instruction->items[i]->child; | 19633 | switch (type_requires_comptime(ira->codegen, container_type)) { |
| 18147 | if (type_is_invalid(arg_value->value.type)) | 19634 | case ReqCompTimeInvalid: |
| 18148 | return ira->codegen->invalid_instruction; | 19635 | return ira->codegen->invalid_instruction; |
| | 19636 | case ReqCompTimeNo: |
| | 19637 | is_comptime = ir_should_inline(ira->new_irb.exec, instruction->base.scope); |
| | 19638 | break; |
| | 19639 | case ReqCompTimeYes: |
| | 19640 | is_comptime = true; |
| | 19641 | break; |
| | 19642 | } |
| 18149 | | 19643 | |
| 18150 | IrInstruction *casted_arg = ir_implicit_cast(ira, arg_value, child_type); | 19644 | IrInstruction *first_non_const_instruction = nullptr; |
| 18151 | if (casted_arg == ira->codegen->invalid_instruction) | | |
| 18152 | return ira->codegen->invalid_instruction; | | |
| 18153 | | 19645 | |
| 18154 | new_items[i] = casted_arg; | 19646 | // The Result Location Mechanism has already emitted runtime instructions to |
| | 19647 | // initialize runtime elements and has omitted instructions for the comptime |
| | 19648 | // elements. However it is only now that we find out whether the array initialization |
| | 19649 | // can be a comptime value. So we must clean up the situation. If it turns out |
| | 19650 | // array initialization can be a comptime value, overwrite ConstPtrMutInfer with |
| | 19651 | // ConstPtrMutComptimeConst. Otherwise, emit instructions to runtime-initialize the |
| | 19652 | // elements that have comptime-known values. |
| | 19653 | ZigList<IrInstruction *> const_ptrs = {}; |
| | 19654 | |
| | 19655 | for (size_t i = 0; i < elem_count; i += 1) { |
| | 19656 | IrInstruction *elem_result_loc = instruction->elem_result_loc_list[i]->child; |
| | 19657 | if (type_is_invalid(elem_result_loc->value.type)) |
| | 19658 | return ira->codegen->invalid_instruction; |
| 18155 | | 19659 | |
| 18156 | if (const_val.special == ConstValSpecialStatic) { | 19660 | assert(elem_result_loc->value.type->id == ZigTypeIdPointer); |
| 18157 | if (is_comptime || casted_arg->value.special != ConstValSpecialRuntime) { | | |
| 18158 | ConstExprValue *elem_val = ir_resolve_const(ira, casted_arg, UndefBad); | | |
| 18159 | if (!elem_val) | | |
| 18160 | return ira->codegen->invalid_instruction; | | |
| 18161 | | 19661 | |
| 18162 | copy_const_val(&const_val.data.x_array.data.s_none.elements[i], elem_val, true); | 19662 | if (instr_is_comptime(elem_result_loc) && |
| 18163 | } else { | 19663 | elem_result_loc->value.data.x_ptr.mut != ConstPtrMutRuntimeVar) |
| 18164 | first_non_const_instruction = casted_arg; | 19664 | { |
| 18165 | const_val.special = ConstValSpecialRuntime; | 19665 | const_ptrs.append(elem_result_loc); |
| 18166 | } | 19666 | } else { |
| 18167 | } | 19667 | first_non_const_instruction = elem_result_loc; |
| 18168 | } | 19668 | } |
| | 19669 | } |
| 18169 | | 19670 | |
| 18170 | if (const_val.special == ConstValSpecialStatic) { | 19671 | if (result_loc->value.data.x_ptr.mut == ConstPtrMutInfer) { |
| 18171 | IrInstruction *result = ir_const(ira, &instruction->base, nullptr); | 19672 | if (const_ptrs.length != elem_count) { |
| 18172 | ConstExprValue *out_val = &result->value; | 19673 | result_loc->value.special = ConstValSpecialRuntime; |
| 18173 | copy_const_val(out_val, &const_val, false); | 19674 | for (size_t i = 0; i < const_ptrs.length; i += 1) { |
| 18174 | result->value.type = fixed_size_array_type; | 19675 | IrInstruction *elem_result_loc = const_ptrs.at(i); |
| 18175 | for (size_t i = 0; i < elem_count; i += 1) { | 19676 | assert(elem_result_loc->value.special == ConstValSpecialStatic); |
| 18176 | ConstExprValue *elem_val = &out_val->data.x_array.data.s_none.elements[i]; | 19677 | IrInstruction *deref = ir_get_deref(ira, elem_result_loc, elem_result_loc, nullptr); |
| 18177 | ConstParent *parent = get_const_val_parent(ira->codegen, elem_val); | 19678 | elem_result_loc->value.special = ConstValSpecialRuntime; |
| 18178 | if (parent != nullptr) { | 19679 | ir_analyze_store_ptr(ira, elem_result_loc, elem_result_loc, deref); |
| 18179 | parent->id = ConstParentIdArray; | | |
| 18180 | parent->data.p_array.array_val = out_val; | | |
| 18181 | parent->data.p_array.elem_index = i; | | |
| 18182 | } | | |
| 18183 | } | 19680 | } |
| 18184 | return result; | | |
| 18185 | } | 19681 | } |
| | 19682 | } |
| 18186 | | 19683 | |
| 18187 | if (is_comptime) { | 19684 | IrInstruction *result = ir_get_deref(ira, &instruction->base, result_loc, nullptr); |
| 18188 | ir_add_error_node(ira, first_non_const_instruction->source_node, | 19685 | if (instr_is_comptime(result)) |
| 18189 | buf_sprintf("unable to evaluate constant expression")); | 19686 | return result; |
| 18190 | return ira->codegen->invalid_instruction; | | |
| 18191 | } | | |
| 18192 | | 19687 | |
| 18193 | IrInstruction *new_instruction = ir_build_container_init_list(&ira->new_irb, | 19688 | if (is_comptime) { |
| 18194 | instruction->base.scope, instruction->base.source_node, | 19689 | ir_add_error_node(ira, first_non_const_instruction->source_node, |
| 18195 | nullptr, nullptr, elem_count, new_items); | 19690 | buf_sprintf("unable to evaluate constant expression")); |
| 18196 | new_instruction->value.type = fixed_size_array_type; | 19691 | return ira->codegen->invalid_instruction; |
| 18197 | ir_add_alloca(ira, new_instruction, fixed_size_array_type); | 19692 | } |
| 18198 | return new_instruction; | 19693 | |
| 18199 | } else if (container_type->id == ZigTypeIdVoid) { | 19694 | ZigType *result_elem_type = result_loc->value.type->data.pointer.child_type; |
| 18200 | if (elem_count != 0) { | 19695 | if (is_slice(result_elem_type)) { |
| 18201 | ir_add_error_node(ira, instruction->base.source_node, | 19696 | ErrorMsg *msg = ir_add_error(ira, &instruction->base, |
| 18202 | buf_sprintf("void expression expects no arguments")); | 19697 | buf_sprintf("runtime-initialized array cannot be casted to slice type '%s'", |
| 18203 | return ira->codegen->invalid_instruction; | 19698 | buf_ptr(&result_elem_type->name))); |
| 18204 | } | 19699 | add_error_note(ira->codegen, msg, first_non_const_instruction->source_node, |
| 18205 | return ir_const_void(ira, &instruction->base); | 19700 | buf_sprintf("this value is not comptime-known")); |
| 18206 | } else { | | |
| 18207 | ir_add_error_node(ira, instruction->base.source_node, | | |
| 18208 | buf_sprintf("type '%s' does not support array initialization", | | |
| 18209 | buf_ptr(&container_type->name))); | | |
| 18210 | return ira->codegen->invalid_instruction; | 19701 | return ira->codegen->invalid_instruction; |
| 18211 | } | 19702 | } |
| | 19703 | return result; |
| 18212 | } | 19704 | } |
| 18213 | | 19705 | |
| 18214 | static IrInstruction *ir_analyze_instruction_container_init_fields(IrAnalyze *ira, | 19706 | static IrInstruction *ir_analyze_instruction_container_init_fields(IrAnalyze *ira, |
| ... | @@ -18219,8 +19711,13 @@ static IrInstruction *ir_analyze_instruction_container_init_fields(IrAnalyze *ir | ... | @@ -18219,8 +19711,13 @@ static IrInstruction *ir_analyze_instruction_container_init_fields(IrAnalyze *ir |
| 18219 | if (type_is_invalid(container_type)) | 19711 | if (type_is_invalid(container_type)) |
| 18220 | return ira->codegen->invalid_instruction; | 19712 | return ira->codegen->invalid_instruction; |
| 18221 | | 19713 | |
| | 19714 | ir_assert(instruction->result_loc != nullptr, &instruction->base); |
| | 19715 | IrInstruction *result_loc = instruction->result_loc->child; |
| | 19716 | if (type_is_invalid(result_loc->value.type)) |
| | 19717 | return result_loc; |
| | 19718 | |
| 18222 | return ir_analyze_container_init_fields(ira, &instruction->base, container_type, | 19719 | return ir_analyze_container_init_fields(ira, &instruction->base, container_type, |
| 18223 | instruction->field_count, instruction->fields); | 19720 | instruction->field_count, instruction->fields, result_loc); |
| 18224 | } | 19721 | } |
| 18225 | | 19722 | |
| 18226 | static IrInstruction *ir_analyze_instruction_compile_err(IrAnalyze *ira, | 19723 | static IrInstruction *ir_analyze_instruction_compile_err(IrAnalyze *ira, |
| ... | @@ -18489,12 +19986,6 @@ static IrInstruction *ir_analyze_instruction_bit_offset_of(IrAnalyze *ira, | ... | @@ -18489,12 +19986,6 @@ static IrInstruction *ir_analyze_instruction_bit_offset_of(IrAnalyze *ira, |
| 18489 | return ir_const_unsigned(ira, &instruction->base, bit_offset); | 19986 | return ir_const_unsigned(ira, &instruction->base, bit_offset); |
| 18490 | } | 19987 | } |
| 18491 | | 19988 | |
| 18492 | static IrInstruction *ir_error_dependency_loop(IrAnalyze *ira, IrInstruction *source_instr) { | | |
| 18493 | ErrorMsg *msg = ir_add_error(ira, source_instr, buf_sprintf("dependency loop detected")); | | |
| 18494 | emit_error_notes_for_ref_stack(ira->codegen, msg); | | |
| 18495 | return ira->codegen->invalid_instruction; | | |
| 18496 | } | | |
| 18497 | | | |
| 18498 | static void ensure_field_index(ZigType *type, const char *field_name, size_t index) { | 19989 | static void ensure_field_index(ZigType *type, const char *field_name, size_t index) { |
| 18499 | Buf *field_name_buf; | 19990 | Buf *field_name_buf; |
| 18500 | | 19991 | |
| ... | @@ -19613,7 +21104,7 @@ static IrInstruction *ir_analyze_instruction_c_import(IrAnalyze *ira, IrInstruct | ... | @@ -19613,7 +21104,7 @@ static IrInstruction *ir_analyze_instruction_c_import(IrAnalyze *ira, IrInstruct |
| 19613 | ir_add_error_node(ira, node, buf_sprintf("C import failed: unable to make dir: %s", err_str(err))); | 21104 | ir_add_error_node(ira, node, buf_sprintf("C import failed: unable to make dir: %s", err_str(err))); |
| 19614 | return ira->codegen->invalid_instruction; | 21105 | return ira->codegen->invalid_instruction; |
| 19615 | } | 21106 | } |
| 19616 | | 21107 | |
| 19617 | if ((err = os_write_file(&tmp_c_file_path, &cimport_scope->buf))) { | 21108 | if ((err = os_write_file(&tmp_c_file_path, &cimport_scope->buf))) { |
| 19618 | ir_add_error_node(ira, node, buf_sprintf("C import failed: unable to write .h file: %s", err_str(err))); | 21109 | ir_add_error_node(ira, node, buf_sprintf("C import failed: unable to write .h file: %s", err_str(err))); |
| 19619 | return ira->codegen->invalid_instruction; | 21110 | return ira->codegen->invalid_instruction; |
| ... | @@ -19900,12 +21391,21 @@ static IrInstruction *ir_analyze_instruction_cmpxchg(IrAnalyze *ira, IrInstructi | ... | @@ -19900,12 +21391,21 @@ static IrInstruction *ir_analyze_instruction_cmpxchg(IrAnalyze *ira, IrInstructi |
| 19900 | zig_panic("TODO compile-time execution of cmpxchg"); | 21391 | zig_panic("TODO compile-time execution of cmpxchg"); |
| 19901 | } | 21392 | } |
| 19902 | | 21393 | |
| 19903 | IrInstruction *result = ir_build_cmpxchg_gen(ira, &instruction->base, | 21394 | ZigType *result_type = get_optional_type(ira->codegen, operand_type); |
| | 21395 | IrInstruction *result_loc; |
| | 21396 | if (handle_is_ptr(result_type)) { |
| | 21397 | result_loc = ir_resolve_result(ira, &instruction->base, instruction->result_loc, |
| | 21398 | result_type, nullptr, true, false); |
| | 21399 | if (type_is_invalid(result_loc->value.type) || instr_is_unreachable(result_loc)) { |
| | 21400 | return result_loc; |
| | 21401 | } |
| | 21402 | } else { |
| | 21403 | result_loc = nullptr; |
| | 21404 | } |
| | 21405 | |
| | 21406 | return ir_build_cmpxchg_gen(ira, &instruction->base, result_type, |
| 19904 | casted_ptr, casted_cmp_value, casted_new_value, | 21407 | casted_ptr, casted_cmp_value, casted_new_value, |
| 19905 | success_order, failure_order, instruction->is_weak); | 21408 | success_order, failure_order, instruction->is_weak, result_loc); |
| 19906 | result->value.type = get_optional_type(ira->codegen, operand_type); | | |
| 19907 | ir_add_alloca(ira, result, result->value.type); | | |
| 19908 | return result; | | |
| 19909 | } | 21409 | } |
| 19910 | | 21410 | |
| 19911 | static IrInstruction *ir_analyze_instruction_fence(IrAnalyze *ira, IrInstructionFence *instruction) { | 21411 | static IrInstruction *ir_analyze_instruction_fence(IrAnalyze *ira, IrInstructionFence *instruction) { |
| ... | @@ -20043,7 +21543,7 @@ static IrInstruction *ir_analyze_instruction_float_cast(IrAnalyze *ira, IrInstru | ... | @@ -20043,7 +21543,7 @@ static IrInstruction *ir_analyze_instruction_float_cast(IrAnalyze *ira, IrInstru |
| 20043 | } else { | 21543 | } else { |
| 20044 | op = CastOpNumLitToConcrete; | 21544 | op = CastOpNumLitToConcrete; |
| 20045 | } | 21545 | } |
| 20046 | return ir_resolve_cast(ira, &instruction->base, target, dest_type, op, false); | 21546 | return ir_resolve_cast(ira, &instruction->base, target, dest_type, op); |
| 20047 | } else { | 21547 | } else { |
| 20048 | return ira->codegen->invalid_instruction; | 21548 | return ira->codegen->invalid_instruction; |
| 20049 | } | 21549 | } |
| ... | @@ -20151,6 +21651,12 @@ static IrInstruction *ir_analyze_instruction_from_bytes(IrAnalyze *ira, IrInstru | ... | @@ -20151,6 +21651,12 @@ static IrInstruction *ir_analyze_instruction_from_bytes(IrAnalyze *ira, IrInstru |
| 20151 | } | 21651 | } |
| 20152 | } | 21652 | } |
| 20153 | | 21653 | |
| | 21654 | IrInstruction *result_loc = ir_resolve_result(ira, &instruction->base, instruction->result_loc, |
| | 21655 | dest_slice_type, nullptr, true, false); |
| | 21656 | if (result_loc != nullptr && (type_is_invalid(result_loc->value.type) || instr_is_unreachable(result_loc))) { |
| | 21657 | return result_loc; |
| | 21658 | } |
| | 21659 | |
| 20154 | if (casted_value->value.data.rh_slice.id == RuntimeHintSliceIdLen) { | 21660 | if (casted_value->value.data.rh_slice.id == RuntimeHintSliceIdLen) { |
| 20155 | known_len = casted_value->value.data.rh_slice.len; | 21661 | known_len = casted_value->value.data.rh_slice.len; |
| 20156 | have_known_len = true; | 21662 | have_known_len = true; |
| ... | @@ -20170,9 +21676,7 @@ static IrInstruction *ir_analyze_instruction_from_bytes(IrAnalyze *ira, IrInstru | ... | @@ -20170,9 +21676,7 @@ static IrInstruction *ir_analyze_instruction_from_bytes(IrAnalyze *ira, IrInstru |
| 20170 | } | 21676 | } |
| 20171 | } | 21677 | } |
| 20172 | | 21678 | |
| 20173 | IrInstruction *result = ir_build_resize_slice(ira, &instruction->base, casted_value, dest_slice_type); | 21679 | return ir_build_resize_slice(ira, &instruction->base, casted_value, dest_slice_type, result_loc); |
| 20174 | ir_add_alloca(ira, result, dest_slice_type); | | |
| 20175 | return result; | | |
| 20176 | } | 21680 | } |
| 20177 | | 21681 | |
| 20178 | static IrInstruction *ir_analyze_instruction_to_bytes(IrAnalyze *ira, IrInstructionToBytes *instruction) { | 21682 | static IrInstruction *ir_analyze_instruction_to_bytes(IrAnalyze *ira, IrInstructionToBytes *instruction) { |
| ... | @@ -20224,9 +21728,13 @@ static IrInstruction *ir_analyze_instruction_to_bytes(IrAnalyze *ira, IrInstruct | ... | @@ -20224,9 +21728,13 @@ static IrInstruction *ir_analyze_instruction_to_bytes(IrAnalyze *ira, IrInstruct |
| 20224 | return result; | 21728 | return result; |
| 20225 | } | 21729 | } |
| 20226 | | 21730 | |
| 20227 | IrInstruction *result = ir_build_resize_slice(ira, &instruction->base, target, dest_slice_type); | 21731 | IrInstruction *result_loc = ir_resolve_result(ira, &instruction->base, instruction->result_loc, |
| 20228 | ir_add_alloca(ira, result, dest_slice_type); | 21732 | dest_slice_type, nullptr, true, false); |
| 20229 | return result; | 21733 | if (type_is_invalid(result_loc->value.type) || instr_is_unreachable(result_loc)) { |
| | 21734 | return result_loc; |
| | 21735 | } |
| | 21736 | |
| | 21737 | return ir_build_resize_slice(ira, &instruction->base, target, dest_slice_type, result_loc); |
| 20230 | } | 21738 | } |
| 20231 | | 21739 | |
| 20232 | static Error resolve_ptr_align(IrAnalyze *ira, ZigType *ty, uint32_t *result_align) { | 21740 | static Error resolve_ptr_align(IrAnalyze *ira, ZigType *ty, uint32_t *result_align) { |
| ... | @@ -20258,7 +21766,7 @@ static IrInstruction *ir_analyze_instruction_int_to_float(IrAnalyze *ira, IrInst | ... | @@ -20258,7 +21766,7 @@ static IrInstruction *ir_analyze_instruction_int_to_float(IrAnalyze *ira, IrInst |
| 20258 | return ira->codegen->invalid_instruction; | 21766 | return ira->codegen->invalid_instruction; |
| 20259 | } | 21767 | } |
| 20260 | | 21768 | |
| 20261 | return ir_resolve_cast(ira, &instruction->base, target, dest_type, CastOpIntToFloat, false); | 21769 | return ir_resolve_cast(ira, &instruction->base, target, dest_type, CastOpIntToFloat); |
| 20262 | } | 21770 | } |
| 20263 | | 21771 | |
| 20264 | static IrInstruction *ir_analyze_instruction_float_to_int(IrAnalyze *ira, IrInstructionFloatToInt *instruction) { | 21772 | static IrInstruction *ir_analyze_instruction_float_to_int(IrAnalyze *ira, IrInstructionFloatToInt *instruction) { |
| ... | @@ -20280,7 +21788,7 @@ static IrInstruction *ir_analyze_instruction_float_to_int(IrAnalyze *ira, IrInst | ... | @@ -20280,7 +21788,7 @@ static IrInstruction *ir_analyze_instruction_float_to_int(IrAnalyze *ira, IrInst |
| 20280 | return ira->codegen->invalid_instruction; | 21788 | return ira->codegen->invalid_instruction; |
| 20281 | } | 21789 | } |
| 20282 | | 21790 | |
| 20283 | return ir_resolve_cast(ira, &instruction->base, target, dest_type, CastOpFloatToInt, false); | 21791 | return ir_resolve_cast(ira, &instruction->base, target, dest_type, CastOpFloatToInt); |
| 20284 | } | 21792 | } |
| 20285 | | 21793 | |
| 20286 | static IrInstruction *ir_analyze_instruction_err_to_int(IrAnalyze *ira, IrInstructionErrToInt *instruction) { | 21794 | static IrInstruction *ir_analyze_instruction_err_to_int(IrAnalyze *ira, IrInstructionErrToInt *instruction) { |
| ... | @@ -20332,7 +21840,7 @@ static IrInstruction *ir_analyze_instruction_bool_to_int(IrAnalyze *ira, IrInstr | ... | @@ -20332,7 +21840,7 @@ static IrInstruction *ir_analyze_instruction_bool_to_int(IrAnalyze *ira, IrInstr |
| 20332 | } | 21840 | } |
| 20333 | | 21841 | |
| 20334 | ZigType *u1_type = get_int_type(ira->codegen, false, 1); | 21842 | ZigType *u1_type = get_int_type(ira->codegen, false, 1); |
| 20335 | return ir_resolve_cast(ira, &instruction->base, target, u1_type, CastOpBoolToInt, false); | 21843 | return ir_resolve_cast(ira, &instruction->base, target, u1_type, CastOpBoolToInt); |
| 20336 | } | 21844 | } |
| 20337 | | 21845 | |
| 20338 | static IrInstruction *ir_analyze_instruction_int_type(IrAnalyze *ira, IrInstructionIntType *instruction) { | 21846 | static IrInstruction *ir_analyze_instruction_int_type(IrAnalyze *ira, IrInstructionIntType *instruction) { |
| ... | @@ -20493,7 +22001,7 @@ static IrInstruction *ir_analyze_instruction_memset(IrAnalyze *ira, IrInstructio | ... | @@ -20493,7 +22001,7 @@ static IrInstruction *ir_analyze_instruction_memset(IrAnalyze *ira, IrInstructio |
| 20493 | | 22001 | |
| 20494 | ConstExprValue *byte_val = &casted_byte->value; | 22002 | ConstExprValue *byte_val = &casted_byte->value; |
| 20495 | for (size_t i = start; i < end; i += 1) { | 22003 | for (size_t i = start; i < end; i += 1) { |
| 20496 | dest_elements[i] = *byte_val; | 22004 | copy_const_val(&dest_elements[i], byte_val, true); |
| 20497 | } | 22005 | } |
| 20498 | | 22006 | |
| 20499 | return ir_const_void(ira, &instruction->base); | 22007 | return ir_const_void(ira, &instruction->base); |
| ... | @@ -20563,7 +22071,7 @@ static IrInstruction *ir_analyze_instruction_memcpy(IrAnalyze *ira, IrInstructio | ... | @@ -20563,7 +22071,7 @@ static IrInstruction *ir_analyze_instruction_memcpy(IrAnalyze *ira, IrInstructio |
| 20563 | return ira->codegen->invalid_instruction; | 22071 | return ira->codegen->invalid_instruction; |
| 20564 | | 22072 | |
| 20565 | // TODO test this at comptime with u8 and non-u8 types | 22073 | // TODO test this at comptime with u8 and non-u8 types |
| 20566 | // TODO test with dest ptr being a global runtime variable | 22074 | // TODO test with dest ptr being a global runtime variable |
| 20567 | if (casted_dest_ptr->value.special == ConstValSpecialStatic && | 22075 | if (casted_dest_ptr->value.special == ConstValSpecialStatic && |
| 20568 | casted_src_ptr->value.special == ConstValSpecialStatic && | 22076 | casted_src_ptr->value.special == ConstValSpecialStatic && |
| 20569 | casted_count->value.special == ConstValSpecialStatic && | 22077 | casted_count->value.special == ConstValSpecialStatic && |
| ... | @@ -20661,7 +22169,7 @@ static IrInstruction *ir_analyze_instruction_memcpy(IrAnalyze *ira, IrInstructio | ... | @@ -20661,7 +22169,7 @@ static IrInstruction *ir_analyze_instruction_memcpy(IrAnalyze *ira, IrInstructio |
| 20661 | // TODO check for noalias violations - this should be generalized to work for any function | 22169 | // TODO check for noalias violations - this should be generalized to work for any function |
| 20662 | | 22170 | |
| 20663 | for (size_t i = 0; i < count; i += 1) { | 22171 | for (size_t i = 0; i < count; i += 1) { |
| 20664 | dest_elements[dest_start + i] = src_elements[src_start + i]; | 22172 | copy_const_val(&dest_elements[dest_start + i], &src_elements[src_start + i], true); |
| 20665 | } | 22173 | } |
| 20666 | | 22174 | |
| 20667 | return ir_const_void(ira, &instruction->base); | 22175 | return ir_const_void(ira, &instruction->base); |
| ... | @@ -20673,7 +22181,7 @@ static IrInstruction *ir_analyze_instruction_memcpy(IrAnalyze *ira, IrInstructio | ... | @@ -20673,7 +22181,7 @@ static IrInstruction *ir_analyze_instruction_memcpy(IrAnalyze *ira, IrInstructio |
| 20673 | return result; | 22181 | return result; |
| 20674 | } | 22182 | } |
| 20675 | | 22183 | |
| 20676 | static IrInstruction *ir_analyze_instruction_slice(IrAnalyze *ira, IrInstructionSlice *instruction) { | 22184 | static IrInstruction *ir_analyze_instruction_slice(IrAnalyze *ira, IrInstructionSliceSrc *instruction) { |
| 20677 | IrInstruction *ptr_ptr = instruction->ptr->child; | 22185 | IrInstruction *ptr_ptr = instruction->ptr->child; |
| 20678 | if (type_is_invalid(ptr_ptr->value.type)) | 22186 | if (type_is_invalid(ptr_ptr->value.type)) |
| 20679 | return ira->codegen->invalid_instruction; | 22187 | return ira->codegen->invalid_instruction; |
| ... | @@ -20962,12 +22470,13 @@ static IrInstruction *ir_analyze_instruction_slice(IrAnalyze *ira, IrInstruction | ... | @@ -20962,12 +22470,13 @@ static IrInstruction *ir_analyze_instruction_slice(IrAnalyze *ira, IrInstruction |
| 20962 | return result; | 22470 | return result; |
| 20963 | } | 22471 | } |
| 20964 | | 22472 | |
| 20965 | IrInstruction *new_instruction = ir_build_slice(&ira->new_irb, | 22473 | IrInstruction *result_loc = ir_resolve_result(ira, &instruction->base, instruction->result_loc, |
| 20966 | instruction->base.scope, instruction->base.source_node, | 22474 | return_type, nullptr, true, false); |
| 20967 | ptr_ptr, casted_start, end, instruction->safety_check_on); | 22475 | if (type_is_invalid(result_loc->value.type) || instr_is_unreachable(result_loc)) { |
| 20968 | new_instruction->value.type = return_type; | 22476 | return result_loc; |
| 20969 | ir_add_alloca(ira, new_instruction, return_type); | 22477 | } |
| 20970 | return new_instruction; | 22478 | return ir_build_slice_gen(ira, &instruction->base, return_type, |
| | 22479 | ptr_ptr, casted_start, end, instruction->safety_check_on, result_loc); |
| 20971 | } | 22480 | } |
| 20972 | | 22481 | |
| 20973 | static IrInstruction *ir_analyze_instruction_member_count(IrAnalyze *ira, IrInstructionMemberCount *instruction) { | 22482 | static IrInstruction *ir_analyze_instruction_member_count(IrAnalyze *ira, IrInstructionMemberCount *instruction) { |
| ... | @@ -21291,6 +22800,19 @@ static IrInstruction *ir_analyze_instruction_overflow_op(IrAnalyze *ira, IrInstr | ... | @@ -21291,6 +22800,19 @@ static IrInstruction *ir_analyze_instruction_overflow_op(IrAnalyze *ira, IrInstr |
| 21291 | return result; | 22800 | return result; |
| 21292 | } | 22801 | } |
| 21293 | | 22802 | |
| | 22803 | static IrInstruction *ir_analyze_instruction_result_ptr(IrAnalyze *ira, IrInstructionResultPtr *instruction) { |
| | 22804 | IrInstruction *result = instruction->result->child; |
| | 22805 | if (type_is_invalid(result->value.type)) |
| | 22806 | return result; |
| | 22807 | |
| | 22808 | if (instruction->result_loc->written && instruction->result_loc->resolved_loc != nullptr && |
| | 22809 | !instr_is_comptime(result)) |
| | 22810 | { |
| | 22811 | return instruction->result_loc->resolved_loc; |
| | 22812 | } |
| | 22813 | return ir_get_ref(ira, &instruction->base, result, true, false); |
| | 22814 | } |
| | 22815 | |
| 21294 | static void ir_eval_mul_add(IrAnalyze *ira, IrInstructionMulAdd *source_instr, ZigType *float_type, | 22816 | static void ir_eval_mul_add(IrAnalyze *ira, IrInstructionMulAdd *source_instr, ZigType *float_type, |
| 21295 | ConstExprValue *op1, ConstExprValue *op2, ConstExprValue *op3, ConstExprValue *out_val) { | 22817 | ConstExprValue *op1, ConstExprValue *op2, ConstExprValue *op3, ConstExprValue *out_val) { |
| 21296 | if (float_type->id == ZigTypeIdComptimeFloat) { | 22818 | if (float_type->id == ZigTypeIdComptimeFloat) { |
| ... | @@ -21410,15 +22932,17 @@ static IrInstruction *ir_analyze_instruction_mul_add(IrAnalyze *ira, IrInstructi | ... | @@ -21410,15 +22932,17 @@ static IrInstruction *ir_analyze_instruction_mul_add(IrAnalyze *ira, IrInstructi |
| 21410 | return result; | 22932 | return result; |
| 21411 | } | 22933 | } |
| 21412 | | 22934 | |
| 21413 | static IrInstruction *ir_analyze_instruction_test_err(IrAnalyze *ira, IrInstructionTestErr *instruction) { | 22935 | static IrInstruction *ir_analyze_instruction_test_err(IrAnalyze *ira, IrInstructionTestErrSrc *instruction) { |
| 21414 | IrInstruction *value = instruction->value->child; | 22936 | IrInstruction *base_ptr = instruction->base_ptr->child; |
| 21415 | if (type_is_invalid(value->value.type)) | 22937 | if (type_is_invalid(base_ptr->value.type)) |
| 21416 | return ira->codegen->invalid_instruction; | 22938 | return ira->codegen->invalid_instruction; |
| 21417 | | 22939 | |
| | 22940 | IrInstruction *value = ir_get_deref(ira, &instruction->base, base_ptr, nullptr); |
| 21418 | ZigType *type_entry = value->value.type; | 22941 | ZigType *type_entry = value->value.type; |
| 21419 | if (type_is_invalid(type_entry)) { | 22942 | if (type_is_invalid(type_entry)) |
| 21420 | return ira->codegen->invalid_instruction; | 22943 | return ira->codegen->invalid_instruction; |
| 21421 | } else if (type_entry->id == ZigTypeIdErrorUnion) { | 22944 | |
| | 22945 | if (type_entry->id == ZigTypeIdErrorUnion) { |
| 21422 | if (instr_is_comptime(value)) { | 22946 | if (instr_is_comptime(value)) { |
| 21423 | ConstExprValue *err_union_val = ir_resolve_const(ira, value, UndefBad); | 22947 | ConstExprValue *err_union_val = ir_resolve_const(ira, value, UndefBad); |
| 21424 | if (!err_union_val) | 22948 | if (!err_union_val) |
| ... | @@ -21430,21 +22954,20 @@ static IrInstruction *ir_analyze_instruction_test_err(IrAnalyze *ira, IrInstruct | ... | @@ -21430,21 +22954,20 @@ static IrInstruction *ir_analyze_instruction_test_err(IrAnalyze *ira, IrInstruct |
| 21430 | } | 22954 | } |
| 21431 | } | 22955 | } |
| 21432 | | 22956 | |
| 21433 | ZigType *err_set_type = type_entry->data.error_union.err_set_type; | 22957 | if (instruction->resolve_err_set) { |
| 21434 | if (!resolve_inferred_error_set(ira->codegen, err_set_type, instruction->base.source_node)) { | 22958 | ZigType *err_set_type = type_entry->data.error_union.err_set_type; |
| 21435 | return ira->codegen->invalid_instruction; | 22959 | if (!resolve_inferred_error_set(ira->codegen, err_set_type, instruction->base.source_node)) { |
| 21436 | } | 22960 | return ira->codegen->invalid_instruction; |
| 21437 | if (!type_is_global_error_set(err_set_type) && | 22961 | } |
| 21438 | err_set_type->data.error_set.err_count == 0) | 22962 | if (!type_is_global_error_set(err_set_type) && |
| 21439 | { | 22963 | err_set_type->data.error_set.err_count == 0) |
| 21440 | assert(err_set_type->data.error_set.infer_fn == nullptr); | 22964 | { |
| 21441 | return ir_const_bool(ira, &instruction->base, false); | 22965 | assert(err_set_type->data.error_set.infer_fn == nullptr); |
| | 22966 | return ir_const_bool(ira, &instruction->base, false); |
| | 22967 | } |
| 21442 | } | 22968 | } |
| 21443 | | 22969 | |
| 21444 | IrInstruction *result = ir_build_test_err(&ira->new_irb, | 22970 | return ir_build_test_err_gen(ira, &instruction->base, value); |
| 21445 | instruction->base.scope, instruction->base.source_node, value); | | |
| 21446 | result->value.type = ira->codegen->builtin_types.entry_bool; | | |
| 21447 | return result; | | |
| 21448 | } else if (type_entry->id == ZigTypeIdErrorSet) { | 22971 | } else if (type_entry->id == ZigTypeIdErrorSet) { |
| 21449 | return ir_const_bool(ira, &instruction->base, true); | 22972 | return ir_const_bool(ira, &instruction->base, true); |
| 21450 | } else { | 22973 | } else { |
| ... | @@ -21452,10 +22975,9 @@ static IrInstruction *ir_analyze_instruction_test_err(IrAnalyze *ira, IrInstruct | ... | @@ -21452,10 +22975,9 @@ static IrInstruction *ir_analyze_instruction_test_err(IrAnalyze *ira, IrInstruct |
| 21452 | } | 22975 | } |
| 21453 | } | 22976 | } |
| 21454 | | 22977 | |
| 21455 | static IrInstruction *ir_analyze_instruction_unwrap_err_code(IrAnalyze *ira, IrInstructionUnwrapErrCode *instruction) { | 22978 | static IrInstruction *ir_analyze_unwrap_err_code(IrAnalyze *ira, IrInstruction *source_instr, |
| 21456 | IrInstruction *base_ptr = instruction->err_union->child; | 22979 | IrInstruction *base_ptr, bool initializing) |
| 21457 | if (type_is_invalid(base_ptr->value.type)) | 22980 | { |
| 21458 | return ira->codegen->invalid_instruction; | | |
| 21459 | ZigType *ptr_type = base_ptr->value.type; | 22981 | ZigType *ptr_type = base_ptr->value.type; |
| 21460 | | 22982 | |
| 21461 | // This will be a pointer type because unwrap err payload IR instruction operates on a pointer to a thing. | 22983 | // This will be a pointer type because unwrap err payload IR instruction operates on a pointer to a thing. |
| ... | @@ -21471,40 +22993,79 @@ static IrInstruction *ir_analyze_instruction_unwrap_err_code(IrAnalyze *ira, IrI | ... | @@ -21471,40 +22993,79 @@ static IrInstruction *ir_analyze_instruction_unwrap_err_code(IrAnalyze *ira, IrI |
| 21471 | return ira->codegen->invalid_instruction; | 22993 | return ira->codegen->invalid_instruction; |
| 21472 | } | 22994 | } |
| 21473 | | 22995 | |
| | 22996 | ZigType *err_set_type = type_entry->data.error_union.err_set_type; |
| | 22997 | ZigType *result_type = get_pointer_to_type_extra(ira->codegen, err_set_type, |
| | 22998 | ptr_type->data.pointer.is_const, ptr_type->data.pointer.is_volatile, PtrLenSingle, |
| | 22999 | ptr_type->data.pointer.explicit_alignment, 0, 0, false); |
| | 23000 | |
| 21474 | if (instr_is_comptime(base_ptr)) { | 23001 | if (instr_is_comptime(base_ptr)) { |
| 21475 | ConstExprValue *ptr_val = ir_resolve_const(ira, base_ptr, UndefBad); | 23002 | ConstExprValue *ptr_val = ir_resolve_const(ira, base_ptr, UndefBad); |
| 21476 | if (!ptr_val) | 23003 | if (!ptr_val) |
| 21477 | return ira->codegen->invalid_instruction; | 23004 | return ira->codegen->invalid_instruction; |
| 21478 | if (ptr_val->data.x_ptr.mut != ConstPtrMutRuntimeVar) { | 23005 | if (ptr_val->data.x_ptr.mut != ConstPtrMutRuntimeVar && |
| 21479 | ConstExprValue *err_union_val = const_ptr_pointee(ira, ira->codegen, ptr_val, instruction->base.source_node); | 23006 | ptr_val->data.x_ptr.special != ConstPtrSpecialHardCodedAddr) |
| | 23007 | { |
| | 23008 | ConstExprValue *err_union_val = const_ptr_pointee(ira, ira->codegen, ptr_val, source_instr->source_node); |
| 21480 | if (err_union_val == nullptr) | 23009 | if (err_union_val == nullptr) |
| 21481 | return ira->codegen->invalid_instruction; | 23010 | return ira->codegen->invalid_instruction; |
| 21482 | if (err_union_val->special != ConstValSpecialRuntime) { | | |
| 21483 | ErrorTableEntry *err = err_union_val->data.x_err_union.error_set->data.x_err_set; | | |
| 21484 | assert(err); | | |
| 21485 | | 23011 | |
| 21486 | IrInstruction *result = ir_const(ira, &instruction->base, | 23012 | if (initializing && err_union_val->special == ConstValSpecialUndef) { |
| 21487 | type_entry->data.error_union.err_set_type); | 23013 | ConstExprValue *vals = create_const_vals(2); |
| 21488 | result->value.data.x_err_set = err; | 23014 | ConstExprValue *err_set_val = &vals[0]; |
| 21489 | return result; | 23015 | ConstExprValue *payload_val = &vals[1]; |
| | 23016 | |
| | 23017 | err_set_val->special = ConstValSpecialUndef; |
| | 23018 | err_set_val->type = err_set_type; |
| | 23019 | err_set_val->parent.id = ConstParentIdErrUnionCode; |
| | 23020 | err_set_val->parent.data.p_err_union_code.err_union_val = err_union_val; |
| | 23021 | |
| | 23022 | payload_val->special = ConstValSpecialUndef; |
| | 23023 | payload_val->type = type_entry->data.error_union.payload_type; |
| | 23024 | payload_val->parent.id = ConstParentIdErrUnionPayload; |
| | 23025 | payload_val->parent.data.p_err_union_payload.err_union_val = err_union_val; |
| | 23026 | |
| | 23027 | err_union_val->special = ConstValSpecialStatic; |
| | 23028 | err_union_val->data.x_err_union.error_set = err_set_val; |
| | 23029 | err_union_val->data.x_err_union.payload = payload_val; |
| | 23030 | } |
| | 23031 | ir_assert(err_union_val->special != ConstValSpecialRuntime, source_instr); |
| | 23032 | |
| | 23033 | IrInstruction *result; |
| | 23034 | if (ptr_val->data.x_ptr.mut == ConstPtrMutInfer) { |
| | 23035 | result = ir_build_unwrap_err_code(&ira->new_irb, source_instr->scope, |
| | 23036 | source_instr->source_node, base_ptr); |
| | 23037 | result->value.type = result_type; |
| | 23038 | result->value.special = ConstValSpecialStatic; |
| | 23039 | } else { |
| | 23040 | result = ir_const(ira, source_instr, result_type); |
| 21490 | } | 23041 | } |
| | 23042 | ConstExprValue *const_val = &result->value; |
| | 23043 | const_val->data.x_ptr.special = ConstPtrSpecialBaseErrorUnionCode; |
| | 23044 | const_val->data.x_ptr.data.base_err_union_code.err_union_val = err_union_val; |
| | 23045 | const_val->data.x_ptr.mut = ptr_val->data.x_ptr.mut; |
| | 23046 | return result; |
| 21491 | } | 23047 | } |
| 21492 | } | 23048 | } |
| 21493 | | 23049 | |
| 21494 | IrInstruction *result = ir_build_unwrap_err_code(&ira->new_irb, | 23050 | IrInstruction *result = ir_build_unwrap_err_code(&ira->new_irb, |
| 21495 | instruction->base.scope, instruction->base.source_node, base_ptr); | 23051 | source_instr->scope, source_instr->source_node, base_ptr); |
| 21496 | result->value.type = type_entry->data.error_union.err_set_type; | 23052 | result->value.type = result_type; |
| 21497 | return result; | 23053 | return result; |
| 21498 | } | 23054 | } |
| 21499 | | 23055 | |
| 21500 | static IrInstruction *ir_analyze_instruction_unwrap_err_payload(IrAnalyze *ira, | 23056 | static IrInstruction *ir_analyze_instruction_unwrap_err_code(IrAnalyze *ira, |
| 21501 | IrInstructionUnwrapErrPayload *instruction) | 23057 | IrInstructionUnwrapErrCode *instruction) |
| 21502 | { | 23058 | { |
| 21503 | assert(instruction->value->child); | 23059 | IrInstruction *base_ptr = instruction->err_union_ptr->child; |
| 21504 | IrInstruction *value = instruction->value->child; | 23060 | if (type_is_invalid(base_ptr->value.type)) |
| 21505 | if (type_is_invalid(value->value.type)) | | |
| 21506 | return ira->codegen->invalid_instruction; | 23061 | return ira->codegen->invalid_instruction; |
| 21507 | ZigType *ptr_type = value->value.type; | 23062 | return ir_analyze_unwrap_err_code(ira, &instruction->base, base_ptr, false); |
| | 23063 | } |
| | 23064 | |
| | 23065 | static IrInstruction *ir_analyze_unwrap_error_payload(IrAnalyze *ira, IrInstruction *source_instr, |
| | 23066 | IrInstruction *base_ptr, bool safety_check_on, bool initializing) |
| | 23067 | { |
| | 23068 | ZigType *ptr_type = base_ptr->value.type; |
| 21508 | | 23069 | |
| 21509 | // This will be a pointer type because unwrap err payload IR instruction operates on a pointer to a thing. | 23070 | // This will be a pointer type because unwrap err payload IR instruction operates on a pointer to a thing. |
| 21510 | assert(ptr_type->id == ZigTypeIdPointer); | 23071 | assert(ptr_type->id == ZigTypeIdPointer); |
| ... | @@ -21514,7 +23075,7 @@ static IrInstruction *ir_analyze_instruction_unwrap_err_payload(IrAnalyze *ira, | ... | @@ -21514,7 +23075,7 @@ static IrInstruction *ir_analyze_instruction_unwrap_err_payload(IrAnalyze *ira, |
| 21514 | return ira->codegen->invalid_instruction; | 23075 | return ira->codegen->invalid_instruction; |
| 21515 | | 23076 | |
| 21516 | if (type_entry->id != ZigTypeIdErrorUnion) { | 23077 | if (type_entry->id != ZigTypeIdErrorUnion) { |
| 21517 | ir_add_error(ira, value, | 23078 | ir_add_error(ira, base_ptr, |
| 21518 | buf_sprintf("expected error union type, found '%s'", buf_ptr(&type_entry->name))); | 23079 | buf_sprintf("expected error union type, found '%s'", buf_ptr(&type_entry->name))); |
| 21519 | return ira->codegen->invalid_instruction; | 23080 | return ira->codegen->invalid_instruction; |
| 21520 | } | 23081 | } |
| ... | @@ -21526,36 +23087,73 @@ static IrInstruction *ir_analyze_instruction_unwrap_err_payload(IrAnalyze *ira, | ... | @@ -21526,36 +23087,73 @@ static IrInstruction *ir_analyze_instruction_unwrap_err_payload(IrAnalyze *ira, |
| 21526 | ZigType *result_type = get_pointer_to_type_extra(ira->codegen, payload_type, | 23087 | ZigType *result_type = get_pointer_to_type_extra(ira->codegen, payload_type, |
| 21527 | ptr_type->data.pointer.is_const, ptr_type->data.pointer.is_volatile, | 23088 | ptr_type->data.pointer.is_const, ptr_type->data.pointer.is_volatile, |
| 21528 | PtrLenSingle, 0, 0, 0, false); | 23089 | PtrLenSingle, 0, 0, 0, false); |
| 21529 | if (instr_is_comptime(value)) { | 23090 | if (instr_is_comptime(base_ptr)) { |
| 21530 | ConstExprValue *ptr_val = ir_resolve_const(ira, value, UndefBad); | 23091 | ConstExprValue *ptr_val = ir_resolve_const(ira, base_ptr, UndefBad); |
| 21531 | if (!ptr_val) | 23092 | if (!ptr_val) |
| 21532 | return ira->codegen->invalid_instruction; | 23093 | return ira->codegen->invalid_instruction; |
| 21533 | if (ptr_val->data.x_ptr.mut != ConstPtrMutRuntimeVar) { | 23094 | if (ptr_val->data.x_ptr.mut != ConstPtrMutRuntimeVar) { |
| 21534 | ConstExprValue *err_union_val = const_ptr_pointee(ira, ira->codegen, ptr_val, instruction->base.source_node); | 23095 | ConstExprValue *err_union_val = const_ptr_pointee(ira, ira->codegen, ptr_val, source_instr->source_node); |
| 21535 | if (err_union_val == nullptr) | 23096 | if (err_union_val == nullptr) |
| 21536 | return ira->codegen->invalid_instruction; | 23097 | return ira->codegen->invalid_instruction; |
| | 23098 | if (err_union_val->special == ConstValSpecialUndef && initializing) { |
| | 23099 | ConstExprValue *vals = create_const_vals(2); |
| | 23100 | ConstExprValue *err_set_val = &vals[0]; |
| | 23101 | ConstExprValue *payload_val = &vals[1]; |
| | 23102 | |
| | 23103 | err_set_val->special = ConstValSpecialStatic; |
| | 23104 | err_set_val->type = type_entry->data.error_union.err_set_type; |
| | 23105 | err_set_val->data.x_err_set = nullptr; |
| | 23106 | |
| | 23107 | payload_val->special = ConstValSpecialUndef; |
| | 23108 | payload_val->type = payload_type; |
| | 23109 | |
| | 23110 | err_union_val->special = ConstValSpecialStatic; |
| | 23111 | err_union_val->data.x_err_union.error_set = err_set_val; |
| | 23112 | err_union_val->data.x_err_union.payload = payload_val; |
| | 23113 | } |
| | 23114 | |
| 21537 | if (err_union_val->special != ConstValSpecialRuntime) { | 23115 | if (err_union_val->special != ConstValSpecialRuntime) { |
| 21538 | ErrorTableEntry *err = err_union_val->data.x_err_union.error_set->data.x_err_set; | 23116 | ErrorTableEntry *err = err_union_val->data.x_err_union.error_set->data.x_err_set; |
| 21539 | if (err != nullptr) { | 23117 | if (err != nullptr) { |
| 21540 | ir_add_error(ira, &instruction->base, | 23118 | ir_add_error(ira, source_instr, |
| 21541 | buf_sprintf("caught unexpected error '%s'", buf_ptr(&err->name))); | 23119 | buf_sprintf("caught unexpected error '%s'", buf_ptr(&err->name))); |
| 21542 | return ira->codegen->invalid_instruction; | 23120 | return ira->codegen->invalid_instruction; |
| 21543 | } | 23121 | } |
| 21544 | | 23122 | |
| 21545 | IrInstruction *result = ir_const(ira, &instruction->base, result_type); | 23123 | IrInstruction *result; |
| | 23124 | if (ptr_val->data.x_ptr.mut == ConstPtrMutInfer) { |
| | 23125 | result = ir_build_unwrap_err_payload(&ira->new_irb, source_instr->scope, |
| | 23126 | source_instr->source_node, base_ptr, safety_check_on, initializing); |
| | 23127 | result->value.type = result_type; |
| | 23128 | result->value.special = ConstValSpecialStatic; |
| | 23129 | } else { |
| | 23130 | result = ir_const(ira, source_instr, result_type); |
| | 23131 | } |
| 21546 | result->value.data.x_ptr.special = ConstPtrSpecialRef; | 23132 | result->value.data.x_ptr.special = ConstPtrSpecialRef; |
| 21547 | result->value.data.x_ptr.data.ref.pointee = err_union_val->data.x_err_union.payload; | 23133 | result->value.data.x_ptr.data.ref.pointee = err_union_val->data.x_err_union.payload; |
| | 23134 | result->value.data.x_ptr.mut = ptr_val->data.x_ptr.mut; |
| 21548 | return result; | 23135 | return result; |
| 21549 | } | 23136 | } |
| 21550 | } | 23137 | } |
| 21551 | } | 23138 | } |
| 21552 | | 23139 | |
| 21553 | IrInstruction *result = ir_build_unwrap_err_payload(&ira->new_irb, | 23140 | IrInstruction *result = ir_build_unwrap_err_payload(&ira->new_irb, source_instr->scope, |
| 21554 | instruction->base.scope, instruction->base.source_node, value, instruction->safety_check_on); | 23141 | source_instr->source_node, base_ptr, safety_check_on, initializing); |
| 21555 | result->value.type = result_type; | 23142 | result->value.type = result_type; |
| 21556 | return result; | 23143 | return result; |
| 21557 | } | 23144 | } |
| 21558 | | 23145 | |
| | 23146 | static IrInstruction *ir_analyze_instruction_unwrap_err_payload(IrAnalyze *ira, |
| | 23147 | IrInstructionUnwrapErrPayload *instruction) |
| | 23148 | { |
| | 23149 | assert(instruction->value->child); |
| | 23150 | IrInstruction *value = instruction->value->child; |
| | 23151 | if (type_is_invalid(value->value.type)) |
| | 23152 | return ira->codegen->invalid_instruction; |
| | 23153 | |
| | 23154 | return ir_analyze_unwrap_error_payload(ira, &instruction->base, value, instruction->safety_check_on, false); |
| | 23155 | } |
| | 23156 | |
| 21559 | static IrInstruction *ir_analyze_instruction_fn_proto(IrAnalyze *ira, IrInstructionFnProto *instruction) { | 23157 | static IrInstruction *ir_analyze_instruction_fn_proto(IrAnalyze *ira, IrInstructionFnProto *instruction) { |
| 21560 | AstNode *proto_node = instruction->base.source_node; | 23158 | AstNode *proto_node = instruction->base.source_node; |
| 21561 | assert(proto_node->type == NodeTypeFnProto); | 23159 | assert(proto_node->type == NodeTypeFnProto); |
| ... | @@ -22047,14 +23645,19 @@ static IrInstruction *ir_analyze_ptr_cast(IrAnalyze *ira, IrInstruction *source_ | ... | @@ -22047,14 +23645,19 @@ static IrInstruction *ir_analyze_ptr_cast(IrAnalyze *ira, IrInstruction *source_ |
| 22047 | } | 23645 | } |
| 22048 | } | 23646 | } |
| 22049 | | 23647 | |
| 22050 | IrInstruction *result = ir_const(ira, source_instr, dest_type); | 23648 | IrInstruction *result; |
| | 23649 | if (ptr->value.data.x_ptr.mut == ConstPtrMutInfer) { |
| | 23650 | result = ir_build_ptr_cast_gen(ira, source_instr, dest_type, ptr, safety_check_on); |
| | 23651 | } else { |
| | 23652 | result = ir_const(ira, source_instr, dest_type); |
| | 23653 | } |
| 22051 | copy_const_val(&result->value, val, true); | 23654 | copy_const_val(&result->value, val, true); |
| 22052 | result->value.type = dest_type; | 23655 | result->value.type = dest_type; |
| 22053 | | 23656 | |
| 22054 | // Keep the bigger alignment, it can only help- | 23657 | // Keep the bigger alignment, it can only help- |
| 22055 | // unless the target is zero bits. | 23658 | // unless the target is zero bits. |
| 22056 | if (src_align_bytes > dest_align_bytes && type_has_bits(dest_type)) { | 23659 | if (src_align_bytes > dest_align_bytes && type_has_bits(dest_type)) { |
| 22057 | result = ir_align_cast(ira, result, src_align_bytes, false); | 23660 | result = ir_align_cast(ira, result, src_align_bytes, false); |
| 22058 | } | 23661 | } |
| 22059 | | 23662 | |
| 22060 | return result; | 23663 | return result; |
| ... | @@ -22138,6 +23741,8 @@ static void buf_write_value_bytes(CodeGen *codegen, uint8_t *buf, ConstExprValue | ... | @@ -22138,6 +23741,8 @@ static void buf_write_value_bytes(CodeGen *codegen, uint8_t *buf, ConstExprValue |
| 22138 | case ZigTypeIdUndefined: | 23741 | case ZigTypeIdUndefined: |
| 22139 | case ZigTypeIdNull: | 23742 | case ZigTypeIdNull: |
| 22140 | case ZigTypeIdPromise: | 23743 | case ZigTypeIdPromise: |
| | 23744 | case ZigTypeIdErrorUnion: |
| | 23745 | case ZigTypeIdErrorSet: |
| 22141 | zig_unreachable(); | 23746 | zig_unreachable(); |
| 22142 | case ZigTypeIdVoid: | 23747 | case ZigTypeIdVoid: |
| 22143 | return; | 23748 | return; |
| ... | @@ -22241,10 +23846,6 @@ static void buf_write_value_bytes(CodeGen *codegen, uint8_t *buf, ConstExprValue | ... | @@ -22241,10 +23846,6 @@ static void buf_write_value_bytes(CodeGen *codegen, uint8_t *buf, ConstExprValue |
| 22241 | } | 23846 | } |
| 22242 | case ZigTypeIdOptional: | 23847 | case ZigTypeIdOptional: |
| 22243 | zig_panic("TODO buf_write_value_bytes maybe type"); | 23848 | zig_panic("TODO buf_write_value_bytes maybe type"); |
| 22244 | case ZigTypeIdErrorUnion: | | |
| 22245 | zig_panic("TODO buf_write_value_bytes error union"); | | |
| 22246 | case ZigTypeIdErrorSet: | | |
| 22247 | zig_panic("TODO buf_write_value_bytes pure error type"); | | |
| 22248 | case ZigTypeIdFn: | 23849 | case ZigTypeIdFn: |
| 22249 | zig_panic("TODO buf_write_value_bytes fn type"); | 23850 | zig_panic("TODO buf_write_value_bytes fn type"); |
| 22250 | case ZigTypeIdUnion: | 23851 | case ZigTypeIdUnion: |
| ... | @@ -22433,28 +24034,6 @@ static Error buf_read_value_bytes(IrAnalyze *ira, CodeGen *codegen, AstNode *sou | ... | @@ -22433,28 +24034,6 @@ static Error buf_read_value_bytes(IrAnalyze *ira, CodeGen *codegen, AstNode *sou |
| 22433 | zig_unreachable(); | 24034 | zig_unreachable(); |
| 22434 | } | 24035 | } |
| 22435 | | 24036 | |
| 22436 | static bool type_can_bit_cast(ZigType *t) { | | |
| 22437 | switch (t->id) { | | |
| 22438 | case ZigTypeIdInvalid: | | |
| 22439 | zig_unreachable(); | | |
| 22440 | case ZigTypeIdMetaType: | | |
| 22441 | case ZigTypeIdOpaque: | | |
| 22442 | case ZigTypeIdBoundFn: | | |
| 22443 | case ZigTypeIdArgTuple: | | |
| 22444 | case ZigTypeIdUnreachable: | | |
| 22445 | case ZigTypeIdComptimeFloat: | | |
| 22446 | case ZigTypeIdComptimeInt: | | |
| 22447 | case ZigTypeIdEnumLiteral: | | |
| 22448 | case ZigTypeIdUndefined: | | |
| 22449 | case ZigTypeIdNull: | | |
| 22450 | case ZigTypeIdPointer: | | |
| 22451 | return false; | | |
| 22452 | default: | | |
| 22453 | // TODO list these types out explicitly, there are probably some other invalid ones here | | |
| 22454 | return true; | | |
| 22455 | } | | |
| 22456 | } | | |
| 22457 | | | |
| 22458 | static IrInstruction *ir_analyze_bit_cast(IrAnalyze *ira, IrInstruction *source_instr, IrInstruction *value, | 24037 | static IrInstruction *ir_analyze_bit_cast(IrAnalyze *ira, IrInstruction *source_instr, IrInstruction *value, |
| 22459 | ZigType *dest_type) | 24038 | ZigType *dest_type) |
| 22460 | { | 24039 | { |
| ... | @@ -22506,49 +24085,7 @@ static IrInstruction *ir_analyze_bit_cast(IrAnalyze *ira, IrInstruction *source_ | ... | @@ -22506,49 +24085,7 @@ static IrInstruction *ir_analyze_bit_cast(IrAnalyze *ira, IrInstruction *source_ |
| 22506 | return result; | 24085 | return result; |
| 22507 | } | 24086 | } |
| 22508 | | 24087 | |
| 22509 | IrInstruction *result = ir_build_bit_cast_gen(ira, source_instr, value, dest_type); | 24088 | return ir_build_bit_cast_gen(ira, source_instr, value, dest_type); |
| 22510 | if (handle_is_ptr(dest_type) && !handle_is_ptr(src_type)) { | | |
| 22511 | ir_add_alloca(ira, result, dest_type); | | |
| 22512 | } | | |
| 22513 | return result; | | |
| 22514 | } | | |
| 22515 | | | |
| 22516 | static IrInstruction *ir_analyze_instruction_bit_cast(IrAnalyze *ira, IrInstructionBitCast *instruction) { | | |
| 22517 | IrInstruction *dest_type_value = instruction->dest_type->child; | | |
| 22518 | ZigType *dest_type = ir_resolve_type(ira, dest_type_value); | | |
| 22519 | if (type_is_invalid(dest_type)) | | |
| 22520 | return ira->codegen->invalid_instruction; | | |
| 22521 | | | |
| 22522 | IrInstruction *value = instruction->value->child; | | |
| 22523 | ZigType *src_type = value->value.type; | | |
| 22524 | if (type_is_invalid(src_type)) | | |
| 22525 | return ira->codegen->invalid_instruction; | | |
| 22526 | | | |
| 22527 | if (get_codegen_ptr_type(src_type) != nullptr) { | | |
| 22528 | ir_add_error(ira, value, | | |
| 22529 | buf_sprintf("unable to @bitCast from pointer type '%s'", buf_ptr(&src_type->name))); | | |
| 22530 | return ira->codegen->invalid_instruction; | | |
| 22531 | } | | |
| 22532 | | | |
| 22533 | if (!type_can_bit_cast(src_type)) { | | |
| 22534 | ir_add_error(ira, dest_type_value, | | |
| 22535 | buf_sprintf("unable to @bitCast from type '%s'", buf_ptr(&src_type->name))); | | |
| 22536 | return ira->codegen->invalid_instruction; | | |
| 22537 | } | | |
| 22538 | | | |
| 22539 | if (get_codegen_ptr_type(dest_type) != nullptr) { | | |
| 22540 | ir_add_error(ira, dest_type_value, | | |
| 22541 | buf_sprintf("unable to @bitCast to pointer type '%s'", buf_ptr(&dest_type->name))); | | |
| 22542 | return ira->codegen->invalid_instruction; | | |
| 22543 | } | | |
| 22544 | | | |
| 22545 | if (!type_can_bit_cast(dest_type)) { | | |
| 22546 | ir_add_error(ira, dest_type_value, | | |
| 22547 | buf_sprintf("unable to @bitCast to type '%s'", buf_ptr(&dest_type->name))); | | |
| 22548 | return ira->codegen->invalid_instruction; | | |
| 22549 | } | | |
| 22550 | | | |
| 22551 | return ir_analyze_bit_cast(ira, &instruction->base, value, dest_type); | | |
| 22552 | } | 24089 | } |
| 22553 | | 24090 | |
| 22554 | static IrInstruction *ir_analyze_int_to_ptr(IrAnalyze *ira, IrInstruction *source_instr, IrInstruction *target, | 24091 | static IrInstruction *ir_analyze_int_to_ptr(IrAnalyze *ira, IrInstruction *source_instr, IrInstruction *target, |
| ... | @@ -22618,58 +24155,15 @@ static IrInstruction *ir_analyze_instruction_int_to_ptr(IrAnalyze *ira, IrInstru | ... | @@ -22618,58 +24155,15 @@ static IrInstruction *ir_analyze_instruction_int_to_ptr(IrAnalyze *ira, IrInstru |
| 22618 | static IrInstruction *ir_analyze_instruction_decl_ref(IrAnalyze *ira, | 24155 | static IrInstruction *ir_analyze_instruction_decl_ref(IrAnalyze *ira, |
| 22619 | IrInstructionDeclRef *instruction) | 24156 | IrInstructionDeclRef *instruction) |
| 22620 | { | 24157 | { |
| 22621 | Tld *tld = instruction->tld; | 24158 | IrInstruction *ref_instruction = ir_analyze_decl_ref(ira, &instruction->base, instruction->tld); |
| 22622 | LVal lval = instruction->lval; | 24159 | if (type_is_invalid(ref_instruction->value.type)) |
| 22623 | | | |
| 22624 | resolve_top_level_decl(ira->codegen, tld, instruction->base.source_node); | | |
| 22625 | if (tld->resolution == TldResolutionInvalid) | | |
| 22626 | return ira->codegen->invalid_instruction; | 24160 | return ira->codegen->invalid_instruction; |
| 22627 | | 24161 | |
| 22628 | switch (tld->id) { | 24162 | if (instruction->lval == LValPtr) { |
| 22629 | case TldIdContainer: | 24163 | return ref_instruction; |
| 22630 | case TldIdCompTime: | 24164 | } else { |
| 22631 | zig_unreachable(); | 24165 | return ir_get_deref(ira, &instruction->base, ref_instruction, nullptr); |
| 22632 | case TldIdVar: { | | |
| 22633 | TldVar *tld_var = (TldVar *)tld; | | |
| 22634 | ZigVar *var = tld_var->var; | | |
| 22635 | | | |
| 22636 | if (var == nullptr) { | | |
| 22637 | return ir_error_dependency_loop(ira, &instruction->base); | | |
| 22638 | } | | |
| 22639 | | | |
| 22640 | IrInstruction *var_ptr = ir_get_var_ptr(ira, &instruction->base, var); | | |
| 22641 | if (type_is_invalid(var_ptr->value.type)) | | |
| 22642 | return ira->codegen->invalid_instruction; | | |
| 22643 | | | |
| 22644 | if (tld_var->extern_lib_name != nullptr) { | | |
| 22645 | add_link_lib_symbol(ira, tld_var->extern_lib_name, &var->name, instruction->base.source_node); | | |
| 22646 | } | | |
| 22647 | | | |
| 22648 | if (lval == LValPtr) { | | |
| 22649 | return var_ptr; | | |
| 22650 | } else { | | |
| 22651 | return ir_get_deref(ira, &instruction->base, var_ptr); | | |
| 22652 | } | | |
| 22653 | } | | |
| 22654 | case TldIdFn: { | | |
| 22655 | TldFn *tld_fn = (TldFn *)tld; | | |
| 22656 | ZigFn *fn_entry = tld_fn->fn_entry; | | |
| 22657 | ir_assert(fn_entry->type_entry, &instruction->base); | | |
| 22658 | | | |
| 22659 | if (tld_fn->extern_lib_name != nullptr) { | | |
| 22660 | add_link_lib_symbol(ira, tld_fn->extern_lib_name, &fn_entry->symbol_name, instruction->base.source_node); | | |
| 22661 | } | | |
| 22662 | | | |
| 22663 | IrInstruction *ref_instruction = ir_create_const_fn(&ira->new_irb, instruction->base.scope, | | |
| 22664 | instruction->base.source_node, fn_entry); | | |
| 22665 | if (lval == LValPtr) { | | |
| 22666 | return ir_get_ref(ira, &instruction->base, ref_instruction, true, false); | | |
| 22667 | } else { | | |
| 22668 | return ref_instruction; | | |
| 22669 | } | | |
| 22670 | } | | |
| 22671 | } | 24166 | } |
| 22672 | zig_unreachable(); | | |
| 22673 | } | 24167 | } |
| 22674 | | 24168 | |
| 22675 | static IrInstruction *ir_analyze_instruction_ptr_to_int(IrAnalyze *ira, IrInstructionPtrToInt *instruction) { | 24169 | static IrInstruction *ir_analyze_instruction_ptr_to_int(IrAnalyze *ira, IrInstructionPtrToInt *instruction) { |
| ... | @@ -23183,7 +24677,7 @@ static IrInstruction *ir_analyze_instruction_atomic_load(IrAnalyze *ira, IrInstr | ... | @@ -23183,7 +24677,7 @@ static IrInstruction *ir_analyze_instruction_atomic_load(IrAnalyze *ira, IrInstr |
| 23183 | } | 24677 | } |
| 23184 | | 24678 | |
| 23185 | if (instr_is_comptime(casted_ptr)) { | 24679 | if (instr_is_comptime(casted_ptr)) { |
| 23186 | IrInstruction *result = ir_get_deref(ira, &instruction->base, casted_ptr); | 24680 | IrInstruction *result = ir_get_deref(ira, &instruction->base, casted_ptr, nullptr); |
| 23187 | ir_assert(result->value.type != nullptr, &instruction->base); | 24681 | ir_assert(result->value.type != nullptr, &instruction->base); |
| 23188 | return result; | 24682 | return result; |
| 23189 | } | 24683 | } |
| ... | @@ -23721,12 +25215,56 @@ static IrInstruction *ir_analyze_instruction_undeclared_ident(IrAnalyze *ira, Ir | ... | @@ -23721,12 +25215,56 @@ static IrInstruction *ir_analyze_instruction_undeclared_ident(IrAnalyze *ira, Ir |
| 23721 | return ira->codegen->invalid_instruction; | 25215 | return ira->codegen->invalid_instruction; |
| 23722 | } | 25216 | } |
| 23723 | | 25217 | |
| 23724 | static IrInstruction *ir_analyze_instruction_nocast(IrAnalyze *ira, IrInstruction *instruction) { | 25218 | static IrInstruction *ir_analyze_instruction_end_expr(IrAnalyze *ira, IrInstructionEndExpr *instruction) { |
| | 25219 | IrInstruction *value = instruction->value->child; |
| | 25220 | if (type_is_invalid(value->value.type)) |
| | 25221 | return ira->codegen->invalid_instruction; |
| | 25222 | |
| | 25223 | bool was_written = instruction->result_loc->written; |
| | 25224 | IrInstruction *result_loc = ir_resolve_result(ira, &instruction->base, instruction->result_loc, |
| | 25225 | value->value.type, value, false, false); |
| | 25226 | if (result_loc != nullptr) { |
| | 25227 | if (type_is_invalid(result_loc->value.type)) |
| | 25228 | return ira->codegen->invalid_instruction; |
| | 25229 | if (result_loc->value.type->id == ZigTypeIdUnreachable) |
| | 25230 | return result_loc; |
| | 25231 | |
| | 25232 | if (!was_written) { |
| | 25233 | IrInstruction *store_ptr = ir_analyze_store_ptr(ira, &instruction->base, result_loc, value); |
| | 25234 | if (type_is_invalid(store_ptr->value.type)) { |
| | 25235 | return ira->codegen->invalid_instruction; |
| | 25236 | } |
| | 25237 | } |
| | 25238 | |
| | 25239 | if (result_loc->value.data.x_ptr.mut == ConstPtrMutInfer) { |
| | 25240 | if (instr_is_comptime(value)) { |
| | 25241 | result_loc->value.data.x_ptr.mut = ConstPtrMutComptimeConst; |
| | 25242 | } else { |
| | 25243 | result_loc->value.special = ConstValSpecialRuntime; |
| | 25244 | } |
| | 25245 | } |
| | 25246 | } |
| | 25247 | |
| | 25248 | return ir_const_void(ira, &instruction->base); |
| | 25249 | } |
| | 25250 | |
| | 25251 | static IrInstruction *ir_analyze_instruction_bit_cast_src(IrAnalyze *ira, IrInstructionBitCastSrc *instruction) { |
| | 25252 | IrInstruction *operand = instruction->operand->child; |
| | 25253 | if (type_is_invalid(operand->value.type)) |
| | 25254 | return operand; |
| | 25255 | |
| | 25256 | IrInstruction *result_loc = ir_resolve_result(ira, &instruction->base, |
| | 25257 | &instruction->result_loc_bit_cast->base, operand->value.type, operand, false, false); |
| | 25258 | if (result_loc != nullptr && (type_is_invalid(result_loc->value.type) || instr_is_unreachable(result_loc))) |
| | 25259 | return result_loc; |
| | 25260 | |
| | 25261 | return instruction->result_loc_bit_cast->parent->gen_instruction; |
| | 25262 | } |
| | 25263 | |
| | 25264 | static IrInstruction *ir_analyze_instruction_base(IrAnalyze *ira, IrInstruction *instruction) { |
| 23725 | switch (instruction->id) { | 25265 | switch (instruction->id) { |
| 23726 | case IrInstructionIdInvalid: | 25266 | case IrInstructionIdInvalid: |
| 23727 | case IrInstructionIdWidenOrShorten: | 25267 | case IrInstructionIdWidenOrShorten: |
| 23728 | case IrInstructionIdStructInit: | | |
| 23729 | case IrInstructionIdUnionInit: | | |
| 23730 | case IrInstructionIdStructFieldPtr: | 25268 | case IrInstructionIdStructFieldPtr: |
| 23731 | case IrInstructionIdUnionFieldPtr: | 25269 | case IrInstructionIdUnionFieldPtr: |
| 23732 | case IrInstructionIdOptionalWrap: | 25270 | case IrInstructionIdOptionalWrap: |
| ... | @@ -23738,11 +25276,18 @@ static IrInstruction *ir_analyze_instruction_nocast(IrAnalyze *ira, IrInstructio | ... | @@ -23738,11 +25276,18 @@ static IrInstruction *ir_analyze_instruction_nocast(IrAnalyze *ira, IrInstructio |
| 23738 | case IrInstructionIdCmpxchgGen: | 25276 | case IrInstructionIdCmpxchgGen: |
| 23739 | case IrInstructionIdArrayToVector: | 25277 | case IrInstructionIdArrayToVector: |
| 23740 | case IrInstructionIdVectorToArray: | 25278 | case IrInstructionIdVectorToArray: |
| | 25279 | case IrInstructionIdPtrOfArrayToSlice: |
| 23741 | case IrInstructionIdAssertZero: | 25280 | case IrInstructionIdAssertZero: |
| 23742 | case IrInstructionIdAssertNonNull: | 25281 | case IrInstructionIdAssertNonNull: |
| 23743 | case IrInstructionIdResizeSlice: | 25282 | case IrInstructionIdResizeSlice: |
| 23744 | case IrInstructionIdLoadPtrGen: | 25283 | case IrInstructionIdLoadPtrGen: |
| 23745 | case IrInstructionIdBitCastGen: | 25284 | case IrInstructionIdBitCastGen: |
| | 25285 | case IrInstructionIdCallGen: |
| | 25286 | case IrInstructionIdReturnPtr: |
| | 25287 | case IrInstructionIdAllocaGen: |
| | 25288 | case IrInstructionIdSliceGen: |
| | 25289 | case IrInstructionIdRefGen: |
| | 25290 | case IrInstructionIdTestErrGen: |
| 23746 | zig_unreachable(); | 25291 | zig_unreachable(); |
| 23747 | | 25292 | |
| 23748 | case IrInstructionIdReturn: | 25293 | case IrInstructionIdReturn: |
| ... | @@ -23765,8 +25310,8 @@ static IrInstruction *ir_analyze_instruction_nocast(IrAnalyze *ira, IrInstructio | ... | @@ -23765,8 +25310,8 @@ static IrInstruction *ir_analyze_instruction_nocast(IrAnalyze *ira, IrInstructio |
| 23765 | return ir_analyze_instruction_var_ptr(ira, (IrInstructionVarPtr *)instruction); | 25310 | return ir_analyze_instruction_var_ptr(ira, (IrInstructionVarPtr *)instruction); |
| 23766 | case IrInstructionIdFieldPtr: | 25311 | case IrInstructionIdFieldPtr: |
| 23767 | return ir_analyze_instruction_field_ptr(ira, (IrInstructionFieldPtr *)instruction); | 25312 | return ir_analyze_instruction_field_ptr(ira, (IrInstructionFieldPtr *)instruction); |
| 23768 | case IrInstructionIdCall: | 25313 | case IrInstructionIdCallSrc: |
| 23769 | return ir_analyze_instruction_call(ira, (IrInstructionCall *)instruction); | 25314 | return ir_analyze_instruction_call(ira, (IrInstructionCallSrc *)instruction); |
| 23770 | case IrInstructionIdBr: | 25315 | case IrInstructionIdBr: |
| 23771 | return ir_analyze_instruction_br(ira, (IrInstructionBr *)instruction); | 25316 | return ir_analyze_instruction_br(ira, (IrInstructionBr *)instruction); |
| 23772 | case IrInstructionIdCondBr: | 25317 | case IrInstructionIdCondBr: |
| ... | @@ -23777,10 +25322,6 @@ static IrInstruction *ir_analyze_instruction_nocast(IrAnalyze *ira, IrInstructio | ... | @@ -23777,10 +25322,6 @@ static IrInstruction *ir_analyze_instruction_nocast(IrAnalyze *ira, IrInstructio |
| 23777 | return ir_analyze_instruction_phi(ira, (IrInstructionPhi *)instruction); | 25322 | return ir_analyze_instruction_phi(ira, (IrInstructionPhi *)instruction); |
| 23778 | case IrInstructionIdTypeOf: | 25323 | case IrInstructionIdTypeOf: |
| 23779 | return ir_analyze_instruction_typeof(ira, (IrInstructionTypeOf *)instruction); | 25324 | return ir_analyze_instruction_typeof(ira, (IrInstructionTypeOf *)instruction); |
| 23780 | case IrInstructionIdToPtrType: | | |
| 23781 | return ir_analyze_instruction_to_ptr_type(ira, (IrInstructionToPtrType *)instruction); | | |
| 23782 | case IrInstructionIdPtrTypeChild: | | |
| 23783 | return ir_analyze_instruction_ptr_type_child(ira, (IrInstructionPtrTypeChild *)instruction); | | |
| 23784 | case IrInstructionIdSetCold: | 25325 | case IrInstructionIdSetCold: |
| 23785 | return ir_analyze_instruction_set_cold(ira, (IrInstructionSetCold *)instruction); | 25326 | return ir_analyze_instruction_set_cold(ira, (IrInstructionSetCold *)instruction); |
| 23786 | case IrInstructionIdSetRuntimeSafety: | 25327 | case IrInstructionIdSetRuntimeSafety: |
| ... | @@ -23881,8 +25422,8 @@ static IrInstruction *ir_analyze_instruction_nocast(IrAnalyze *ira, IrInstructio | ... | @@ -23881,8 +25422,8 @@ static IrInstruction *ir_analyze_instruction_nocast(IrAnalyze *ira, IrInstructio |
| 23881 | return ir_analyze_instruction_memset(ira, (IrInstructionMemset *)instruction); | 25422 | return ir_analyze_instruction_memset(ira, (IrInstructionMemset *)instruction); |
| 23882 | case IrInstructionIdMemcpy: | 25423 | case IrInstructionIdMemcpy: |
| 23883 | return ir_analyze_instruction_memcpy(ira, (IrInstructionMemcpy *)instruction); | 25424 | return ir_analyze_instruction_memcpy(ira, (IrInstructionMemcpy *)instruction); |
| 23884 | case IrInstructionIdSlice: | 25425 | case IrInstructionIdSliceSrc: |
| 23885 | return ir_analyze_instruction_slice(ira, (IrInstructionSlice *)instruction); | 25426 | return ir_analyze_instruction_slice(ira, (IrInstructionSliceSrc *)instruction); |
| 23886 | case IrInstructionIdMemberCount: | 25427 | case IrInstructionIdMemberCount: |
| 23887 | return ir_analyze_instruction_member_count(ira, (IrInstructionMemberCount *)instruction); | 25428 | return ir_analyze_instruction_member_count(ira, (IrInstructionMemberCount *)instruction); |
| 23888 | case IrInstructionIdMemberType: | 25429 | case IrInstructionIdMemberType: |
| ... | @@ -23901,8 +25442,8 @@ static IrInstruction *ir_analyze_instruction_nocast(IrAnalyze *ira, IrInstructio | ... | @@ -23901,8 +25442,8 @@ static IrInstruction *ir_analyze_instruction_nocast(IrAnalyze *ira, IrInstructio |
| 23901 | return ir_analyze_instruction_align_of(ira, (IrInstructionAlignOf *)instruction); | 25442 | return ir_analyze_instruction_align_of(ira, (IrInstructionAlignOf *)instruction); |
| 23902 | case IrInstructionIdOverflowOp: | 25443 | case IrInstructionIdOverflowOp: |
| 23903 | return ir_analyze_instruction_overflow_op(ira, (IrInstructionOverflowOp *)instruction); | 25444 | return ir_analyze_instruction_overflow_op(ira, (IrInstructionOverflowOp *)instruction); |
| 23904 | case IrInstructionIdTestErr: | 25445 | case IrInstructionIdTestErrSrc: |
| 23905 | return ir_analyze_instruction_test_err(ira, (IrInstructionTestErr *)instruction); | 25446 | return ir_analyze_instruction_test_err(ira, (IrInstructionTestErrSrc *)instruction); |
| 23906 | case IrInstructionIdUnwrapErrCode: | 25447 | case IrInstructionIdUnwrapErrCode: |
| 23907 | return ir_analyze_instruction_unwrap_err_code(ira, (IrInstructionUnwrapErrCode *)instruction); | 25448 | return ir_analyze_instruction_unwrap_err_code(ira, (IrInstructionUnwrapErrCode *)instruction); |
| 23908 | case IrInstructionIdUnwrapErrPayload: | 25449 | case IrInstructionIdUnwrapErrPayload: |
| ... | @@ -23921,8 +25462,6 @@ static IrInstruction *ir_analyze_instruction_nocast(IrAnalyze *ira, IrInstructio | ... | @@ -23921,8 +25462,6 @@ static IrInstruction *ir_analyze_instruction_nocast(IrAnalyze *ira, IrInstructio |
| 23921 | return ir_analyze_instruction_panic(ira, (IrInstructionPanic *)instruction); | 25462 | return ir_analyze_instruction_panic(ira, (IrInstructionPanic *)instruction); |
| 23922 | case IrInstructionIdPtrCastSrc: | 25463 | case IrInstructionIdPtrCastSrc: |
| 23923 | return ir_analyze_instruction_ptr_cast(ira, (IrInstructionPtrCastSrc *)instruction); | 25464 | return ir_analyze_instruction_ptr_cast(ira, (IrInstructionPtrCastSrc *)instruction); |
| 23924 | case IrInstructionIdBitCast: | | |
| 23925 | return ir_analyze_instruction_bit_cast(ira, (IrInstructionBitCast *)instruction); | | |
| 23926 | case IrInstructionIdIntToPtr: | 25465 | case IrInstructionIdIntToPtr: |
| 23927 | return ir_analyze_instruction_int_to_ptr(ira, (IrInstructionIntToPtr *)instruction); | 25466 | return ir_analyze_instruction_int_to_ptr(ira, (IrInstructionIntToPtr *)instruction); |
| 23928 | case IrInstructionIdPtrToInt: | 25467 | case IrInstructionIdPtrToInt: |
| ... | @@ -23945,6 +25484,14 @@ static IrInstruction *ir_analyze_instruction_nocast(IrAnalyze *ira, IrInstructio | ... | @@ -23945,6 +25484,14 @@ static IrInstruction *ir_analyze_instruction_nocast(IrAnalyze *ira, IrInstructio |
| 23945 | return ir_analyze_instruction_ptr_type(ira, (IrInstructionPtrType *)instruction); | 25484 | return ir_analyze_instruction_ptr_type(ira, (IrInstructionPtrType *)instruction); |
| 23946 | case IrInstructionIdAlignCast: | 25485 | case IrInstructionIdAlignCast: |
| 23947 | return ir_analyze_instruction_align_cast(ira, (IrInstructionAlignCast *)instruction); | 25486 | return ir_analyze_instruction_align_cast(ira, (IrInstructionAlignCast *)instruction); |
| | 25487 | case IrInstructionIdImplicitCast: |
| | 25488 | return ir_analyze_instruction_implicit_cast(ira, (IrInstructionImplicitCast *)instruction); |
| | 25489 | case IrInstructionIdResolveResult: |
| | 25490 | return ir_analyze_instruction_resolve_result(ira, (IrInstructionResolveResult *)instruction); |
| | 25491 | case IrInstructionIdResetResult: |
| | 25492 | return ir_analyze_instruction_reset_result(ira, (IrInstructionResetResult *)instruction); |
| | 25493 | case IrInstructionIdResultPtr: |
| | 25494 | return ir_analyze_instruction_result_ptr(ira, (IrInstructionResultPtr *)instruction); |
| 23948 | case IrInstructionIdOpaqueType: | 25495 | case IrInstructionIdOpaqueType: |
| 23949 | return ir_analyze_instruction_opaque_type(ira, (IrInstructionOpaqueType *)instruction); | 25496 | return ir_analyze_instruction_opaque_type(ira, (IrInstructionOpaqueType *)instruction); |
| 23950 | case IrInstructionIdSetAlignStack: | 25497 | case IrInstructionIdSetAlignStack: |
| ... | @@ -24021,17 +25568,16 @@ static IrInstruction *ir_analyze_instruction_nocast(IrAnalyze *ira, IrInstructio | ... | @@ -24021,17 +25568,16 @@ static IrInstruction *ir_analyze_instruction_nocast(IrAnalyze *ira, IrInstructio |
| 24021 | return ir_analyze_instruction_has_decl(ira, (IrInstructionHasDecl *)instruction); | 25568 | return ir_analyze_instruction_has_decl(ira, (IrInstructionHasDecl *)instruction); |
| 24022 | case IrInstructionIdUndeclaredIdent: | 25569 | case IrInstructionIdUndeclaredIdent: |
| 24023 | return ir_analyze_instruction_undeclared_ident(ira, (IrInstructionUndeclaredIdent *)instruction); | 25570 | return ir_analyze_instruction_undeclared_ident(ira, (IrInstructionUndeclaredIdent *)instruction); |
| | 25571 | case IrInstructionIdAllocaSrc: |
| | 25572 | return nullptr; |
| | 25573 | case IrInstructionIdEndExpr: |
| | 25574 | return ir_analyze_instruction_end_expr(ira, (IrInstructionEndExpr *)instruction); |
| | 25575 | case IrInstructionIdBitCastSrc: |
| | 25576 | return ir_analyze_instruction_bit_cast_src(ira, (IrInstructionBitCastSrc *)instruction); |
| 24024 | } | 25577 | } |
| 24025 | zig_unreachable(); | 25578 | zig_unreachable(); |
| 24026 | } | 25579 | } |
| 24027 | | 25580 | |
| 24028 | static IrInstruction *ir_analyze_instruction(IrAnalyze *ira, IrInstruction *old_instruction) { | | |
| 24029 | IrInstruction *new_instruction = ir_analyze_instruction_nocast(ira, old_instruction); | | |
| 24030 | ir_assert(new_instruction->value.type != nullptr, old_instruction); | | |
| 24031 | old_instruction->child = new_instruction; | | |
| 24032 | return new_instruction; | | |
| 24033 | } | | |
| 24034 | | | |
| 24035 | // This function attempts to evaluate IR code while doing type checking and other analysis. | 25581 | // This function attempts to evaluate IR code while doing type checking and other analysis. |
| 24036 | // It emits a new IrExecutable which is partially evaluated IR code. | 25582 | // It emits a new IrExecutable which is partially evaluated IR code. |
| 24037 | ZigType *ir_analyze(CodeGen *codegen, IrExecutable *old_exec, IrExecutable *new_exec, | 25583 | ZigType *ir_analyze(CodeGen *codegen, IrExecutable *old_exec, IrExecutable *new_exec, |
| ... | @@ -24077,14 +25623,22 @@ ZigType *ir_analyze(CodeGen *codegen, IrExecutable *old_exec, IrExecutable *new_ | ... | @@ -24077,14 +25623,22 @@ ZigType *ir_analyze(CodeGen *codegen, IrExecutable *old_exec, IrExecutable *new_ |
| 24077 | continue; | 25623 | continue; |
| 24078 | } | 25624 | } |
| 24079 | | 25625 | |
| 24080 | IrInstruction *new_instruction = ir_analyze_instruction(ira, old_instruction); | 25626 | if (ira->codegen->verbose_ir) { |
| 24081 | if (type_is_invalid(new_instruction->value.type) && ir_should_inline(new_exec, old_instruction->scope)) { | 25627 | fprintf(stderr, "analyze #%zu\n", old_instruction->debug_id); |
| 24082 | return ira->codegen->builtin_types.entry_invalid; | | |
| 24083 | } | 25628 | } |
| | 25629 | IrInstruction *new_instruction = ir_analyze_instruction_base(ira, old_instruction); |
| | 25630 | if (new_instruction != nullptr) { |
| | 25631 | ir_assert(new_instruction->value.type != nullptr || new_instruction->value.type != nullptr, old_instruction); |
| | 25632 | old_instruction->child = new_instruction; |
| 24084 | | 25633 | |
| 24085 | // unreachable instructions do their own control flow. | 25634 | if (type_is_invalid(new_instruction->value.type)) { |
| 24086 | if (new_instruction->value.type->id == ZigTypeIdUnreachable) | 25635 | return ira->codegen->builtin_types.entry_invalid; |
| 24087 | continue; | 25636 | } |
| | 25637 | |
| | 25638 | // unreachable instructions do their own control flow. |
| | 25639 | if (new_instruction->value.type->id == ZigTypeIdUnreachable) |
| | 25640 | continue; |
| | 25641 | } |
| 24088 | | 25642 | |
| 24089 | ira->instruction_index += 1; | 25643 | ira->instruction_index += 1; |
| 24090 | } | 25644 | } |
| ... | @@ -24109,7 +25663,8 @@ bool ir_has_side_effects(IrInstruction *instruction) { | ... | @@ -24109,7 +25663,8 @@ bool ir_has_side_effects(IrInstruction *instruction) { |
| 24109 | case IrInstructionIdDeclVarSrc: | 25663 | case IrInstructionIdDeclVarSrc: |
| 24110 | case IrInstructionIdDeclVarGen: | 25664 | case IrInstructionIdDeclVarGen: |
| 24111 | case IrInstructionIdStorePtr: | 25665 | case IrInstructionIdStorePtr: |
| 24112 | case IrInstructionIdCall: | 25666 | case IrInstructionIdCallSrc: |
| | 25667 | case IrInstructionIdCallGen: |
| 24113 | case IrInstructionIdReturn: | 25668 | case IrInstructionIdReturn: |
| 24114 | case IrInstructionIdUnreachable: | 25669 | case IrInstructionIdUnreachable: |
| 24115 | case IrInstructionIdSetCold: | 25670 | case IrInstructionIdSetCold: |
| ... | @@ -24156,27 +25711,28 @@ bool ir_has_side_effects(IrInstruction *instruction) { | ... | @@ -24156,27 +25711,28 @@ bool ir_has_side_effects(IrInstruction *instruction) { |
| 24156 | case IrInstructionIdResizeSlice: | 25711 | case IrInstructionIdResizeSlice: |
| 24157 | case IrInstructionIdGlobalAsm: | 25712 | case IrInstructionIdGlobalAsm: |
| 24158 | case IrInstructionIdUndeclaredIdent: | 25713 | case IrInstructionIdUndeclaredIdent: |
| | 25714 | case IrInstructionIdEndExpr: |
| | 25715 | case IrInstructionIdPtrOfArrayToSlice: |
| | 25716 | case IrInstructionIdSliceGen: |
| | 25717 | case IrInstructionIdOptionalWrap: |
| | 25718 | case IrInstructionIdVectorToArray: |
| | 25719 | case IrInstructionIdResetResult: |
| 24159 | return true; | 25720 | return true; |
| 24160 | | 25721 | |
| 24161 | case IrInstructionIdPhi: | 25722 | case IrInstructionIdPhi: |
| 24162 | case IrInstructionIdUnOp: | 25723 | case IrInstructionIdUnOp: |
| 24163 | case IrInstructionIdBinOp: | 25724 | case IrInstructionIdBinOp: |
| 24164 | case IrInstructionIdLoadPtr: | 25725 | case IrInstructionIdLoadPtr: |
| 24165 | case IrInstructionIdLoadPtrGen: | | |
| 24166 | case IrInstructionIdConst: | 25726 | case IrInstructionIdConst: |
| 24167 | case IrInstructionIdCast: | 25727 | case IrInstructionIdCast: |
| 24168 | case IrInstructionIdContainerInitList: | 25728 | case IrInstructionIdContainerInitList: |
| 24169 | case IrInstructionIdContainerInitFields: | 25729 | case IrInstructionIdContainerInitFields: |
| 24170 | case IrInstructionIdStructInit: | | |
| 24171 | case IrInstructionIdUnionInit: | | |
| 24172 | case IrInstructionIdFieldPtr: | 25730 | case IrInstructionIdFieldPtr: |
| 24173 | case IrInstructionIdElemPtr: | 25731 | case IrInstructionIdElemPtr: |
| 24174 | case IrInstructionIdVarPtr: | 25732 | case IrInstructionIdVarPtr: |
| | 25733 | case IrInstructionIdReturnPtr: |
| 24175 | case IrInstructionIdTypeOf: | 25734 | case IrInstructionIdTypeOf: |
| 24176 | case IrInstructionIdToPtrType: | | |
| 24177 | case IrInstructionIdPtrTypeChild: | | |
| 24178 | case IrInstructionIdStructFieldPtr: | 25735 | case IrInstructionIdStructFieldPtr: |
| 24179 | case IrInstructionIdUnionFieldPtr: | | |
| 24180 | case IrInstructionIdArrayType: | 25736 | case IrInstructionIdArrayType: |
| 24181 | case IrInstructionIdPromiseType: | 25737 | case IrInstructionIdPromiseType: |
| 24182 | case IrInstructionIdSliceType: | 25738 | case IrInstructionIdSliceType: |
| ... | @@ -24198,7 +25754,7 @@ bool ir_has_side_effects(IrInstruction *instruction) { | ... | @@ -24198,7 +25754,7 @@ bool ir_has_side_effects(IrInstruction *instruction) { |
| 24198 | case IrInstructionIdIntType: | 25754 | case IrInstructionIdIntType: |
| 24199 | case IrInstructionIdVectorType: | 25755 | case IrInstructionIdVectorType: |
| 24200 | case IrInstructionIdBoolNot: | 25756 | case IrInstructionIdBoolNot: |
| 24201 | case IrInstructionIdSlice: | 25757 | case IrInstructionIdSliceSrc: |
| 24202 | case IrInstructionIdMemberCount: | 25758 | case IrInstructionIdMemberCount: |
| 24203 | case IrInstructionIdMemberType: | 25759 | case IrInstructionIdMemberType: |
| 24204 | case IrInstructionIdMemberName: | 25760 | case IrInstructionIdMemberName: |
| ... | @@ -24206,16 +25762,13 @@ bool ir_has_side_effects(IrInstruction *instruction) { | ... | @@ -24206,16 +25762,13 @@ bool ir_has_side_effects(IrInstruction *instruction) { |
| 24206 | case IrInstructionIdReturnAddress: | 25762 | case IrInstructionIdReturnAddress: |
| 24207 | case IrInstructionIdFrameAddress: | 25763 | case IrInstructionIdFrameAddress: |
| 24208 | case IrInstructionIdHandle: | 25764 | case IrInstructionIdHandle: |
| 24209 | case IrInstructionIdTestErr: | 25765 | case IrInstructionIdTestErrSrc: |
| 24210 | case IrInstructionIdUnwrapErrCode: | 25766 | case IrInstructionIdTestErrGen: |
| 24211 | case IrInstructionIdOptionalWrap: | | |
| 24212 | case IrInstructionIdErrWrapCode: | | |
| 24213 | case IrInstructionIdErrWrapPayload: | | |
| 24214 | case IrInstructionIdFnProto: | 25767 | case IrInstructionIdFnProto: |
| 24215 | case IrInstructionIdTestComptime: | 25768 | case IrInstructionIdTestComptime: |
| 24216 | case IrInstructionIdPtrCastSrc: | 25769 | case IrInstructionIdPtrCastSrc: |
| 24217 | case IrInstructionIdPtrCastGen: | 25770 | case IrInstructionIdPtrCastGen: |
| 24218 | case IrInstructionIdBitCast: | 25771 | case IrInstructionIdBitCastSrc: |
| 24219 | case IrInstructionIdBitCastGen: | 25772 | case IrInstructionIdBitCastGen: |
| 24220 | case IrInstructionIdWidenOrShorten: | 25773 | case IrInstructionIdWidenOrShorten: |
| 24221 | case IrInstructionIdPtrToInt: | 25774 | case IrInstructionIdPtrToInt: |
| ... | @@ -24233,6 +25786,8 @@ bool ir_has_side_effects(IrInstruction *instruction) { | ... | @@ -24233,6 +25786,8 @@ bool ir_has_side_effects(IrInstruction *instruction) { |
| 24233 | case IrInstructionIdTypeInfo: | 25786 | case IrInstructionIdTypeInfo: |
| 24234 | case IrInstructionIdTypeId: | 25787 | case IrInstructionIdTypeId: |
| 24235 | case IrInstructionIdAlignCast: | 25788 | case IrInstructionIdAlignCast: |
| | 25789 | case IrInstructionIdImplicitCast: |
| | 25790 | case IrInstructionIdResolveResult: |
| 24236 | case IrInstructionIdOpaqueType: | 25791 | case IrInstructionIdOpaqueType: |
| 24237 | case IrInstructionIdArgType: | 25792 | case IrInstructionIdArgType: |
| 24238 | case IrInstructionIdTagType: | 25793 | case IrInstructionIdTagType: |
| ... | @@ -24257,9 +25812,11 @@ bool ir_has_side_effects(IrInstruction *instruction) { | ... | @@ -24257,9 +25812,11 @@ bool ir_has_side_effects(IrInstruction *instruction) { |
| 24257 | case IrInstructionIdFromBytes: | 25812 | case IrInstructionIdFromBytes: |
| 24258 | case IrInstructionIdToBytes: | 25813 | case IrInstructionIdToBytes: |
| 24259 | case IrInstructionIdEnumToInt: | 25814 | case IrInstructionIdEnumToInt: |
| 24260 | case IrInstructionIdVectorToArray: | | |
| 24261 | case IrInstructionIdArrayToVector: | 25815 | case IrInstructionIdArrayToVector: |
| 24262 | case IrInstructionIdHasDecl: | 25816 | case IrInstructionIdHasDecl: |
| | 25817 | case IrInstructionIdAllocaSrc: |
| | 25818 | case IrInstructionIdAllocaGen: |
| | 25819 | case IrInstructionIdResultPtr: |
| 24263 | return false; | 25820 | return false; |
| 24264 | | 25821 | |
| 24265 | case IrInstructionIdAsm: | 25822 | case IrInstructionIdAsm: |
| ... | @@ -24271,8 +25828,21 @@ bool ir_has_side_effects(IrInstruction *instruction) { | ... | @@ -24271,8 +25828,21 @@ bool ir_has_side_effects(IrInstruction *instruction) { |
| 24271 | { | 25828 | { |
| 24272 | IrInstructionUnwrapErrPayload *unwrap_err_payload_instruction = | 25829 | IrInstructionUnwrapErrPayload *unwrap_err_payload_instruction = |
| 24273 | (IrInstructionUnwrapErrPayload *)instruction; | 25830 | (IrInstructionUnwrapErrPayload *)instruction; |
| 24274 | return unwrap_err_payload_instruction->safety_check_on; | 25831 | return unwrap_err_payload_instruction->safety_check_on || |
| | 25832 | unwrap_err_payload_instruction->initializing; |
| 24275 | } | 25833 | } |
| | 25834 | case IrInstructionIdUnwrapErrCode: |
| | 25835 | return reinterpret_cast<IrInstructionUnwrapErrCode *>(instruction)->initializing; |
| | 25836 | case IrInstructionIdUnionFieldPtr: |
| | 25837 | return reinterpret_cast<IrInstructionUnionFieldPtr *>(instruction)->initializing; |
| | 25838 | case IrInstructionIdErrWrapPayload: |
| | 25839 | return reinterpret_cast<IrInstructionErrWrapPayload *>(instruction)->result_loc != nullptr; |
| | 25840 | case IrInstructionIdErrWrapCode: |
| | 25841 | return reinterpret_cast<IrInstructionErrWrapCode *>(instruction)->result_loc != nullptr; |
| | 25842 | case IrInstructionIdLoadPtrGen: |
| | 25843 | return reinterpret_cast<IrInstructionLoadPtrGen *>(instruction)->result_loc != nullptr; |
| | 25844 | case IrInstructionIdRefGen: |
| | 25845 | return reinterpret_cast<IrInstructionRefGen *>(instruction)->result_loc != nullptr; |
| 24276 | } | 25846 | } |
| 24277 | zig_unreachable(); | 25847 | zig_unreachable(); |
| 24278 | } | 25848 | } |