| ... | ... | @@ -38,6 +38,7 @@ struct IrAnalyze { |
| 38 | 38 | ZigType *explicit_return_type; |
| 39 | 39 | AstNode *explicit_return_type_source_node; |
| 40 | 40 | ZigList<IrInstruction *> src_implicit_return_type_list; |
| 41 | ZigList<IrSuspendPosition> resume_stack; |
| 41 | 42 | IrBasicBlock *const_predecessor_bb; |
| 42 | 43 | }; |
| 43 | 44 | |
| ... | ... | @@ -157,16 +158,19 @@ enum UndefAllowed { |
| 157 | 158 | }; |
| 158 | 159 | |
| 159 | 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_analyze_instruction(IrAnalyze *ira, IrInstruction *instruction); |
| 161 | static IrInstruction *ir_gen_node_extra(IrBuilder *irb, AstNode *node, Scope *scope, LVal lval, |
| 162 | ResultLoc *result_loc); |
| 162 | 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 | 166 | static ErrorMsg *exec_add_error_node(CodeGen *codegen, IrExecutable *exec, AstNode *source_node, Buf *msg); |
| 165 | 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 | 170 | static IrInstruction *ir_get_var_ptr(IrAnalyze *ira, IrInstruction *instruction, ZigVar *var); |
| 168 | 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 | 174 | static ZigType *adjust_ptr_align(CodeGen *g, ZigType *ptr_type, uint32_t new_align); |
| 171 | 175 | static ZigType *adjust_slice_align(CodeGen *g, ZigType *slice_type, uint32_t new_align); |
| 172 | 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 | 182 | static ConstExprValue *ir_resolve_const(IrAnalyze *ira, IrInstruction *value, UndefAllowed undef_allowed); |
| 179 | 183 | static void copy_const_val(ConstExprValue *dest, ConstExprValue *src, bool same_global_refs); |
| 180 | 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 | 185 | static IrInstruction *ir_analyze_int_to_ptr(IrAnalyze *ira, IrInstruction *source_instr, IrInstruction *target, |
| 183 | 186 | ZigType *ptr_type); |
| 184 | 187 | static IrInstruction *ir_analyze_bit_cast(IrAnalyze *ira, IrInstruction *source_instr, IrInstruction *value, |
| 185 | 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 | 202 | static ConstExprValue *const_ptr_pointee_unchecked(CodeGen *g, ConstExprValue *const_val) { |
| 188 | 203 | assert(get_src_ptr_type(const_val->type) != nullptr); |
| 189 | 204 | assert(const_val->special == ConstValSpecialStatic); |
| 190 | 205 | ConstExprValue *result; |
| 191 | | |
| 206 | |
| 192 | 207 | switch (type_has_one_possible_value(g, const_val->type->data.pointer.child_type)) { |
| 193 | 208 | case OnePossibleValueInvalid: |
| 194 | 209 | zig_unreachable(); |
| ... | ... | @@ -200,7 +215,7 @@ static ConstExprValue *const_ptr_pointee_unchecked(CodeGen *g, ConstExprValue *c |
| 200 | 215 | case OnePossibleValueNo: |
| 201 | 216 | break; |
| 202 | 217 | } |
| 203 | | |
| 218 | |
| 204 | 219 | switch (const_val->data.x_ptr.special) { |
| 205 | 220 | case ConstPtrSpecialInvalid: |
| 206 | 221 | zig_unreachable(); |
| ... | ... | @@ -246,6 +261,15 @@ static bool is_opt_err_set(ZigType *ty) { |
| 246 | 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 | 273 | // This function returns true when you can change the type of a ConstExprValue and the |
| 250 | 274 | // value remains meaningful. |
| 251 | 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 | 306 | return a->data.floating.bit_count == b->data.floating.bit_count; |
| 283 | 307 | case ZigTypeIdInt: |
| 284 | 308 | return a->data.integral.is_signed == b->data.integral.is_signed; |
| 285 | | case ZigTypeIdArray: |
| 286 | 309 | case ZigTypeIdStruct: |
| 310 | return is_slice(a) && is_slice(b); |
| 311 | case ZigTypeIdArray: |
| 287 | 312 | case ZigTypeIdOptional: |
| 288 | 313 | case ZigTypeIdErrorUnion: |
| 289 | 314 | case ZigTypeIdEnum: |
| ... | ... | @@ -386,6 +411,7 @@ static IrBasicBlock *ir_create_basic_block(IrBuilder *irb, Scope *scope, const c |
| 386 | 411 | result->scope = scope; |
| 387 | 412 | result->name_hint = name_hint; |
| 388 | 413 | result->debug_id = exec_next_debug_id(irb->exec); |
| 414 | result->index = SIZE_MAX; // set later |
| 389 | 415 | return result; |
| 390 | 416 | } |
| 391 | 417 | |
| ... | ... | @@ -475,8 +501,16 @@ static constexpr IrInstructionId ir_instruction_id(IrInstructionVarPtr *) { |
| 475 | 501 | return IrInstructionIdVarPtr; |
| 476 | 502 | } |
| 477 | 503 | |
| 478 | | static constexpr IrInstructionId ir_instruction_id(IrInstructionCall *) { |
| 479 | | return IrInstructionIdCall; |
| 504 | static constexpr IrInstructionId ir_instruction_id(IrInstructionReturnPtr *) { |
| 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 | 516 | static constexpr IrInstructionId ir_instruction_id(IrInstructionConst *) { |
| ... | ... | @@ -511,14 +545,6 @@ static constexpr IrInstructionId ir_instruction_id(IrInstructionTypeOf *) { |
| 511 | 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 | 548 | static constexpr IrInstructionId ir_instruction_id(IrInstructionSetCold *) { |
| 523 | 549 | return IrInstructionIdSetCold; |
| 524 | 550 | } |
| ... | ... | @@ -611,12 +637,8 @@ static constexpr IrInstructionId ir_instruction_id(IrInstructionRef *) { |
| 611 | 637 | return IrInstructionIdRef; |
| 612 | 638 | } |
| 613 | 639 | |
| 614 | | static constexpr IrInstructionId ir_instruction_id(IrInstructionStructInit *) { |
| 615 | | return IrInstructionIdStructInit; |
| 616 | | } |
| 617 | | |
| 618 | | static constexpr IrInstructionId ir_instruction_id(IrInstructionUnionInit *) { |
| 619 | | return IrInstructionIdUnionInit; |
| 640 | static constexpr IrInstructionId ir_instruction_id(IrInstructionRefGen *) { |
| 641 | return IrInstructionIdRefGen; |
| 620 | 642 | } |
| 621 | 643 | |
| 622 | 644 | static constexpr IrInstructionId ir_instruction_id(IrInstructionCompileErr *) { |
| ... | ... | @@ -703,8 +725,12 @@ static constexpr IrInstructionId ir_instruction_id(IrInstructionMemcpy *) { |
| 703 | 725 | return IrInstructionIdMemcpy; |
| 704 | 726 | } |
| 705 | 727 | |
| 706 | | static constexpr IrInstructionId ir_instruction_id(IrInstructionSlice *) { |
| 707 | | return IrInstructionIdSlice; |
| 728 | static constexpr IrInstructionId ir_instruction_id(IrInstructionSliceSrc *) { |
| 729 | return IrInstructionIdSliceSrc; |
| 730 | } |
| 731 | |
| 732 | static constexpr IrInstructionId ir_instruction_id(IrInstructionSliceGen *) { |
| 733 | return IrInstructionIdSliceGen; |
| 708 | 734 | } |
| 709 | 735 | |
| 710 | 736 | static constexpr IrInstructionId ir_instruction_id(IrInstructionMemberCount *) { |
| ... | ... | @@ -743,8 +769,16 @@ static constexpr IrInstructionId ir_instruction_id(IrInstructionOverflowOp *) { |
| 743 | 769 | return IrInstructionIdOverflowOp; |
| 744 | 770 | } |
| 745 | 771 | |
| 746 | | static constexpr IrInstructionId ir_instruction_id(IrInstructionTestErr *) { |
| 747 | | return IrInstructionIdTestErr; |
| 772 | static constexpr IrInstructionId ir_instruction_id(IrInstructionTestErrSrc *) { |
| 773 | return IrInstructionIdTestErrSrc; |
| 774 | } |
| 775 | |
| 776 | static constexpr IrInstructionId ir_instruction_id(IrInstructionTestErrGen *) { |
| 777 | return IrInstructionIdTestErrGen; |
| 778 | } |
| 779 | |
| 780 | static constexpr IrInstructionId ir_instruction_id(IrInstructionMulAdd *) { |
| 781 | return IrInstructionIdMulAdd; |
| 748 | 782 | } |
| 749 | 783 | |
| 750 | 784 | static constexpr IrInstructionId ir_instruction_id(IrInstructionUnwrapErrCode *) { |
| ... | ... | @@ -783,8 +817,8 @@ static constexpr IrInstructionId ir_instruction_id(IrInstructionPtrCastGen *) { |
| 783 | 817 | return IrInstructionIdPtrCastGen; |
| 784 | 818 | } |
| 785 | 819 | |
| 786 | | static constexpr IrInstructionId ir_instruction_id(IrInstructionBitCast *) { |
| 787 | | return IrInstructionIdBitCast; |
| 820 | static constexpr IrInstructionId ir_instruction_id(IrInstructionBitCastSrc *) { |
| 821 | return IrInstructionIdBitCastSrc; |
| 788 | 822 | } |
| 789 | 823 | |
| 790 | 824 | static constexpr IrInstructionId ir_instruction_id(IrInstructionBitCastGen *) { |
| ... | ... | @@ -879,6 +913,26 @@ static constexpr IrInstructionId ir_instruction_id(IrInstructionAlignCast *) { |
| 879 | 913 | return IrInstructionIdAlignCast; |
| 880 | 914 | } |
| 881 | 915 | |
| 916 | static constexpr IrInstructionId ir_instruction_id(IrInstructionImplicitCast *) { |
| 917 | return IrInstructionIdImplicitCast; |
| 918 | } |
| 919 | |
| 920 | static constexpr IrInstructionId ir_instruction_id(IrInstructionResolveResult *) { |
| 921 | return IrInstructionIdResolveResult; |
| 922 | } |
| 923 | |
| 924 | static constexpr IrInstructionId ir_instruction_id(IrInstructionResetResult *) { |
| 925 | return IrInstructionIdResetResult; |
| 926 | } |
| 927 | |
| 928 | static constexpr IrInstructionId ir_instruction_id(IrInstructionResultPtr *) { |
| 929 | return IrInstructionIdResultPtr; |
| 930 | } |
| 931 | |
| 932 | static constexpr IrInstructionId ir_instruction_id(IrInstructionPtrOfArrayToSlice *) { |
| 933 | return IrInstructionIdPtrOfArrayToSlice; |
| 934 | } |
| 935 | |
| 882 | 936 | static constexpr IrInstructionId ir_instruction_id(IrInstructionOpaqueType *) { |
| 883 | 937 | return IrInstructionIdOpaqueType; |
| 884 | 938 | } |
| ... | ... | @@ -987,8 +1041,8 @@ static constexpr IrInstructionId ir_instruction_id(IrInstructionMarkErrRetTraceP |
| 987 | 1041 | return IrInstructionIdMarkErrRetTracePtr; |
| 988 | 1042 | } |
| 989 | 1043 | |
| 990 | | static constexpr IrInstructionId ir_instruction_id(IrInstructionSqrt *) { |
| 991 | | return IrInstructionIdSqrt; |
| 1044 | static constexpr IrInstructionId ir_instruction_id(IrInstructionFloatOp *) { |
| 1045 | return IrInstructionIdFloatOp; |
| 992 | 1046 | } |
| 993 | 1047 | |
| 994 | 1048 | static constexpr IrInstructionId ir_instruction_id(IrInstructionCheckRuntimeScope *) { |
| ... | ... | @@ -1019,6 +1073,18 @@ static constexpr IrInstructionId ir_instruction_id(IrInstructionUndeclaredIdent |
| 1019 | 1073 | return IrInstructionIdUndeclaredIdent; |
| 1020 | 1074 | } |
| 1021 | 1075 | |
| 1076 | static constexpr IrInstructionId ir_instruction_id(IrInstructionAllocaSrc *) { |
| 1077 | return IrInstructionIdAllocaSrc; |
| 1078 | } |
| 1079 | |
| 1080 | static constexpr IrInstructionId ir_instruction_id(IrInstructionAllocaGen *) { |
| 1081 | return IrInstructionIdAllocaGen; |
| 1082 | } |
| 1083 | |
| 1084 | static constexpr IrInstructionId ir_instruction_id(IrInstructionEndExpr *) { |
| 1085 | return IrInstructionIdEndExpr; |
| 1086 | } |
| 1087 | |
| 1022 | 1088 | template<typename T> |
| 1023 | 1089 | static T *ir_create_instruction(IrBuilder *irb, Scope *scope, AstNode *source_node) { |
| 1024 | 1090 | T *special_instruction = allocate<T>(1); |
| ... | ... | @@ -1070,13 +1136,15 @@ static IrInstruction *ir_build_cond_br(IrBuilder *irb, Scope *scope, AstNode *so |
| 1070 | 1136 | return &cond_br_instruction->base; |
| 1071 | 1137 | } |
| 1072 | 1138 | |
| 1073 | | static IrInstruction *ir_build_return(IrBuilder *irb, Scope *scope, AstNode *source_node, IrInstruction *return_value) { |
| 1139 | static IrInstruction *ir_build_return(IrBuilder *irb, Scope *scope, AstNode *source_node, |
| 1140 | IrInstruction *return_value) |
| 1141 | { |
| 1074 | 1142 | IrInstructionReturn *return_instruction = ir_build_instruction<IrInstructionReturn>(irb, scope, source_node); |
| 1075 | 1143 | return_instruction->base.value.type = irb->codegen->builtin_types.entry_unreachable; |
| 1076 | 1144 | return_instruction->base.value.special = ConstValSpecialStatic; |
| 1077 | 1145 | return_instruction->value = return_value; |
| 1078 | 1146 | |
| 1079 | | ir_ref_instruction(return_value, irb->current_basic_block); |
| 1147 | if (return_value != nullptr) ir_ref_instruction(return_value, irb->current_basic_block); |
| 1080 | 1148 | |
| 1081 | 1149 | return &return_instruction->base; |
| 1082 | 1150 | } |
| ... | ... | @@ -1254,17 +1322,27 @@ static IrInstruction *ir_build_var_ptr(IrBuilder *irb, Scope *scope, AstNode *so |
| 1254 | 1322 | return ir_build_var_ptr_x(irb, scope, source_node, var, nullptr); |
| 1255 | 1323 | } |
| 1256 | 1324 | |
| 1257 | | static IrInstruction *ir_build_elem_ptr(IrBuilder *irb, Scope *scope, AstNode *source_node, IrInstruction *array_ptr, |
| 1258 | | IrInstruction *elem_index, bool safety_check_on, PtrLen ptr_len) |
| 1325 | static IrInstruction *ir_build_return_ptr(IrAnalyze *ira, IrInstruction *source_instruction, ZigType *ty) { |
| 1326 | IrInstructionReturnPtr *instruction = ir_build_instruction<IrInstructionReturnPtr>(&ira->new_irb, |
| 1327 | source_instruction->scope, source_instruction->source_node); |
| 1328 | instruction->base.value.type = ty; |
| 1329 | return &instruction->base; |
| 1330 | } |
| 1331 | |
| 1332 | static IrInstruction *ir_build_elem_ptr(IrBuilder *irb, Scope *scope, AstNode *source_node, |
| 1333 | IrInstruction *array_ptr, IrInstruction *elem_index, bool safety_check_on, PtrLen ptr_len, |
| 1334 | IrInstruction *init_array_type) |
| 1259 | 1335 | { |
| 1260 | 1336 | IrInstructionElemPtr *instruction = ir_build_instruction<IrInstructionElemPtr>(irb, scope, source_node); |
| 1261 | 1337 | instruction->array_ptr = array_ptr; |
| 1262 | 1338 | instruction->elem_index = elem_index; |
| 1263 | 1339 | instruction->safety_check_on = safety_check_on; |
| 1264 | 1340 | instruction->ptr_len = ptr_len; |
| 1341 | instruction->init_array_type = init_array_type; |
| 1265 | 1342 | |
| 1266 | 1343 | ir_ref_instruction(array_ptr, irb->current_basic_block); |
| 1267 | 1344 | ir_ref_instruction(elem_index, irb->current_basic_block); |
| 1345 | if (init_array_type != nullptr) ir_ref_instruction(init_array_type, irb->current_basic_block); |
| 1268 | 1346 | |
| 1269 | 1347 | return &instruction->base; |
| 1270 | 1348 | } |
| ... | ... | @@ -1284,12 +1362,13 @@ static IrInstruction *ir_build_field_ptr_instruction(IrBuilder *irb, Scope *scop |
| 1284 | 1362 | } |
| 1285 | 1363 | |
| 1286 | 1364 | static IrInstruction *ir_build_field_ptr(IrBuilder *irb, Scope *scope, AstNode *source_node, |
| 1287 | | IrInstruction *container_ptr, Buf *field_name) |
| 1365 | IrInstruction *container_ptr, Buf *field_name, bool initializing) |
| 1288 | 1366 | { |
| 1289 | 1367 | IrInstructionFieldPtr *instruction = ir_build_instruction<IrInstructionFieldPtr>(irb, scope, source_node); |
| 1290 | 1368 | instruction->container_ptr = container_ptr; |
| 1291 | 1369 | instruction->field_name_buffer = field_name; |
| 1292 | 1370 | instruction->field_name_expr = nullptr; |
| 1371 | instruction->initializing = initializing; |
| 1293 | 1372 | |
| 1294 | 1373 | ir_ref_instruction(container_ptr, irb->current_basic_block); |
| 1295 | 1374 | |
| ... | ... | @@ -1309,9 +1388,11 @@ static IrInstruction *ir_build_struct_field_ptr(IrBuilder *irb, Scope *scope, As |
| 1309 | 1388 | } |
| 1310 | 1389 | |
| 1311 | 1390 | static IrInstruction *ir_build_union_field_ptr(IrBuilder *irb, Scope *scope, AstNode *source_node, |
| 1312 | | IrInstruction *union_ptr, TypeUnionField *field) |
| 1391 | IrInstruction *union_ptr, TypeUnionField *field, bool safety_check_on, bool initializing) |
| 1313 | 1392 | { |
| 1314 | 1393 | IrInstructionUnionFieldPtr *instruction = ir_build_instruction<IrInstructionUnionFieldPtr>(irb, scope, source_node); |
| 1394 | instruction->initializing = initializing; |
| 1395 | instruction->safety_check_on = safety_check_on; |
| 1315 | 1396 | instruction->union_ptr = union_ptr; |
| 1316 | 1397 | instruction->field = field; |
| 1317 | 1398 | |
| ... | ... | @@ -1320,12 +1401,12 @@ static IrInstruction *ir_build_union_field_ptr(IrBuilder *irb, Scope *scope, Ast |
| 1320 | 1401 | return &instruction->base; |
| 1321 | 1402 | } |
| 1322 | 1403 | |
| 1323 | | static IrInstruction *ir_build_call(IrBuilder *irb, Scope *scope, AstNode *source_node, |
| 1404 | static IrInstruction *ir_build_call_src(IrBuilder *irb, Scope *scope, AstNode *source_node, |
| 1324 | 1405 | ZigFn *fn_entry, IrInstruction *fn_ref, size_t arg_count, IrInstruction **args, |
| 1325 | 1406 | bool is_comptime, FnInline fn_inline, bool is_async, IrInstruction *async_allocator, |
| 1326 | | IrInstruction *new_stack) |
| 1407 | IrInstruction *new_stack, ResultLoc *result_loc) |
| 1327 | 1408 | { |
| 1328 | | IrInstructionCall *call_instruction = ir_build_instruction<IrInstructionCall>(irb, scope, source_node); |
| 1409 | IrInstructionCallSrc *call_instruction = ir_build_instruction<IrInstructionCallSrc>(irb, scope, source_node); |
| 1329 | 1410 | call_instruction->fn_entry = fn_entry; |
| 1330 | 1411 | call_instruction->fn_ref = fn_ref; |
| 1331 | 1412 | call_instruction->is_comptime = is_comptime; |
| ... | ... | @@ -1335,6 +1416,7 @@ static IrInstruction *ir_build_call(IrBuilder *irb, Scope *scope, AstNode *sourc |
| 1335 | 1416 | call_instruction->is_async = is_async; |
| 1336 | 1417 | call_instruction->async_allocator = async_allocator; |
| 1337 | 1418 | call_instruction->new_stack = new_stack; |
| 1419 | call_instruction->result_loc = result_loc; |
| 1338 | 1420 | |
| 1339 | 1421 | if (fn_ref != nullptr) ir_ref_instruction(fn_ref, irb->current_basic_block); |
| 1340 | 1422 | for (size_t i = 0; i < arg_count; i += 1) |
| ... | ... | @@ -1345,8 +1427,37 @@ static IrInstruction *ir_build_call(IrBuilder *irb, Scope *scope, AstNode *sourc |
| 1345 | 1427 | return &call_instruction->base; |
| 1346 | 1428 | } |
| 1347 | 1429 | |
| 1430 | static IrInstruction *ir_build_call_gen(IrAnalyze *ira, IrInstruction *source_instruction, |
| 1431 | ZigFn *fn_entry, IrInstruction *fn_ref, size_t arg_count, IrInstruction **args, |
| 1432 | FnInline fn_inline, bool is_async, IrInstruction *async_allocator, IrInstruction *new_stack, |
| 1433 | IrInstruction *result_loc, ZigType *return_type) |
| 1434 | { |
| 1435 | IrInstructionCallGen *call_instruction = ir_build_instruction<IrInstructionCallGen>(&ira->new_irb, |
| 1436 | source_instruction->scope, source_instruction->source_node); |
| 1437 | call_instruction->base.value.type = return_type; |
| 1438 | call_instruction->fn_entry = fn_entry; |
| 1439 | call_instruction->fn_ref = fn_ref; |
| 1440 | call_instruction->fn_inline = fn_inline; |
| 1441 | call_instruction->args = args; |
| 1442 | call_instruction->arg_count = arg_count; |
| 1443 | call_instruction->is_async = is_async; |
| 1444 | call_instruction->async_allocator = async_allocator; |
| 1445 | call_instruction->new_stack = new_stack; |
| 1446 | call_instruction->result_loc = result_loc; |
| 1447 | |
| 1448 | if (fn_ref != nullptr) ir_ref_instruction(fn_ref, ira->new_irb.current_basic_block); |
| 1449 | for (size_t i = 0; i < arg_count; i += 1) |
| 1450 | ir_ref_instruction(args[i], ira->new_irb.current_basic_block); |
| 1451 | if (async_allocator != nullptr) ir_ref_instruction(async_allocator, ira->new_irb.current_basic_block); |
| 1452 | if (new_stack != nullptr) ir_ref_instruction(new_stack, ira->new_irb.current_basic_block); |
| 1453 | if (result_loc != nullptr) ir_ref_instruction(result_loc, ira->new_irb.current_basic_block); |
| 1454 | |
| 1455 | return &call_instruction->base; |
| 1456 | } |
| 1457 | |
| 1348 | 1458 | static IrInstruction *ir_build_phi(IrBuilder *irb, Scope *scope, AstNode *source_node, |
| 1349 | | size_t incoming_count, IrBasicBlock **incoming_blocks, IrInstruction **incoming_values) |
| 1459 | size_t incoming_count, IrBasicBlock **incoming_blocks, IrInstruction **incoming_values, |
| 1460 | ResultLocPeerParent *peer_parent) |
| 1350 | 1461 | { |
| 1351 | 1462 | assert(incoming_count != 0); |
| 1352 | 1463 | assert(incoming_count != SIZE_MAX); |
| ... | ... | @@ -1355,6 +1466,7 @@ static IrInstruction *ir_build_phi(IrBuilder *irb, Scope *scope, AstNode *source |
| 1355 | 1466 | phi_instruction->incoming_count = incoming_count; |
| 1356 | 1467 | phi_instruction->incoming_blocks = incoming_blocks; |
| 1357 | 1468 | phi_instruction->incoming_values = incoming_values; |
| 1469 | phi_instruction->peer_parent = peer_parent; |
| 1358 | 1470 | |
| 1359 | 1471 | for (size_t i = 0; i < incoming_count; i += 1) { |
| 1360 | 1472 | ir_ref_bb(incoming_blocks[i]); |
| ... | ... | @@ -1408,12 +1520,13 @@ static IrInstruction *ir_build_ptr_type(IrBuilder *irb, Scope *scope, AstNode *s |
| 1408 | 1520 | } |
| 1409 | 1521 | |
| 1410 | 1522 | static IrInstruction *ir_build_un_op_lval(IrBuilder *irb, Scope *scope, AstNode *source_node, IrUnOp op_id, |
| 1411 | | IrInstruction *value, LVal lval) |
| 1523 | IrInstruction *value, LVal lval, ResultLoc *result_loc) |
| 1412 | 1524 | { |
| 1413 | 1525 | IrInstructionUnOp *instruction = ir_build_instruction<IrInstructionUnOp>(irb, scope, source_node); |
| 1414 | 1526 | instruction->op_id = op_id; |
| 1415 | 1527 | instruction->value = value; |
| 1416 | 1528 | instruction->lval = lval; |
| 1529 | instruction->result_loc = result_loc; |
| 1417 | 1530 | |
| 1418 | 1531 | ir_ref_instruction(value, irb->current_basic_block); |
| 1419 | 1532 | |
| ... | ... | @@ -1423,72 +1536,49 @@ static IrInstruction *ir_build_un_op_lval(IrBuilder *irb, Scope *scope, AstNode |
| 1423 | 1536 | static IrInstruction *ir_build_un_op(IrBuilder *irb, Scope *scope, AstNode *source_node, IrUnOp op_id, |
| 1424 | 1537 | IrInstruction *value) |
| 1425 | 1538 | { |
| 1426 | | return ir_build_un_op_lval(irb, scope, source_node, op_id, value, LValNone); |
| 1539 | return ir_build_un_op_lval(irb, scope, source_node, op_id, value, LValNone, nullptr); |
| 1427 | 1540 | } |
| 1428 | 1541 | |
| 1429 | 1542 | static IrInstruction *ir_build_container_init_list(IrBuilder *irb, Scope *scope, AstNode *source_node, |
| 1430 | | IrInstruction *container_type, IrInstruction *elem_type, size_t item_count, IrInstruction **items) |
| 1543 | IrInstruction *container_type, size_t item_count, IrInstruction **elem_result_loc_list, |
| 1544 | IrInstruction *result_loc) |
| 1431 | 1545 | { |
| 1432 | 1546 | IrInstructionContainerInitList *container_init_list_instruction = |
| 1433 | 1547 | ir_build_instruction<IrInstructionContainerInitList>(irb, scope, source_node); |
| 1434 | 1548 | container_init_list_instruction->container_type = container_type; |
| 1435 | | container_init_list_instruction->elem_type = elem_type; |
| 1436 | 1549 | container_init_list_instruction->item_count = item_count; |
| 1437 | | container_init_list_instruction->items = items; |
| 1550 | container_init_list_instruction->elem_result_loc_list = elem_result_loc_list; |
| 1551 | container_init_list_instruction->result_loc = result_loc; |
| 1438 | 1552 | |
| 1439 | | if (container_type != nullptr) ir_ref_instruction(container_type, irb->current_basic_block); |
| 1440 | | if (elem_type != nullptr) ir_ref_instruction(elem_type, irb->current_basic_block); |
| 1553 | ir_ref_instruction(container_type, irb->current_basic_block); |
| 1441 | 1554 | for (size_t i = 0; i < item_count; i += 1) { |
| 1442 | | ir_ref_instruction(items[i], irb->current_basic_block); |
| 1555 | ir_ref_instruction(elem_result_loc_list[i], irb->current_basic_block); |
| 1443 | 1556 | } |
| 1557 | if (result_loc != nullptr) ir_ref_instruction(result_loc, irb->current_basic_block); |
| 1444 | 1558 | |
| 1445 | 1559 | return &container_init_list_instruction->base; |
| 1446 | 1560 | } |
| 1447 | 1561 | |
| 1448 | 1562 | static IrInstruction *ir_build_container_init_fields(IrBuilder *irb, Scope *scope, AstNode *source_node, |
| 1449 | | IrInstruction *container_type, size_t field_count, IrInstructionContainerInitFieldsField *fields) |
| 1563 | IrInstruction *container_type, size_t field_count, IrInstructionContainerInitFieldsField *fields, |
| 1564 | IrInstruction *result_loc) |
| 1450 | 1565 | { |
| 1451 | 1566 | IrInstructionContainerInitFields *container_init_fields_instruction = |
| 1452 | 1567 | ir_build_instruction<IrInstructionContainerInitFields>(irb, scope, source_node); |
| 1453 | 1568 | container_init_fields_instruction->container_type = container_type; |
| 1454 | 1569 | container_init_fields_instruction->field_count = field_count; |
| 1455 | 1570 | container_init_fields_instruction->fields = fields; |
| 1571 | container_init_fields_instruction->result_loc = result_loc; |
| 1456 | 1572 | |
| 1457 | 1573 | ir_ref_instruction(container_type, irb->current_basic_block); |
| 1458 | 1574 | for (size_t i = 0; i < field_count; i += 1) { |
| 1459 | | ir_ref_instruction(fields[i].value, irb->current_basic_block); |
| 1575 | ir_ref_instruction(fields[i].result_loc, irb->current_basic_block); |
| 1460 | 1576 | } |
| 1577 | if (result_loc != nullptr) ir_ref_instruction(result_loc, irb->current_basic_block); |
| 1461 | 1578 | |
| 1462 | 1579 | return &container_init_fields_instruction->base; |
| 1463 | 1580 | } |
| 1464 | 1581 | |
| 1465 | | static IrInstruction *ir_build_struct_init(IrBuilder *irb, Scope *scope, AstNode *source_node, |
| 1466 | | ZigType *struct_type, size_t field_count, IrInstructionStructInitField *fields) |
| 1467 | | { |
| 1468 | | IrInstructionStructInit *struct_init_instruction = ir_build_instruction<IrInstructionStructInit>(irb, scope, source_node); |
| 1469 | | struct_init_instruction->struct_type = struct_type; |
| 1470 | | struct_init_instruction->field_count = field_count; |
| 1471 | | struct_init_instruction->fields = fields; |
| 1472 | | |
| 1473 | | for (size_t i = 0; i < field_count; i += 1) |
| 1474 | | ir_ref_instruction(fields[i].value, irb->current_basic_block); |
| 1475 | | |
| 1476 | | return &struct_init_instruction->base; |
| 1477 | | } |
| 1478 | | |
| 1479 | | static IrInstruction *ir_build_union_init(IrBuilder *irb, Scope *scope, AstNode *source_node, |
| 1480 | | ZigType *union_type, TypeUnionField *field, IrInstruction *init_value) |
| 1481 | | { |
| 1482 | | IrInstructionUnionInit *union_init_instruction = ir_build_instruction<IrInstructionUnionInit>(irb, scope, source_node); |
| 1483 | | union_init_instruction->union_type = union_type; |
| 1484 | | union_init_instruction->field = field; |
| 1485 | | union_init_instruction->init_value = init_value; |
| 1486 | | |
| 1487 | | ir_ref_instruction(init_value, irb->current_basic_block); |
| 1488 | | |
| 1489 | | return &union_init_instruction->base; |
| 1490 | | } |
| 1491 | | |
| 1492 | 1582 | static IrInstruction *ir_build_unreachable(IrBuilder *irb, Scope *scope, AstNode *source_node) { |
| 1493 | 1583 | IrInstructionUnreachable *unreachable_instruction = |
| 1494 | 1584 | ir_build_instruction<IrInstructionUnreachable>(irb, scope, source_node); |
| ... | ... | @@ -1513,47 +1603,47 @@ static IrInstruction *ir_build_store_ptr(IrBuilder *irb, Scope *scope, AstNode * |
| 1513 | 1603 | } |
| 1514 | 1604 | |
| 1515 | 1605 | static IrInstruction *ir_build_var_decl_src(IrBuilder *irb, Scope *scope, AstNode *source_node, |
| 1516 | | ZigVar *var, IrInstruction *var_type, IrInstruction *align_value, IrInstruction *init_value) |
| 1606 | ZigVar *var, IrInstruction *align_value, IrInstruction *ptr) |
| 1517 | 1607 | { |
| 1518 | 1608 | IrInstructionDeclVarSrc *decl_var_instruction = ir_build_instruction<IrInstructionDeclVarSrc>(irb, scope, source_node); |
| 1519 | 1609 | decl_var_instruction->base.value.special = ConstValSpecialStatic; |
| 1520 | 1610 | decl_var_instruction->base.value.type = irb->codegen->builtin_types.entry_void; |
| 1521 | 1611 | decl_var_instruction->var = var; |
| 1522 | | decl_var_instruction->var_type = var_type; |
| 1523 | 1612 | decl_var_instruction->align_value = align_value; |
| 1524 | | decl_var_instruction->init_value = init_value; |
| 1613 | decl_var_instruction->ptr = ptr; |
| 1525 | 1614 | |
| 1526 | | if (var_type != nullptr) ir_ref_instruction(var_type, irb->current_basic_block); |
| 1527 | 1615 | if (align_value != nullptr) ir_ref_instruction(align_value, irb->current_basic_block); |
| 1528 | | ir_ref_instruction(init_value, irb->current_basic_block); |
| 1616 | ir_ref_instruction(ptr, irb->current_basic_block); |
| 1529 | 1617 | |
| 1530 | 1618 | return &decl_var_instruction->base; |
| 1531 | 1619 | } |
| 1532 | 1620 | |
| 1533 | 1621 | static IrInstruction *ir_build_var_decl_gen(IrAnalyze *ira, IrInstruction *source_instruction, |
| 1534 | | ZigVar *var, IrInstruction *init_value) |
| 1622 | ZigVar *var, IrInstruction *var_ptr) |
| 1535 | 1623 | { |
| 1536 | 1624 | IrInstructionDeclVarGen *decl_var_instruction = ir_build_instruction<IrInstructionDeclVarGen>(&ira->new_irb, |
| 1537 | 1625 | source_instruction->scope, source_instruction->source_node); |
| 1538 | 1626 | decl_var_instruction->base.value.special = ConstValSpecialStatic; |
| 1539 | 1627 | decl_var_instruction->base.value.type = ira->codegen->builtin_types.entry_void; |
| 1540 | 1628 | decl_var_instruction->var = var; |
| 1541 | | decl_var_instruction->init_value = init_value; |
| 1629 | decl_var_instruction->var_ptr = var_ptr; |
| 1542 | 1630 | |
| 1543 | | ir_ref_instruction(init_value, ira->new_irb.current_basic_block); |
| 1631 | ir_ref_instruction(var_ptr, ira->new_irb.current_basic_block); |
| 1544 | 1632 | |
| 1545 | 1633 | return &decl_var_instruction->base; |
| 1546 | 1634 | } |
| 1547 | 1635 | |
| 1548 | 1636 | static IrInstruction *ir_build_resize_slice(IrAnalyze *ira, IrInstruction *source_instruction, |
| 1549 | | IrInstruction *operand, ZigType *ty) |
| 1637 | IrInstruction *operand, ZigType *ty, IrInstruction *result_loc) |
| 1550 | 1638 | { |
| 1551 | 1639 | IrInstructionResizeSlice *instruction = ir_build_instruction<IrInstructionResizeSlice>(&ira->new_irb, |
| 1552 | 1640 | source_instruction->scope, source_instruction->source_node); |
| 1553 | 1641 | instruction->base.value.type = ty; |
| 1554 | 1642 | instruction->operand = operand; |
| 1643 | instruction->result_loc = result_loc; |
| 1555 | 1644 | |
| 1556 | 1645 | ir_ref_instruction(operand, ira->new_irb.current_basic_block); |
| 1646 | ir_ref_instruction(result_loc, ira->new_irb.current_basic_block); |
| 1557 | 1647 | |
| 1558 | 1648 | return &instruction->base; |
| 1559 | 1649 | } |
| ... | ... | @@ -1594,27 +1684,6 @@ static IrInstruction *ir_build_typeof(IrBuilder *irb, Scope *scope, AstNode *sou |
| 1594 | 1684 | return &instruction->base; |
| 1595 | 1685 | } |
| 1596 | 1686 | |
| 1597 | | static IrInstruction *ir_build_to_ptr_type(IrBuilder *irb, Scope *scope, AstNode *source_node, IrInstruction *ptr) { |
| 1598 | | IrInstructionToPtrType *instruction = ir_build_instruction<IrInstructionToPtrType>(irb, scope, source_node); |
| 1599 | | instruction->ptr = ptr; |
| 1600 | | |
| 1601 | | ir_ref_instruction(ptr, irb->current_basic_block); |
| 1602 | | |
| 1603 | | return &instruction->base; |
| 1604 | | } |
| 1605 | | |
| 1606 | | static IrInstruction *ir_build_ptr_type_child(IrBuilder *irb, Scope *scope, AstNode *source_node, |
| 1607 | | IrInstruction *value) |
| 1608 | | { |
| 1609 | | IrInstructionPtrTypeChild *instruction = ir_build_instruction<IrInstructionPtrTypeChild>( |
| 1610 | | irb, scope, source_node); |
| 1611 | | instruction->value = value; |
| 1612 | | |
| 1613 | | ir_ref_instruction(value, irb->current_basic_block); |
| 1614 | | |
| 1615 | | return &instruction->base; |
| 1616 | | } |
| 1617 | | |
| 1618 | 1687 | static IrInstruction *ir_build_set_cold(IrBuilder *irb, Scope *scope, AstNode *source_node, IrInstruction *is_cold) { |
| 1619 | 1688 | IrInstructionSetCold *instruction = ir_build_instruction<IrInstructionSetCold>(irb, scope, source_node); |
| 1620 | 1689 | instruction->is_cold = is_cold; |
| ... | ... | @@ -1740,40 +1809,59 @@ static IrInstruction *ir_build_test_nonnull(IrBuilder *irb, Scope *scope, AstNod |
| 1740 | 1809 | } |
| 1741 | 1810 | |
| 1742 | 1811 | static IrInstruction *ir_build_optional_unwrap_ptr(IrBuilder *irb, Scope *scope, AstNode *source_node, |
| 1743 | | IrInstruction *base_ptr, bool safety_check_on) |
| 1812 | IrInstruction *base_ptr, bool safety_check_on, bool initializing) |
| 1744 | 1813 | { |
| 1745 | 1814 | IrInstructionOptionalUnwrapPtr *instruction = ir_build_instruction<IrInstructionOptionalUnwrapPtr>(irb, scope, source_node); |
| 1746 | 1815 | instruction->base_ptr = base_ptr; |
| 1747 | 1816 | instruction->safety_check_on = safety_check_on; |
| 1817 | instruction->initializing = initializing; |
| 1748 | 1818 | |
| 1749 | 1819 | ir_ref_instruction(base_ptr, irb->current_basic_block); |
| 1750 | 1820 | |
| 1751 | 1821 | return &instruction->base; |
| 1752 | 1822 | } |
| 1753 | 1823 | |
| 1754 | | static IrInstruction *ir_build_maybe_wrap(IrBuilder *irb, Scope *scope, AstNode *source_node, IrInstruction *value) { |
| 1755 | | IrInstructionOptionalWrap *instruction = ir_build_instruction<IrInstructionOptionalWrap>(irb, scope, source_node); |
| 1756 | | instruction->value = value; |
| 1824 | static IrInstruction *ir_build_optional_wrap(IrAnalyze *ira, IrInstruction *source_instruction, ZigType *result_ty, |
| 1825 | IrInstruction *operand, IrInstruction *result_loc) |
| 1826 | { |
| 1827 | IrInstructionOptionalWrap *instruction = ir_build_instruction<IrInstructionOptionalWrap>( |
| 1828 | &ira->new_irb, source_instruction->scope, source_instruction->source_node); |
| 1829 | instruction->base.value.type = result_ty; |
| 1830 | instruction->operand = operand; |
| 1831 | instruction->result_loc = result_loc; |
| 1757 | 1832 | |
| 1758 | | ir_ref_instruction(value, irb->current_basic_block); |
| 1833 | ir_ref_instruction(operand, ira->new_irb.current_basic_block); |
| 1834 | if (result_loc != nullptr) ir_ref_instruction(result_loc, ira->new_irb.current_basic_block); |
| 1759 | 1835 | |
| 1760 | 1836 | return &instruction->base; |
| 1761 | 1837 | } |
| 1762 | 1838 | |
| 1763 | | static IrInstruction *ir_build_err_wrap_payload(IrBuilder *irb, Scope *scope, AstNode *source_node, IrInstruction *value) { |
| 1764 | | IrInstructionErrWrapPayload *instruction = ir_build_instruction<IrInstructionErrWrapPayload>(irb, scope, source_node); |
| 1765 | | instruction->value = value; |
| 1839 | static IrInstruction *ir_build_err_wrap_payload(IrAnalyze *ira, IrInstruction *source_instruction, |
| 1840 | ZigType *result_type, IrInstruction *operand, IrInstruction *result_loc) |
| 1841 | { |
| 1842 | IrInstructionErrWrapPayload *instruction = ir_build_instruction<IrInstructionErrWrapPayload>( |
| 1843 | &ira->new_irb, source_instruction->scope, source_instruction->source_node); |
| 1844 | instruction->base.value.type = result_type; |
| 1845 | instruction->operand = operand; |
| 1846 | instruction->result_loc = result_loc; |
| 1766 | 1847 | |
| 1767 | | ir_ref_instruction(value, irb->current_basic_block); |
| 1848 | ir_ref_instruction(operand, ira->new_irb.current_basic_block); |
| 1849 | if (result_loc != nullptr) ir_ref_instruction(result_loc, ira->new_irb.current_basic_block); |
| 1768 | 1850 | |
| 1769 | 1851 | return &instruction->base; |
| 1770 | 1852 | } |
| 1771 | 1853 | |
| 1772 | | static IrInstruction *ir_build_err_wrap_code(IrBuilder *irb, Scope *scope, AstNode *source_node, IrInstruction *value) { |
| 1773 | | IrInstructionErrWrapCode *instruction = ir_build_instruction<IrInstructionErrWrapCode>(irb, scope, source_node); |
| 1774 | | instruction->value = value; |
| 1854 | static IrInstruction *ir_build_err_wrap_code(IrAnalyze *ira, IrInstruction *source_instruction, |
| 1855 | ZigType *result_type, IrInstruction *operand, IrInstruction *result_loc) |
| 1856 | { |
| 1857 | IrInstructionErrWrapCode *instruction = ir_build_instruction<IrInstructionErrWrapCode>( |
| 1858 | &ira->new_irb, source_instruction->scope, source_instruction->source_node); |
| 1859 | instruction->base.value.type = result_type; |
| 1860 | instruction->operand = operand; |
| 1861 | instruction->result_loc = result_loc; |
| 1775 | 1862 | |
| 1776 | | ir_ref_instruction(value, irb->current_basic_block); |
| 1863 | ir_ref_instruction(operand, ira->new_irb.current_basic_block); |
| 1864 | if (result_loc != nullptr) ir_ref_instruction(result_loc, ira->new_irb.current_basic_block); |
| 1777 | 1865 | |
| 1778 | 1866 | return &instruction->base; |
| 1779 | 1867 | } |
| ... | ... | @@ -1930,6 +2018,21 @@ static IrInstruction *ir_build_ref(IrBuilder *irb, Scope *scope, AstNode *source |
| 1930 | 2018 | return &instruction->base; |
| 1931 | 2019 | } |
| 1932 | 2020 | |
| 2021 | static IrInstruction *ir_build_ref_gen(IrAnalyze *ira, IrInstruction *source_instruction, ZigType *result_type, |
| 2022 | IrInstruction *operand, IrInstruction *result_loc) |
| 2023 | { |
| 2024 | IrInstructionRefGen *instruction = ir_build_instruction<IrInstructionRefGen>(&ira->new_irb, |
| 2025 | source_instruction->scope, source_instruction->source_node); |
| 2026 | instruction->base.value.type = result_type; |
| 2027 | instruction->operand = operand; |
| 2028 | instruction->result_loc = result_loc; |
| 2029 | |
| 2030 | ir_ref_instruction(operand, ira->new_irb.current_basic_block); |
| 2031 | if (result_loc != nullptr) ir_ref_instruction(result_loc, ira->new_irb.current_basic_block); |
| 2032 | |
| 2033 | return &instruction->base; |
| 2034 | } |
| 2035 | |
| 1933 | 2036 | static IrInstruction *ir_build_compile_err(IrBuilder *irb, Scope *scope, AstNode *source_node, IrInstruction *msg) { |
| 1934 | 2037 | IrInstructionCompileErr *instruction = ir_build_instruction<IrInstructionCompileErr>(irb, scope, source_node); |
| 1935 | 2038 | instruction->msg = msg; |
| ... | ... | @@ -2007,8 +2110,7 @@ static IrInstruction *ir_build_embed_file(IrBuilder *irb, Scope *scope, AstNode |
| 2007 | 2110 | |
| 2008 | 2111 | static IrInstruction *ir_build_cmpxchg_src(IrBuilder *irb, Scope *scope, AstNode *source_node, |
| 2009 | 2112 | IrInstruction *type_value, IrInstruction *ptr, IrInstruction *cmp_value, IrInstruction *new_value, |
| 2010 | | IrInstruction *success_order_value, IrInstruction *failure_order_value, |
| 2011 | | bool is_weak) |
| 2113 | IrInstruction *success_order_value, IrInstruction *failure_order_value, bool is_weak, ResultLoc *result_loc) |
| 2012 | 2114 | { |
| 2013 | 2115 | IrInstructionCmpxchgSrc *instruction = ir_build_instruction<IrInstructionCmpxchgSrc>(irb, scope, source_node); |
| 2014 | 2116 | instruction->type_value = type_value; |
| ... | ... | @@ -2018,6 +2120,7 @@ static IrInstruction *ir_build_cmpxchg_src(IrBuilder *irb, Scope *scope, AstNode |
| 2018 | 2120 | instruction->success_order_value = success_order_value; |
| 2019 | 2121 | instruction->failure_order_value = failure_order_value; |
| 2020 | 2122 | instruction->is_weak = is_weak; |
| 2123 | instruction->result_loc = result_loc; |
| 2021 | 2124 | |
| 2022 | 2125 | ir_ref_instruction(type_value, irb->current_basic_block); |
| 2023 | 2126 | ir_ref_instruction(ptr, irb->current_basic_block); |
| ... | ... | @@ -2029,22 +2132,25 @@ static IrInstruction *ir_build_cmpxchg_src(IrBuilder *irb, Scope *scope, AstNode |
| 2029 | 2132 | return &instruction->base; |
| 2030 | 2133 | } |
| 2031 | 2134 | |
| 2032 | | static IrInstruction *ir_build_cmpxchg_gen(IrAnalyze *ira, IrInstruction *source_instruction, |
| 2135 | static IrInstruction *ir_build_cmpxchg_gen(IrAnalyze *ira, IrInstruction *source_instruction, ZigType *result_type, |
| 2033 | 2136 | IrInstruction *ptr, IrInstruction *cmp_value, IrInstruction *new_value, |
| 2034 | | AtomicOrder success_order, AtomicOrder failure_order, bool is_weak) |
| 2137 | AtomicOrder success_order, AtomicOrder failure_order, bool is_weak, IrInstruction *result_loc) |
| 2035 | 2138 | { |
| 2036 | 2139 | IrInstructionCmpxchgGen *instruction = ir_build_instruction<IrInstructionCmpxchgGen>(&ira->new_irb, |
| 2037 | 2140 | source_instruction->scope, source_instruction->source_node); |
| 2141 | instruction->base.value.type = result_type; |
| 2038 | 2142 | instruction->ptr = ptr; |
| 2039 | 2143 | instruction->cmp_value = cmp_value; |
| 2040 | 2144 | instruction->new_value = new_value; |
| 2041 | 2145 | instruction->success_order = success_order; |
| 2042 | 2146 | instruction->failure_order = failure_order; |
| 2043 | 2147 | instruction->is_weak = is_weak; |
| 2148 | instruction->result_loc = result_loc; |
| 2044 | 2149 | |
| 2045 | 2150 | ir_ref_instruction(ptr, ira->new_irb.current_basic_block); |
| 2046 | 2151 | ir_ref_instruction(cmp_value, ira->new_irb.current_basic_block); |
| 2047 | 2152 | ir_ref_instruction(new_value, ira->new_irb.current_basic_block); |
| 2153 | if (result_loc != nullptr) ir_ref_instruction(result_loc, ira->new_irb.current_basic_block); |
| 2048 | 2154 | |
| 2049 | 2155 | return &instruction->base; |
| 2050 | 2156 | } |
| ... | ... | @@ -2103,19 +2209,25 @@ static IrInstruction *ir_build_err_set_cast(IrBuilder *irb, Scope *scope, AstNod |
| 2103 | 2209 | return &instruction->base; |
| 2104 | 2210 | } |
| 2105 | 2211 | |
| 2106 | | static IrInstruction *ir_build_to_bytes(IrBuilder *irb, Scope *scope, AstNode *source_node, IrInstruction *target) { |
| 2212 | static IrInstruction *ir_build_to_bytes(IrBuilder *irb, Scope *scope, AstNode *source_node, IrInstruction *target, |
| 2213 | ResultLoc *result_loc) |
| 2214 | { |
| 2107 | 2215 | IrInstructionToBytes *instruction = ir_build_instruction<IrInstructionToBytes>(irb, scope, source_node); |
| 2108 | 2216 | instruction->target = target; |
| 2217 | instruction->result_loc = result_loc; |
| 2109 | 2218 | |
| 2110 | 2219 | ir_ref_instruction(target, irb->current_basic_block); |
| 2111 | 2220 | |
| 2112 | 2221 | return &instruction->base; |
| 2113 | 2222 | } |
| 2114 | 2223 | |
| 2115 | | static IrInstruction *ir_build_from_bytes(IrBuilder *irb, Scope *scope, AstNode *source_node, IrInstruction *dest_child_type, IrInstruction *target) { |
| 2224 | static IrInstruction *ir_build_from_bytes(IrBuilder *irb, Scope *scope, AstNode *source_node, |
| 2225 | IrInstruction *dest_child_type, IrInstruction *target, ResultLoc *result_loc) |
| 2226 | { |
| 2116 | 2227 | IrInstructionFromBytes *instruction = ir_build_instruction<IrInstructionFromBytes>(irb, scope, source_node); |
| 2117 | 2228 | instruction->dest_child_type = dest_child_type; |
| 2118 | 2229 | instruction->target = target; |
| 2230 | instruction->result_loc = result_loc; |
| 2119 | 2231 | |
| 2120 | 2232 | ir_ref_instruction(dest_child_type, irb->current_basic_block); |
| 2121 | 2233 | ir_ref_instruction(target, irb->current_basic_block); |
| ... | ... | @@ -2217,14 +2329,15 @@ static IrInstruction *ir_build_memcpy(IrBuilder *irb, Scope *scope, AstNode *sou |
| 2217 | 2329 | return &instruction->base; |
| 2218 | 2330 | } |
| 2219 | 2331 | |
| 2220 | | static IrInstruction *ir_build_slice(IrBuilder *irb, Scope *scope, AstNode *source_node, |
| 2221 | | IrInstruction *ptr, IrInstruction *start, IrInstruction *end, bool safety_check_on) |
| 2332 | static IrInstruction *ir_build_slice_src(IrBuilder *irb, Scope *scope, AstNode *source_node, |
| 2333 | IrInstruction *ptr, IrInstruction *start, IrInstruction *end, bool safety_check_on, ResultLoc *result_loc) |
| 2222 | 2334 | { |
| 2223 | | IrInstructionSlice *instruction = ir_build_instruction<IrInstructionSlice>(irb, scope, source_node); |
| 2335 | IrInstructionSliceSrc *instruction = ir_build_instruction<IrInstructionSliceSrc>(irb, scope, source_node); |
| 2224 | 2336 | instruction->ptr = ptr; |
| 2225 | 2337 | instruction->start = start; |
| 2226 | 2338 | instruction->end = end; |
| 2227 | 2339 | instruction->safety_check_on = safety_check_on; |
| 2340 | instruction->result_loc = result_loc; |
| 2228 | 2341 | |
| 2229 | 2342 | ir_ref_instruction(ptr, irb->current_basic_block); |
| 2230 | 2343 | ir_ref_instruction(start, irb->current_basic_block); |
| ... | ... | @@ -2233,6 +2346,26 @@ static IrInstruction *ir_build_slice(IrBuilder *irb, Scope *scope, AstNode *sour |
| 2233 | 2346 | return &instruction->base; |
| 2234 | 2347 | } |
| 2235 | 2348 | |
| 2349 | static IrInstruction *ir_build_slice_gen(IrAnalyze *ira, IrInstruction *source_instruction, ZigType *slice_type, |
| 2350 | IrInstruction *ptr, IrInstruction *start, IrInstruction *end, bool safety_check_on, IrInstruction *result_loc) |
| 2351 | { |
| 2352 | IrInstructionSliceGen *instruction = ir_build_instruction<IrInstructionSliceGen>( |
| 2353 | &ira->new_irb, source_instruction->scope, source_instruction->source_node); |
| 2354 | instruction->base.value.type = slice_type; |
| 2355 | instruction->ptr = ptr; |
| 2356 | instruction->start = start; |
| 2357 | instruction->end = end; |
| 2358 | instruction->safety_check_on = safety_check_on; |
| 2359 | instruction->result_loc = result_loc; |
| 2360 | |
| 2361 | ir_ref_instruction(ptr, ira->new_irb.current_basic_block); |
| 2362 | ir_ref_instruction(start, ira->new_irb.current_basic_block); |
| 2363 | if (end) ir_ref_instruction(end, ira->new_irb.current_basic_block); |
| 2364 | ir_ref_instruction(result_loc, ira->new_irb.current_basic_block); |
| 2365 | |
| 2366 | return &instruction->base; |
| 2367 | } |
| 2368 | |
| 2236 | 2369 | static IrInstruction *ir_build_member_count(IrBuilder *irb, Scope *scope, AstNode *source_node, IrInstruction *container) { |
| 2237 | 2370 | IrInstructionMemberCount *instruction = ir_build_instruction<IrInstructionMemberCount>(irb, scope, source_node); |
| 2238 | 2371 | instruction->container = container; |
| ... | ... | @@ -2308,6 +2441,75 @@ static IrInstruction *ir_build_overflow_op(IrBuilder *irb, Scope *scope, AstNode |
| 2308 | 2441 | return &instruction->base; |
| 2309 | 2442 | } |
| 2310 | 2443 | |
| 2444 | |
| 2445 | //TODO Powi, Pow, minnum, maxnum, maximum, minimum, copysign, |
| 2446 | // lround, llround, lrint, llrint |
| 2447 | // So far this is only non-complicated type functions. |
| 2448 | const char *float_op_to_name(BuiltinFnId op, bool llvm_name) { |
| 2449 | const bool b = llvm_name; |
| 2450 | |
| 2451 | switch (op) { |
| 2452 | case BuiltinFnIdSqrt: |
| 2453 | return "sqrt"; |
| 2454 | case BuiltinFnIdSin: |
| 2455 | return "sin"; |
| 2456 | case BuiltinFnIdCos: |
| 2457 | return "cos"; |
| 2458 | case BuiltinFnIdExp: |
| 2459 | return "exp"; |
| 2460 | case BuiltinFnIdExp2: |
| 2461 | return "exp2"; |
| 2462 | case BuiltinFnIdLn: |
| 2463 | return b ? "log" : "ln"; |
| 2464 | case BuiltinFnIdLog10: |
| 2465 | return "log10"; |
| 2466 | case BuiltinFnIdLog2: |
| 2467 | return "log2"; |
| 2468 | case BuiltinFnIdFabs: |
| 2469 | return "fabs"; |
| 2470 | case BuiltinFnIdFloor: |
| 2471 | return "floor"; |
| 2472 | case BuiltinFnIdCeil: |
| 2473 | return "ceil"; |
| 2474 | case BuiltinFnIdTrunc: |
| 2475 | return "trunc"; |
| 2476 | case BuiltinFnIdNearbyInt: |
| 2477 | return b ? "nearbyint" : "nearbyInt"; |
| 2478 | case BuiltinFnIdRound: |
| 2479 | return "round"; |
| 2480 | default: |
| 2481 | zig_unreachable(); |
| 2482 | } |
| 2483 | } |
| 2484 | |
| 2485 | static IrInstruction *ir_build_float_op(IrBuilder *irb, Scope *scope, AstNode *source_node, IrInstruction *type, IrInstruction *op1, BuiltinFnId op) { |
| 2486 | IrInstructionFloatOp *instruction = ir_build_instruction<IrInstructionFloatOp>(irb, scope, source_node); |
| 2487 | instruction->type = type; |
| 2488 | instruction->op1 = op1; |
| 2489 | instruction->op = op; |
| 2490 | |
| 2491 | if (type != nullptr) ir_ref_instruction(type, irb->current_basic_block); |
| 2492 | ir_ref_instruction(op1, irb->current_basic_block); |
| 2493 | |
| 2494 | return &instruction->base; |
| 2495 | } |
| 2496 | |
| 2497 | static IrInstruction *ir_build_mul_add(IrBuilder *irb, Scope *scope, AstNode *source_node, |
| 2498 | IrInstruction *type_value, IrInstruction *op1, IrInstruction *op2, IrInstruction *op3) { |
| 2499 | IrInstructionMulAdd *instruction = ir_build_instruction<IrInstructionMulAdd>(irb, scope, source_node); |
| 2500 | instruction->type_value = type_value; |
| 2501 | instruction->op1 = op1; |
| 2502 | instruction->op2 = op2; |
| 2503 | instruction->op3 = op3; |
| 2504 | |
| 2505 | ir_ref_instruction(type_value, irb->current_basic_block); |
| 2506 | ir_ref_instruction(op1, irb->current_basic_block); |
| 2507 | ir_ref_instruction(op2, irb->current_basic_block); |
| 2508 | ir_ref_instruction(op3, irb->current_basic_block); |
| 2509 | |
| 2510 | return &instruction->base; |
| 2511 | } |
| 2512 | |
| 2311 | 2513 | static IrInstruction *ir_build_align_of(IrBuilder *irb, Scope *scope, AstNode *source_node, IrInstruction *type_value) { |
| 2312 | 2514 | IrInstructionAlignOf *instruction = ir_build_instruction<IrInstructionAlignOf>(irb, scope, source_node); |
| 2313 | 2515 | instruction->type_value = type_value; |
| ... | ... | @@ -2317,34 +2519,49 @@ static IrInstruction *ir_build_align_of(IrBuilder *irb, Scope *scope, AstNode *s |
| 2317 | 2519 | return &instruction->base; |
| 2318 | 2520 | } |
| 2319 | 2521 | |
| 2320 | | static IrInstruction *ir_build_test_err(IrBuilder *irb, Scope *scope, AstNode *source_node, |
| 2321 | | IrInstruction *value) |
| 2522 | static IrInstruction *ir_build_test_err_src(IrBuilder *irb, Scope *scope, AstNode *source_node, |
| 2523 | IrInstruction *base_ptr, bool resolve_err_set) |
| 2322 | 2524 | { |
| 2323 | | IrInstructionTestErr *instruction = ir_build_instruction<IrInstructionTestErr>(irb, scope, source_node); |
| 2324 | | instruction->value = value; |
| 2525 | IrInstructionTestErrSrc *instruction = ir_build_instruction<IrInstructionTestErrSrc>(irb, scope, source_node); |
| 2526 | instruction->base_ptr = base_ptr; |
| 2527 | instruction->resolve_err_set = resolve_err_set; |
| 2325 | 2528 | |
| 2326 | | ir_ref_instruction(value, irb->current_basic_block); |
| 2529 | ir_ref_instruction(base_ptr, irb->current_basic_block); |
| 2327 | 2530 | |
| 2328 | 2531 | return &instruction->base; |
| 2329 | 2532 | } |
| 2330 | 2533 | |
| 2331 | | static IrInstruction *ir_build_unwrap_err_code(IrBuilder *irb, Scope *scope, AstNode *source_node, |
| 2534 | static IrInstruction *ir_build_test_err_gen(IrAnalyze *ira, IrInstruction *source_instruction, |
| 2332 | 2535 | IrInstruction *err_union) |
| 2333 | 2536 | { |
| 2334 | | IrInstructionUnwrapErrCode *instruction = ir_build_instruction<IrInstructionUnwrapErrCode>(irb, scope, source_node); |
| 2537 | IrInstructionTestErrGen *instruction = ir_build_instruction<IrInstructionTestErrGen>( |
| 2538 | &ira->new_irb, source_instruction->scope, source_instruction->source_node); |
| 2539 | instruction->base.value.type = ira->codegen->builtin_types.entry_bool; |
| 2335 | 2540 | instruction->err_union = err_union; |
| 2336 | 2541 | |
| 2337 | | ir_ref_instruction(err_union, irb->current_basic_block); |
| 2542 | ir_ref_instruction(err_union, ira->new_irb.current_basic_block); |
| 2543 | |
| 2544 | return &instruction->base; |
| 2545 | } |
| 2546 | |
| 2547 | static IrInstruction *ir_build_unwrap_err_code(IrBuilder *irb, Scope *scope, AstNode *source_node, |
| 2548 | IrInstruction *err_union_ptr) |
| 2549 | { |
| 2550 | IrInstructionUnwrapErrCode *instruction = ir_build_instruction<IrInstructionUnwrapErrCode>(irb, scope, source_node); |
| 2551 | instruction->err_union_ptr = err_union_ptr; |
| 2552 | |
| 2553 | ir_ref_instruction(err_union_ptr, irb->current_basic_block); |
| 2338 | 2554 | |
| 2339 | 2555 | return &instruction->base; |
| 2340 | 2556 | } |
| 2341 | 2557 | |
| 2342 | 2558 | static IrInstruction *ir_build_unwrap_err_payload(IrBuilder *irb, Scope *scope, AstNode *source_node, |
| 2343 | | IrInstruction *value, bool safety_check_on) |
| 2559 | IrInstruction *value, bool safety_check_on, bool initializing) |
| 2344 | 2560 | { |
| 2345 | 2561 | IrInstructionUnwrapErrPayload *instruction = ir_build_instruction<IrInstructionUnwrapErrPayload>(irb, scope, source_node); |
| 2346 | 2562 | instruction->value = value; |
| 2347 | 2563 | instruction->safety_check_on = safety_check_on; |
| 2564 | instruction->initializing = initializing; |
| 2348 | 2565 | |
| 2349 | 2566 | ir_ref_instruction(value, irb->current_basic_block); |
| 2350 | 2567 | |
| ... | ... | @@ -2414,28 +2631,28 @@ static IrInstruction *ir_build_ptr_cast_gen(IrAnalyze *ira, IrInstruction *sourc |
| 2414 | 2631 | } |
| 2415 | 2632 | |
| 2416 | 2633 | static IrInstruction *ir_build_load_ptr_gen(IrAnalyze *ira, IrInstruction *source_instruction, |
| 2417 | | IrInstruction *ptr, ZigType *ty) |
| 2634 | IrInstruction *ptr, ZigType *ty, IrInstruction *result_loc) |
| 2418 | 2635 | { |
| 2419 | 2636 | IrInstructionLoadPtrGen *instruction = ir_build_instruction<IrInstructionLoadPtrGen>( |
| 2420 | 2637 | &ira->new_irb, source_instruction->scope, source_instruction->source_node); |
| 2421 | 2638 | instruction->base.value.type = ty; |
| 2422 | 2639 | instruction->ptr = ptr; |
| 2640 | instruction->result_loc = result_loc; |
| 2423 | 2641 | |
| 2424 | 2642 | ir_ref_instruction(ptr, ira->new_irb.current_basic_block); |
| 2643 | if (result_loc != nullptr) ir_ref_instruction(result_loc, ira->new_irb.current_basic_block); |
| 2425 | 2644 | |
| 2426 | 2645 | return &instruction->base; |
| 2427 | 2646 | } |
| 2428 | 2647 | |
| 2429 | | static IrInstruction *ir_build_bit_cast(IrBuilder *irb, Scope *scope, AstNode *source_node, |
| 2430 | | IrInstruction *dest_type, IrInstruction *value) |
| 2648 | static IrInstruction *ir_build_bit_cast_src(IrBuilder *irb, Scope *scope, AstNode *source_node, |
| 2649 | IrInstruction *operand, ResultLocBitCast *result_loc_bit_cast) |
| 2431 | 2650 | { |
| 2432 | | IrInstructionBitCast *instruction = ir_build_instruction<IrInstructionBitCast>( |
| 2433 | | irb, scope, source_node); |
| 2434 | | instruction->dest_type = dest_type; |
| 2435 | | instruction->value = value; |
| 2651 | IrInstructionBitCastSrc *instruction = ir_build_instruction<IrInstructionBitCastSrc>(irb, scope, source_node); |
| 2652 | instruction->operand = operand; |
| 2653 | instruction->result_loc_bit_cast = result_loc_bit_cast; |
| 2436 | 2654 | |
| 2437 | | ir_ref_instruction(dest_type, irb->current_basic_block); |
| 2438 | | ir_ref_instruction(value, irb->current_basic_block); |
| 2655 | ir_ref_instruction(operand, irb->current_basic_block); |
| 2439 | 2656 | |
| 2440 | 2657 | return &instruction->base; |
| 2441 | 2658 | } |
| ... | ... | @@ -2587,11 +2804,8 @@ static IrInstruction *ir_build_type_name(IrBuilder *irb, Scope *scope, AstNode * |
| 2587 | 2804 | return &instruction->base; |
| 2588 | 2805 | } |
| 2589 | 2806 | |
| 2590 | | static IrInstruction *ir_build_decl_ref(IrBuilder *irb, Scope *scope, AstNode *source_node, |
| 2591 | | Tld *tld, LVal lval) |
| 2592 | | { |
| 2593 | | IrInstructionDeclRef *instruction = ir_build_instruction<IrInstructionDeclRef>( |
| 2594 | | irb, scope, source_node); |
| 2807 | static IrInstruction *ir_build_decl_ref(IrBuilder *irb, Scope *scope, AstNode *source_node, Tld *tld, LVal lval) { |
| 2808 | IrInstructionDeclRef *instruction = ir_build_instruction<IrInstructionDeclRef>(irb, scope, source_node); |
| 2595 | 2809 | instruction->tld = tld; |
| 2596 | 2810 | instruction->lval = lval; |
| 2597 | 2811 | |
| ... | ... | @@ -2719,6 +2933,53 @@ static IrInstruction *ir_build_align_cast(IrBuilder *irb, Scope *scope, AstNode |
| 2719 | 2933 | return &instruction->base; |
| 2720 | 2934 | } |
| 2721 | 2935 | |
| 2936 | static IrInstruction *ir_build_implicit_cast(IrBuilder *irb, Scope *scope, AstNode *source_node, |
| 2937 | IrInstruction *dest_type, IrInstruction *target, ResultLoc *result_loc) |
| 2938 | { |
| 2939 | IrInstructionImplicitCast *instruction = ir_build_instruction<IrInstructionImplicitCast>(irb, scope, source_node); |
| 2940 | instruction->dest_type = dest_type; |
| 2941 | instruction->target = target; |
| 2942 | instruction->result_loc = result_loc; |
| 2943 | |
| 2944 | ir_ref_instruction(dest_type, irb->current_basic_block); |
| 2945 | ir_ref_instruction(target, irb->current_basic_block); |
| 2946 | |
| 2947 | return &instruction->base; |
| 2948 | } |
| 2949 | |
| 2950 | static IrInstruction *ir_build_resolve_result(IrBuilder *irb, Scope *scope, AstNode *source_node, |
| 2951 | ResultLoc *result_loc, IrInstruction *ty) |
| 2952 | { |
| 2953 | IrInstructionResolveResult *instruction = ir_build_instruction<IrInstructionResolveResult>(irb, scope, source_node); |
| 2954 | instruction->result_loc = result_loc; |
| 2955 | instruction->ty = ty; |
| 2956 | |
| 2957 | ir_ref_instruction(ty, irb->current_basic_block); |
| 2958 | |
| 2959 | return &instruction->base; |
| 2960 | } |
| 2961 | |
| 2962 | static IrInstruction *ir_build_reset_result(IrBuilder *irb, Scope *scope, AstNode *source_node, |
| 2963 | ResultLoc *result_loc) |
| 2964 | { |
| 2965 | IrInstructionResetResult *instruction = ir_build_instruction<IrInstructionResetResult>(irb, scope, source_node); |
| 2966 | instruction->result_loc = result_loc; |
| 2967 | |
| 2968 | return &instruction->base; |
| 2969 | } |
| 2970 | |
| 2971 | static IrInstruction *ir_build_result_ptr(IrBuilder *irb, Scope *scope, AstNode *source_node, |
| 2972 | ResultLoc *result_loc, IrInstruction *result) |
| 2973 | { |
| 2974 | IrInstructionResultPtr *instruction = ir_build_instruction<IrInstructionResultPtr>(irb, scope, source_node); |
| 2975 | instruction->result_loc = result_loc; |
| 2976 | instruction->result = result; |
| 2977 | |
| 2978 | ir_ref_instruction(result, irb->current_basic_block); |
| 2979 | |
| 2980 | return &instruction->base; |
| 2981 | } |
| 2982 | |
| 2722 | 2983 | static IrInstruction *ir_build_opaque_type(IrBuilder *irb, Scope *scope, AstNode *source_node) { |
| 2723 | 2984 | IrInstructionOpaqueType *instruction = ir_build_instruction<IrInstructionOpaqueType>(irb, scope, source_node); |
| 2724 | 2985 | |
| ... | ... | @@ -3013,17 +3274,6 @@ static IrInstruction *ir_build_mark_err_ret_trace_ptr(IrBuilder *irb, Scope *sco |
| 3013 | 3274 | return &instruction->base; |
| 3014 | 3275 | } |
| 3015 | 3276 | |
| 3016 | | static IrInstruction *ir_build_sqrt(IrBuilder *irb, Scope *scope, AstNode *source_node, IrInstruction *type, IrInstruction *op) { |
| 3017 | | IrInstructionSqrt *instruction = ir_build_instruction<IrInstructionSqrt>(irb, scope, source_node); |
| 3018 | | instruction->type = type; |
| 3019 | | instruction->op = op; |
| 3020 | | |
| 3021 | | if (type != nullptr) ir_ref_instruction(type, irb->current_basic_block); |
| 3022 | | ir_ref_instruction(op, irb->current_basic_block); |
| 3023 | | |
| 3024 | | return &instruction->base; |
| 3025 | | } |
| 3026 | | |
| 3027 | 3277 | static IrInstruction *ir_build_has_decl(IrBuilder *irb, Scope *scope, AstNode *source_node, |
| 3028 | 3278 | IrInstruction *container, IrInstruction *name) |
| 3029 | 3279 | { |
| ... | ... | @@ -3058,16 +3308,31 @@ static IrInstruction *ir_build_check_runtime_scope(IrBuilder *irb, Scope *scope, |
| 3058 | 3308 | } |
| 3059 | 3309 | |
| 3060 | 3310 | static IrInstruction *ir_build_vector_to_array(IrAnalyze *ira, IrInstruction *source_instruction, |
| 3061 | | IrInstruction *vector, ZigType *result_type) |
| 3311 | ZigType *result_type, IrInstruction *vector, IrInstruction *result_loc) |
| 3062 | 3312 | { |
| 3063 | 3313 | IrInstructionVectorToArray *instruction = ir_build_instruction<IrInstructionVectorToArray>(&ira->new_irb, |
| 3064 | 3314 | source_instruction->scope, source_instruction->source_node); |
| 3065 | 3315 | instruction->base.value.type = result_type; |
| 3066 | 3316 | instruction->vector = vector; |
| 3317 | instruction->result_loc = result_loc; |
| 3067 | 3318 | |
| 3068 | 3319 | ir_ref_instruction(vector, ira->new_irb.current_basic_block); |
| 3320 | ir_ref_instruction(result_loc, ira->new_irb.current_basic_block); |
| 3321 | |
| 3322 | return &instruction->base; |
| 3323 | } |
| 3324 | |
| 3325 | static IrInstruction *ir_build_ptr_of_array_to_slice(IrAnalyze *ira, IrInstruction *source_instruction, |
| 3326 | ZigType *result_type, IrInstruction *operand, IrInstruction *result_loc) |
| 3327 | { |
| 3328 | IrInstructionPtrOfArrayToSlice *instruction = ir_build_instruction<IrInstructionPtrOfArrayToSlice>(&ira->new_irb, |
| 3329 | source_instruction->scope, source_instruction->source_node); |
| 3330 | instruction->base.value.type = result_type; |
| 3331 | instruction->operand = operand; |
| 3332 | instruction->result_loc = result_loc; |
| 3069 | 3333 | |
| 3070 | | ir_add_alloca(ira, &instruction->base, result_type); |
| 3334 | ir_ref_instruction(operand, ira->new_irb.current_basic_block); |
| 3335 | ir_ref_instruction(result_loc, ira->new_irb.current_basic_block); |
| 3071 | 3336 | |
| 3072 | 3337 | return &instruction->base; |
| 3073 | 3338 | } |
| ... | ... | @@ -3111,18 +3376,57 @@ static IrInstruction *ir_build_assert_non_null(IrAnalyze *ira, IrInstruction *so |
| 3111 | 3376 | return &instruction->base; |
| 3112 | 3377 | } |
| 3113 | 3378 | |
| 3114 | | static void ir_count_defers(IrBuilder *irb, Scope *inner_scope, Scope *outer_scope, size_t *results) { |
| 3115 | | results[ReturnKindUnconditional] = 0; |
| 3116 | | results[ReturnKindError] = 0; |
| 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; |
| 3117 | 3387 | |
| 3118 | | Scope *scope = inner_scope; |
| 3388 | if (align != nullptr) ir_ref_instruction(align, irb->current_basic_block); |
| 3389 | if (is_comptime != nullptr) ir_ref_instruction(is_comptime, irb->current_basic_block); |
| 3119 | 3390 | |
| 3120 | | while (scope != outer_scope) { |
| 3121 | | assert(scope); |
| 3122 | | switch (scope->id) { |
| 3123 | | case ScopeIdDefer: { |
| 3124 | | AstNode *defer_node = scope->source_node; |
| 3125 | | assert(defer_node->type == NodeTypeDefer); |
| 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 | |
| 3418 | static void ir_count_defers(IrBuilder *irb, Scope *inner_scope, Scope *outer_scope, size_t *results) { |
| 3419 | results[ReturnKindUnconditional] = 0; |
| 3420 | results[ReturnKindError] = 0; |
| 3421 | |
| 3422 | Scope *scope = inner_scope; |
| 3423 | |
| 3424 | while (scope != outer_scope) { |
| 3425 | assert(scope); |
| 3426 | switch (scope->id) { |
| 3427 | case ScopeIdDefer: { |
| 3428 | AstNode *defer_node = scope->source_node; |
| 3429 | assert(defer_node->type == NodeTypeDefer); |
| 3126 | 3430 | ReturnKind defer_kind = defer_node->data.defer.kind; |
| 3127 | 3431 | results[defer_kind] += 1; |
| 3128 | 3432 | scope = scope->parent; |
| ... | ... | @@ -3211,6 +3515,7 @@ static void ir_set_cursor_at_end(IrBuilder *irb, IrBasicBlock *basic_block) { |
| 3211 | 3515 | } |
| 3212 | 3516 | |
| 3213 | 3517 | static void ir_set_cursor_at_end_and_append_block(IrBuilder *irb, IrBasicBlock *basic_block) { |
| 3518 | basic_block->index = irb->exec->basic_block_list.length; |
| 3214 | 3519 | irb->exec->basic_block_list.append(basic_block); |
| 3215 | 3520 | ir_set_cursor_at_end(irb, basic_block); |
| 3216 | 3521 | } |
| ... | ... | @@ -3299,7 +3604,7 @@ static IrInstruction *ir_gen_async_return(IrBuilder *irb, Scope *scope, AstNode |
| 3299 | 3604 | return ir_build_cond_br(irb, scope, node, is_canceled_bool, irb->exec->coro_final_cleanup_block, irb->exec->coro_early_final, is_comptime); |
| 3300 | 3605 | } |
| 3301 | 3606 | |
| 3302 | | static IrInstruction *ir_gen_return(IrBuilder *irb, Scope *scope, AstNode *node, LVal lval) { |
| 3607 | static IrInstruction *ir_gen_return(IrBuilder *irb, Scope *scope, AstNode *node, LVal lval, ResultLoc *result_loc) { |
| 3303 | 3608 | assert(node->type == NodeTypeReturnExpr); |
| 3304 | 3609 | |
| 3305 | 3610 | ZigFn *fn_entry = exec_fn_entry(irb->exec); |
| ... | ... | @@ -3323,12 +3628,16 @@ static IrInstruction *ir_gen_return(IrBuilder *irb, Scope *scope, AstNode *node, |
| 3323 | 3628 | switch (node->data.return_expr.kind) { |
| 3324 | 3629 | case ReturnKindUnconditional: |
| 3325 | 3630 | { |
| 3631 | ResultLocReturn *result_loc_ret = allocate<ResultLocReturn>(1); |
| 3632 | result_loc_ret->base.id = ResultLocIdReturn; |
| 3633 | ir_build_reset_result(irb, scope, node, &result_loc_ret->base); |
| 3634 | |
| 3326 | 3635 | IrInstruction *return_value; |
| 3327 | 3636 | if (expr_node) { |
| 3328 | 3637 | // Temporarily set this so that if we return a type it gets the name of the function |
| 3329 | 3638 | ZigFn *prev_name_fn = irb->exec->name_fn; |
| 3330 | 3639 | irb->exec->name_fn = exec_fn_entry(irb->exec); |
| 3331 | | return_value = ir_gen_node(irb, expr_node, scope); |
| 3640 | return_value = ir_gen_node_extra(irb, expr_node, scope, LValNone, &result_loc_ret->base); |
| 3332 | 3641 | irb->exec->name_fn = prev_name_fn; |
| 3333 | 3642 | if (return_value == irb->codegen->invalid_instruction) |
| 3334 | 3643 | return irb->codegen->invalid_instruction; |
| ... | ... | @@ -3346,7 +3655,9 @@ static IrInstruction *ir_gen_return(IrBuilder *irb, Scope *scope, AstNode *node, |
| 3346 | 3655 | ir_gen_defers_for_block(irb, scope, outer_scope, false); |
| 3347 | 3656 | } |
| 3348 | 3657 | |
| 3349 | | IrInstruction *is_err = ir_build_test_err(irb, scope, node, return_value); |
| 3658 | IrInstruction *ret_ptr = ir_build_result_ptr(irb, scope, node, &result_loc_ret->base, |
| 3659 | return_value); |
| 3660 | IrInstruction *is_err = ir_build_test_err_src(irb, scope, node, ret_ptr, false); |
| 3350 | 3661 | |
| 3351 | 3662 | bool should_inline = ir_should_inline(irb->exec, scope); |
| 3352 | 3663 | IrInstruction *is_comptime; |
| ... | ... | @@ -3375,21 +3686,24 @@ static IrInstruction *ir_gen_return(IrBuilder *irb, Scope *scope, AstNode *node, |
| 3375 | 3686 | ir_build_br(irb, scope, node, ret_stmt_block, is_comptime); |
| 3376 | 3687 | |
| 3377 | 3688 | ir_set_cursor_at_end_and_append_block(irb, ret_stmt_block); |
| 3378 | | return ir_gen_async_return(irb, scope, node, return_value, false); |
| 3689 | IrInstruction *result = ir_gen_async_return(irb, scope, node, return_value, false); |
| 3690 | result_loc_ret->base.source_instruction = result; |
| 3691 | return result; |
| 3379 | 3692 | } else { |
| 3380 | 3693 | // generate unconditional defers |
| 3381 | 3694 | ir_gen_defers_for_block(irb, scope, outer_scope, false); |
| 3382 | | return ir_gen_async_return(irb, scope, node, return_value, false); |
| 3695 | IrInstruction *result = ir_gen_async_return(irb, scope, node, return_value, false); |
| 3696 | result_loc_ret->base.source_instruction = result; |
| 3697 | return result; |
| 3383 | 3698 | } |
| 3384 | 3699 | } |
| 3385 | 3700 | case ReturnKindError: |
| 3386 | 3701 | { |
| 3387 | 3702 | assert(expr_node); |
| 3388 | | IrInstruction *err_union_ptr = ir_gen_node_extra(irb, expr_node, scope, LValPtr); |
| 3703 | IrInstruction *err_union_ptr = ir_gen_node_extra(irb, expr_node, scope, LValPtr, nullptr); |
| 3389 | 3704 | if (err_union_ptr == irb->codegen->invalid_instruction) |
| 3390 | 3705 | return irb->codegen->invalid_instruction; |
| 3391 | | IrInstruction *err_union_val = ir_build_load_ptr(irb, scope, node, err_union_ptr); |
| 3392 | | IrInstruction *is_err_val = ir_build_test_err(irb, scope, node, err_union_val); |
| 3706 | IrInstruction *is_err_val = ir_build_test_err_src(irb, scope, node, err_union_ptr, true); |
| 3393 | 3707 | |
| 3394 | 3708 | IrBasicBlock *return_block = ir_create_basic_block(irb, scope, "ErrRetReturn"); |
| 3395 | 3709 | IrBasicBlock *continue_block = ir_create_basic_block(irb, scope, "ErrRetContinue"); |
| ... | ... | @@ -3404,19 +3718,27 @@ static IrInstruction *ir_gen_return(IrBuilder *irb, Scope *scope, AstNode *node, |
| 3404 | 3718 | |
| 3405 | 3719 | ir_set_cursor_at_end_and_append_block(irb, return_block); |
| 3406 | 3720 | if (!ir_gen_defers_for_block(irb, scope, outer_scope, true)) { |
| 3407 | | IrInstruction *err_val = ir_build_unwrap_err_code(irb, scope, node, err_union_ptr); |
| 3721 | IrInstruction *err_val_ptr = ir_build_unwrap_err_code(irb, scope, node, err_union_ptr); |
| 3722 | IrInstruction *err_val = ir_build_load_ptr(irb, scope, node, err_val_ptr); |
| 3723 | |
| 3724 | ResultLocReturn *result_loc_ret = allocate<ResultLocReturn>(1); |
| 3725 | result_loc_ret->base.id = ResultLocIdReturn; |
| 3726 | ir_build_reset_result(irb, scope, node, &result_loc_ret->base); |
| 3727 | ir_build_end_expr(irb, scope, node, err_val, &result_loc_ret->base); |
| 3728 | |
| 3408 | 3729 | if (irb->codegen->have_err_ret_tracing && !should_inline) { |
| 3409 | 3730 | ir_build_save_err_ret_addr(irb, scope, node); |
| 3410 | 3731 | } |
| 3411 | | ir_gen_async_return(irb, scope, node, err_val, false); |
| 3732 | IrInstruction *ret_inst = ir_gen_async_return(irb, scope, node, err_val, false); |
| 3733 | result_loc_ret->base.source_instruction = ret_inst; |
| 3412 | 3734 | } |
| 3413 | 3735 | |
| 3414 | 3736 | ir_set_cursor_at_end_and_append_block(irb, continue_block); |
| 3415 | | IrInstruction *unwrapped_ptr = ir_build_unwrap_err_payload(irb, scope, node, err_union_ptr, false); |
| 3737 | IrInstruction *unwrapped_ptr = ir_build_unwrap_err_payload(irb, scope, node, err_union_ptr, false, false); |
| 3416 | 3738 | if (lval == LValPtr) |
| 3417 | 3739 | return unwrapped_ptr; |
| 3418 | 3740 | else |
| 3419 | | return ir_build_load_ptr(irb, scope, node, unwrapped_ptr); |
| 3741 | return ir_expr_wrap(irb, scope, ir_build_load_ptr(irb, scope, node, unwrapped_ptr), result_loc); |
| 3420 | 3742 | } |
| 3421 | 3743 | } |
| 3422 | 3744 | zig_unreachable(); |
| ... | ... | @@ -3500,7 +3822,17 @@ static ZigVar *ir_create_var(IrBuilder *irb, AstNode *node, Scope *scope, Buf *n |
| 3500 | 3822 | return var; |
| 3501 | 3823 | } |
| 3502 | 3824 | |
| 3503 | | static IrInstruction *ir_gen_block(IrBuilder *irb, Scope *parent_scope, AstNode *block_node) { |
| 3825 | static ResultLocPeer *create_peer_result(ResultLocPeerParent *peer_parent) { |
| 3826 | ResultLocPeer *result = allocate<ResultLocPeer>(1); |
| 3827 | result->base.id = ResultLocIdPeer; |
| 3828 | result->base.source_instruction = peer_parent->base.source_instruction; |
| 3829 | result->parent = peer_parent; |
| 3830 | return result; |
| 3831 | } |
| 3832 | |
| 3833 | static IrInstruction *ir_gen_block(IrBuilder *irb, Scope *parent_scope, AstNode *block_node, LVal lval, |
| 3834 | ResultLoc *result_loc) |
| 3835 | { |
| 3504 | 3836 | assert(block_node->type == NodeTypeBlock); |
| 3505 | 3837 | |
| 3506 | 3838 | ZigList<IrInstruction *> incoming_values = {0}; |
| ... | ... | @@ -3518,15 +3850,24 @@ static IrInstruction *ir_gen_block(IrBuilder *irb, Scope *parent_scope, AstNode |
| 3518 | 3850 | |
| 3519 | 3851 | if (block_node->data.block.statements.length == 0) { |
| 3520 | 3852 | // {} |
| 3521 | | return ir_build_const_void(irb, child_scope, block_node); |
| 3853 | return ir_lval_wrap(irb, parent_scope, ir_build_const_void(irb, child_scope, block_node), lval, result_loc); |
| 3522 | 3854 | } |
| 3523 | 3855 | |
| 3524 | 3856 | if (block_node->data.block.name != nullptr) { |
| 3857 | scope_block->lval = lval; |
| 3525 | 3858 | scope_block->incoming_blocks = &incoming_blocks; |
| 3526 | 3859 | scope_block->incoming_values = &incoming_values; |
| 3527 | 3860 | scope_block->end_block = ir_create_basic_block(irb, parent_scope, "BlockEnd"); |
| 3528 | 3861 | scope_block->is_comptime = ir_build_const_bool(irb, parent_scope, block_node, |
| 3529 | 3862 | ir_should_inline(irb->exec, parent_scope)); |
| 3863 | |
| 3864 | scope_block->peer_parent = allocate<ResultLocPeerParent>(1); |
| 3865 | scope_block->peer_parent->base.id = ResultLocIdPeerParent; |
| 3866 | scope_block->peer_parent->base.source_instruction = scope_block->is_comptime; |
| 3867 | scope_block->peer_parent->end_bb = scope_block->end_block; |
| 3868 | scope_block->peer_parent->is_comptime = scope_block->is_comptime; |
| 3869 | scope_block->peer_parent->parent = result_loc; |
| 3870 | ir_build_reset_result(irb, parent_scope, block_node, &scope_block->peer_parent->base); |
| 3530 | 3871 | } |
| 3531 | 3872 | |
| 3532 | 3873 | bool is_continuation_unreachable = false; |
| ... | ... | @@ -3540,6 +3881,8 @@ static IrInstruction *ir_gen_block(IrBuilder *irb, Scope *parent_scope, AstNode |
| 3540 | 3881 | // keep the last noreturn statement value around in case we need to return it |
| 3541 | 3882 | noreturn_return_value = statement_value; |
| 3542 | 3883 | } |
| 3884 | // This logic must be kept in sync with |
| 3885 | // [STMT_EXPR_TEST_THING] <--- (search this token) |
| 3543 | 3886 | if (statement_node->type == NodeTypeDefer && statement_value != irb->codegen->invalid_instruction) { |
| 3544 | 3887 | // defer starts a new scope |
| 3545 | 3888 | child_scope = statement_node->data.defer.child_scope; |
| ... | ... | @@ -3560,21 +3903,41 @@ static IrInstruction *ir_gen_block(IrBuilder *irb, Scope *parent_scope, AstNode |
| 3560 | 3903 | return noreturn_return_value; |
| 3561 | 3904 | } |
| 3562 | 3905 | |
| 3906 | if (scope_block->peer_parent != nullptr && scope_block->peer_parent->peers.length != 0) { |
| 3907 | scope_block->peer_parent->peers.last()->next_bb = scope_block->end_block; |
| 3908 | } |
| 3563 | 3909 | ir_set_cursor_at_end_and_append_block(irb, scope_block->end_block); |
| 3564 | | return ir_build_phi(irb, parent_scope, block_node, incoming_blocks.length, incoming_blocks.items, incoming_values.items); |
| 3910 | IrInstruction *phi = ir_build_phi(irb, parent_scope, block_node, incoming_blocks.length, |
| 3911 | incoming_blocks.items, incoming_values.items, scope_block->peer_parent); |
| 3912 | return ir_expr_wrap(irb, parent_scope, phi, result_loc); |
| 3565 | 3913 | } else { |
| 3566 | 3914 | incoming_blocks.append(irb->current_basic_block); |
| 3567 | | incoming_values.append(ir_mark_gen(ir_build_const_void(irb, parent_scope, block_node))); |
| 3915 | IrInstruction *else_expr_result = ir_mark_gen(ir_build_const_void(irb, parent_scope, block_node)); |
| 3916 | |
| 3917 | if (scope_block->peer_parent != nullptr) { |
| 3918 | ResultLocPeer *peer_result = create_peer_result(scope_block->peer_parent); |
| 3919 | scope_block->peer_parent->peers.append(peer_result); |
| 3920 | ir_build_end_expr(irb, parent_scope, block_node, else_expr_result, &peer_result->base); |
| 3921 | |
| 3922 | if (scope_block->peer_parent->peers.length != 0) { |
| 3923 | scope_block->peer_parent->peers.last()->next_bb = scope_block->end_block; |
| 3924 | } |
| 3925 | } |
| 3926 | |
| 3927 | incoming_values.append(else_expr_result); |
| 3568 | 3928 | } |
| 3569 | 3929 | |
| 3570 | 3930 | if (block_node->data.block.name != nullptr) { |
| 3571 | 3931 | ir_gen_defers_for_block(irb, child_scope, outer_block_scope, false); |
| 3572 | 3932 | ir_mark_gen(ir_build_br(irb, parent_scope, block_node, scope_block->end_block, scope_block->is_comptime)); |
| 3573 | 3933 | ir_set_cursor_at_end_and_append_block(irb, scope_block->end_block); |
| 3574 | | return ir_build_phi(irb, parent_scope, block_node, incoming_blocks.length, incoming_blocks.items, incoming_values.items); |
| 3934 | IrInstruction *phi = ir_build_phi(irb, parent_scope, block_node, incoming_blocks.length, |
| 3935 | incoming_blocks.items, incoming_values.items, scope_block->peer_parent); |
| 3936 | return ir_expr_wrap(irb, parent_scope, phi, result_loc); |
| 3575 | 3937 | } else { |
| 3576 | 3938 | ir_gen_defers_for_block(irb, child_scope, outer_block_scope, false); |
| 3577 | | return ir_mark_gen(ir_mark_gen(ir_build_const_void(irb, child_scope, block_node))); |
| 3939 | IrInstruction *void_inst = ir_mark_gen(ir_build_const_void(irb, child_scope, block_node)); |
| 3940 | return ir_lval_wrap(irb, parent_scope, void_inst, lval, result_loc); |
| 3578 | 3941 | } |
| 3579 | 3942 | } |
| 3580 | 3943 | |
| ... | ... | @@ -3594,7 +3957,7 @@ static IrInstruction *ir_gen_bin_op_id(IrBuilder *irb, Scope *scope, AstNode *no |
| 3594 | 3957 | } |
| 3595 | 3958 | |
| 3596 | 3959 | static IrInstruction *ir_gen_assign(IrBuilder *irb, Scope *scope, AstNode *node) { |
| 3597 | | IrInstruction *lvalue = ir_gen_node_extra(irb, node->data.bin_op_expr.op1, scope, LValPtr); |
| 3960 | IrInstruction *lvalue = ir_gen_node_extra(irb, node->data.bin_op_expr.op1, scope, LValPtr, nullptr); |
| 3598 | 3961 | IrInstruction *rvalue = ir_gen_node(irb, node->data.bin_op_expr.op2, scope); |
| 3599 | 3962 | |
| 3600 | 3963 | if (lvalue == irb->codegen->invalid_instruction || rvalue == irb->codegen->invalid_instruction) |
| ... | ... | @@ -3605,7 +3968,7 @@ static IrInstruction *ir_gen_assign(IrBuilder *irb, Scope *scope, AstNode *node) |
| 3605 | 3968 | } |
| 3606 | 3969 | |
| 3607 | 3970 | static IrInstruction *ir_gen_assign_op(IrBuilder *irb, Scope *scope, AstNode *node, IrBinOp op_id) { |
| 3608 | | IrInstruction *lvalue = ir_gen_node_extra(irb, node->data.bin_op_expr.op1, scope, LValPtr); |
| 3971 | IrInstruction *lvalue = ir_gen_node_extra(irb, node->data.bin_op_expr.op1, scope, LValPtr, nullptr); |
| 3609 | 3972 | if (lvalue == irb->codegen->invalid_instruction) |
| 3610 | 3973 | return lvalue; |
| 3611 | 3974 | IrInstruction *op1 = ir_build_load_ptr(irb, scope, node->data.bin_op_expr.op1, lvalue); |
| ... | ... | @@ -3656,7 +4019,7 @@ static IrInstruction *ir_gen_bool_or(IrBuilder *irb, Scope *scope, AstNode *node |
| 3656 | 4019 | incoming_blocks[0] = post_val1_block; |
| 3657 | 4020 | incoming_blocks[1] = post_val2_block; |
| 3658 | 4021 | |
| 3659 | | return ir_build_phi(irb, scope, node, 2, incoming_blocks, incoming_values); |
| 4022 | return ir_build_phi(irb, scope, node, 2, incoming_blocks, incoming_values, nullptr); |
| 3660 | 4023 | } |
| 3661 | 4024 | |
| 3662 | 4025 | static IrInstruction *ir_gen_bool_and(IrBuilder *irb, Scope *scope, AstNode *node) { |
| ... | ... | @@ -3698,16 +4061,51 @@ static IrInstruction *ir_gen_bool_and(IrBuilder *irb, Scope *scope, AstNode *nod |
| 3698 | 4061 | incoming_blocks[0] = post_val1_block; |
| 3699 | 4062 | incoming_blocks[1] = post_val2_block; |
| 3700 | 4063 | |
| 3701 | | return ir_build_phi(irb, scope, node, 2, incoming_blocks, incoming_values); |
| 4064 | return ir_build_phi(irb, scope, node, 2, incoming_blocks, incoming_values, nullptr); |
| 4065 | } |
| 4066 | |
| 4067 | static ResultLocPeerParent *ir_build_result_peers(IrBuilder *irb, IrInstruction *cond_br_inst, |
| 4068 | IrBasicBlock *end_block, ResultLoc *parent, IrInstruction *is_comptime) |
| 4069 | { |
| 4070 | ResultLocPeerParent *peer_parent = allocate<ResultLocPeerParent>(1); |
| 4071 | peer_parent->base.id = ResultLocIdPeerParent; |
| 4072 | peer_parent->base.source_instruction = cond_br_inst; |
| 4073 | peer_parent->end_bb = end_block; |
| 4074 | peer_parent->is_comptime = is_comptime; |
| 4075 | peer_parent->parent = parent; |
| 4076 | |
| 4077 | IrInstruction *popped_inst = irb->current_basic_block->instruction_list.pop(); |
| 4078 | ir_assert(popped_inst == cond_br_inst, cond_br_inst); |
| 4079 | |
| 4080 | ir_build_reset_result(irb, cond_br_inst->scope, cond_br_inst->source_node, &peer_parent->base); |
| 4081 | irb->current_basic_block->instruction_list.append(popped_inst); |
| 4082 | |
| 4083 | return peer_parent; |
| 4084 | } |
| 4085 | |
| 4086 | static ResultLocPeerParent *ir_build_binary_result_peers(IrBuilder *irb, IrInstruction *cond_br_inst, |
| 4087 | IrBasicBlock *else_block, IrBasicBlock *end_block, ResultLoc *parent, IrInstruction *is_comptime) |
| 4088 | { |
| 4089 | ResultLocPeerParent *peer_parent = ir_build_result_peers(irb, cond_br_inst, end_block, parent, is_comptime); |
| 4090 | |
| 4091 | peer_parent->peers.append(create_peer_result(peer_parent)); |
| 4092 | peer_parent->peers.last()->next_bb = else_block; |
| 4093 | |
| 4094 | peer_parent->peers.append(create_peer_result(peer_parent)); |
| 4095 | peer_parent->peers.last()->next_bb = end_block; |
| 4096 | |
| 4097 | return peer_parent; |
| 3702 | 4098 | } |
| 3703 | 4099 | |
| 3704 | | static IrInstruction *ir_gen_orelse(IrBuilder *irb, Scope *parent_scope, AstNode *node) { |
| 4100 | static IrInstruction *ir_gen_orelse(IrBuilder *irb, Scope *parent_scope, AstNode *node, LVal lval, |
| 4101 | ResultLoc *result_loc) |
| 4102 | { |
| 3705 | 4103 | assert(node->type == NodeTypeBinOpExpr); |
| 3706 | 4104 | |
| 3707 | 4105 | AstNode *op1_node = node->data.bin_op_expr.op1; |
| 3708 | 4106 | AstNode *op2_node = node->data.bin_op_expr.op2; |
| 3709 | 4107 | |
| 3710 | | IrInstruction *maybe_ptr = ir_gen_node_extra(irb, op1_node, parent_scope, LValPtr); |
| 4108 | IrInstruction *maybe_ptr = ir_gen_node_extra(irb, op1_node, parent_scope, LValPtr, nullptr); |
| 3711 | 4109 | if (maybe_ptr == irb->codegen->invalid_instruction) |
| 3712 | 4110 | return irb->codegen->invalid_instruction; |
| 3713 | 4111 | |
| ... | ... | @@ -3724,10 +4122,14 @@ static IrInstruction *ir_gen_orelse(IrBuilder *irb, Scope *parent_scope, AstNode |
| 3724 | 4122 | IrBasicBlock *ok_block = ir_create_basic_block(irb, parent_scope, "OptionalNonNull"); |
| 3725 | 4123 | IrBasicBlock *null_block = ir_create_basic_block(irb, parent_scope, "OptionalNull"); |
| 3726 | 4124 | IrBasicBlock *end_block = ir_create_basic_block(irb, parent_scope, "OptionalEnd"); |
| 3727 | | ir_build_cond_br(irb, parent_scope, node, is_non_null, ok_block, null_block, is_comptime); |
| 4125 | IrInstruction *cond_br_inst = ir_build_cond_br(irb, parent_scope, node, is_non_null, ok_block, null_block, is_comptime); |
| 4126 | |
| 4127 | ResultLocPeerParent *peer_parent = ir_build_binary_result_peers(irb, cond_br_inst, ok_block, end_block, |
| 4128 | result_loc, is_comptime); |
| 3728 | 4129 | |
| 3729 | 4130 | ir_set_cursor_at_end_and_append_block(irb, null_block); |
| 3730 | | IrInstruction *null_result = ir_gen_node(irb, op2_node, parent_scope); |
| 4131 | IrInstruction *null_result = ir_gen_node_extra(irb, op2_node, parent_scope, LValNone, |
| 4132 | &peer_parent->peers.at(0)->base); |
| 3731 | 4133 | if (null_result == irb->codegen->invalid_instruction) |
| 3732 | 4134 | return irb->codegen->invalid_instruction; |
| 3733 | 4135 | IrBasicBlock *after_null_block = irb->current_basic_block; |
| ... | ... | @@ -3735,8 +4137,9 @@ static IrInstruction *ir_gen_orelse(IrBuilder *irb, Scope *parent_scope, AstNode |
| 3735 | 4137 | ir_mark_gen(ir_build_br(irb, parent_scope, node, end_block, is_comptime)); |
| 3736 | 4138 | |
| 3737 | 4139 | ir_set_cursor_at_end_and_append_block(irb, ok_block); |
| 3738 | | IrInstruction *unwrapped_ptr = ir_build_optional_unwrap_ptr(irb, parent_scope, node, maybe_ptr, false); |
| 4140 | IrInstruction *unwrapped_ptr = ir_build_optional_unwrap_ptr(irb, parent_scope, node, maybe_ptr, false, false); |
| 3739 | 4141 | IrInstruction *unwrapped_payload = ir_build_load_ptr(irb, parent_scope, node, unwrapped_ptr); |
| 4142 | ir_build_end_expr(irb, parent_scope, node, unwrapped_payload, &peer_parent->peers.at(1)->base); |
| 3740 | 4143 | IrBasicBlock *after_ok_block = irb->current_basic_block; |
| 3741 | 4144 | ir_build_br(irb, parent_scope, node, end_block, is_comptime); |
| 3742 | 4145 | |
| ... | ... | @@ -3747,7 +4150,8 @@ static IrInstruction *ir_gen_orelse(IrBuilder *irb, Scope *parent_scope, AstNode |
| 3747 | 4150 | IrBasicBlock **incoming_blocks = allocate<IrBasicBlock *>(2); |
| 3748 | 4151 | incoming_blocks[0] = after_null_block; |
| 3749 | 4152 | incoming_blocks[1] = after_ok_block; |
| 3750 | | return ir_build_phi(irb, parent_scope, node, 2, incoming_blocks, incoming_values); |
| 4153 | IrInstruction *phi = ir_build_phi(irb, parent_scope, node, 2, incoming_blocks, incoming_values, peer_parent); |
| 4154 | return ir_lval_wrap(irb, parent_scope, phi, lval, result_loc); |
| 3751 | 4155 | } |
| 3752 | 4156 | |
| 3753 | 4157 | static IrInstruction *ir_gen_error_union(IrBuilder *irb, Scope *parent_scope, AstNode *node) { |
| ... | ... | @@ -3767,7 +4171,7 @@ static IrInstruction *ir_gen_error_union(IrBuilder *irb, Scope *parent_scope, As |
| 3767 | 4171 | return ir_build_error_union(irb, parent_scope, node, err_set, payload); |
| 3768 | 4172 | } |
| 3769 | 4173 | |
| 3770 | | static IrInstruction *ir_gen_bin_op(IrBuilder *irb, Scope *scope, AstNode *node) { |
| 4174 | static IrInstruction *ir_gen_bin_op(IrBuilder *irb, Scope *scope, AstNode *node, LVal lval, ResultLoc *result_loc) { |
| 3771 | 4175 | assert(node->type == NodeTypeBinOpExpr); |
| 3772 | 4176 | |
| 3773 | 4177 | BinOpType bin_op_type = node->data.bin_op_expr.bin_op; |
| ... | ... | @@ -3775,87 +4179,87 @@ static IrInstruction *ir_gen_bin_op(IrBuilder *irb, Scope *scope, AstNode *node) |
| 3775 | 4179 | case BinOpTypeInvalid: |
| 3776 | 4180 | zig_unreachable(); |
| 3777 | 4181 | case BinOpTypeAssign: |
| 3778 | | return ir_gen_assign(irb, scope, node); |
| 4182 | return ir_lval_wrap(irb, scope, ir_gen_assign(irb, scope, node), lval, result_loc); |
| 3779 | 4183 | case BinOpTypeAssignTimes: |
| 3780 | | return ir_gen_assign_op(irb, scope, node, IrBinOpMult); |
| 4184 | return ir_lval_wrap(irb, scope, ir_gen_assign_op(irb, scope, node, IrBinOpMult), lval, result_loc); |
| 3781 | 4185 | case BinOpTypeAssignTimesWrap: |
| 3782 | | return ir_gen_assign_op(irb, scope, node, IrBinOpMultWrap); |
| 4186 | return ir_lval_wrap(irb, scope, ir_gen_assign_op(irb, scope, node, IrBinOpMultWrap), lval, result_loc); |
| 3783 | 4187 | case BinOpTypeAssignDiv: |
| 3784 | | return ir_gen_assign_op(irb, scope, node, IrBinOpDivUnspecified); |
| 4188 | return ir_lval_wrap(irb, scope, ir_gen_assign_op(irb, scope, node, IrBinOpDivUnspecified), lval, result_loc); |
| 3785 | 4189 | case BinOpTypeAssignMod: |
| 3786 | | return ir_gen_assign_op(irb, scope, node, IrBinOpRemUnspecified); |
| 4190 | return ir_lval_wrap(irb, scope, ir_gen_assign_op(irb, scope, node, IrBinOpRemUnspecified), lval, result_loc); |
| 3787 | 4191 | case BinOpTypeAssignPlus: |
| 3788 | | return ir_gen_assign_op(irb, scope, node, IrBinOpAdd); |
| 4192 | return ir_lval_wrap(irb, scope, ir_gen_assign_op(irb, scope, node, IrBinOpAdd), lval, result_loc); |
| 3789 | 4193 | case BinOpTypeAssignPlusWrap: |
| 3790 | | return ir_gen_assign_op(irb, scope, node, IrBinOpAddWrap); |
| 4194 | return ir_lval_wrap(irb, scope, ir_gen_assign_op(irb, scope, node, IrBinOpAddWrap), lval, result_loc); |
| 3791 | 4195 | case BinOpTypeAssignMinus: |
| 3792 | | return ir_gen_assign_op(irb, scope, node, IrBinOpSub); |
| 4196 | return ir_lval_wrap(irb, scope, ir_gen_assign_op(irb, scope, node, IrBinOpSub), lval, result_loc); |
| 3793 | 4197 | case BinOpTypeAssignMinusWrap: |
| 3794 | | return ir_gen_assign_op(irb, scope, node, IrBinOpSubWrap); |
| 4198 | return ir_lval_wrap(irb, scope, ir_gen_assign_op(irb, scope, node, IrBinOpSubWrap), lval, result_loc); |
| 3795 | 4199 | case BinOpTypeAssignBitShiftLeft: |
| 3796 | | return ir_gen_assign_op(irb, scope, node, IrBinOpBitShiftLeftLossy); |
| 4200 | return ir_lval_wrap(irb, scope, ir_gen_assign_op(irb, scope, node, IrBinOpBitShiftLeftLossy), lval, result_loc); |
| 3797 | 4201 | case BinOpTypeAssignBitShiftRight: |
| 3798 | | return ir_gen_assign_op(irb, scope, node, IrBinOpBitShiftRightLossy); |
| 4202 | return ir_lval_wrap(irb, scope, ir_gen_assign_op(irb, scope, node, IrBinOpBitShiftRightLossy), lval, result_loc); |
| 3799 | 4203 | case BinOpTypeAssignBitAnd: |
| 3800 | | return ir_gen_assign_op(irb, scope, node, IrBinOpBinAnd); |
| 4204 | return ir_lval_wrap(irb, scope, ir_gen_assign_op(irb, scope, node, IrBinOpBinAnd), lval, result_loc); |
| 3801 | 4205 | case BinOpTypeAssignBitXor: |
| 3802 | | return ir_gen_assign_op(irb, scope, node, IrBinOpBinXor); |
| 4206 | return ir_lval_wrap(irb, scope, ir_gen_assign_op(irb, scope, node, IrBinOpBinXor), lval, result_loc); |
| 3803 | 4207 | case BinOpTypeAssignBitOr: |
| 3804 | | return ir_gen_assign_op(irb, scope, node, IrBinOpBinOr); |
| 4208 | return ir_lval_wrap(irb, scope, ir_gen_assign_op(irb, scope, node, IrBinOpBinOr), lval, result_loc); |
| 3805 | 4209 | case BinOpTypeAssignMergeErrorSets: |
| 3806 | | return ir_gen_assign_op(irb, scope, node, IrBinOpMergeErrorSets); |
| 4210 | return ir_lval_wrap(irb, scope, ir_gen_assign_op(irb, scope, node, IrBinOpMergeErrorSets), lval, result_loc); |
| 3807 | 4211 | case BinOpTypeBoolOr: |
| 3808 | | return ir_gen_bool_or(irb, scope, node); |
| 4212 | return ir_lval_wrap(irb, scope, ir_gen_bool_or(irb, scope, node), lval, result_loc); |
| 3809 | 4213 | case BinOpTypeBoolAnd: |
| 3810 | | return ir_gen_bool_and(irb, scope, node); |
| 4214 | return ir_lval_wrap(irb, scope, ir_gen_bool_and(irb, scope, node), lval, result_loc); |
| 3811 | 4215 | case BinOpTypeCmpEq: |
| 3812 | | return ir_gen_bin_op_id(irb, scope, node, IrBinOpCmpEq); |
| 4216 | return ir_lval_wrap(irb, scope, ir_gen_bin_op_id(irb, scope, node, IrBinOpCmpEq), lval, result_loc); |
| 3813 | 4217 | case BinOpTypeCmpNotEq: |
| 3814 | | return ir_gen_bin_op_id(irb, scope, node, IrBinOpCmpNotEq); |
| 4218 | return ir_lval_wrap(irb, scope, ir_gen_bin_op_id(irb, scope, node, IrBinOpCmpNotEq), lval, result_loc); |
| 3815 | 4219 | case BinOpTypeCmpLessThan: |
| 3816 | | return ir_gen_bin_op_id(irb, scope, node, IrBinOpCmpLessThan); |
| 4220 | return ir_lval_wrap(irb, scope, ir_gen_bin_op_id(irb, scope, node, IrBinOpCmpLessThan), lval, result_loc); |
| 3817 | 4221 | case BinOpTypeCmpGreaterThan: |
| 3818 | | return ir_gen_bin_op_id(irb, scope, node, IrBinOpCmpGreaterThan); |
| 4222 | return ir_lval_wrap(irb, scope, ir_gen_bin_op_id(irb, scope, node, IrBinOpCmpGreaterThan), lval, result_loc); |
| 3819 | 4223 | case BinOpTypeCmpLessOrEq: |
| 3820 | | return ir_gen_bin_op_id(irb, scope, node, IrBinOpCmpLessOrEq); |
| 4224 | return ir_lval_wrap(irb, scope, ir_gen_bin_op_id(irb, scope, node, IrBinOpCmpLessOrEq), lval, result_loc); |
| 3821 | 4225 | case BinOpTypeCmpGreaterOrEq: |
| 3822 | | return ir_gen_bin_op_id(irb, scope, node, IrBinOpCmpGreaterOrEq); |
| 4226 | return ir_lval_wrap(irb, scope, ir_gen_bin_op_id(irb, scope, node, IrBinOpCmpGreaterOrEq), lval, result_loc); |
| 3823 | 4227 | case BinOpTypeBinOr: |
| 3824 | | return ir_gen_bin_op_id(irb, scope, node, IrBinOpBinOr); |
| 4228 | return ir_lval_wrap(irb, scope, ir_gen_bin_op_id(irb, scope, node, IrBinOpBinOr), lval, result_loc); |
| 3825 | 4229 | case BinOpTypeBinXor: |
| 3826 | | return ir_gen_bin_op_id(irb, scope, node, IrBinOpBinXor); |
| 4230 | return ir_lval_wrap(irb, scope, ir_gen_bin_op_id(irb, scope, node, IrBinOpBinXor), lval, result_loc); |
| 3827 | 4231 | case BinOpTypeBinAnd: |
| 3828 | | return ir_gen_bin_op_id(irb, scope, node, IrBinOpBinAnd); |
| 4232 | return ir_lval_wrap(irb, scope, ir_gen_bin_op_id(irb, scope, node, IrBinOpBinAnd), lval, result_loc); |
| 3829 | 4233 | case BinOpTypeBitShiftLeft: |
| 3830 | | return ir_gen_bin_op_id(irb, scope, node, IrBinOpBitShiftLeftLossy); |
| 4234 | return ir_lval_wrap(irb, scope, ir_gen_bin_op_id(irb, scope, node, IrBinOpBitShiftLeftLossy), lval, result_loc); |
| 3831 | 4235 | case BinOpTypeBitShiftRight: |
| 3832 | | return ir_gen_bin_op_id(irb, scope, node, IrBinOpBitShiftRightLossy); |
| 4236 | return ir_lval_wrap(irb, scope, ir_gen_bin_op_id(irb, scope, node, IrBinOpBitShiftRightLossy), lval, result_loc); |
| 3833 | 4237 | case BinOpTypeAdd: |
| 3834 | | return ir_gen_bin_op_id(irb, scope, node, IrBinOpAdd); |
| 4238 | return ir_lval_wrap(irb, scope, ir_gen_bin_op_id(irb, scope, node, IrBinOpAdd), lval, result_loc); |
| 3835 | 4239 | case BinOpTypeAddWrap: |
| 3836 | | return ir_gen_bin_op_id(irb, scope, node, IrBinOpAddWrap); |
| 4240 | return ir_lval_wrap(irb, scope, ir_gen_bin_op_id(irb, scope, node, IrBinOpAddWrap), lval, result_loc); |
| 3837 | 4241 | case BinOpTypeSub: |
| 3838 | | return ir_gen_bin_op_id(irb, scope, node, IrBinOpSub); |
| 4242 | return ir_lval_wrap(irb, scope, ir_gen_bin_op_id(irb, scope, node, IrBinOpSub), lval, result_loc); |
| 3839 | 4243 | case BinOpTypeSubWrap: |
| 3840 | | return ir_gen_bin_op_id(irb, scope, node, IrBinOpSubWrap); |
| 4244 | return ir_lval_wrap(irb, scope, ir_gen_bin_op_id(irb, scope, node, IrBinOpSubWrap), lval, result_loc); |
| 3841 | 4245 | case BinOpTypeMult: |
| 3842 | | return ir_gen_bin_op_id(irb, scope, node, IrBinOpMult); |
| 4246 | return ir_lval_wrap(irb, scope, ir_gen_bin_op_id(irb, scope, node, IrBinOpMult), lval, result_loc); |
| 3843 | 4247 | case BinOpTypeMultWrap: |
| 3844 | | return ir_gen_bin_op_id(irb, scope, node, IrBinOpMultWrap); |
| 4248 | return ir_lval_wrap(irb, scope, ir_gen_bin_op_id(irb, scope, node, IrBinOpMultWrap), lval, result_loc); |
| 3845 | 4249 | case BinOpTypeDiv: |
| 3846 | | return ir_gen_bin_op_id(irb, scope, node, IrBinOpDivUnspecified); |
| 4250 | return ir_lval_wrap(irb, scope, ir_gen_bin_op_id(irb, scope, node, IrBinOpDivUnspecified), lval, result_loc); |
| 3847 | 4251 | case BinOpTypeMod: |
| 3848 | | return ir_gen_bin_op_id(irb, scope, node, IrBinOpRemUnspecified); |
| 4252 | return ir_lval_wrap(irb, scope, ir_gen_bin_op_id(irb, scope, node, IrBinOpRemUnspecified), lval, result_loc); |
| 3849 | 4253 | case BinOpTypeArrayCat: |
| 3850 | | return ir_gen_bin_op_id(irb, scope, node, IrBinOpArrayCat); |
| 4254 | return ir_lval_wrap(irb, scope, ir_gen_bin_op_id(irb, scope, node, IrBinOpArrayCat), lval, result_loc); |
| 3851 | 4255 | case BinOpTypeArrayMult: |
| 3852 | | return ir_gen_bin_op_id(irb, scope, node, IrBinOpArrayMult); |
| 4256 | return ir_lval_wrap(irb, scope, ir_gen_bin_op_id(irb, scope, node, IrBinOpArrayMult), lval, result_loc); |
| 3853 | 4257 | case BinOpTypeMergeErrorSets: |
| 3854 | | return ir_gen_bin_op_id(irb, scope, node, IrBinOpMergeErrorSets); |
| 4258 | return ir_lval_wrap(irb, scope, ir_gen_bin_op_id(irb, scope, node, IrBinOpMergeErrorSets), lval, result_loc); |
| 3855 | 4259 | case BinOpTypeUnwrapOptional: |
| 3856 | | return ir_gen_orelse(irb, scope, node); |
| 4260 | return ir_gen_orelse(irb, scope, node, lval, result_loc); |
| 3857 | 4261 | case BinOpTypeErrorUnion: |
| 3858 | | return ir_gen_error_union(irb, scope, node); |
| 4262 | return ir_lval_wrap(irb, scope, ir_gen_error_union(irb, scope, node), lval, result_loc); |
| 3859 | 4263 | } |
| 3860 | 4264 | zig_unreachable(); |
| 3861 | 4265 | } |
| ... | ... | @@ -3900,12 +4304,12 @@ static void populate_invalid_variable_in_scope(CodeGen *g, Scope *scope, AstNode |
| 3900 | 4304 | TldVar *tld_var = allocate<TldVar>(1); |
| 3901 | 4305 | init_tld(&tld_var->base, TldIdVar, var_name, VisibModPub, node, &scope_decls->base); |
| 3902 | 4306 | tld_var->base.resolution = TldResolutionInvalid; |
| 3903 | | tld_var->var = add_variable(g, node, &scope_decls->base, var_name, false, |
| 4307 | tld_var->var = add_variable(g, node, &scope_decls->base, var_name, false, |
| 3904 | 4308 | &g->invalid_instruction->value, &tld_var->base, g->builtin_types.entry_invalid); |
| 3905 | 4309 | scope_decls->decl_table.put(var_name, &tld_var->base); |
| 3906 | 4310 | } |
| 3907 | 4311 | |
| 3908 | | static IrInstruction *ir_gen_symbol(IrBuilder *irb, Scope *scope, AstNode *node, LVal lval) { |
| 4312 | static IrInstruction *ir_gen_symbol(IrBuilder *irb, Scope *scope, AstNode *node, LVal lval, ResultLoc *result_loc) { |
| 3909 | 4313 | Error err; |
| 3910 | 4314 | assert(node->type == NodeTypeSymbol); |
| 3911 | 4315 | |
| ... | ... | @@ -3939,7 +4343,7 @@ static IrInstruction *ir_gen_symbol(IrBuilder *irb, Scope *scope, AstNode *node, |
| 3939 | 4343 | if (lval == LValPtr) { |
| 3940 | 4344 | return ir_build_ref(irb, scope, node, value, false, false); |
| 3941 | 4345 | } else { |
| 3942 | | return value; |
| 4346 | return ir_expr_wrap(irb, scope, value, result_loc); |
| 3943 | 4347 | } |
| 3944 | 4348 | } |
| 3945 | 4349 | |
| ... | ... | @@ -3947,15 +4351,22 @@ static IrInstruction *ir_gen_symbol(IrBuilder *irb, Scope *scope, AstNode *node, |
| 3947 | 4351 | ZigVar *var = find_variable(irb->codegen, scope, variable_name, &crossed_fndef_scope); |
| 3948 | 4352 | if (var) { |
| 3949 | 4353 | IrInstruction *var_ptr = ir_build_var_ptr_x(irb, scope, node, var, crossed_fndef_scope); |
| 3950 | | if (lval == LValPtr) |
| 4354 | if (lval == LValPtr) { |
| 3951 | 4355 | return var_ptr; |
| 3952 | | else |
| 3953 | | return ir_build_load_ptr(irb, scope, node, var_ptr); |
| 4356 | } else { |
| 4357 | return ir_expr_wrap(irb, scope, ir_build_load_ptr(irb, scope, node, var_ptr), result_loc); |
| 4358 | } |
| 3954 | 4359 | } |
| 3955 | 4360 | |
| 3956 | 4361 | Tld *tld = find_decl(irb->codegen, scope, variable_name); |
| 3957 | | if (tld) |
| 3958 | | return ir_build_decl_ref(irb, scope, node, tld, lval); |
| 4362 | if (tld) { |
| 4363 | IrInstruction *decl_ref = ir_build_decl_ref(irb, scope, node, tld, lval); |
| 4364 | if (lval == LValPtr) { |
| 4365 | return decl_ref; |
| 4366 | } else { |
| 4367 | return ir_expr_wrap(irb, scope, decl_ref, result_loc); |
| 4368 | } |
| 4369 | } |
| 3959 | 4370 | |
| 3960 | 4371 | if (get_container_scope(node->owner)->any_imports_failed) { |
| 3961 | 4372 | // skip the error message since we had a failing import in this file |
| ... | ... | @@ -3966,11 +4377,13 @@ static IrInstruction *ir_gen_symbol(IrBuilder *irb, Scope *scope, AstNode *node, |
| 3966 | 4377 | return ir_build_undeclared_identifier(irb, scope, node, variable_name); |
| 3967 | 4378 | } |
| 3968 | 4379 | |
| 3969 | | static IrInstruction *ir_gen_array_access(IrBuilder *irb, Scope *scope, AstNode *node, LVal lval) { |
| 4380 | static IrInstruction *ir_gen_array_access(IrBuilder *irb, Scope *scope, AstNode *node, LVal lval, |
| 4381 | ResultLoc *result_loc) |
| 4382 | { |
| 3970 | 4383 | assert(node->type == NodeTypeArrayAccessExpr); |
| 3971 | 4384 | |
| 3972 | 4385 | AstNode *array_ref_node = node->data.array_access_expr.array_ref_expr; |
| 3973 | | IrInstruction *array_ref_instruction = ir_gen_node_extra(irb, array_ref_node, scope, LValPtr); |
| 4386 | IrInstruction *array_ref_instruction = ir_gen_node_extra(irb, array_ref_node, scope, LValPtr, nullptr); |
| 3974 | 4387 | if (array_ref_instruction == irb->codegen->invalid_instruction) |
| 3975 | 4388 | return array_ref_instruction; |
| 3976 | 4389 | |
| ... | ... | @@ -3980,11 +4393,12 @@ static IrInstruction *ir_gen_array_access(IrBuilder *irb, Scope *scope, AstNode |
| 3980 | 4393 | return subscript_instruction; |
| 3981 | 4394 | |
| 3982 | 4395 | IrInstruction *ptr_instruction = ir_build_elem_ptr(irb, scope, node, array_ref_instruction, |
| 3983 | | subscript_instruction, true, PtrLenSingle); |
| 4396 | subscript_instruction, true, PtrLenSingle, nullptr); |
| 3984 | 4397 | if (lval == LValPtr) |
| 3985 | 4398 | return ptr_instruction; |
| 3986 | 4399 | |
| 3987 | | return ir_build_load_ptr(irb, scope, node, ptr_instruction); |
| 4400 | IrInstruction *load_ptr = ir_build_load_ptr(irb, scope, node, ptr_instruction); |
| 4401 | return ir_expr_wrap(irb, scope, load_ptr, result_loc); |
| 3988 | 4402 | } |
| 3989 | 4403 | |
| 3990 | 4404 | static IrInstruction *ir_gen_field_access(IrBuilder *irb, Scope *scope, AstNode *node) { |
| ... | ... | @@ -3993,11 +4407,11 @@ static IrInstruction *ir_gen_field_access(IrBuilder *irb, Scope *scope, AstNode |
| 3993 | 4407 | AstNode *container_ref_node = node->data.field_access_expr.struct_expr; |
| 3994 | 4408 | Buf *field_name = node->data.field_access_expr.field_name; |
| 3995 | 4409 | |
| 3996 | | IrInstruction *container_ref_instruction = ir_gen_node_extra(irb, container_ref_node, scope, LValPtr); |
| 4410 | IrInstruction *container_ref_instruction = ir_gen_node_extra(irb, container_ref_node, scope, LValPtr, nullptr); |
| 3997 | 4411 | if (container_ref_instruction == irb->codegen->invalid_instruction) |
| 3998 | 4412 | return container_ref_instruction; |
| 3999 | 4413 | |
| 4000 | | return ir_build_field_ptr(irb, scope, node, container_ref_instruction, field_name); |
| 4414 | return ir_build_field_ptr(irb, scope, node, container_ref_instruction, field_name, false); |
| 4001 | 4415 | } |
| 4002 | 4416 | |
| 4003 | 4417 | static IrInstruction *ir_gen_overflow_op(IrBuilder *irb, Scope *scope, AstNode *node, IrOverflowOp op) { |
| ... | ... | @@ -4028,6 +4442,33 @@ static IrInstruction *ir_gen_overflow_op(IrBuilder *irb, Scope *scope, AstNode * |
| 4028 | 4442 | return ir_build_overflow_op(irb, scope, node, op, type_value, op1, op2, result_ptr, nullptr); |
| 4029 | 4443 | } |
| 4030 | 4444 | |
| 4445 | static IrInstruction *ir_gen_mul_add(IrBuilder *irb, Scope *scope, AstNode *node) { |
| 4446 | assert(node->type == NodeTypeFnCallExpr); |
| 4447 | |
| 4448 | AstNode *type_node = node->data.fn_call_expr.params.at(0); |
| 4449 | AstNode *op1_node = node->data.fn_call_expr.params.at(1); |
| 4450 | AstNode *op2_node = node->data.fn_call_expr.params.at(2); |
| 4451 | AstNode *op3_node = node->data.fn_call_expr.params.at(3); |
| 4452 | |
| 4453 | IrInstruction *type_value = ir_gen_node(irb, type_node, scope); |
| 4454 | if (type_value == irb->codegen->invalid_instruction) |
| 4455 | return irb->codegen->invalid_instruction; |
| 4456 | |
| 4457 | IrInstruction *op1 = ir_gen_node(irb, op1_node, scope); |
| 4458 | if (op1 == irb->codegen->invalid_instruction) |
| 4459 | return irb->codegen->invalid_instruction; |
| 4460 | |
| 4461 | IrInstruction *op2 = ir_gen_node(irb, op2_node, scope); |
| 4462 | if (op2 == irb->codegen->invalid_instruction) |
| 4463 | return irb->codegen->invalid_instruction; |
| 4464 | |
| 4465 | IrInstruction *op3 = ir_gen_node(irb, op3_node, scope); |
| 4466 | if (op3 == irb->codegen->invalid_instruction) |
| 4467 | return irb->codegen->invalid_instruction; |
| 4468 | |
| 4469 | return ir_build_mul_add(irb, scope, node, type_value, op1, op2, op3); |
| 4470 | } |
| 4471 | |
| 4031 | 4472 | static IrInstruction *ir_gen_this(IrBuilder *irb, Scope *orig_scope, AstNode *node) { |
| 4032 | 4473 | for (Scope *it_scope = orig_scope; it_scope != nullptr; it_scope = it_scope->parent) { |
| 4033 | 4474 | if (it_scope->id == ScopeIdDecls) { |
| ... | ... | @@ -4043,7 +4484,9 @@ static IrInstruction *ir_gen_this(IrBuilder *irb, Scope *orig_scope, AstNode *no |
| 4043 | 4484 | zig_unreachable(); |
| 4044 | 4485 | } |
| 4045 | 4486 | |
| 4046 | | static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNode *node, LVal lval) { |
| 4487 | static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNode *node, LVal lval, |
| 4488 | ResultLoc *result_loc) |
| 4489 | { |
| 4047 | 4490 | assert(node->type == NodeTypeFnCallExpr); |
| 4048 | 4491 | |
| 4049 | 4492 | AstNode *fn_ref_expr = node->data.fn_call_expr.fn_ref_expr; |
| ... | ... | @@ -4079,7 +4522,7 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo |
| 4079 | 4522 | return arg; |
| 4080 | 4523 | |
| 4081 | 4524 | IrInstruction *type_of = ir_build_typeof(irb, scope, node, arg); |
| 4082 | | return ir_lval_wrap(irb, scope, type_of, lval); |
| 4525 | return ir_lval_wrap(irb, scope, type_of, lval, result_loc); |
| 4083 | 4526 | } |
| 4084 | 4527 | case BuiltinFnIdSetCold: |
| 4085 | 4528 | { |
| ... | ... | @@ -4089,7 +4532,7 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo |
| 4089 | 4532 | return arg0_value; |
| 4090 | 4533 | |
| 4091 | 4534 | IrInstruction *set_cold = ir_build_set_cold(irb, scope, node, arg0_value); |
| 4092 | | return ir_lval_wrap(irb, scope, set_cold, lval); |
| 4535 | return ir_lval_wrap(irb, scope, set_cold, lval, result_loc); |
| 4093 | 4536 | } |
| 4094 | 4537 | case BuiltinFnIdSetRuntimeSafety: |
| 4095 | 4538 | { |
| ... | ... | @@ -4099,7 +4542,7 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo |
| 4099 | 4542 | return arg0_value; |
| 4100 | 4543 | |
| 4101 | 4544 | IrInstruction *set_safety = ir_build_set_runtime_safety(irb, scope, node, arg0_value); |
| 4102 | | return ir_lval_wrap(irb, scope, set_safety, lval); |
| 4545 | return ir_lval_wrap(irb, scope, set_safety, lval, result_loc); |
| 4103 | 4546 | } |
| 4104 | 4547 | case BuiltinFnIdSetFloatMode: |
| 4105 | 4548 | { |
| ... | ... | @@ -4109,7 +4552,7 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo |
| 4109 | 4552 | return arg0_value; |
| 4110 | 4553 | |
| 4111 | 4554 | IrInstruction *set_float_mode = ir_build_set_float_mode(irb, scope, node, arg0_value); |
| 4112 | | return ir_lval_wrap(irb, scope, set_float_mode, lval); |
| 4555 | return ir_lval_wrap(irb, scope, set_float_mode, lval, result_loc); |
| 4113 | 4556 | } |
| 4114 | 4557 | case BuiltinFnIdSizeof: |
| 4115 | 4558 | { |
| ... | ... | @@ -4119,7 +4562,7 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo |
| 4119 | 4562 | return arg0_value; |
| 4120 | 4563 | |
| 4121 | 4564 | IrInstruction *size_of = ir_build_size_of(irb, scope, node, arg0_value); |
| 4122 | | return ir_lval_wrap(irb, scope, size_of, lval); |
| 4565 | return ir_lval_wrap(irb, scope, size_of, lval, result_loc); |
| 4123 | 4566 | } |
| 4124 | 4567 | case BuiltinFnIdImport: |
| 4125 | 4568 | { |
| ... | ... | @@ -4129,12 +4572,12 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo |
| 4129 | 4572 | return arg0_value; |
| 4130 | 4573 | |
| 4131 | 4574 | IrInstruction *import = ir_build_import(irb, scope, node, arg0_value); |
| 4132 | | return ir_lval_wrap(irb, scope, import, lval); |
| 4575 | return ir_lval_wrap(irb, scope, import, lval, result_loc); |
| 4133 | 4576 | } |
| 4134 | 4577 | case BuiltinFnIdCImport: |
| 4135 | 4578 | { |
| 4136 | 4579 | IrInstruction *c_import = ir_build_c_import(irb, scope, node); |
| 4137 | | return ir_lval_wrap(irb, scope, c_import, lval); |
| 4580 | return ir_lval_wrap(irb, scope, c_import, lval, result_loc); |
| 4138 | 4581 | } |
| 4139 | 4582 | case BuiltinFnIdCInclude: |
| 4140 | 4583 | { |
| ... | ... | @@ -4149,7 +4592,7 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo |
| 4149 | 4592 | } |
| 4150 | 4593 | |
| 4151 | 4594 | IrInstruction *c_include = ir_build_c_include(irb, scope, node, arg0_value); |
| 4152 | | return ir_lval_wrap(irb, scope, c_include, lval); |
| 4595 | return ir_lval_wrap(irb, scope, c_include, lval, result_loc); |
| 4153 | 4596 | } |
| 4154 | 4597 | case BuiltinFnIdCDefine: |
| 4155 | 4598 | { |
| ... | ... | @@ -4169,7 +4612,7 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo |
| 4169 | 4612 | } |
| 4170 | 4613 | |
| 4171 | 4614 | IrInstruction *c_define = ir_build_c_define(irb, scope, node, arg0_value, arg1_value); |
| 4172 | | return ir_lval_wrap(irb, scope, c_define, lval); |
| 4615 | return ir_lval_wrap(irb, scope, c_define, lval, result_loc); |
| 4173 | 4616 | } |
| 4174 | 4617 | case BuiltinFnIdCUndef: |
| 4175 | 4618 | { |
| ... | ... | @@ -4184,7 +4627,7 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo |
| 4184 | 4627 | } |
| 4185 | 4628 | |
| 4186 | 4629 | IrInstruction *c_undef = ir_build_c_undef(irb, scope, node, arg0_value); |
| 4187 | | return ir_lval_wrap(irb, scope, c_undef, lval); |
| 4630 | return ir_lval_wrap(irb, scope, c_undef, lval, result_loc); |
| 4188 | 4631 | } |
| 4189 | 4632 | case BuiltinFnIdCompileErr: |
| 4190 | 4633 | { |
| ... | ... | @@ -4194,7 +4637,7 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo |
| 4194 | 4637 | return arg0_value; |
| 4195 | 4638 | |
| 4196 | 4639 | IrInstruction *compile_err = ir_build_compile_err(irb, scope, node, arg0_value); |
| 4197 | | return ir_lval_wrap(irb, scope, compile_err, lval); |
| 4640 | return ir_lval_wrap(irb, scope, compile_err, lval, result_loc); |
| 4198 | 4641 | } |
| 4199 | 4642 | case BuiltinFnIdCompileLog: |
| 4200 | 4643 | { |
| ... | ... | @@ -4208,7 +4651,7 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo |
| 4208 | 4651 | } |
| 4209 | 4652 | |
| 4210 | 4653 | IrInstruction *compile_log = ir_build_compile_log(irb, scope, node, actual_param_count, args); |
| 4211 | | return ir_lval_wrap(irb, scope, compile_log, lval); |
| 4654 | return ir_lval_wrap(irb, scope, compile_log, lval, result_loc); |
| 4212 | 4655 | } |
| 4213 | 4656 | case BuiltinFnIdErrName: |
| 4214 | 4657 | { |
| ... | ... | @@ -4218,7 +4661,7 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo |
| 4218 | 4661 | return arg0_value; |
| 4219 | 4662 | |
| 4220 | 4663 | IrInstruction *err_name = ir_build_err_name(irb, scope, node, arg0_value); |
| 4221 | | return ir_lval_wrap(irb, scope, err_name, lval); |
| 4664 | return ir_lval_wrap(irb, scope, err_name, lval, result_loc); |
| 4222 | 4665 | } |
| 4223 | 4666 | case BuiltinFnIdEmbedFile: |
| 4224 | 4667 | { |
| ... | ... | @@ -4228,7 +4671,7 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo |
| 4228 | 4671 | return arg0_value; |
| 4229 | 4672 | |
| 4230 | 4673 | IrInstruction *embed_file = ir_build_embed_file(irb, scope, node, arg0_value); |
| 4231 | | return ir_lval_wrap(irb, scope, embed_file, lval); |
| 4674 | return ir_lval_wrap(irb, scope, embed_file, lval, result_loc); |
| 4232 | 4675 | } |
| 4233 | 4676 | case BuiltinFnIdCmpxchgWeak: |
| 4234 | 4677 | case BuiltinFnIdCmpxchgStrong: |
| ... | ... | @@ -4264,8 +4707,9 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo |
| 4264 | 4707 | return arg5_value; |
| 4265 | 4708 | |
| 4266 | 4709 | IrInstruction *cmpxchg = ir_build_cmpxchg_src(irb, scope, node, arg0_value, arg1_value, |
| 4267 | | arg2_value, arg3_value, arg4_value, arg5_value, (builtin_fn->id == BuiltinFnIdCmpxchgWeak)); |
| 4268 | | return ir_lval_wrap(irb, scope, cmpxchg, lval); |
| 4710 | arg2_value, arg3_value, arg4_value, arg5_value, (builtin_fn->id == BuiltinFnIdCmpxchgWeak), |
| 4711 | result_loc); |
| 4712 | return ir_lval_wrap(irb, scope, cmpxchg, lval, result_loc); |
| 4269 | 4713 | } |
| 4270 | 4714 | case BuiltinFnIdFence: |
| 4271 | 4715 | { |
| ... | ... | @@ -4275,7 +4719,7 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo |
| 4275 | 4719 | return arg0_value; |
| 4276 | 4720 | |
| 4277 | 4721 | IrInstruction *fence = ir_build_fence(irb, scope, node, arg0_value, AtomicOrderUnordered); |
| 4278 | | return ir_lval_wrap(irb, scope, fence, lval); |
| 4722 | return ir_lval_wrap(irb, scope, fence, lval, result_loc); |
| 4279 | 4723 | } |
| 4280 | 4724 | case BuiltinFnIdDivExact: |
| 4281 | 4725 | { |
| ... | ... | @@ -4290,7 +4734,7 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo |
| 4290 | 4734 | return arg1_value; |
| 4291 | 4735 | |
| 4292 | 4736 | IrInstruction *bin_op = ir_build_bin_op(irb, scope, node, IrBinOpDivExact, arg0_value, arg1_value, true); |
| 4293 | | return ir_lval_wrap(irb, scope, bin_op, lval); |
| 4737 | return ir_lval_wrap(irb, scope, bin_op, lval, result_loc); |
| 4294 | 4738 | } |
| 4295 | 4739 | case BuiltinFnIdDivTrunc: |
| 4296 | 4740 | { |
| ... | ... | @@ -4305,7 +4749,7 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo |
| 4305 | 4749 | return arg1_value; |
| 4306 | 4750 | |
| 4307 | 4751 | IrInstruction *bin_op = ir_build_bin_op(irb, scope, node, IrBinOpDivTrunc, arg0_value, arg1_value, true); |
| 4308 | | return ir_lval_wrap(irb, scope, bin_op, lval); |
| 4752 | return ir_lval_wrap(irb, scope, bin_op, lval, result_loc); |
| 4309 | 4753 | } |
| 4310 | 4754 | case BuiltinFnIdDivFloor: |
| 4311 | 4755 | { |
| ... | ... | @@ -4320,7 +4764,7 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo |
| 4320 | 4764 | return arg1_value; |
| 4321 | 4765 | |
| 4322 | 4766 | IrInstruction *bin_op = ir_build_bin_op(irb, scope, node, IrBinOpDivFloor, arg0_value, arg1_value, true); |
| 4323 | | return ir_lval_wrap(irb, scope, bin_op, lval); |
| 4767 | return ir_lval_wrap(irb, scope, bin_op, lval, result_loc); |
| 4324 | 4768 | } |
| 4325 | 4769 | case BuiltinFnIdRem: |
| 4326 | 4770 | { |
| ... | ... | @@ -4335,7 +4779,7 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo |
| 4335 | 4779 | return arg1_value; |
| 4336 | 4780 | |
| 4337 | 4781 | IrInstruction *bin_op = ir_build_bin_op(irb, scope, node, IrBinOpRemRem, arg0_value, arg1_value, true); |
| 4338 | | return ir_lval_wrap(irb, scope, bin_op, lval); |
| 4782 | return ir_lval_wrap(irb, scope, bin_op, lval, result_loc); |
| 4339 | 4783 | } |
| 4340 | 4784 | case BuiltinFnIdMod: |
| 4341 | 4785 | { |
| ... | ... | @@ -4350,9 +4794,22 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo |
| 4350 | 4794 | return arg1_value; |
| 4351 | 4795 | |
| 4352 | 4796 | IrInstruction *bin_op = ir_build_bin_op(irb, scope, node, IrBinOpRemMod, arg0_value, arg1_value, true); |
| 4353 | | return ir_lval_wrap(irb, scope, bin_op, lval); |
| 4797 | return ir_lval_wrap(irb, scope, bin_op, lval, result_loc); |
| 4354 | 4798 | } |
| 4355 | 4799 | case BuiltinFnIdSqrt: |
| 4800 | case BuiltinFnIdSin: |
| 4801 | case BuiltinFnIdCos: |
| 4802 | case BuiltinFnIdExp: |
| 4803 | case BuiltinFnIdExp2: |
| 4804 | case BuiltinFnIdLn: |
| 4805 | case BuiltinFnIdLog2: |
| 4806 | case BuiltinFnIdLog10: |
| 4807 | case BuiltinFnIdFabs: |
| 4808 | case BuiltinFnIdFloor: |
| 4809 | case BuiltinFnIdCeil: |
| 4810 | case BuiltinFnIdTrunc: |
| 4811 | case BuiltinFnIdNearbyInt: |
| 4812 | case BuiltinFnIdRound: |
| 4356 | 4813 | { |
| 4357 | 4814 | AstNode *arg0_node = node->data.fn_call_expr.params.at(0); |
| 4358 | 4815 | IrInstruction *arg0_value = ir_gen_node(irb, arg0_node, scope); |
| ... | ... | @@ -4364,8 +4821,8 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo |
| 4364 | 4821 | if (arg1_value == irb->codegen->invalid_instruction) |
| 4365 | 4822 | return arg1_value; |
| 4366 | 4823 | |
| 4367 | | IrInstruction *ir_sqrt = ir_build_sqrt(irb, scope, node, arg0_value, arg1_value); |
| 4368 | | return ir_lval_wrap(irb, scope, ir_sqrt, lval); |
| 4824 | IrInstruction *ir_sqrt = ir_build_float_op(irb, scope, node, arg0_value, arg1_value, builtin_fn->id); |
| 4825 | return ir_lval_wrap(irb, scope, ir_sqrt, lval, result_loc); |
| 4369 | 4826 | } |
| 4370 | 4827 | case BuiltinFnIdTruncate: |
| 4371 | 4828 | { |
| ... | ... | @@ -4380,7 +4837,7 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo |
| 4380 | 4837 | return arg1_value; |
| 4381 | 4838 | |
| 4382 | 4839 | IrInstruction *truncate = ir_build_truncate(irb, scope, node, arg0_value, arg1_value); |
| 4383 | | return ir_lval_wrap(irb, scope, truncate, lval); |
| 4840 | return ir_lval_wrap(irb, scope, truncate, lval, result_loc); |
| 4384 | 4841 | } |
| 4385 | 4842 | case BuiltinFnIdIntCast: |
| 4386 | 4843 | { |
| ... | ... | @@ -4395,7 +4852,7 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo |
| 4395 | 4852 | return arg1_value; |
| 4396 | 4853 | |
| 4397 | 4854 | IrInstruction *result = ir_build_int_cast(irb, scope, node, arg0_value, arg1_value); |
| 4398 | | return ir_lval_wrap(irb, scope, result, lval); |
| 4855 | return ir_lval_wrap(irb, scope, result, lval, result_loc); |
| 4399 | 4856 | } |
| 4400 | 4857 | case BuiltinFnIdFloatCast: |
| 4401 | 4858 | { |
| ... | ... | @@ -4410,7 +4867,7 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo |
| 4410 | 4867 | return arg1_value; |
| 4411 | 4868 | |
| 4412 | 4869 | IrInstruction *result = ir_build_float_cast(irb, scope, node, arg0_value, arg1_value); |
| 4413 | | return ir_lval_wrap(irb, scope, result, lval); |
| 4870 | return ir_lval_wrap(irb, scope, result, lval, result_loc); |
| 4414 | 4871 | } |
| 4415 | 4872 | case BuiltinFnIdErrSetCast: |
| 4416 | 4873 | { |
| ... | ... | @@ -4425,7 +4882,7 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo |
| 4425 | 4882 | return arg1_value; |
| 4426 | 4883 | |
| 4427 | 4884 | IrInstruction *result = ir_build_err_set_cast(irb, scope, node, arg0_value, arg1_value); |
| 4428 | | return ir_lval_wrap(irb, scope, result, lval); |
| 4885 | return ir_lval_wrap(irb, scope, result, lval, result_loc); |
| 4429 | 4886 | } |
| 4430 | 4887 | case BuiltinFnIdFromBytes: |
| 4431 | 4888 | { |
| ... | ... | @@ -4439,8 +4896,8 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo |
| 4439 | 4896 | if (arg1_value == irb->codegen->invalid_instruction) |
| 4440 | 4897 | return arg1_value; |
| 4441 | 4898 | |
| 4442 | | IrInstruction *result = ir_build_from_bytes(irb, scope, node, arg0_value, arg1_value); |
| 4443 | | return ir_lval_wrap(irb, scope, result, lval); |
| 4899 | IrInstruction *result = ir_build_from_bytes(irb, scope, node, arg0_value, arg1_value, result_loc); |
| 4900 | return ir_lval_wrap(irb, scope, result, lval, result_loc); |
| 4444 | 4901 | } |
| 4445 | 4902 | case BuiltinFnIdToBytes: |
| 4446 | 4903 | { |
| ... | ... | @@ -4449,8 +4906,8 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo |
| 4449 | 4906 | if (arg0_value == irb->codegen->invalid_instruction) |
| 4450 | 4907 | return arg0_value; |
| 4451 | 4908 | |
| 4452 | | IrInstruction *result = ir_build_to_bytes(irb, scope, node, arg0_value); |
| 4453 | | return ir_lval_wrap(irb, scope, result, lval); |
| 4909 | IrInstruction *result = ir_build_to_bytes(irb, scope, node, arg0_value, result_loc); |
| 4910 | return ir_lval_wrap(irb, scope, result, lval, result_loc); |
| 4454 | 4911 | } |
| 4455 | 4912 | case BuiltinFnIdIntToFloat: |
| 4456 | 4913 | { |
| ... | ... | @@ -4465,7 +4922,7 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo |
| 4465 | 4922 | return arg1_value; |
| 4466 | 4923 | |
| 4467 | 4924 | IrInstruction *result = ir_build_int_to_float(irb, scope, node, arg0_value, arg1_value); |
| 4468 | | return ir_lval_wrap(irb, scope, result, lval); |
| 4925 | return ir_lval_wrap(irb, scope, result, lval, result_loc); |
| 4469 | 4926 | } |
| 4470 | 4927 | case BuiltinFnIdFloatToInt: |
| 4471 | 4928 | { |
| ... | ... | @@ -4480,7 +4937,7 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo |
| 4480 | 4937 | return arg1_value; |
| 4481 | 4938 | |
| 4482 | 4939 | IrInstruction *result = ir_build_float_to_int(irb, scope, node, arg0_value, arg1_value); |
| 4483 | | return ir_lval_wrap(irb, scope, result, lval); |
| 4940 | return ir_lval_wrap(irb, scope, result, lval, result_loc); |
| 4484 | 4941 | } |
| 4485 | 4942 | case BuiltinFnIdErrToInt: |
| 4486 | 4943 | { |
| ... | ... | @@ -4490,7 +4947,7 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo |
| 4490 | 4947 | return arg0_value; |
| 4491 | 4948 | |
| 4492 | 4949 | IrInstruction *result = ir_build_err_to_int(irb, scope, node, arg0_value); |
| 4493 | | return ir_lval_wrap(irb, scope, result, lval); |
| 4950 | return ir_lval_wrap(irb, scope, result, lval, result_loc); |
| 4494 | 4951 | } |
| 4495 | 4952 | case BuiltinFnIdIntToErr: |
| 4496 | 4953 | { |
| ... | ... | @@ -4500,7 +4957,7 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo |
| 4500 | 4957 | return arg0_value; |
| 4501 | 4958 | |
| 4502 | 4959 | IrInstruction *result = ir_build_int_to_err(irb, scope, node, arg0_value); |
| 4503 | | return ir_lval_wrap(irb, scope, result, lval); |
| 4960 | return ir_lval_wrap(irb, scope, result, lval, result_loc); |
| 4504 | 4961 | } |
| 4505 | 4962 | case BuiltinFnIdBoolToInt: |
| 4506 | 4963 | { |
| ... | ... | @@ -4510,7 +4967,7 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo |
| 4510 | 4967 | return arg0_value; |
| 4511 | 4968 | |
| 4512 | 4969 | IrInstruction *result = ir_build_bool_to_int(irb, scope, node, arg0_value); |
| 4513 | | return ir_lval_wrap(irb, scope, result, lval); |
| 4970 | return ir_lval_wrap(irb, scope, result, lval, result_loc); |
| 4514 | 4971 | } |
| 4515 | 4972 | case BuiltinFnIdIntType: |
| 4516 | 4973 | { |
| ... | ... | @@ -4525,7 +4982,7 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo |
| 4525 | 4982 | return arg1_value; |
| 4526 | 4983 | |
| 4527 | 4984 | IrInstruction *int_type = ir_build_int_type(irb, scope, node, arg0_value, arg1_value); |
| 4528 | | return ir_lval_wrap(irb, scope, int_type, lval); |
| 4985 | return ir_lval_wrap(irb, scope, int_type, lval, result_loc); |
| 4529 | 4986 | } |
| 4530 | 4987 | case BuiltinFnIdVectorType: |
| 4531 | 4988 | { |
| ... | ... | @@ -4540,7 +4997,7 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo |
| 4540 | 4997 | return arg1_value; |
| 4541 | 4998 | |
| 4542 | 4999 | IrInstruction *vector_type = ir_build_vector_type(irb, scope, node, arg0_value, arg1_value); |
| 4543 | | return ir_lval_wrap(irb, scope, vector_type, lval); |
| 5000 | return ir_lval_wrap(irb, scope, vector_type, lval, result_loc); |
| 4544 | 5001 | } |
| 4545 | 5002 | case BuiltinFnIdMemcpy: |
| 4546 | 5003 | { |
| ... | ... | @@ -4560,7 +5017,7 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo |
| 4560 | 5017 | return arg2_value; |
| 4561 | 5018 | |
| 4562 | 5019 | IrInstruction *ir_memcpy = ir_build_memcpy(irb, scope, node, arg0_value, arg1_value, arg2_value); |
| 4563 | | return ir_lval_wrap(irb, scope, ir_memcpy, lval); |
| 5020 | return ir_lval_wrap(irb, scope, ir_memcpy, lval, result_loc); |
| 4564 | 5021 | } |
| 4565 | 5022 | case BuiltinFnIdMemset: |
| 4566 | 5023 | { |
| ... | ... | @@ -4580,7 +5037,7 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo |
| 4580 | 5037 | return arg2_value; |
| 4581 | 5038 | |
| 4582 | 5039 | IrInstruction *ir_memset = ir_build_memset(irb, scope, node, arg0_value, arg1_value, arg2_value); |
| 4583 | | return ir_lval_wrap(irb, scope, ir_memset, lval); |
| 5040 | return ir_lval_wrap(irb, scope, ir_memset, lval, result_loc); |
| 4584 | 5041 | } |
| 4585 | 5042 | case BuiltinFnIdMemberCount: |
| 4586 | 5043 | { |
| ... | ... | @@ -4590,7 +5047,7 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo |
| 4590 | 5047 | return arg0_value; |
| 4591 | 5048 | |
| 4592 | 5049 | IrInstruction *member_count = ir_build_member_count(irb, scope, node, arg0_value); |
| 4593 | | return ir_lval_wrap(irb, scope, member_count, lval); |
| 5050 | return ir_lval_wrap(irb, scope, member_count, lval, result_loc); |
| 4594 | 5051 | } |
| 4595 | 5052 | case BuiltinFnIdMemberType: |
| 4596 | 5053 | { |
| ... | ... | @@ -4606,7 +5063,7 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo |
| 4606 | 5063 | |
| 4607 | 5064 | |
| 4608 | 5065 | IrInstruction *member_type = ir_build_member_type(irb, scope, node, arg0_value, arg1_value); |
| 4609 | | return ir_lval_wrap(irb, scope, member_type, lval); |
| 5066 | return ir_lval_wrap(irb, scope, member_type, lval, result_loc); |
| 4610 | 5067 | } |
| 4611 | 5068 | case BuiltinFnIdMemberName: |
| 4612 | 5069 | { |
| ... | ... | @@ -4622,12 +5079,12 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo |
| 4622 | 5079 | |
| 4623 | 5080 | |
| 4624 | 5081 | IrInstruction *member_name = ir_build_member_name(irb, scope, node, arg0_value, arg1_value); |
| 4625 | | return ir_lval_wrap(irb, scope, member_name, lval); |
| 5082 | return ir_lval_wrap(irb, scope, member_name, lval, result_loc); |
| 4626 | 5083 | } |
| 4627 | 5084 | case BuiltinFnIdField: |
| 4628 | 5085 | { |
| 4629 | 5086 | AstNode *arg0_node = node->data.fn_call_expr.params.at(0); |
| 4630 | | IrInstruction *arg0_value = ir_gen_node_extra(irb, arg0_node, scope, LValPtr); |
| 5087 | IrInstruction *arg0_value = ir_gen_node_extra(irb, arg0_node, scope, LValPtr, nullptr); |
| 4631 | 5088 | if (arg0_value == irb->codegen->invalid_instruction) |
| 4632 | 5089 | return arg0_value; |
| 4633 | 5090 | |
| ... | ... | @@ -4641,7 +5098,8 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo |
| 4641 | 5098 | if (lval == LValPtr) |
| 4642 | 5099 | return ptr_instruction; |
| 4643 | 5100 | |
| 4644 | | return ir_build_load_ptr(irb, scope, node, ptr_instruction); |
| 5101 | IrInstruction *load_ptr = ir_build_load_ptr(irb, scope, node, ptr_instruction); |
| 5102 | return ir_expr_wrap(irb, scope, load_ptr, result_loc); |
| 4645 | 5103 | } |
| 4646 | 5104 | case BuiltinFnIdTypeInfo: |
| 4647 | 5105 | { |
| ... | ... | @@ -4651,14 +5109,14 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo |
| 4651 | 5109 | return arg0_value; |
| 4652 | 5110 | |
| 4653 | 5111 | IrInstruction *type_info = ir_build_type_info(irb, scope, node, arg0_value); |
| 4654 | | return ir_lval_wrap(irb, scope, type_info, lval); |
| 5112 | return ir_lval_wrap(irb, scope, type_info, lval, result_loc); |
| 4655 | 5113 | } |
| 4656 | 5114 | case BuiltinFnIdBreakpoint: |
| 4657 | | return ir_lval_wrap(irb, scope, ir_build_breakpoint(irb, scope, node), lval); |
| 5115 | return ir_lval_wrap(irb, scope, ir_build_breakpoint(irb, scope, node), lval, result_loc); |
| 4658 | 5116 | case BuiltinFnIdReturnAddress: |
| 4659 | | return ir_lval_wrap(irb, scope, ir_build_return_address(irb, scope, node), lval); |
| 5117 | return ir_lval_wrap(irb, scope, ir_build_return_address(irb, scope, node), lval, result_loc); |
| 4660 | 5118 | case BuiltinFnIdFrameAddress: |
| 4661 | | return ir_lval_wrap(irb, scope, ir_build_frame_address(irb, scope, node), lval); |
| 5119 | return ir_lval_wrap(irb, scope, ir_build_frame_address(irb, scope, node), lval, result_loc); |
| 4662 | 5120 | case BuiltinFnIdHandle: |
| 4663 | 5121 | if (!irb->exec->fn_entry) { |
| 4664 | 5122 | add_node_error(irb->codegen, node, buf_sprintf("@handle() called outside of function definition")); |
| ... | ... | @@ -4668,7 +5126,7 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo |
| 4668 | 5126 | add_node_error(irb->codegen, node, buf_sprintf("@handle() in non-async function")); |
| 4669 | 5127 | return irb->codegen->invalid_instruction; |
| 4670 | 5128 | } |
| 4671 | | return ir_lval_wrap(irb, scope, ir_build_handle(irb, scope, node), lval); |
| 5129 | return ir_lval_wrap(irb, scope, ir_build_handle(irb, scope, node), lval, result_loc); |
| 4672 | 5130 | case BuiltinFnIdAlignOf: |
| 4673 | 5131 | { |
| 4674 | 5132 | AstNode *arg0_node = node->data.fn_call_expr.params.at(0); |
| ... | ... | @@ -4677,16 +5135,18 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo |
| 4677 | 5135 | return arg0_value; |
| 4678 | 5136 | |
| 4679 | 5137 | IrInstruction *align_of = ir_build_align_of(irb, scope, node, arg0_value); |
| 4680 | | return ir_lval_wrap(irb, scope, align_of, lval); |
| 5138 | return ir_lval_wrap(irb, scope, align_of, lval, result_loc); |
| 4681 | 5139 | } |
| 4682 | 5140 | case BuiltinFnIdAddWithOverflow: |
| 4683 | | return ir_lval_wrap(irb, scope, ir_gen_overflow_op(irb, scope, node, IrOverflowOpAdd), lval); |
| 5141 | return ir_lval_wrap(irb, scope, ir_gen_overflow_op(irb, scope, node, IrOverflowOpAdd), lval, result_loc); |
| 4684 | 5142 | case BuiltinFnIdSubWithOverflow: |
| 4685 | | return ir_lval_wrap(irb, scope, ir_gen_overflow_op(irb, scope, node, IrOverflowOpSub), lval); |
| 5143 | return ir_lval_wrap(irb, scope, ir_gen_overflow_op(irb, scope, node, IrOverflowOpSub), lval, result_loc); |
| 4686 | 5144 | case BuiltinFnIdMulWithOverflow: |
| 4687 | | return ir_lval_wrap(irb, scope, ir_gen_overflow_op(irb, scope, node, IrOverflowOpMul), lval); |
| 5145 | return ir_lval_wrap(irb, scope, ir_gen_overflow_op(irb, scope, node, IrOverflowOpMul), lval, result_loc); |
| 4688 | 5146 | case BuiltinFnIdShlWithOverflow: |
| 4689 | | return ir_lval_wrap(irb, scope, ir_gen_overflow_op(irb, scope, node, IrOverflowOpShl), lval); |
| 5147 | return ir_lval_wrap(irb, scope, ir_gen_overflow_op(irb, scope, node, IrOverflowOpShl), lval, result_loc); |
| 5148 | case BuiltinFnIdMulAdd: |
| 5149 | return ir_lval_wrap(irb, scope, ir_gen_mul_add(irb, scope, node), lval, result_loc); |
| 4690 | 5150 | case BuiltinFnIdTypeName: |
| 4691 | 5151 | { |
| 4692 | 5152 | AstNode *arg0_node = node->data.fn_call_expr.params.at(0); |
| ... | ... | @@ -4695,7 +5155,7 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo |
| 4695 | 5155 | return arg0_value; |
| 4696 | 5156 | |
| 4697 | 5157 | IrInstruction *type_name = ir_build_type_name(irb, scope, node, arg0_value); |
| 4698 | | return ir_lval_wrap(irb, scope, type_name, lval); |
| 5158 | return ir_lval_wrap(irb, scope, type_name, lval, result_loc); |
| 4699 | 5159 | } |
| 4700 | 5160 | case BuiltinFnIdPanic: |
| 4701 | 5161 | { |
| ... | ... | @@ -4705,7 +5165,7 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo |
| 4705 | 5165 | return arg0_value; |
| 4706 | 5166 | |
| 4707 | 5167 | IrInstruction *panic = ir_build_panic(irb, scope, node, arg0_value); |
| 4708 | | return ir_lval_wrap(irb, scope, panic, lval); |
| 5168 | return ir_lval_wrap(irb, scope, panic, lval, result_loc); |
| 4709 | 5169 | } |
| 4710 | 5170 | case BuiltinFnIdPtrCast: |
| 4711 | 5171 | { |
| ... | ... | @@ -4720,22 +5180,31 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo |
| 4720 | 5180 | return arg1_value; |
| 4721 | 5181 | |
| 4722 | 5182 | IrInstruction *ptr_cast = ir_build_ptr_cast_src(irb, scope, node, arg0_value, arg1_value, true); |
| 4723 | | return ir_lval_wrap(irb, scope, ptr_cast, lval); |
| 5183 | return ir_lval_wrap(irb, scope, ptr_cast, lval, result_loc); |
| 4724 | 5184 | } |
| 4725 | 5185 | case BuiltinFnIdBitCast: |
| 4726 | 5186 | { |
| 4727 | | AstNode *arg0_node = node->data.fn_call_expr.params.at(0); |
| 4728 | | IrInstruction *arg0_value = ir_gen_node(irb, arg0_node, scope); |
| 4729 | | if (arg0_value == irb->codegen->invalid_instruction) |
| 4730 | | return arg0_value; |
| 5187 | AstNode *dest_type_node = node->data.fn_call_expr.params.at(0); |
| 5188 | IrInstruction *dest_type = ir_gen_node(irb, dest_type_node, scope); |
| 5189 | if (dest_type == irb->codegen->invalid_instruction) |
| 5190 | return dest_type; |
| 5191 | |
| 5192 | ResultLocBitCast *result_loc_bit_cast = allocate<ResultLocBitCast>(1); |
| 5193 | result_loc_bit_cast->base.id = ResultLocIdBitCast; |
| 5194 | result_loc_bit_cast->base.source_instruction = dest_type; |
| 5195 | ir_ref_instruction(dest_type, irb->current_basic_block); |
| 5196 | result_loc_bit_cast->parent = result_loc; |
| 5197 | |
| 5198 | ir_build_reset_result(irb, scope, node, &result_loc_bit_cast->base); |
| 4731 | 5199 | |
| 4732 | 5200 | AstNode *arg1_node = node->data.fn_call_expr.params.at(1); |
| 4733 | | IrInstruction *arg1_value = ir_gen_node(irb, arg1_node, scope); |
| 5201 | IrInstruction *arg1_value = ir_gen_node_extra(irb, arg1_node, scope, LValNone, |
| 5202 | &result_loc_bit_cast->base); |
| 4734 | 5203 | if (arg1_value == irb->codegen->invalid_instruction) |
| 4735 | 5204 | return arg1_value; |
| 4736 | 5205 | |
| 4737 | | IrInstruction *bit_cast = ir_build_bit_cast(irb, scope, node, arg0_value, arg1_value); |
| 4738 | | return ir_lval_wrap(irb, scope, bit_cast, lval); |
| 5206 | IrInstruction *bitcast = ir_build_bit_cast_src(irb, scope, arg1_node, arg1_value, result_loc_bit_cast); |
| 5207 | return ir_lval_wrap(irb, scope, bitcast, lval, result_loc); |
| 4739 | 5208 | } |
| 4740 | 5209 | case BuiltinFnIdIntToPtr: |
| 4741 | 5210 | { |
| ... | ... | @@ -4750,7 +5219,7 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo |
| 4750 | 5219 | return arg1_value; |
| 4751 | 5220 | |
| 4752 | 5221 | IrInstruction *int_to_ptr = ir_build_int_to_ptr(irb, scope, node, arg0_value, arg1_value); |
| 4753 | | return ir_lval_wrap(irb, scope, int_to_ptr, lval); |
| 5222 | return ir_lval_wrap(irb, scope, int_to_ptr, lval, result_loc); |
| 4754 | 5223 | } |
| 4755 | 5224 | case BuiltinFnIdPtrToInt: |
| 4756 | 5225 | { |
| ... | ... | @@ -4760,7 +5229,7 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo |
| 4760 | 5229 | return arg0_value; |
| 4761 | 5230 | |
| 4762 | 5231 | IrInstruction *ptr_to_int = ir_build_ptr_to_int(irb, scope, node, arg0_value); |
| 4763 | | return ir_lval_wrap(irb, scope, ptr_to_int, lval); |
| 5232 | return ir_lval_wrap(irb, scope, ptr_to_int, lval, result_loc); |
| 4764 | 5233 | } |
| 4765 | 5234 | case BuiltinFnIdTagName: |
| 4766 | 5235 | { |
| ... | ... | @@ -4771,7 +5240,7 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo |
| 4771 | 5240 | |
| 4772 | 5241 | IrInstruction *actual_tag = ir_build_union_tag(irb, scope, node, arg0_value); |
| 4773 | 5242 | IrInstruction *tag_name = ir_build_tag_name(irb, scope, node, actual_tag); |
| 4774 | | return ir_lval_wrap(irb, scope, tag_name, lval); |
| 5243 | return ir_lval_wrap(irb, scope, tag_name, lval, result_loc); |
| 4775 | 5244 | } |
| 4776 | 5245 | case BuiltinFnIdTagType: |
| 4777 | 5246 | { |
| ... | ... | @@ -4781,7 +5250,7 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo |
| 4781 | 5250 | return arg0_value; |
| 4782 | 5251 | |
| 4783 | 5252 | IrInstruction *tag_type = ir_build_tag_type(irb, scope, node, arg0_value); |
| 4784 | | return ir_lval_wrap(irb, scope, tag_type, lval); |
| 5253 | return ir_lval_wrap(irb, scope, tag_type, lval, result_loc); |
| 4785 | 5254 | } |
| 4786 | 5255 | case BuiltinFnIdFieldParentPtr: |
| 4787 | 5256 | { |
| ... | ... | @@ -4801,7 +5270,7 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo |
| 4801 | 5270 | return arg2_value; |
| 4802 | 5271 | |
| 4803 | 5272 | IrInstruction *field_parent_ptr = ir_build_field_parent_ptr(irb, scope, node, arg0_value, arg1_value, arg2_value, nullptr); |
| 4804 | | return ir_lval_wrap(irb, scope, field_parent_ptr, lval); |
| 5273 | return ir_lval_wrap(irb, scope, field_parent_ptr, lval, result_loc); |
| 4805 | 5274 | } |
| 4806 | 5275 | case BuiltinFnIdByteOffsetOf: |
| 4807 | 5276 | { |
| ... | ... | @@ -4816,7 +5285,7 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo |
| 4816 | 5285 | return arg1_value; |
| 4817 | 5286 | |
| 4818 | 5287 | IrInstruction *offset_of = ir_build_byte_offset_of(irb, scope, node, arg0_value, arg1_value); |
| 4819 | | return ir_lval_wrap(irb, scope, offset_of, lval); |
| 5288 | return ir_lval_wrap(irb, scope, offset_of, lval, result_loc); |
| 4820 | 5289 | } |
| 4821 | 5290 | case BuiltinFnIdBitOffsetOf: |
| 4822 | 5291 | { |
| ... | ... | @@ -4831,7 +5300,7 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo |
| 4831 | 5300 | return arg1_value; |
| 4832 | 5301 | |
| 4833 | 5302 | IrInstruction *offset_of = ir_build_bit_offset_of(irb, scope, node, arg0_value, arg1_value); |
| 4834 | | return ir_lval_wrap(irb, scope, offset_of, lval); |
| 5303 | return ir_lval_wrap(irb, scope, offset_of, lval, result_loc); |
| 4835 | 5304 | } |
| 4836 | 5305 | case BuiltinFnIdInlineCall: |
| 4837 | 5306 | case BuiltinFnIdNoInlineCall: |
| ... | ... | @@ -4857,8 +5326,9 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo |
| 4857 | 5326 | } |
| 4858 | 5327 | FnInline fn_inline = (builtin_fn->id == BuiltinFnIdInlineCall) ? FnInlineAlways : FnInlineNever; |
| 4859 | 5328 | |
| 4860 | | IrInstruction *call = ir_build_call(irb, scope, node, nullptr, fn_ref, arg_count, args, false, fn_inline, false, nullptr, nullptr); |
| 4861 | | return ir_lval_wrap(irb, scope, call, lval); |
| 5329 | IrInstruction *call = ir_build_call_src(irb, scope, node, nullptr, fn_ref, arg_count, args, false, |
| 5330 | fn_inline, false, nullptr, nullptr, result_loc); |
| 5331 | return ir_lval_wrap(irb, scope, call, lval, result_loc); |
| 4862 | 5332 | } |
| 4863 | 5333 | case BuiltinFnIdNewStackCall: |
| 4864 | 5334 | { |
| ... | ... | @@ -4887,8 +5357,9 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo |
| 4887 | 5357 | return args[i]; |
| 4888 | 5358 | } |
| 4889 | 5359 | |
| 4890 | | IrInstruction *call = ir_build_call(irb, scope, node, nullptr, fn_ref, arg_count, args, false, FnInlineAuto, false, nullptr, new_stack); |
| 4891 | | return ir_lval_wrap(irb, scope, call, lval); |
| 5360 | IrInstruction *call = ir_build_call_src(irb, scope, node, nullptr, fn_ref, arg_count, args, false, |
| 5361 | FnInlineAuto, false, nullptr, new_stack, result_loc); |
| 5362 | return ir_lval_wrap(irb, scope, call, lval, result_loc); |
| 4892 | 5363 | } |
| 4893 | 5364 | case BuiltinFnIdTypeId: |
| 4894 | 5365 | { |
| ... | ... | @@ -4898,7 +5369,7 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo |
| 4898 | 5369 | return arg0_value; |
| 4899 | 5370 | |
| 4900 | 5371 | IrInstruction *type_id = ir_build_type_id(irb, scope, node, arg0_value); |
| 4901 | | return ir_lval_wrap(irb, scope, type_id, lval); |
| 5372 | return ir_lval_wrap(irb, scope, type_id, lval, result_loc); |
| 4902 | 5373 | } |
| 4903 | 5374 | case BuiltinFnIdShlExact: |
| 4904 | 5375 | { |
| ... | ... | @@ -4913,7 +5384,7 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo |
| 4913 | 5384 | return arg1_value; |
| 4914 | 5385 | |
| 4915 | 5386 | IrInstruction *bin_op = ir_build_bin_op(irb, scope, node, IrBinOpBitShiftLeftExact, arg0_value, arg1_value, true); |
| 4916 | | return ir_lval_wrap(irb, scope, bin_op, lval); |
| 5387 | return ir_lval_wrap(irb, scope, bin_op, lval, result_loc); |
| 4917 | 5388 | } |
| 4918 | 5389 | case BuiltinFnIdShrExact: |
| 4919 | 5390 | { |
| ... | ... | @@ -4928,7 +5399,7 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo |
| 4928 | 5399 | return arg1_value; |
| 4929 | 5400 | |
| 4930 | 5401 | IrInstruction *bin_op = ir_build_bin_op(irb, scope, node, IrBinOpBitShiftRightExact, arg0_value, arg1_value, true); |
| 4931 | | return ir_lval_wrap(irb, scope, bin_op, lval); |
| 5402 | return ir_lval_wrap(irb, scope, bin_op, lval, result_loc); |
| 4932 | 5403 | } |
| 4933 | 5404 | case BuiltinFnIdSetEvalBranchQuota: |
| 4934 | 5405 | { |
| ... | ... | @@ -4938,7 +5409,7 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo |
| 4938 | 5409 | return arg0_value; |
| 4939 | 5410 | |
| 4940 | 5411 | IrInstruction *set_eval_branch_quota = ir_build_set_eval_branch_quota(irb, scope, node, arg0_value); |
| 4941 | | return ir_lval_wrap(irb, scope, set_eval_branch_quota, lval); |
| 5412 | return ir_lval_wrap(irb, scope, set_eval_branch_quota, lval, result_loc); |
| 4942 | 5413 | } |
| 4943 | 5414 | case BuiltinFnIdAlignCast: |
| 4944 | 5415 | { |
| ... | ... | @@ -4953,17 +5424,17 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo |
| 4953 | 5424 | return arg1_value; |
| 4954 | 5425 | |
| 4955 | 5426 | IrInstruction *align_cast = ir_build_align_cast(irb, scope, node, arg0_value, arg1_value); |
| 4956 | | return ir_lval_wrap(irb, scope, align_cast, lval); |
| 5427 | return ir_lval_wrap(irb, scope, align_cast, lval, result_loc); |
| 4957 | 5428 | } |
| 4958 | 5429 | case BuiltinFnIdOpaqueType: |
| 4959 | 5430 | { |
| 4960 | 5431 | IrInstruction *opaque_type = ir_build_opaque_type(irb, scope, node); |
| 4961 | | return ir_lval_wrap(irb, scope, opaque_type, lval); |
| 5432 | return ir_lval_wrap(irb, scope, opaque_type, lval, result_loc); |
| 4962 | 5433 | } |
| 4963 | 5434 | case BuiltinFnIdThis: |
| 4964 | 5435 | { |
| 4965 | 5436 | IrInstruction *this_inst = ir_gen_this(irb, scope, node); |
| 4966 | | return ir_lval_wrap(irb, scope, this_inst, lval); |
| 5437 | return ir_lval_wrap(irb, scope, this_inst, lval, result_loc); |
| 4967 | 5438 | } |
| 4968 | 5439 | case BuiltinFnIdSetAlignStack: |
| 4969 | 5440 | { |
| ... | ... | @@ -4973,7 +5444,7 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo |
| 4973 | 5444 | return arg0_value; |
| 4974 | 5445 | |
| 4975 | 5446 | IrInstruction *set_align_stack = ir_build_set_align_stack(irb, scope, node, arg0_value); |
| 4976 | | return ir_lval_wrap(irb, scope, set_align_stack, lval); |
| 5447 | return ir_lval_wrap(irb, scope, set_align_stack, lval, result_loc); |
| 4977 | 5448 | } |
| 4978 | 5449 | case BuiltinFnIdArgType: |
| 4979 | 5450 | { |
| ... | ... | @@ -4988,7 +5459,7 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo |
| 4988 | 5459 | return arg1_value; |
| 4989 | 5460 | |
| 4990 | 5461 | IrInstruction *arg_type = ir_build_arg_type(irb, scope, node, arg0_value, arg1_value); |
| 4991 | | return ir_lval_wrap(irb, scope, arg_type, lval); |
| 5462 | return ir_lval_wrap(irb, scope, arg_type, lval, result_loc); |
| 4992 | 5463 | } |
| 4993 | 5464 | case BuiltinFnIdExport: |
| 4994 | 5465 | { |
| ... | ... | @@ -5008,12 +5479,12 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo |
| 5008 | 5479 | return arg2_value; |
| 5009 | 5480 | |
| 5010 | 5481 | IrInstruction *ir_export = ir_build_export(irb, scope, node, arg0_value, arg1_value, arg2_value); |
| 5011 | | return ir_lval_wrap(irb, scope, ir_export, lval); |
| 5482 | return ir_lval_wrap(irb, scope, ir_export, lval, result_loc); |
| 5012 | 5483 | } |
| 5013 | 5484 | case BuiltinFnIdErrorReturnTrace: |
| 5014 | 5485 | { |
| 5015 | 5486 | IrInstruction *error_return_trace = ir_build_error_return_trace(irb, scope, node, IrInstructionErrorReturnTrace::Null); |
| 5016 | | return ir_lval_wrap(irb, scope, error_return_trace, lval); |
| 5487 | return ir_lval_wrap(irb, scope, error_return_trace, lval, result_loc); |
| 5017 | 5488 | } |
| 5018 | 5489 | case BuiltinFnIdAtomicRmw: |
| 5019 | 5490 | { |
| ... | ... | @@ -5042,10 +5513,11 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo |
| 5042 | 5513 | if (arg4_value == irb->codegen->invalid_instruction) |
| 5043 | 5514 | return arg4_value; |
| 5044 | 5515 | |
| 5045 | | return ir_build_atomic_rmw(irb, scope, node, arg0_value, arg1_value, arg2_value, arg3_value, |
| 5516 | IrInstruction *inst = ir_build_atomic_rmw(irb, scope, node, arg0_value, arg1_value, arg2_value, arg3_value, |
| 5046 | 5517 | arg4_value, |
| 5047 | 5518 | // these 2 values don't mean anything since we passed non-null values for other args |
| 5048 | 5519 | AtomicRmwOp_xchg, AtomicOrderMonotonic); |
| 5520 | return ir_lval_wrap(irb, scope, inst, lval, result_loc); |
| 5049 | 5521 | } |
| 5050 | 5522 | case BuiltinFnIdAtomicLoad: |
| 5051 | 5523 | { |
| ... | ... | @@ -5064,9 +5536,10 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo |
| 5064 | 5536 | if (arg2_value == irb->codegen->invalid_instruction) |
| 5065 | 5537 | return arg2_value; |
| 5066 | 5538 | |
| 5067 | | return ir_build_atomic_load(irb, scope, node, arg0_value, arg1_value, arg2_value, |
| 5539 | IrInstruction *inst = ir_build_atomic_load(irb, scope, node, arg0_value, arg1_value, arg2_value, |
| 5068 | 5540 | // this value does not mean anything since we passed non-null values for other arg |
| 5069 | 5541 | AtomicOrderMonotonic); |
| 5542 | return ir_lval_wrap(irb, scope, inst, lval, result_loc); |
| 5070 | 5543 | } |
| 5071 | 5544 | case BuiltinFnIdIntToEnum: |
| 5072 | 5545 | { |
| ... | ... | @@ -5081,7 +5554,7 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo |
| 5081 | 5554 | return arg1_value; |
| 5082 | 5555 | |
| 5083 | 5556 | IrInstruction *result = ir_build_int_to_enum(irb, scope, node, arg0_value, arg1_value); |
| 5084 | | return ir_lval_wrap(irb, scope, result, lval); |
| 5557 | return ir_lval_wrap(irb, scope, result, lval, result_loc); |
| 5085 | 5558 | } |
| 5086 | 5559 | case BuiltinFnIdEnumToInt: |
| 5087 | 5560 | { |
| ... | ... | @@ -5091,7 +5564,7 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo |
| 5091 | 5564 | return arg0_value; |
| 5092 | 5565 | |
| 5093 | 5566 | IrInstruction *result = ir_build_enum_to_int(irb, scope, node, arg0_value); |
| 5094 | | return ir_lval_wrap(irb, scope, result, lval); |
| 5567 | return ir_lval_wrap(irb, scope, result, lval, result_loc); |
| 5095 | 5568 | } |
| 5096 | 5569 | case BuiltinFnIdCtz: |
| 5097 | 5570 | case BuiltinFnIdPopCount: |
| ... | ... | @@ -5129,7 +5602,7 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo |
| 5129 | 5602 | default: |
| 5130 | 5603 | zig_unreachable(); |
| 5131 | 5604 | } |
| 5132 | | return ir_lval_wrap(irb, scope, result, lval); |
| 5605 | return ir_lval_wrap(irb, scope, result, lval, result_loc); |
| 5133 | 5606 | } |
| 5134 | 5607 | case BuiltinFnIdHasDecl: |
| 5135 | 5608 | { |
| ... | ... | @@ -5144,17 +5617,19 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo |
| 5144 | 5617 | return arg1_value; |
| 5145 | 5618 | |
| 5146 | 5619 | IrInstruction *has_decl = ir_build_has_decl(irb, scope, node, arg0_value, arg1_value); |
| 5147 | | return ir_lval_wrap(irb, scope, has_decl, lval); |
| 5620 | return ir_lval_wrap(irb, scope, has_decl, lval, result_loc); |
| 5148 | 5621 | } |
| 5149 | 5622 | } |
| 5150 | 5623 | zig_unreachable(); |
| 5151 | 5624 | } |
| 5152 | 5625 | |
| 5153 | | static IrInstruction *ir_gen_fn_call(IrBuilder *irb, Scope *scope, AstNode *node, LVal lval) { |
| 5626 | static IrInstruction *ir_gen_fn_call(IrBuilder *irb, Scope *scope, AstNode *node, LVal lval, |
| 5627 | ResultLoc *result_loc) |
| 5628 | { |
| 5154 | 5629 | assert(node->type == NodeTypeFnCallExpr); |
| 5155 | 5630 | |
| 5156 | 5631 | if (node->data.fn_call_expr.is_builtin) |
| 5157 | | return ir_gen_builtin_fn_call(irb, scope, node, lval); |
| 5632 | return ir_gen_builtin_fn_call(irb, scope, node, lval, result_loc); |
| 5158 | 5633 | |
| 5159 | 5634 | AstNode *fn_ref_node = node->data.fn_call_expr.fn_ref_expr; |
| 5160 | 5635 | IrInstruction *fn_ref = ir_gen_node(irb, fn_ref_node, scope); |
| ... | ... | @@ -5180,12 +5655,14 @@ static IrInstruction *ir_gen_fn_call(IrBuilder *irb, Scope *scope, AstNode *node |
| 5180 | 5655 | } |
| 5181 | 5656 | } |
| 5182 | 5657 | |
| 5183 | | IrInstruction *fn_call = ir_build_call(irb, scope, node, nullptr, fn_ref, arg_count, args, false, FnInlineAuto, |
| 5184 | | is_async, async_allocator, nullptr); |
| 5185 | | return ir_lval_wrap(irb, scope, fn_call, lval); |
| 5658 | IrInstruction *fn_call = ir_build_call_src(irb, scope, node, nullptr, fn_ref, arg_count, args, false, FnInlineAuto, |
| 5659 | is_async, async_allocator, nullptr, result_loc); |
| 5660 | return ir_lval_wrap(irb, scope, fn_call, lval, result_loc); |
| 5186 | 5661 | } |
| 5187 | 5662 | |
| 5188 | | static IrInstruction *ir_gen_if_bool_expr(IrBuilder *irb, Scope *scope, AstNode *node) { |
| 5663 | static IrInstruction *ir_gen_if_bool_expr(IrBuilder *irb, Scope *scope, AstNode *node, LVal lval, |
| 5664 | ResultLoc *result_loc) |
| 5665 | { |
| 5189 | 5666 | assert(node->type == NodeTypeIfBoolExpr); |
| 5190 | 5667 | |
| 5191 | 5668 | IrInstruction *condition = ir_gen_node(irb, node->data.if_bool_expr.condition, scope); |
| ... | ... | @@ -5206,12 +5683,16 @@ static IrInstruction *ir_gen_if_bool_expr(IrBuilder *irb, Scope *scope, AstNode |
| 5206 | 5683 | IrBasicBlock *else_block = ir_create_basic_block(irb, scope, "Else"); |
| 5207 | 5684 | IrBasicBlock *endif_block = ir_create_basic_block(irb, scope, "EndIf"); |
| 5208 | 5685 | |
| 5209 | | ir_build_cond_br(irb, scope, condition->source_node, condition, then_block, else_block, is_comptime); |
| 5686 | IrInstruction *cond_br_inst = ir_build_cond_br(irb, scope, node, condition, |
| 5687 | then_block, else_block, is_comptime); |
| 5688 | ResultLocPeerParent *peer_parent = ir_build_binary_result_peers(irb, cond_br_inst, else_block, endif_block, |
| 5689 | result_loc, is_comptime); |
| 5210 | 5690 | |
| 5211 | 5691 | ir_set_cursor_at_end_and_append_block(irb, then_block); |
| 5212 | 5692 | |
| 5213 | 5693 | Scope *subexpr_scope = create_runtime_scope(irb->codegen, node, scope, is_comptime); |
| 5214 | | IrInstruction *then_expr_result = ir_gen_node(irb, then_node, subexpr_scope); |
| 5694 | IrInstruction *then_expr_result = ir_gen_node_extra(irb, then_node, subexpr_scope, lval, |
| 5695 | &peer_parent->peers.at(0)->base); |
| 5215 | 5696 | if (then_expr_result == irb->codegen->invalid_instruction) |
| 5216 | 5697 | return irb->codegen->invalid_instruction; |
| 5217 | 5698 | IrBasicBlock *after_then_block = irb->current_basic_block; |
| ... | ... | @@ -5221,11 +5702,12 @@ static IrInstruction *ir_gen_if_bool_expr(IrBuilder *irb, Scope *scope, AstNode |
| 5221 | 5702 | ir_set_cursor_at_end_and_append_block(irb, else_block); |
| 5222 | 5703 | IrInstruction *else_expr_result; |
| 5223 | 5704 | if (else_node) { |
| 5224 | | else_expr_result = ir_gen_node(irb, else_node, subexpr_scope); |
| 5705 | else_expr_result = ir_gen_node_extra(irb, else_node, subexpr_scope, lval, &peer_parent->peers.at(1)->base); |
| 5225 | 5706 | if (else_expr_result == irb->codegen->invalid_instruction) |
| 5226 | 5707 | return irb->codegen->invalid_instruction; |
| 5227 | 5708 | } else { |
| 5228 | 5709 | else_expr_result = ir_build_const_void(irb, scope, node); |
| 5710 | ir_build_end_expr(irb, scope, node, else_expr_result, &peer_parent->peers.at(1)->base); |
| 5229 | 5711 | } |
| 5230 | 5712 | IrBasicBlock *after_else_block = irb->current_basic_block; |
| 5231 | 5713 | if (!instr_is_unreachable(else_expr_result)) |
| ... | ... | @@ -5239,14 +5721,15 @@ static IrInstruction *ir_gen_if_bool_expr(IrBuilder *irb, Scope *scope, AstNode |
| 5239 | 5721 | incoming_blocks[0] = after_then_block; |
| 5240 | 5722 | incoming_blocks[1] = after_else_block; |
| 5241 | 5723 | |
| 5242 | | return ir_build_phi(irb, scope, node, 2, incoming_blocks, incoming_values); |
| 5724 | IrInstruction *phi = ir_build_phi(irb, scope, node, 2, incoming_blocks, incoming_values, peer_parent); |
| 5725 | return ir_expr_wrap(irb, scope, phi, result_loc); |
| 5243 | 5726 | } |
| 5244 | 5727 | |
| 5245 | 5728 | static IrInstruction *ir_gen_prefix_op_id_lval(IrBuilder *irb, Scope *scope, AstNode *node, IrUnOp op_id, LVal lval) { |
| 5246 | 5729 | assert(node->type == NodeTypePrefixOpExpr); |
| 5247 | 5730 | AstNode *expr_node = node->data.prefix_op_expr.primary_expr; |
| 5248 | 5731 | |
| 5249 | | IrInstruction *value = ir_gen_node_extra(irb, expr_node, scope, lval); |
| 5732 | IrInstruction *value = ir_gen_node_extra(irb, expr_node, scope, lval, nullptr); |
| 5250 | 5733 | if (value == irb->codegen->invalid_instruction) |
| 5251 | 5734 | return value; |
| 5252 | 5735 | |
| ... | ... | @@ -5257,15 +5740,34 @@ static IrInstruction *ir_gen_prefix_op_id(IrBuilder *irb, Scope *scope, AstNode |
| 5257 | 5740 | return ir_gen_prefix_op_id_lval(irb, scope, node, op_id, LValNone); |
| 5258 | 5741 | } |
| 5259 | 5742 | |
| 5260 | | static IrInstruction *ir_lval_wrap(IrBuilder *irb, Scope *scope, IrInstruction *value, LVal lval) { |
| 5261 | | if (lval != LValPtr) |
| 5743 | static IrInstruction *ir_expr_wrap(IrBuilder *irb, Scope *scope, IrInstruction *inst, ResultLoc *result_loc) { |
| 5744 | ir_build_end_expr(irb, scope, inst->source_node, inst, result_loc); |
| 5745 | return inst; |
| 5746 | } |
| 5747 | |
| 5748 | static IrInstruction *ir_lval_wrap(IrBuilder *irb, Scope *scope, IrInstruction *value, LVal lval, |
| 5749 | ResultLoc *result_loc) |
| 5750 | { |
| 5751 | // This logic must be kept in sync with |
| 5752 | // [STMT_EXPR_TEST_THING] <--- (search this token) |
| 5753 | if (value == irb->codegen->invalid_instruction || |
| 5754 | instr_is_unreachable(value) || |
| 5755 | value->source_node->type == NodeTypeDefer || |
| 5756 | value->id == IrInstructionIdDeclVarSrc) |
| 5757 | { |
| 5262 | 5758 | return value; |
| 5263 | | if (value == irb->codegen->invalid_instruction) |
| 5759 | } |
| 5760 | |
| 5761 | if (lval == LValPtr) { |
| 5762 | // We needed a pointer to a value, but we got a value. So we create |
| 5763 | // an instruction which just makes a pointer of it. |
| 5764 | return ir_build_ref(irb, scope, value->source_node, value, false, false); |
| 5765 | } else if (result_loc != nullptr) { |
| 5766 | return ir_expr_wrap(irb, scope, value, result_loc); |
| 5767 | } else { |
| 5264 | 5768 | return value; |
| 5769 | } |
| 5265 | 5770 | |
| 5266 | | // We needed a pointer to a value, but we got a value. So we create |
| 5267 | | // an instruction which just makes a const pointer of it. |
| 5268 | | return ir_build_ref(irb, scope, value->source_node, value, false, false); |
| 5269 | 5771 | } |
| 5270 | 5772 | |
| 5271 | 5773 | static PtrLen star_token_to_ptr_len(TokenId token_id) { |
| ... | ... | @@ -5338,21 +5840,22 @@ static IrInstruction *ir_gen_pointer_type(IrBuilder *irb, Scope *scope, AstNode |
| 5338 | 5840 | ptr_len, align_value, bit_offset_start, host_int_bytes, is_allow_zero); |
| 5339 | 5841 | } |
| 5340 | 5842 | |
| 5341 | | static IrInstruction *ir_gen_catch_unreachable(IrBuilder *irb, Scope *scope, AstNode *source_node, AstNode *expr_node, |
| 5342 | | LVal lval) |
| 5843 | static IrInstruction *ir_gen_catch_unreachable(IrBuilder *irb, Scope *scope, AstNode *source_node, |
| 5844 | AstNode *expr_node, LVal lval, ResultLoc *result_loc) |
| 5343 | 5845 | { |
| 5344 | | IrInstruction *err_union_ptr = ir_gen_node_extra(irb, expr_node, scope, LValPtr); |
| 5846 | IrInstruction *err_union_ptr = ir_gen_node_extra(irb, expr_node, scope, LValPtr, nullptr); |
| 5345 | 5847 | if (err_union_ptr == irb->codegen->invalid_instruction) |
| 5346 | 5848 | return irb->codegen->invalid_instruction; |
| 5347 | 5849 | |
| 5348 | | IrInstruction *payload_ptr = ir_build_unwrap_err_payload(irb, scope, source_node, err_union_ptr, true); |
| 5850 | IrInstruction *payload_ptr = ir_build_unwrap_err_payload(irb, scope, source_node, err_union_ptr, true, false); |
| 5349 | 5851 | if (payload_ptr == irb->codegen->invalid_instruction) |
| 5350 | 5852 | return irb->codegen->invalid_instruction; |
| 5351 | 5853 | |
| 5352 | 5854 | if (lval == LValPtr) |
| 5353 | 5855 | return payload_ptr; |
| 5354 | 5856 | |
| 5355 | | return ir_build_load_ptr(irb, scope, source_node, payload_ptr); |
| 5857 | IrInstruction *load_ptr = ir_build_load_ptr(irb, scope, source_node, payload_ptr); |
| 5858 | return ir_expr_wrap(irb, scope, load_ptr, result_loc); |
| 5356 | 5859 | } |
| 5357 | 5860 | |
| 5358 | 5861 | static IrInstruction *ir_gen_bool_not(IrBuilder *irb, Scope *scope, AstNode *node) { |
| ... | ... | @@ -5366,7 +5869,9 @@ static IrInstruction *ir_gen_bool_not(IrBuilder *irb, Scope *scope, AstNode *nod |
| 5366 | 5869 | return ir_build_bool_not(irb, scope, node, value); |
| 5367 | 5870 | } |
| 5368 | 5871 | |
| 5369 | | static IrInstruction *ir_gen_prefix_op_expr(IrBuilder *irb, Scope *scope, AstNode *node, LVal lval) { |
| 5872 | static IrInstruction *ir_gen_prefix_op_expr(IrBuilder *irb, Scope *scope, AstNode *node, LVal lval, |
| 5873 | ResultLoc *result_loc) |
| 5874 | { |
| 5370 | 5875 | assert(node->type == NodeTypePrefixOpExpr); |
| 5371 | 5876 | |
| 5372 | 5877 | PrefixOp prefix_op = node->data.prefix_op_expr.prefix_op; |
| ... | ... | @@ -5375,24 +5880,26 @@ static IrInstruction *ir_gen_prefix_op_expr(IrBuilder *irb, Scope *scope, AstNod |
| 5375 | 5880 | case PrefixOpInvalid: |
| 5376 | 5881 | zig_unreachable(); |
| 5377 | 5882 | case PrefixOpBoolNot: |
| 5378 | | return ir_lval_wrap(irb, scope, ir_gen_bool_not(irb, scope, node), lval); |
| 5883 | return ir_lval_wrap(irb, scope, ir_gen_bool_not(irb, scope, node), lval, result_loc); |
| 5379 | 5884 | case PrefixOpBinNot: |
| 5380 | | return ir_lval_wrap(irb, scope, ir_gen_prefix_op_id(irb, scope, node, IrUnOpBinNot), lval); |
| 5885 | return ir_lval_wrap(irb, scope, ir_gen_prefix_op_id(irb, scope, node, IrUnOpBinNot), lval, result_loc); |
| 5381 | 5886 | case PrefixOpNegation: |
| 5382 | | return ir_lval_wrap(irb, scope, ir_gen_prefix_op_id(irb, scope, node, IrUnOpNegation), lval); |
| 5887 | return ir_lval_wrap(irb, scope, ir_gen_prefix_op_id(irb, scope, node, IrUnOpNegation), lval, result_loc); |
| 5383 | 5888 | case PrefixOpNegationWrap: |
| 5384 | | return ir_lval_wrap(irb, scope, ir_gen_prefix_op_id(irb, scope, node, IrUnOpNegationWrap), lval); |
| 5889 | return ir_lval_wrap(irb, scope, ir_gen_prefix_op_id(irb, scope, node, IrUnOpNegationWrap), lval, result_loc); |
| 5385 | 5890 | case PrefixOpOptional: |
| 5386 | | return ir_lval_wrap(irb, scope, ir_gen_prefix_op_id(irb, scope, node, IrUnOpOptional), lval); |
| 5891 | return ir_lval_wrap(irb, scope, ir_gen_prefix_op_id(irb, scope, node, IrUnOpOptional), lval, result_loc); |
| 5387 | 5892 | case PrefixOpAddrOf: { |
| 5388 | 5893 | AstNode *expr_node = node->data.prefix_op_expr.primary_expr; |
| 5389 | | return ir_lval_wrap(irb, scope, ir_gen_node_extra(irb, expr_node, scope, LValPtr), lval); |
| 5894 | return ir_lval_wrap(irb, scope, ir_gen_node_extra(irb, expr_node, scope, LValPtr, nullptr), lval, result_loc); |
| 5390 | 5895 | } |
| 5391 | 5896 | } |
| 5392 | 5897 | zig_unreachable(); |
| 5393 | 5898 | } |
| 5394 | 5899 | |
| 5395 | | static IrInstruction *ir_gen_container_init_expr(IrBuilder *irb, Scope *scope, AstNode *node) { |
| 5900 | static IrInstruction *ir_gen_container_init_expr(IrBuilder *irb, Scope *scope, AstNode *node, LVal lval, |
| 5901 | ResultLoc *parent_result_loc) |
| 5902 | { |
| 5396 | 5903 | assert(node->type == NodeTypeContainerInitExpr); |
| 5397 | 5904 | |
| 5398 | 5905 | AstNodeContainerInitExpr *container_init_expr = &node->data.container_init_expr; |
| ... | ... | @@ -5410,45 +5917,104 @@ static IrInstruction *ir_gen_container_init_expr(IrBuilder *irb, Scope *scope, A |
| 5410 | 5917 | return container_type; |
| 5411 | 5918 | } |
| 5412 | 5919 | |
| 5413 | | if (kind == ContainerInitKindStruct) { |
| 5414 | | if (elem_type != nullptr) { |
| 5415 | | add_node_error(irb->codegen, container_init_expr->type, |
| 5416 | | buf_sprintf("initializing array with struct syntax")); |
| 5417 | | return irb->codegen->invalid_instruction; |
| 5418 | | } |
| 5920 | switch (kind) { |
| 5921 | case ContainerInitKindStruct: { |
| 5922 | if (elem_type != nullptr) { |
| 5923 | add_node_error(irb->codegen, container_init_expr->type, |
| 5924 | buf_sprintf("initializing array with struct syntax")); |
| 5925 | return irb->codegen->invalid_instruction; |
| 5926 | } |
| 5927 | |
| 5928 | IrInstruction *container_ptr = ir_build_resolve_result(irb, scope, node, parent_result_loc, |
| 5929 | container_type); |
| 5930 | |
| 5931 | size_t field_count = container_init_expr->entries.length; |
| 5932 | IrInstructionContainerInitFieldsField *fields = allocate<IrInstructionContainerInitFieldsField>(field_count); |
| 5933 | for (size_t i = 0; i < field_count; i += 1) { |
| 5934 | AstNode *entry_node = container_init_expr->entries.at(i); |
| 5935 | assert(entry_node->type == NodeTypeStructValueField); |
| 5419 | 5936 | |
| 5420 | | size_t field_count = container_init_expr->entries.length; |
| 5421 | | IrInstructionContainerInitFieldsField *fields = allocate<IrInstructionContainerInitFieldsField>(field_count); |
| 5422 | | for (size_t i = 0; i < field_count; i += 1) { |
| 5423 | | AstNode *entry_node = container_init_expr->entries.at(i); |
| 5424 | | assert(entry_node->type == NodeTypeStructValueField); |
| 5937 | Buf *name = entry_node->data.struct_val_field.name; |
| 5938 | AstNode *expr_node = entry_node->data.struct_val_field.expr; |
| 5425 | 5939 | |
| 5426 | | Buf *name = entry_node->data.struct_val_field.name; |
| 5427 | | AstNode *expr_node = entry_node->data.struct_val_field.expr; |
| 5428 | | IrInstruction *expr_value = ir_gen_node(irb, expr_node, scope); |
| 5429 | | if (expr_value == irb->codegen->invalid_instruction) |
| 5430 | | return expr_value; |
| 5940 | IrInstruction *field_ptr = ir_build_field_ptr(irb, scope, entry_node, container_ptr, name, true); |
| 5941 | ResultLocInstruction *result_loc_inst = allocate<ResultLocInstruction>(1); |
| 5942 | result_loc_inst->base.id = ResultLocIdInstruction; |
| 5943 | result_loc_inst->base.source_instruction = field_ptr; |
| 5944 | ir_ref_instruction(field_ptr, irb->current_basic_block); |
| 5945 | ir_build_reset_result(irb, scope, expr_node, &result_loc_inst->base); |
| 5431 | 5946 | |
| 5432 | | fields[i].name = name; |
| 5433 | | fields[i].value = expr_value; |
| 5434 | | fields[i].source_node = entry_node; |
| 5947 | IrInstruction *expr_value = ir_gen_node_extra(irb, expr_node, scope, LValNone, |
| 5948 | &result_loc_inst->base); |
| 5949 | if (expr_value == irb->codegen->invalid_instruction) |
| 5950 | return expr_value; |
| 5951 | |
| 5952 | fields[i].name = name; |
| 5953 | fields[i].source_node = entry_node; |
| 5954 | fields[i].result_loc = field_ptr; |
| 5955 | } |
| 5956 | IrInstruction *init_fields = ir_build_container_init_fields(irb, scope, node, container_type, |
| 5957 | field_count, fields, container_ptr); |
| 5958 | |
| 5959 | return ir_lval_wrap(irb, scope, init_fields, lval, parent_result_loc); |
| 5435 | 5960 | } |
| 5436 | | return ir_build_container_init_fields(irb, scope, node, container_type, field_count, fields); |
| 5437 | | } else if (kind == ContainerInitKindArray) { |
| 5438 | | size_t item_count = container_init_expr->entries.length; |
| 5439 | | IrInstruction **values = allocate<IrInstruction *>(item_count); |
| 5440 | | for (size_t i = 0; i < item_count; i += 1) { |
| 5441 | | AstNode *expr_node = container_init_expr->entries.at(i); |
| 5442 | | IrInstruction *expr_value = ir_gen_node(irb, expr_node, scope); |
| 5443 | | if (expr_value == irb->codegen->invalid_instruction) |
| 5444 | | return expr_value; |
| 5961 | case ContainerInitKindArray: { |
| 5962 | size_t item_count = container_init_expr->entries.length; |
| 5963 | |
| 5964 | if (container_type == nullptr) { |
| 5965 | IrInstruction *item_count_inst = ir_build_const_usize(irb, scope, node, item_count); |
| 5966 | container_type = ir_build_array_type(irb, scope, node, item_count_inst, elem_type); |
| 5967 | } |
| 5968 | |
| 5969 | IrInstruction *container_ptr = ir_build_resolve_result(irb, scope, node, parent_result_loc, |
| 5970 | container_type); |
| 5971 | |
| 5972 | IrInstruction **result_locs = allocate<IrInstruction *>(item_count); |
| 5973 | for (size_t i = 0; i < item_count; i += 1) { |
| 5974 | AstNode *expr_node = container_init_expr->entries.at(i); |
| 5975 | |
| 5976 | IrInstruction *elem_index = ir_build_const_usize(irb, scope, expr_node, i); |
| 5977 | IrInstruction *elem_ptr = ir_build_elem_ptr(irb, scope, expr_node, container_ptr, elem_index, |
| 5978 | false, PtrLenSingle, container_type); |
| 5979 | ResultLocInstruction *result_loc_inst = allocate<ResultLocInstruction>(1); |
| 5980 | result_loc_inst->base.id = ResultLocIdInstruction; |
| 5981 | result_loc_inst->base.source_instruction = elem_ptr; |
| 5982 | ir_ref_instruction(elem_ptr, irb->current_basic_block); |
| 5983 | ir_build_reset_result(irb, scope, expr_node, &result_loc_inst->base); |
| 5445 | 5984 | |
| 5446 | | values[i] = expr_value; |
| 5985 | IrInstruction *expr_value = ir_gen_node_extra(irb, expr_node, scope, LValNone, |
| 5986 | &result_loc_inst->base); |
| 5987 | if (expr_value == irb->codegen->invalid_instruction) |
| 5988 | return expr_value; |
| 5989 | |
| 5990 | result_locs[i] = elem_ptr; |
| 5991 | } |
| 5992 | IrInstruction *init_list = ir_build_container_init_list(irb, scope, node, container_type, |
| 5993 | item_count, result_locs, container_ptr); |
| 5994 | return ir_lval_wrap(irb, scope, init_list, lval, parent_result_loc); |
| 5447 | 5995 | } |
| 5448 | | return ir_build_container_init_list(irb, scope, node, container_type, elem_type, item_count, values); |
| 5449 | | } else { |
| 5450 | | zig_unreachable(); |
| 5451 | 5996 | } |
| 5997 | zig_unreachable(); |
| 5998 | } |
| 5999 | |
| 6000 | static ResultLocVar *ir_build_var_result_loc(IrBuilder *irb, IrInstruction *alloca, ZigVar *var) { |
| 6001 | ResultLocVar *result_loc_var = allocate<ResultLocVar>(1); |
| 6002 | result_loc_var->base.id = ResultLocIdVar; |
| 6003 | result_loc_var->base.source_instruction = alloca; |
| 6004 | result_loc_var->var = var; |
| 6005 | |
| 6006 | ir_build_reset_result(irb, alloca->scope, alloca->source_node, &result_loc_var->base); |
| 6007 | |
| 6008 | return result_loc_var; |
| 6009 | } |
| 6010 | |
| 6011 | static void build_decl_var_and_init(IrBuilder *irb, Scope *scope, AstNode *source_node, ZigVar *var, |
| 6012 | IrInstruction *init, const char *name_hint, IrInstruction *is_comptime) |
| 6013 | { |
| 6014 | IrInstruction *alloca = ir_build_alloca_src(irb, scope, source_node, nullptr, name_hint, is_comptime); |
| 6015 | ResultLocVar *var_result_loc = ir_build_var_result_loc(irb, alloca, var); |
| 6016 | ir_build_end_expr(irb, scope, source_node, init, &var_result_loc->base); |
| 6017 | ir_build_var_decl_src(irb, scope, source_node, var, nullptr, alloca); |
| 5452 | 6018 | } |
| 5453 | 6019 | |
| 5454 | 6020 | static IrInstruction *ir_gen_var_decl(IrBuilder *irb, Scope *scope, AstNode *node) { |
| ... | ... | @@ -5461,9 +6027,12 @@ static IrInstruction *ir_gen_var_decl(IrBuilder *irb, Scope *scope, AstNode *nod |
| 5461 | 6027 | return irb->codegen->invalid_instruction; |
| 5462 | 6028 | } |
| 5463 | 6029 | |
| 6030 | // Used for the type expr and the align expr |
| 6031 | Scope *comptime_scope = create_comptime_scope(irb->codegen, node, scope); |
| 6032 | |
| 5464 | 6033 | IrInstruction *type_instruction; |
| 5465 | 6034 | if (variable_declaration->type != nullptr) { |
| 5466 | | type_instruction = ir_gen_node(irb, variable_declaration->type, scope); |
| 6035 | type_instruction = ir_gen_node(irb, variable_declaration->type, comptime_scope); |
| 5467 | 6036 | if (type_instruction == irb->codegen->invalid_instruction) |
| 5468 | 6037 | return type_instruction; |
| 5469 | 6038 | } else { |
| ... | ... | @@ -5474,8 +6043,8 @@ static IrInstruction *ir_gen_var_decl(IrBuilder *irb, Scope *scope, AstNode *nod |
| 5474 | 6043 | bool is_const = variable_declaration->is_const; |
| 5475 | 6044 | bool is_extern = variable_declaration->is_extern; |
| 5476 | 6045 | |
| 5477 | | IrInstruction *is_comptime = ir_build_const_bool(irb, scope, node, |
| 5478 | | ir_should_inline(irb->exec, scope) || variable_declaration->is_comptime); |
| 6046 | bool is_comptime_scalar = ir_should_inline(irb->exec, scope) || variable_declaration->is_comptime; |
| 6047 | IrInstruction *is_comptime = ir_build_const_bool(irb, scope, node, is_comptime_scalar); |
| 5479 | 6048 | ZigVar *var = ir_create_var(irb, node, scope, variable_declaration->symbol, |
| 5480 | 6049 | is_const, is_const, is_shadowable, is_comptime); |
| 5481 | 6050 | // we detect IrInstructionIdDeclVarSrc in gen_block to make sure the next node |
| ... | ... | @@ -5489,7 +6058,7 @@ static IrInstruction *ir_gen_var_decl(IrBuilder *irb, Scope *scope, AstNode *nod |
| 5489 | 6058 | |
| 5490 | 6059 | IrInstruction *align_value = nullptr; |
| 5491 | 6060 | if (variable_declaration->align_expr != nullptr) { |
| 5492 | | align_value = ir_gen_node(irb, variable_declaration->align_expr, scope); |
| 6061 | align_value = ir_gen_node(irb, variable_declaration->align_expr, comptime_scope); |
| 5493 | 6062 | if (align_value == irb->codegen->invalid_instruction) |
| 5494 | 6063 | return align_value; |
| 5495 | 6064 | } |
| ... | ... | @@ -5502,20 +6071,39 @@ static IrInstruction *ir_gen_var_decl(IrBuilder *irb, Scope *scope, AstNode *nod |
| 5502 | 6071 | // Parser should ensure that this never happens |
| 5503 | 6072 | assert(variable_declaration->threadlocal_tok == nullptr); |
| 5504 | 6073 | |
| 6074 | IrInstruction *alloca = ir_build_alloca_src(irb, scope, node, align_value, |
| 6075 | buf_ptr(variable_declaration->symbol), is_comptime); |
| 6076 | |
| 6077 | // Create a result location for the initialization expression. |
| 6078 | ResultLocVar *result_loc_var = ir_build_var_result_loc(irb, alloca, var); |
| 6079 | ResultLoc *init_result_loc = (type_instruction == nullptr) ? &result_loc_var->base : nullptr; |
| 6080 | |
| 6081 | Scope *init_scope = is_comptime_scalar ? |
| 6082 | create_comptime_scope(irb->codegen, variable_declaration->expr, scope) : scope; |
| 6083 | |
| 5505 | 6084 | // Temporarily set the name of the IrExecutable to the VariableDeclaration |
| 5506 | 6085 | // so that the struct or enum from the init expression inherits the name. |
| 5507 | 6086 | Buf *old_exec_name = irb->exec->name; |
| 5508 | 6087 | irb->exec->name = variable_declaration->symbol; |
| 5509 | | IrInstruction *init_value = ir_gen_node(irb, variable_declaration->expr, scope); |
| 6088 | IrInstruction *init_value = ir_gen_node_extra(irb, variable_declaration->expr, init_scope, |
| 6089 | LValNone, init_result_loc); |
| 5510 | 6090 | irb->exec->name = old_exec_name; |
| 5511 | 6091 | |
| 5512 | 6092 | if (init_value == irb->codegen->invalid_instruction) |
| 5513 | | return init_value; |
| 6093 | return irb->codegen->invalid_instruction; |
| 6094 | |
| 6095 | if (type_instruction != nullptr) { |
| 6096 | IrInstruction *implicit_cast = ir_build_implicit_cast(irb, scope, node, type_instruction, init_value, |
| 6097 | &result_loc_var->base); |
| 6098 | ir_build_end_expr(irb, scope, node, implicit_cast, &result_loc_var->base); |
| 6099 | } |
| 5514 | 6100 | |
| 5515 | | return ir_build_var_decl_src(irb, scope, node, var, type_instruction, align_value, init_value); |
| 6101 | return ir_build_var_decl_src(irb, scope, node, var, align_value, alloca); |
| 5516 | 6102 | } |
| 5517 | 6103 | |
| 5518 | | static IrInstruction *ir_gen_while_expr(IrBuilder *irb, Scope *scope, AstNode *node) { |
| 6104 | static IrInstruction *ir_gen_while_expr(IrBuilder *irb, Scope *scope, AstNode *node, LVal lval, |
| 6105 | ResultLoc *result_loc) |
| 6106 | { |
| 5519 | 6107 | assert(node->type == NodeTypeWhileExpr); |
| 5520 | 6108 | |
| 5521 | 6109 | AstNode *continue_expr_node = node->data.while_expr.continue_expr; |
| ... | ... | @@ -5550,25 +6138,33 @@ static IrInstruction *ir_gen_while_expr(IrBuilder *irb, Scope *scope, AstNode *n |
| 5550 | 6138 | } else { |
| 5551 | 6139 | payload_scope = subexpr_scope; |
| 5552 | 6140 | } |
| 5553 | | IrInstruction *err_val_ptr = ir_gen_node_extra(irb, node->data.while_expr.condition, subexpr_scope, LValPtr); |
| 6141 | IrInstruction *err_val_ptr = ir_gen_node_extra(irb, node->data.while_expr.condition, subexpr_scope, |
| 6142 | LValPtr, nullptr); |
| 5554 | 6143 | if (err_val_ptr == irb->codegen->invalid_instruction) |
| 5555 | 6144 | return err_val_ptr; |
| 5556 | | IrInstruction *err_val = ir_build_load_ptr(irb, scope, node->data.while_expr.condition, err_val_ptr); |
| 5557 | | IrInstruction *is_err = ir_build_test_err(irb, scope, node->data.while_expr.condition, err_val); |
| 6145 | IrInstruction *is_err = ir_build_test_err_src(irb, scope, node->data.while_expr.condition, err_val_ptr, true); |
| 5558 | 6146 | IrBasicBlock *after_cond_block = irb->current_basic_block; |
| 5559 | 6147 | IrInstruction *void_else_result = else_node ? nullptr : ir_mark_gen(ir_build_const_void(irb, scope, node)); |
| 6148 | IrInstruction *cond_br_inst; |
| 5560 | 6149 | if (!instr_is_unreachable(is_err)) { |
| 5561 | | ir_mark_gen(ir_build_cond_br(irb, scope, node->data.while_expr.condition, is_err, |
| 5562 | | else_block, body_block, is_comptime)); |
| 6150 | cond_br_inst = ir_build_cond_br(irb, scope, node->data.while_expr.condition, is_err, |
| 6151 | else_block, body_block, is_comptime); |
| 6152 | cond_br_inst->is_gen = true; |
| 6153 | } else { |
| 6154 | // for the purposes of the source instruction to ir_build_result_peers |
| 6155 | cond_br_inst = irb->current_basic_block->instruction_list.last(); |
| 5563 | 6156 | } |
| 5564 | 6157 | |
| 6158 | ResultLocPeerParent *peer_parent = ir_build_result_peers(irb, cond_br_inst, end_block, result_loc, |
| 6159 | is_comptime); |
| 6160 | |
| 5565 | 6161 | ir_set_cursor_at_end_and_append_block(irb, body_block); |
| 5566 | 6162 | if (var_symbol) { |
| 5567 | | IrInstruction *var_ptr_value = ir_build_unwrap_err_payload(irb, payload_scope, symbol_node, |
| 5568 | | err_val_ptr, false); |
| 5569 | | IrInstruction *var_value = node->data.while_expr.var_is_ptr ? |
| 5570 | | var_ptr_value : ir_build_load_ptr(irb, payload_scope, symbol_node, var_ptr_value); |
| 5571 | | ir_build_var_decl_src(irb, payload_scope, symbol_node, payload_var, nullptr, nullptr, var_value); |
| 6163 | IrInstruction *payload_ptr = ir_build_unwrap_err_payload(irb, payload_scope, symbol_node, |
| 6164 | err_val_ptr, false, false); |
| 6165 | IrInstruction *var_ptr = node->data.while_expr.var_is_ptr ? |
| 6166 | ir_build_ref(irb, payload_scope, symbol_node, payload_ptr, true, false) : payload_ptr; |
| 6167 | ir_build_var_decl_src(irb, payload_scope, symbol_node, payload_var, nullptr, var_ptr); |
| 5572 | 6168 | } |
| 5573 | 6169 | |
| 5574 | 6170 | ZigList<IrInstruction *> incoming_values = {0}; |
| ... | ... | @@ -5580,7 +6176,12 @@ static IrInstruction *ir_gen_while_expr(IrBuilder *irb, Scope *scope, AstNode *n |
| 5580 | 6176 | loop_scope->is_comptime = is_comptime; |
| 5581 | 6177 | loop_scope->incoming_blocks = &incoming_blocks; |
| 5582 | 6178 | loop_scope->incoming_values = &incoming_values; |
| 6179 | loop_scope->lval = lval; |
| 6180 | loop_scope->peer_parent = peer_parent; |
| 5583 | 6181 | |
| 6182 | // Note the body block of the loop is not the place that lval and result_loc are used - |
| 6183 | // it's actually in break statements, handled similarly to return statements. |
| 6184 | // That is why we set those values in loop_scope above and not in this ir_gen_node call. |
| 5584 | 6185 | IrInstruction *body_result = ir_gen_node(irb, node->data.while_expr.body, &loop_scope->base); |
| 5585 | 6186 | if (body_result == irb->codegen->invalid_instruction) |
| 5586 | 6187 | return body_result; |
| ... | ... | @@ -5609,10 +6210,15 @@ static IrInstruction *ir_gen_while_expr(IrBuilder *irb, Scope *scope, AstNode *n |
| 5609 | 6210 | ZigVar *err_var = ir_create_var(irb, err_symbol_node, scope, err_symbol, |
| 5610 | 6211 | true, false, false, is_comptime); |
| 5611 | 6212 | Scope *err_scope = err_var->child_scope; |
| 5612 | | IrInstruction *err_var_value = ir_build_unwrap_err_code(irb, err_scope, err_symbol_node, err_val_ptr); |
| 5613 | | ir_build_var_decl_src(irb, err_scope, symbol_node, err_var, nullptr, nullptr, err_var_value); |
| 6213 | IrInstruction *err_ptr = ir_build_unwrap_err_code(irb, err_scope, err_symbol_node, err_val_ptr); |
| 6214 | ir_build_var_decl_src(irb, err_scope, symbol_node, err_var, nullptr, err_ptr); |
| 5614 | 6215 | |
| 5615 | | IrInstruction *else_result = ir_gen_node(irb, else_node, err_scope); |
| 6216 | if (peer_parent->peers.length != 0) { |
| 6217 | peer_parent->peers.last()->next_bb = else_block; |
| 6218 | } |
| 6219 | ResultLocPeer *peer_result = create_peer_result(peer_parent); |
| 6220 | peer_parent->peers.append(peer_result); |
| 6221 | IrInstruction *else_result = ir_gen_node_extra(irb, else_node, err_scope, lval, &peer_result->base); |
| 5616 | 6222 | if (else_result == irb->codegen->invalid_instruction) |
| 5617 | 6223 | return else_result; |
| 5618 | 6224 | if (!instr_is_unreachable(else_result)) |
| ... | ... | @@ -5626,8 +6232,13 @@ static IrInstruction *ir_gen_while_expr(IrBuilder *irb, Scope *scope, AstNode *n |
| 5626 | 6232 | incoming_blocks.append(after_cond_block); |
| 5627 | 6233 | incoming_values.append(void_else_result); |
| 5628 | 6234 | } |
| 6235 | if (peer_parent->peers.length != 0) { |
| 6236 | peer_parent->peers.last()->next_bb = end_block; |
| 6237 | } |
| 5629 | 6238 | |
| 5630 | | return ir_build_phi(irb, scope, node, incoming_blocks.length, incoming_blocks.items, incoming_values.items); |
| 6239 | IrInstruction *phi = ir_build_phi(irb, scope, node, incoming_blocks.length, |
| 6240 | incoming_blocks.items, incoming_values.items, peer_parent); |
| 6241 | return ir_expr_wrap(irb, scope, phi, result_loc); |
| 5631 | 6242 | } else if (var_symbol != nullptr) { |
| 5632 | 6243 | ir_set_cursor_at_end_and_append_block(irb, cond_block); |
| 5633 | 6244 | Scope *subexpr_scope = create_runtime_scope(irb->codegen, node, scope, is_comptime); |
| ... | ... | @@ -5637,23 +6248,32 @@ static IrInstruction *ir_gen_while_expr(IrBuilder *irb, Scope *scope, AstNode *n |
| 5637 | 6248 | ZigVar *payload_var = ir_create_var(irb, symbol_node, subexpr_scope, var_symbol, |
| 5638 | 6249 | true, false, false, is_comptime); |
| 5639 | 6250 | Scope *child_scope = payload_var->child_scope; |
| 5640 | | IrInstruction *maybe_val_ptr = ir_gen_node_extra(irb, node->data.while_expr.condition, subexpr_scope, LValPtr); |
| 6251 | IrInstruction *maybe_val_ptr = ir_gen_node_extra(irb, node->data.while_expr.condition, subexpr_scope, |
| 6252 | LValPtr, nullptr); |
| 5641 | 6253 | if (maybe_val_ptr == irb->codegen->invalid_instruction) |
| 5642 | 6254 | return maybe_val_ptr; |
| 5643 | 6255 | IrInstruction *maybe_val = ir_build_load_ptr(irb, scope, node->data.while_expr.condition, maybe_val_ptr); |
| 5644 | 6256 | IrInstruction *is_non_null = ir_build_test_nonnull(irb, scope, node->data.while_expr.condition, maybe_val); |
| 5645 | 6257 | IrBasicBlock *after_cond_block = irb->current_basic_block; |
| 5646 | 6258 | IrInstruction *void_else_result = else_node ? nullptr : ir_mark_gen(ir_build_const_void(irb, scope, node)); |
| 6259 | IrInstruction *cond_br_inst; |
| 5647 | 6260 | if (!instr_is_unreachable(is_non_null)) { |
| 5648 | | ir_mark_gen(ir_build_cond_br(irb, scope, node->data.while_expr.condition, is_non_null, |
| 5649 | | body_block, else_block, is_comptime)); |
| 6261 | cond_br_inst = ir_build_cond_br(irb, scope, node->data.while_expr.condition, is_non_null, |
| 6262 | body_block, else_block, is_comptime); |
| 6263 | cond_br_inst->is_gen = true; |
| 6264 | } else { |
| 6265 | // for the purposes of the source instruction to ir_build_result_peers |
| 6266 | cond_br_inst = irb->current_basic_block->instruction_list.last(); |
| 5650 | 6267 | } |
| 5651 | 6268 | |
| 6269 | ResultLocPeerParent *peer_parent = ir_build_result_peers(irb, cond_br_inst, end_block, result_loc, |
| 6270 | is_comptime); |
| 6271 | |
| 5652 | 6272 | ir_set_cursor_at_end_and_append_block(irb, body_block); |
| 5653 | | IrInstruction *var_ptr_value = ir_build_optional_unwrap_ptr(irb, child_scope, symbol_node, maybe_val_ptr, false); |
| 5654 | | IrInstruction *var_value = node->data.while_expr.var_is_ptr ? |
| 5655 | | var_ptr_value : ir_build_load_ptr(irb, child_scope, symbol_node, var_ptr_value); |
| 5656 | | ir_build_var_decl_src(irb, child_scope, symbol_node, payload_var, nullptr, nullptr, var_value); |
| 6273 | IrInstruction *payload_ptr = ir_build_optional_unwrap_ptr(irb, child_scope, symbol_node, maybe_val_ptr, false, false); |
| 6274 | IrInstruction *var_ptr = node->data.while_expr.var_is_ptr ? |
| 6275 | ir_build_ref(irb, child_scope, symbol_node, payload_ptr, true, false) : payload_ptr; |
| 6276 | ir_build_var_decl_src(irb, child_scope, symbol_node, payload_var, nullptr, var_ptr); |
| 5657 | 6277 | |
| 5658 | 6278 | ZigList<IrInstruction *> incoming_values = {0}; |
| 5659 | 6279 | ZigList<IrBasicBlock *> incoming_blocks = {0}; |
| ... | ... | @@ -5664,7 +6284,12 @@ static IrInstruction *ir_gen_while_expr(IrBuilder *irb, Scope *scope, AstNode *n |
| 5664 | 6284 | loop_scope->is_comptime = is_comptime; |
| 5665 | 6285 | loop_scope->incoming_blocks = &incoming_blocks; |
| 5666 | 6286 | loop_scope->incoming_values = &incoming_values; |
| 6287 | loop_scope->lval = lval; |
| 6288 | loop_scope->peer_parent = peer_parent; |
| 5667 | 6289 | |
| 6290 | // Note the body block of the loop is not the place that lval and result_loc are used - |
| 6291 | // it's actually in break statements, handled similarly to return statements. |
| 6292 | // That is why we set those values in loop_scope above and not in this ir_gen_node call. |
| 5668 | 6293 | IrInstruction *body_result = ir_gen_node(irb, node->data.while_expr.body, &loop_scope->base); |
| 5669 | 6294 | if (body_result == irb->codegen->invalid_instruction) |
| 5670 | 6295 | return body_result; |
| ... | ... | @@ -5689,7 +6314,12 @@ static IrInstruction *ir_gen_while_expr(IrBuilder *irb, Scope *scope, AstNode *n |
| 5689 | 6314 | if (else_node) { |
| 5690 | 6315 | ir_set_cursor_at_end_and_append_block(irb, else_block); |
| 5691 | 6316 | |
| 5692 | | else_result = ir_gen_node(irb, else_node, scope); |
| 6317 | if (peer_parent->peers.length != 0) { |
| 6318 | peer_parent->peers.last()->next_bb = else_block; |
| 6319 | } |
| 6320 | ResultLocPeer *peer_result = create_peer_result(peer_parent); |
| 6321 | peer_parent->peers.append(peer_result); |
| 6322 | else_result = ir_gen_node_extra(irb, else_node, scope, lval, &peer_result->base); |
| 5693 | 6323 | if (else_result == irb->codegen->invalid_instruction) |
| 5694 | 6324 | return else_result; |
| 5695 | 6325 | if (!instr_is_unreachable(else_result)) |
| ... | ... | @@ -5704,8 +6334,13 @@ static IrInstruction *ir_gen_while_expr(IrBuilder *irb, Scope *scope, AstNode *n |
| 5704 | 6334 | incoming_blocks.append(after_cond_block); |
| 5705 | 6335 | incoming_values.append(void_else_result); |
| 5706 | 6336 | } |
| 6337 | if (peer_parent->peers.length != 0) { |
| 6338 | peer_parent->peers.last()->next_bb = end_block; |
| 6339 | } |
| 5707 | 6340 | |
| 5708 | | return ir_build_phi(irb, scope, node, incoming_blocks.length, incoming_blocks.items, incoming_values.items); |
| 6341 | IrInstruction *phi = ir_build_phi(irb, scope, node, incoming_blocks.length, |
| 6342 | incoming_blocks.items, incoming_values.items, peer_parent); |
| 6343 | return ir_expr_wrap(irb, scope, phi, result_loc); |
| 5709 | 6344 | } else { |
| 5710 | 6345 | ir_set_cursor_at_end_and_append_block(irb, cond_block); |
| 5711 | 6346 | IrInstruction *cond_val = ir_gen_node(irb, node->data.while_expr.condition, scope); |
| ... | ... | @@ -5713,11 +6348,18 @@ static IrInstruction *ir_gen_while_expr(IrBuilder *irb, Scope *scope, AstNode *n |
| 5713 | 6348 | return cond_val; |
| 5714 | 6349 | IrBasicBlock *after_cond_block = irb->current_basic_block; |
| 5715 | 6350 | IrInstruction *void_else_result = else_node ? nullptr : ir_mark_gen(ir_build_const_void(irb, scope, node)); |
| 6351 | IrInstruction *cond_br_inst; |
| 5716 | 6352 | if (!instr_is_unreachable(cond_val)) { |
| 5717 | | ir_mark_gen(ir_build_cond_br(irb, scope, node->data.while_expr.condition, cond_val, |
| 5718 | | body_block, else_block, is_comptime)); |
| 6353 | cond_br_inst = ir_build_cond_br(irb, scope, node->data.while_expr.condition, cond_val, |
| 6354 | body_block, else_block, is_comptime); |
| 6355 | cond_br_inst->is_gen = true; |
| 6356 | } else { |
| 6357 | // for the purposes of the source instruction to ir_build_result_peers |
| 6358 | cond_br_inst = irb->current_basic_block->instruction_list.last(); |
| 5719 | 6359 | } |
| 5720 | 6360 | |
| 6361 | ResultLocPeerParent *peer_parent = ir_build_result_peers(irb, cond_br_inst, end_block, result_loc, |
| 6362 | is_comptime); |
| 5721 | 6363 | ir_set_cursor_at_end_and_append_block(irb, body_block); |
| 5722 | 6364 | |
| 5723 | 6365 | ZigList<IrInstruction *> incoming_values = {0}; |
| ... | ... | @@ -5731,7 +6373,12 @@ static IrInstruction *ir_gen_while_expr(IrBuilder *irb, Scope *scope, AstNode *n |
| 5731 | 6373 | loop_scope->is_comptime = is_comptime; |
| 5732 | 6374 | loop_scope->incoming_blocks = &incoming_blocks; |
| 5733 | 6375 | loop_scope->incoming_values = &incoming_values; |
| 6376 | loop_scope->lval = lval; |
| 6377 | loop_scope->peer_parent = peer_parent; |
| 5734 | 6378 | |
| 6379 | // Note the body block of the loop is not the place that lval and result_loc are used - |
| 6380 | // it's actually in break statements, handled similarly to return statements. |
| 6381 | // That is why we set those values in loop_scope above and not in this ir_gen_node call. |
| 5735 | 6382 | IrInstruction *body_result = ir_gen_node(irb, node->data.while_expr.body, &loop_scope->base); |
| 5736 | 6383 | if (body_result == irb->codegen->invalid_instruction) |
| 5737 | 6384 | return body_result; |
| ... | ... | @@ -5756,7 +6403,13 @@ static IrInstruction *ir_gen_while_expr(IrBuilder *irb, Scope *scope, AstNode *n |
| 5756 | 6403 | if (else_node) { |
| 5757 | 6404 | ir_set_cursor_at_end_and_append_block(irb, else_block); |
| 5758 | 6405 | |
| 5759 | | else_result = ir_gen_node(irb, else_node, subexpr_scope); |
| 6406 | if (peer_parent->peers.length != 0) { |
| 6407 | peer_parent->peers.last()->next_bb = else_block; |
| 6408 | } |
| 6409 | ResultLocPeer *peer_result = create_peer_result(peer_parent); |
| 6410 | peer_parent->peers.append(peer_result); |
| 6411 | |
| 6412 | else_result = ir_gen_node_extra(irb, else_node, subexpr_scope, lval, &peer_result->base); |
| 5760 | 6413 | if (else_result == irb->codegen->invalid_instruction) |
| 5761 | 6414 | return else_result; |
| 5762 | 6415 | if (!instr_is_unreachable(else_result)) |
| ... | ... | @@ -5771,12 +6424,19 @@ static IrInstruction *ir_gen_while_expr(IrBuilder *irb, Scope *scope, AstNode *n |
| 5771 | 6424 | incoming_blocks.append(after_cond_block); |
| 5772 | 6425 | incoming_values.append(void_else_result); |
| 5773 | 6426 | } |
| 6427 | if (peer_parent->peers.length != 0) { |
| 6428 | peer_parent->peers.last()->next_bb = end_block; |
| 6429 | } |
| 5774 | 6430 | |
| 5775 | | return ir_build_phi(irb, scope, node, incoming_blocks.length, incoming_blocks.items, incoming_values.items); |
| 6431 | IrInstruction *phi = ir_build_phi(irb, scope, node, incoming_blocks.length, |
| 6432 | incoming_blocks.items, incoming_values.items, peer_parent); |
| 6433 | return ir_expr_wrap(irb, scope, phi, result_loc); |
| 5776 | 6434 | } |
| 5777 | 6435 | } |
| 5778 | 6436 | |
| 5779 | | static IrInstruction *ir_gen_for_expr(IrBuilder *irb, Scope *parent_scope, AstNode *node) { |
| 6437 | static IrInstruction *ir_gen_for_expr(IrBuilder *irb, Scope *parent_scope, AstNode *node, LVal lval, |
| 6438 | ResultLoc *result_loc) |
| 6439 | { |
| 5780 | 6440 | assert(node->type == NodeTypeForExpr); |
| 5781 | 6441 | |
| 5782 | 6442 | AstNode *array_node = node->data.for_expr.array_expr; |
| ... | ... | @@ -5791,76 +6451,67 @@ static IrInstruction *ir_gen_for_expr(IrBuilder *irb, Scope *parent_scope, AstNo |
| 5791 | 6451 | } |
| 5792 | 6452 | assert(elem_node->type == NodeTypeSymbol); |
| 5793 | 6453 | |
| 5794 | | IrInstruction *array_val_ptr = ir_gen_node_extra(irb, array_node, parent_scope, LValPtr); |
| 6454 | IrInstruction *array_val_ptr = ir_gen_node_extra(irb, array_node, parent_scope, LValPtr, nullptr); |
| 5795 | 6455 | if (array_val_ptr == irb->codegen->invalid_instruction) |
| 5796 | 6456 | return array_val_ptr; |
| 5797 | 6457 | |
| 5798 | | IrInstruction *pointer_type = ir_build_to_ptr_type(irb, parent_scope, array_node, array_val_ptr); |
| 5799 | | IrInstruction *elem_var_type; |
| 5800 | | if (node->data.for_expr.elem_is_ptr) { |
| 5801 | | elem_var_type = pointer_type; |
| 5802 | | } else { |
| 5803 | | elem_var_type = ir_build_ptr_type_child(irb, parent_scope, elem_node, pointer_type); |
| 5804 | | } |
| 5805 | | |
| 5806 | 6458 | IrInstruction *is_comptime = ir_build_const_bool(irb, parent_scope, node, |
| 5807 | 6459 | ir_should_inline(irb->exec, parent_scope) || node->data.for_expr.is_inline); |
| 5808 | 6460 | |
| 5809 | | // TODO make it an error to write to element variable or i variable. |
| 5810 | | Buf *elem_var_name = elem_node->data.symbol_expr.symbol; |
| 5811 | | ZigVar *elem_var = ir_create_var(irb, elem_node, parent_scope, elem_var_name, true, false, false, is_comptime); |
| 5812 | | Scope *child_scope = elem_var->child_scope; |
| 5813 | | |
| 5814 | | IrInstruction *undefined_value = ir_build_const_undefined(irb, child_scope, elem_node); |
| 5815 | | ir_build_var_decl_src(irb, child_scope, elem_node, elem_var, elem_var_type, nullptr, undefined_value); |
| 5816 | | IrInstruction *elem_var_ptr = ir_build_var_ptr(irb, child_scope, node, elem_var); |
| 5817 | | |
| 5818 | 6461 | AstNode *index_var_source_node; |
| 5819 | 6462 | ZigVar *index_var; |
| 6463 | const char *index_var_name; |
| 5820 | 6464 | if (index_node) { |
| 5821 | 6465 | index_var_source_node = index_node; |
| 5822 | | Buf *index_var_name = index_node->data.symbol_expr.symbol; |
| 5823 | | index_var = ir_create_var(irb, index_node, child_scope, index_var_name, true, false, false, is_comptime); |
| 6466 | Buf *index_var_name_buf = index_node->data.symbol_expr.symbol; |
| 6467 | index_var = ir_create_var(irb, index_node, parent_scope, index_var_name_buf, true, false, false, is_comptime); |
| 6468 | index_var_name = buf_ptr(index_var_name_buf); |
| 5824 | 6469 | } else { |
| 5825 | 6470 | index_var_source_node = node; |
| 5826 | | index_var = ir_create_var(irb, node, child_scope, nullptr, true, false, true, is_comptime); |
| 6471 | index_var = ir_create_var(irb, node, parent_scope, nullptr, true, false, true, is_comptime); |
| 6472 | index_var_name = "i"; |
| 5827 | 6473 | } |
| 5828 | | child_scope = index_var->child_scope; |
| 5829 | 6474 | |
| 5830 | | IrInstruction *usize = ir_build_const_type(irb, child_scope, node, irb->codegen->builtin_types.entry_usize); |
| 5831 | | IrInstruction *zero = ir_build_const_usize(irb, child_scope, node, 0); |
| 5832 | | IrInstruction *one = ir_build_const_usize(irb, child_scope, node, 1); |
| 5833 | | ir_build_var_decl_src(irb, child_scope, index_var_source_node, index_var, usize, nullptr, zero); |
| 5834 | | IrInstruction *index_ptr = ir_build_var_ptr(irb, child_scope, node, index_var); |
| 6475 | IrInstruction *zero = ir_build_const_usize(irb, parent_scope, node, 0); |
| 6476 | build_decl_var_and_init(irb, parent_scope, index_var_source_node, index_var, zero, index_var_name, is_comptime); |
| 6477 | parent_scope = index_var->child_scope; |
| 6478 | |
| 6479 | IrInstruction *one = ir_build_const_usize(irb, parent_scope, node, 1); |
| 6480 | IrInstruction *index_ptr = ir_build_var_ptr(irb, parent_scope, node, index_var); |
| 5835 | 6481 | |
| 5836 | 6482 | |
| 5837 | | IrBasicBlock *cond_block = ir_create_basic_block(irb, child_scope, "ForCond"); |
| 5838 | | IrBasicBlock *body_block = ir_create_basic_block(irb, child_scope, "ForBody"); |
| 5839 | | IrBasicBlock *end_block = ir_create_basic_block(irb, child_scope, "ForEnd"); |
| 5840 | | IrBasicBlock *else_block = else_node ? ir_create_basic_block(irb, child_scope, "ForElse") : end_block; |
| 5841 | | IrBasicBlock *continue_block = ir_create_basic_block(irb, child_scope, "ForContinue"); |
| 6483 | IrBasicBlock *cond_block = ir_create_basic_block(irb, parent_scope, "ForCond"); |
| 6484 | IrBasicBlock *body_block = ir_create_basic_block(irb, parent_scope, "ForBody"); |
| 6485 | IrBasicBlock *end_block = ir_create_basic_block(irb, parent_scope, "ForEnd"); |
| 6486 | IrBasicBlock *else_block = else_node ? ir_create_basic_block(irb, parent_scope, "ForElse") : end_block; |
| 6487 | IrBasicBlock *continue_block = ir_create_basic_block(irb, parent_scope, "ForContinue"); |
| 5842 | 6488 | |
| 5843 | 6489 | Buf *len_field_name = buf_create_from_str("len"); |
| 5844 | | IrInstruction *len_ref = ir_build_field_ptr(irb, child_scope, node, array_val_ptr, len_field_name); |
| 5845 | | IrInstruction *len_val = ir_build_load_ptr(irb, child_scope, node, len_ref); |
| 5846 | | ir_build_br(irb, child_scope, node, cond_block, is_comptime); |
| 6490 | IrInstruction *len_ref = ir_build_field_ptr(irb, parent_scope, node, array_val_ptr, len_field_name, false); |
| 6491 | IrInstruction *len_val = ir_build_load_ptr(irb, parent_scope, node, len_ref); |
| 6492 | ir_build_br(irb, parent_scope, node, cond_block, is_comptime); |
| 5847 | 6493 | |
| 5848 | 6494 | ir_set_cursor_at_end_and_append_block(irb, cond_block); |
| 5849 | | IrInstruction *index_val = ir_build_load_ptr(irb, child_scope, node, index_ptr); |
| 5850 | | IrInstruction *cond = ir_build_bin_op(irb, child_scope, node, IrBinOpCmpLessThan, index_val, len_val, false); |
| 6495 | IrInstruction *index_val = ir_build_load_ptr(irb, parent_scope, node, index_ptr); |
| 6496 | IrInstruction *cond = ir_build_bin_op(irb, parent_scope, node, IrBinOpCmpLessThan, index_val, len_val, false); |
| 5851 | 6497 | IrBasicBlock *after_cond_block = irb->current_basic_block; |
| 5852 | 6498 | IrInstruction *void_else_value = else_node ? nullptr : ir_mark_gen(ir_build_const_void(irb, parent_scope, node)); |
| 5853 | | ir_mark_gen(ir_build_cond_br(irb, child_scope, node, cond, body_block, else_block, is_comptime)); |
| 6499 | IrInstruction *cond_br_inst = ir_mark_gen(ir_build_cond_br(irb, parent_scope, node, cond, |
| 6500 | body_block, else_block, is_comptime)); |
| 6501 | |
| 6502 | ResultLocPeerParent *peer_parent = ir_build_result_peers(irb, cond_br_inst, end_block, result_loc, is_comptime); |
| 5854 | 6503 | |
| 5855 | 6504 | ir_set_cursor_at_end_and_append_block(irb, body_block); |
| 5856 | | IrInstruction *elem_ptr = ir_build_elem_ptr(irb, child_scope, node, array_val_ptr, index_val, false, PtrLenSingle); |
| 5857 | | IrInstruction *elem_val; |
| 5858 | | if (node->data.for_expr.elem_is_ptr) { |
| 5859 | | elem_val = elem_ptr; |
| 5860 | | } else { |
| 5861 | | elem_val = ir_build_load_ptr(irb, child_scope, node, elem_ptr); |
| 5862 | | } |
| 5863 | | ir_mark_gen(ir_build_store_ptr(irb, child_scope, node, elem_var_ptr, elem_val)); |
| 6505 | IrInstruction *elem_ptr = ir_build_elem_ptr(irb, parent_scope, node, array_val_ptr, index_val, false, |
| 6506 | PtrLenSingle, nullptr); |
| 6507 | // TODO make it an error to write to element variable or i variable. |
| 6508 | Buf *elem_var_name = elem_node->data.symbol_expr.symbol; |
| 6509 | ZigVar *elem_var = ir_create_var(irb, elem_node, parent_scope, elem_var_name, true, false, false, is_comptime); |
| 6510 | Scope *child_scope = elem_var->child_scope; |
| 6511 | |
| 6512 | IrInstruction *var_ptr = node->data.for_expr.elem_is_ptr ? |
| 6513 | ir_build_ref(irb, parent_scope, elem_node, elem_ptr, true, false) : elem_ptr; |
| 6514 | ir_build_var_decl_src(irb, parent_scope, elem_node, elem_var, nullptr, var_ptr); |
| 5864 | 6515 | |
| 5865 | 6516 | ZigList<IrInstruction *> incoming_values = {0}; |
| 5866 | 6517 | ZigList<IrBasicBlock *> incoming_blocks = {0}; |
| ... | ... | @@ -5870,7 +6521,12 @@ static IrInstruction *ir_gen_for_expr(IrBuilder *irb, Scope *parent_scope, AstNo |
| 5870 | 6521 | loop_scope->is_comptime = is_comptime; |
| 5871 | 6522 | loop_scope->incoming_blocks = &incoming_blocks; |
| 5872 | 6523 | loop_scope->incoming_values = &incoming_values; |
| 6524 | loop_scope->lval = LValNone; |
| 6525 | loop_scope->peer_parent = peer_parent; |
| 5873 | 6526 | |
| 6527 | // Note the body block of the loop is not the place that lval and result_loc are used - |
| 6528 | // it's actually in break statements, handled similarly to return statements. |
| 6529 | // That is why we set those values in loop_scope above and not in this ir_gen_node call. |
| 5874 | 6530 | IrInstruction *body_result = ir_gen_node(irb, body_node, &loop_scope->base); |
| 5875 | 6531 | |
| 5876 | 6532 | if (!instr_is_unreachable(body_result)) { |
| ... | ... | @@ -5887,7 +6543,12 @@ static IrInstruction *ir_gen_for_expr(IrBuilder *irb, Scope *parent_scope, AstNo |
| 5887 | 6543 | if (else_node) { |
| 5888 | 6544 | ir_set_cursor_at_end_and_append_block(irb, else_block); |
| 5889 | 6545 | |
| 5890 | | else_result = ir_gen_node(irb, else_node, parent_scope); |
| 6546 | if (peer_parent->peers.length != 0) { |
| 6547 | peer_parent->peers.last()->next_bb = else_block; |
| 6548 | } |
| 6549 | ResultLocPeer *peer_result = create_peer_result(peer_parent); |
| 6550 | peer_parent->peers.append(peer_result); |
| 6551 | else_result = ir_gen_node_extra(irb, else_node, parent_scope, LValNone, &peer_result->base); |
| 5891 | 6552 | if (else_result == irb->codegen->invalid_instruction) |
| 5892 | 6553 | return else_result; |
| 5893 | 6554 | if (!instr_is_unreachable(else_result)) |
| ... | ... | @@ -5903,8 +6564,13 @@ static IrInstruction *ir_gen_for_expr(IrBuilder *irb, Scope *parent_scope, AstNo |
| 5903 | 6564 | incoming_blocks.append(after_cond_block); |
| 5904 | 6565 | incoming_values.append(void_else_value); |
| 5905 | 6566 | } |
| 6567 | if (peer_parent->peers.length != 0) { |
| 6568 | peer_parent->peers.last()->next_bb = end_block; |
| 6569 | } |
| 5906 | 6570 | |
| 5907 | | return ir_build_phi(irb, parent_scope, node, incoming_blocks.length, incoming_blocks.items, incoming_values.items); |
| 6571 | IrInstruction *phi = ir_build_phi(irb, parent_scope, node, incoming_blocks.length, |
| 6572 | incoming_blocks.items, incoming_values.items, peer_parent); |
| 6573 | return ir_lval_wrap(irb, parent_scope, phi, lval, result_loc); |
| 5908 | 6574 | } |
| 5909 | 6575 | |
| 5910 | 6576 | static IrInstruction *ir_gen_bool_literal(IrBuilder *irb, Scope *scope, AstNode *node) { |
| ... | ... | @@ -6189,7 +6855,9 @@ static IrInstruction *ir_gen_asm_expr(IrBuilder *irb, Scope *scope, AstNode *nod |
| 6189 | 6855 | input_list, output_types, output_vars, return_count, is_volatile); |
| 6190 | 6856 | } |
| 6191 | 6857 | |
| 6192 | | static IrInstruction *ir_gen_if_optional_expr(IrBuilder *irb, Scope *scope, AstNode *node) { |
| 6858 | static IrInstruction *ir_gen_if_optional_expr(IrBuilder *irb, Scope *scope, AstNode *node, LVal lval, |
| 6859 | ResultLoc *result_loc) |
| 6860 | { |
| 6193 | 6861 | assert(node->type == NodeTypeIfOptional); |
| 6194 | 6862 | |
| 6195 | 6863 | Buf *var_symbol = node->data.test_expr.var_symbol; |
| ... | ... | @@ -6198,7 +6866,7 @@ static IrInstruction *ir_gen_if_optional_expr(IrBuilder *irb, Scope *scope, AstN |
| 6198 | 6866 | AstNode *else_node = node->data.test_expr.else_node; |
| 6199 | 6867 | bool var_is_ptr = node->data.test_expr.var_is_ptr; |
| 6200 | 6868 | |
| 6201 | | IrInstruction *maybe_val_ptr = ir_gen_node_extra(irb, expr_node, scope, LValPtr); |
| 6869 | IrInstruction *maybe_val_ptr = ir_gen_node_extra(irb, expr_node, scope, LValPtr, nullptr); |
| 6202 | 6870 | if (maybe_val_ptr == irb->codegen->invalid_instruction) |
| 6203 | 6871 | return maybe_val_ptr; |
| 6204 | 6872 | |
| ... | ... | @@ -6215,27 +6883,31 @@ static IrInstruction *ir_gen_if_optional_expr(IrBuilder *irb, Scope *scope, AstN |
| 6215 | 6883 | } else { |
| 6216 | 6884 | is_comptime = ir_build_test_comptime(irb, scope, node, is_non_null); |
| 6217 | 6885 | } |
| 6218 | | ir_build_cond_br(irb, scope, node, is_non_null, then_block, else_block, is_comptime); |
| 6886 | IrInstruction *cond_br_inst = ir_build_cond_br(irb, scope, node, is_non_null, |
| 6887 | then_block, else_block, is_comptime); |
| 6888 | |
| 6889 | ResultLocPeerParent *peer_parent = ir_build_binary_result_peers(irb, cond_br_inst, else_block, endif_block, |
| 6890 | result_loc, is_comptime); |
| 6219 | 6891 | |
| 6220 | 6892 | ir_set_cursor_at_end_and_append_block(irb, then_block); |
| 6221 | 6893 | |
| 6222 | 6894 | Scope *subexpr_scope = create_runtime_scope(irb->codegen, node, scope, is_comptime); |
| 6223 | 6895 | Scope *var_scope; |
| 6224 | 6896 | if (var_symbol) { |
| 6225 | | IrInstruction *var_type = nullptr; |
| 6226 | 6897 | bool is_shadowable = false; |
| 6227 | 6898 | bool is_const = true; |
| 6228 | 6899 | ZigVar *var = ir_create_var(irb, node, subexpr_scope, |
| 6229 | 6900 | var_symbol, is_const, is_const, is_shadowable, is_comptime); |
| 6230 | 6901 | |
| 6231 | | IrInstruction *var_ptr_value = ir_build_optional_unwrap_ptr(irb, subexpr_scope, node, maybe_val_ptr, false); |
| 6232 | | IrInstruction *var_value = var_is_ptr ? var_ptr_value : ir_build_load_ptr(irb, subexpr_scope, node, var_ptr_value); |
| 6233 | | ir_build_var_decl_src(irb, subexpr_scope, node, var, var_type, nullptr, var_value); |
| 6902 | IrInstruction *payload_ptr = ir_build_optional_unwrap_ptr(irb, subexpr_scope, node, maybe_val_ptr, false, false); |
| 6903 | IrInstruction *var_ptr = var_is_ptr ? ir_build_ref(irb, subexpr_scope, node, payload_ptr, true, false) : payload_ptr; |
| 6904 | ir_build_var_decl_src(irb, subexpr_scope, node, var, nullptr, var_ptr); |
| 6234 | 6905 | var_scope = var->child_scope; |
| 6235 | 6906 | } else { |
| 6236 | 6907 | var_scope = subexpr_scope; |
| 6237 | 6908 | } |
| 6238 | | IrInstruction *then_expr_result = ir_gen_node(irb, then_node, var_scope); |
| 6909 | IrInstruction *then_expr_result = ir_gen_node_extra(irb, then_node, var_scope, lval, |
| 6910 | &peer_parent->peers.at(0)->base); |
| 6239 | 6911 | if (then_expr_result == irb->codegen->invalid_instruction) |
| 6240 | 6912 | return then_expr_result; |
| 6241 | 6913 | IrBasicBlock *after_then_block = irb->current_basic_block; |
| ... | ... | @@ -6245,11 +6917,12 @@ static IrInstruction *ir_gen_if_optional_expr(IrBuilder *irb, Scope *scope, AstN |
| 6245 | 6917 | ir_set_cursor_at_end_and_append_block(irb, else_block); |
| 6246 | 6918 | IrInstruction *else_expr_result; |
| 6247 | 6919 | if (else_node) { |
| 6248 | | else_expr_result = ir_gen_node(irb, else_node, subexpr_scope); |
| 6920 | else_expr_result = ir_gen_node_extra(irb, else_node, subexpr_scope, lval, &peer_parent->peers.at(1)->base); |
| 6249 | 6921 | if (else_expr_result == irb->codegen->invalid_instruction) |
| 6250 | 6922 | return else_expr_result; |
| 6251 | 6923 | } else { |
| 6252 | 6924 | else_expr_result = ir_build_const_void(irb, scope, node); |
| 6925 | ir_build_end_expr(irb, scope, node, else_expr_result, &peer_parent->peers.at(1)->base); |
| 6253 | 6926 | } |
| 6254 | 6927 | IrBasicBlock *after_else_block = irb->current_basic_block; |
| 6255 | 6928 | if (!instr_is_unreachable(else_expr_result)) |
| ... | ... | @@ -6263,10 +6936,13 @@ static IrInstruction *ir_gen_if_optional_expr(IrBuilder *irb, Scope *scope, AstN |
| 6263 | 6936 | incoming_blocks[0] = after_then_block; |
| 6264 | 6937 | incoming_blocks[1] = after_else_block; |
| 6265 | 6938 | |
| 6266 | | return ir_build_phi(irb, scope, node, 2, incoming_blocks, incoming_values); |
| 6939 | IrInstruction *phi = ir_build_phi(irb, scope, node, 2, incoming_blocks, incoming_values, peer_parent); |
| 6940 | return ir_expr_wrap(irb, scope, phi, result_loc); |
| 6267 | 6941 | } |
| 6268 | 6942 | |
| 6269 | | static IrInstruction *ir_gen_if_err_expr(IrBuilder *irb, Scope *scope, AstNode *node) { |
| 6943 | static IrInstruction *ir_gen_if_err_expr(IrBuilder *irb, Scope *scope, AstNode *node, LVal lval, |
| 6944 | ResultLoc *result_loc) |
| 6945 | { |
| 6270 | 6946 | assert(node->type == NodeTypeIfErrorExpr); |
| 6271 | 6947 | |
| 6272 | 6948 | AstNode *target_node = node->data.if_err_expr.target_node; |
| ... | ... | @@ -6277,12 +6953,12 @@ static IrInstruction *ir_gen_if_err_expr(IrBuilder *irb, Scope *scope, AstNode * |
| 6277 | 6953 | Buf *var_symbol = node->data.if_err_expr.var_symbol; |
| 6278 | 6954 | Buf *err_symbol = node->data.if_err_expr.err_symbol; |
| 6279 | 6955 | |
| 6280 | | IrInstruction *err_val_ptr = ir_gen_node_extra(irb, target_node, scope, LValPtr); |
| 6956 | IrInstruction *err_val_ptr = ir_gen_node_extra(irb, target_node, scope, LValPtr, nullptr); |
| 6281 | 6957 | if (err_val_ptr == irb->codegen->invalid_instruction) |
| 6282 | 6958 | return err_val_ptr; |
| 6283 | 6959 | |
| 6284 | 6960 | IrInstruction *err_val = ir_build_load_ptr(irb, scope, node, err_val_ptr); |
| 6285 | | IrInstruction *is_err = ir_build_test_err(irb, scope, node, err_val); |
| 6961 | IrInstruction *is_err = ir_build_test_err_src(irb, scope, node, err_val_ptr, true); |
| 6286 | 6962 | |
| 6287 | 6963 | IrBasicBlock *ok_block = ir_create_basic_block(irb, scope, "TryOk"); |
| 6288 | 6964 | IrBasicBlock *else_block = ir_create_basic_block(irb, scope, "TryElse"); |
| ... | ... | @@ -6290,27 +6966,31 @@ static IrInstruction *ir_gen_if_err_expr(IrBuilder *irb, Scope *scope, AstNode * |
| 6290 | 6966 | |
| 6291 | 6967 | bool force_comptime = ir_should_inline(irb->exec, scope); |
| 6292 | 6968 | IrInstruction *is_comptime = force_comptime ? ir_build_const_bool(irb, scope, node, true) : ir_build_test_comptime(irb, scope, node, is_err); |
| 6293 | | ir_build_cond_br(irb, scope, node, is_err, else_block, ok_block, is_comptime); |
| 6969 | IrInstruction *cond_br_inst = ir_build_cond_br(irb, scope, node, is_err, else_block, ok_block, is_comptime); |
| 6970 | |
| 6971 | ResultLocPeerParent *peer_parent = ir_build_binary_result_peers(irb, cond_br_inst, else_block, endif_block, |
| 6972 | result_loc, is_comptime); |
| 6294 | 6973 | |
| 6295 | 6974 | ir_set_cursor_at_end_and_append_block(irb, ok_block); |
| 6296 | 6975 | |
| 6297 | 6976 | Scope *subexpr_scope = create_runtime_scope(irb->codegen, node, scope, is_comptime); |
| 6298 | 6977 | Scope *var_scope; |
| 6299 | 6978 | if (var_symbol) { |
| 6300 | | IrInstruction *var_type = nullptr; |
| 6301 | 6979 | bool is_shadowable = false; |
| 6302 | 6980 | IrInstruction *var_is_comptime = force_comptime ? ir_build_const_bool(irb, subexpr_scope, node, true) : ir_build_test_comptime(irb, subexpr_scope, node, err_val); |
| 6303 | 6981 | ZigVar *var = ir_create_var(irb, node, subexpr_scope, |
| 6304 | 6982 | var_symbol, var_is_const, var_is_const, is_shadowable, var_is_comptime); |
| 6305 | 6983 | |
| 6306 | | IrInstruction *var_ptr_value = ir_build_unwrap_err_payload(irb, subexpr_scope, node, err_val_ptr, false); |
| 6307 | | IrInstruction *var_value = var_is_ptr ? var_ptr_value : ir_build_load_ptr(irb, subexpr_scope, node, var_ptr_value); |
| 6308 | | ir_build_var_decl_src(irb, subexpr_scope, node, var, var_type, nullptr, var_value); |
| 6984 | IrInstruction *payload_ptr = ir_build_unwrap_err_payload(irb, subexpr_scope, node, err_val_ptr, false, false); |
| 6985 | IrInstruction *var_ptr = var_is_ptr ? |
| 6986 | ir_build_ref(irb, subexpr_scope, node, payload_ptr, true, false) : payload_ptr; |
| 6987 | ir_build_var_decl_src(irb, subexpr_scope, node, var, nullptr, var_ptr); |
| 6309 | 6988 | var_scope = var->child_scope; |
| 6310 | 6989 | } else { |
| 6311 | 6990 | var_scope = subexpr_scope; |
| 6312 | 6991 | } |
| 6313 | | IrInstruction *then_expr_result = ir_gen_node(irb, then_node, var_scope); |
| 6992 | IrInstruction *then_expr_result = ir_gen_node_extra(irb, then_node, var_scope, lval, |
| 6993 | &peer_parent->peers.at(0)->base); |
| 6314 | 6994 | if (then_expr_result == irb->codegen->invalid_instruction) |
| 6315 | 6995 | return then_expr_result; |
| 6316 | 6996 | IrBasicBlock *after_then_block = irb->current_basic_block; |
| ... | ... | @@ -6323,23 +7003,23 @@ static IrInstruction *ir_gen_if_err_expr(IrBuilder *irb, Scope *scope, AstNode * |
| 6323 | 7003 | if (else_node) { |
| 6324 | 7004 | Scope *err_var_scope; |
| 6325 | 7005 | if (err_symbol) { |
| 6326 | | IrInstruction *var_type = nullptr; |
| 6327 | 7006 | bool is_shadowable = false; |
| 6328 | 7007 | bool is_const = true; |
| 6329 | 7008 | ZigVar *var = ir_create_var(irb, node, subexpr_scope, |
| 6330 | 7009 | err_symbol, is_const, is_const, is_shadowable, is_comptime); |
| 6331 | 7010 | |
| 6332 | | IrInstruction *var_value = ir_build_unwrap_err_code(irb, subexpr_scope, node, err_val_ptr); |
| 6333 | | ir_build_var_decl_src(irb, subexpr_scope, node, var, var_type, nullptr, var_value); |
| 7011 | IrInstruction *err_ptr = ir_build_unwrap_err_code(irb, subexpr_scope, node, err_val_ptr); |
| 7012 | ir_build_var_decl_src(irb, subexpr_scope, node, var, nullptr, err_ptr); |
| 6334 | 7013 | err_var_scope = var->child_scope; |
| 6335 | 7014 | } else { |
| 6336 | 7015 | err_var_scope = subexpr_scope; |
| 6337 | 7016 | } |
| 6338 | | else_expr_result = ir_gen_node(irb, else_node, err_var_scope); |
| 7017 | else_expr_result = ir_gen_node_extra(irb, else_node, err_var_scope, lval, &peer_parent->peers.at(1)->base); |
| 6339 | 7018 | if (else_expr_result == irb->codegen->invalid_instruction) |
| 6340 | 7019 | return else_expr_result; |
| 6341 | 7020 | } else { |
| 6342 | 7021 | else_expr_result = ir_build_const_void(irb, scope, node); |
| 7022 | ir_build_end_expr(irb, scope, node, else_expr_result, &peer_parent->peers.at(1)->base); |
| 6343 | 7023 | } |
| 6344 | 7024 | IrBasicBlock *after_else_block = irb->current_basic_block; |
| 6345 | 7025 | if (!instr_is_unreachable(else_expr_result)) |
| ... | ... | @@ -6353,14 +7033,15 @@ static IrInstruction *ir_gen_if_err_expr(IrBuilder *irb, Scope *scope, AstNode * |
| 6353 | 7033 | incoming_blocks[0] = after_then_block; |
| 6354 | 7034 | incoming_blocks[1] = after_else_block; |
| 6355 | 7035 | |
| 6356 | | return ir_build_phi(irb, scope, node, 2, incoming_blocks, incoming_values); |
| 7036 | IrInstruction *phi = ir_build_phi(irb, scope, node, 2, incoming_blocks, incoming_values, peer_parent); |
| 7037 | return ir_expr_wrap(irb, scope, phi, result_loc); |
| 6357 | 7038 | } |
| 6358 | 7039 | |
| 6359 | 7040 | static bool ir_gen_switch_prong_expr(IrBuilder *irb, Scope *scope, AstNode *switch_node, AstNode *prong_node, |
| 6360 | 7041 | IrBasicBlock *end_block, IrInstruction *is_comptime, IrInstruction *var_is_comptime, |
| 6361 | 7042 | IrInstruction *target_value_ptr, IrInstruction **prong_values, size_t prong_values_len, |
| 6362 | 7043 | ZigList<IrBasicBlock *> *incoming_blocks, ZigList<IrInstruction *> *incoming_values, |
| 6363 | | IrInstructionSwitchElseVar **out_switch_else_var) |
| 7044 | IrInstructionSwitchElseVar **out_switch_else_var, LVal lval, ResultLoc *result_loc) |
| 6364 | 7045 | { |
| 6365 | 7046 | assert(switch_node->type == NodeTypeSwitchExpr); |
| 6366 | 7047 | assert(prong_node->type == NodeTypeSwitchProng); |
| ... | ... | @@ -6378,28 +7059,27 @@ static bool ir_gen_switch_prong_expr(IrBuilder *irb, Scope *scope, AstNode *swit |
| 6378 | 7059 | ZigVar *var = ir_create_var(irb, var_symbol_node, scope, |
| 6379 | 7060 | var_name, is_const, is_const, is_shadowable, var_is_comptime); |
| 6380 | 7061 | child_scope = var->child_scope; |
| 6381 | | IrInstruction *var_value; |
| 7062 | IrInstruction *var_ptr; |
| 6382 | 7063 | if (out_switch_else_var != nullptr) { |
| 6383 | 7064 | IrInstructionSwitchElseVar *switch_else_var = ir_build_switch_else_var(irb, scope, var_symbol_node, |
| 6384 | 7065 | target_value_ptr); |
| 6385 | 7066 | *out_switch_else_var = switch_else_var; |
| 6386 | | IrInstruction *var_ptr_value = &switch_else_var->base; |
| 6387 | | var_value = var_is_ptr ? var_ptr_value : ir_build_load_ptr(irb, scope, var_symbol_node, var_ptr_value); |
| 7067 | IrInstruction *payload_ptr = &switch_else_var->base; |
| 7068 | var_ptr = var_is_ptr ? ir_build_ref(irb, scope, var_symbol_node, payload_ptr, true, false) : payload_ptr; |
| 6388 | 7069 | } else if (prong_values != nullptr) { |
| 6389 | | IrInstruction *var_ptr_value = ir_build_switch_var(irb, scope, var_symbol_node, target_value_ptr, |
| 7070 | IrInstruction *payload_ptr = ir_build_switch_var(irb, scope, var_symbol_node, target_value_ptr, |
| 6390 | 7071 | prong_values, prong_values_len); |
| 6391 | | var_value = var_is_ptr ? var_ptr_value : ir_build_load_ptr(irb, scope, var_symbol_node, var_ptr_value); |
| 7072 | var_ptr = var_is_ptr ? ir_build_ref(irb, scope, var_symbol_node, payload_ptr, true, false) : payload_ptr; |
| 6392 | 7073 | } else { |
| 6393 | | var_value = var_is_ptr ? target_value_ptr : ir_build_load_ptr(irb, scope, var_symbol_node, |
| 6394 | | target_value_ptr); |
| 7074 | var_ptr = var_is_ptr ? |
| 7075 | ir_build_ref(irb, scope, var_symbol_node, target_value_ptr, true, false) : target_value_ptr; |
| 6395 | 7076 | } |
| 6396 | | IrInstruction *var_type = nullptr; // infer the type |
| 6397 | | ir_build_var_decl_src(irb, scope, var_symbol_node, var, var_type, nullptr, var_value); |
| 7077 | ir_build_var_decl_src(irb, scope, var_symbol_node, var, nullptr, var_ptr); |
| 6398 | 7078 | } else { |
| 6399 | 7079 | child_scope = scope; |
| 6400 | 7080 | } |
| 6401 | 7081 | |
| 6402 | | IrInstruction *expr_result = ir_gen_node(irb, expr_node, child_scope); |
| 7082 | IrInstruction *expr_result = ir_gen_node_extra(irb, expr_node, child_scope, lval, result_loc); |
| 6403 | 7083 | if (expr_result == irb->codegen->invalid_instruction) |
| 6404 | 7084 | return false; |
| 6405 | 7085 | if (!instr_is_unreachable(expr_result)) |
| ... | ... | @@ -6409,11 +7089,13 @@ target_value_ptr); |
| 6409 | 7089 | return true; |
| 6410 | 7090 | } |
| 6411 | 7091 | |
| 6412 | | static IrInstruction *ir_gen_switch_expr(IrBuilder *irb, Scope *scope, AstNode *node) { |
| 7092 | static IrInstruction *ir_gen_switch_expr(IrBuilder *irb, Scope *scope, AstNode *node, LVal lval, |
| 7093 | ResultLoc *result_loc) |
| 7094 | { |
| 6413 | 7095 | assert(node->type == NodeTypeSwitchExpr); |
| 6414 | 7096 | |
| 6415 | 7097 | AstNode *target_node = node->data.switch_expr.expr; |
| 6416 | | IrInstruction *target_value_ptr = ir_gen_node_extra(irb, target_node, scope, LValPtr); |
| 7098 | IrInstruction *target_value_ptr = ir_gen_node_extra(irb, target_node, scope, LValPtr, nullptr); |
| 6417 | 7099 | if (target_value_ptr == irb->codegen->invalid_instruction) |
| 6418 | 7100 | return target_value_ptr; |
| 6419 | 7101 | IrInstruction *target_value = ir_build_switch_target(irb, scope, node, target_value_ptr); |
| ... | ... | @@ -6440,6 +7122,14 @@ static IrInstruction *ir_gen_switch_expr(IrBuilder *irb, Scope *scope, AstNode * |
| 6440 | 7122 | |
| 6441 | 7123 | IrInstructionSwitchElseVar *switch_else_var = nullptr; |
| 6442 | 7124 | |
| 7125 | ResultLocPeerParent *peer_parent = allocate<ResultLocPeerParent>(1); |
| 7126 | peer_parent->base.id = ResultLocIdPeerParent; |
| 7127 | peer_parent->end_bb = end_block; |
| 7128 | peer_parent->is_comptime = is_comptime; |
| 7129 | peer_parent->parent = result_loc; |
| 7130 | |
| 7131 | ir_build_reset_result(irb, scope, node, &peer_parent->base); |
| 7132 | |
| 6443 | 7133 | // First do the else and the ranges |
| 6444 | 7134 | Scope *subexpr_scope = create_runtime_scope(irb->codegen, node, scope, is_comptime); |
| 6445 | 7135 | Scope *comptime_scope = create_comptime_scope(irb->codegen, node, scope); |
| ... | ... | @@ -6448,6 +7138,7 @@ static IrInstruction *ir_gen_switch_expr(IrBuilder *irb, Scope *scope, AstNode * |
| 6448 | 7138 | AstNode *prong_node = node->data.switch_expr.prongs.at(prong_i); |
| 6449 | 7139 | size_t prong_item_count = prong_node->data.switch_prong.items.length; |
| 6450 | 7140 | if (prong_item_count == 0) { |
| 7141 | ResultLocPeer *this_peer_result_loc = create_peer_result(peer_parent); |
| 6451 | 7142 | if (else_prong) { |
| 6452 | 7143 | ErrorMsg *msg = add_node_error(irb->codegen, prong_node, |
| 6453 | 7144 | buf_sprintf("multiple else prongs in switch expression")); |
| ... | ... | @@ -6458,15 +7149,21 @@ static IrInstruction *ir_gen_switch_expr(IrBuilder *irb, Scope *scope, AstNode * |
| 6458 | 7149 | else_prong = prong_node; |
| 6459 | 7150 | |
| 6460 | 7151 | IrBasicBlock *prev_block = irb->current_basic_block; |
| 7152 | if (peer_parent->peers.length > 0) { |
| 7153 | peer_parent->peers.last()->next_bb = else_block; |
| 7154 | } |
| 7155 | peer_parent->peers.append(this_peer_result_loc); |
| 6461 | 7156 | ir_set_cursor_at_end_and_append_block(irb, else_block); |
| 6462 | 7157 | if (!ir_gen_switch_prong_expr(irb, subexpr_scope, node, prong_node, end_block, |
| 6463 | 7158 | is_comptime, var_is_comptime, target_value_ptr, nullptr, 0, &incoming_blocks, &incoming_values, |
| 6464 | | &switch_else_var)) |
| 7159 | &switch_else_var, LValNone, &this_peer_result_loc->base)) |
| 6465 | 7160 | { |
| 6466 | 7161 | return irb->codegen->invalid_instruction; |
| 6467 | 7162 | } |
| 6468 | 7163 | ir_set_cursor_at_end(irb, prev_block); |
| 6469 | 7164 | } else if (prong_node->data.switch_prong.any_items_are_range) { |
| 7165 | ResultLocPeer *this_peer_result_loc = create_peer_result(peer_parent); |
| 7166 | |
| 6470 | 7167 | IrInstruction *ok_bit = nullptr; |
| 6471 | 7168 | AstNode *last_item_node = nullptr; |
| 6472 | 7169 | for (size_t item_i = 0; item_i < prong_item_count; item_i += 1) { |
| ... | ... | @@ -6523,13 +7220,20 @@ static IrInstruction *ir_gen_switch_expr(IrBuilder *irb, Scope *scope, AstNode * |
| 6523 | 7220 | |
| 6524 | 7221 | assert(ok_bit); |
| 6525 | 7222 | assert(last_item_node); |
| 6526 | | ir_mark_gen(ir_build_cond_br(irb, scope, last_item_node, ok_bit, range_block_yes, |
| 6527 | | range_block_no, is_comptime)); |
| 7223 | IrInstruction *br_inst = ir_mark_gen(ir_build_cond_br(irb, scope, last_item_node, ok_bit, |
| 7224 | range_block_yes, range_block_no, is_comptime)); |
| 7225 | if (peer_parent->base.source_instruction == nullptr) { |
| 7226 | peer_parent->base.source_instruction = br_inst; |
| 7227 | } |
| 6528 | 7228 | |
| 7229 | if (peer_parent->peers.length > 0) { |
| 7230 | peer_parent->peers.last()->next_bb = range_block_yes; |
| 7231 | } |
| 7232 | peer_parent->peers.append(this_peer_result_loc); |
| 6529 | 7233 | ir_set_cursor_at_end_and_append_block(irb, range_block_yes); |
| 6530 | 7234 | if (!ir_gen_switch_prong_expr(irb, subexpr_scope, node, prong_node, end_block, |
| 6531 | 7235 | is_comptime, var_is_comptime, target_value_ptr, nullptr, 0, |
| 6532 | | &incoming_blocks, &incoming_values, nullptr)) |
| 7236 | &incoming_blocks, &incoming_values, nullptr, LValNone, &this_peer_result_loc->base)) |
| 6533 | 7237 | { |
| 6534 | 7238 | return irb->codegen->invalid_instruction; |
| 6535 | 7239 | } |
| ... | ... | @@ -6547,6 +7251,8 @@ static IrInstruction *ir_gen_switch_expr(IrBuilder *irb, Scope *scope, AstNode * |
| 6547 | 7251 | if (prong_node->data.switch_prong.any_items_are_range) |
| 6548 | 7252 | continue; |
| 6549 | 7253 | |
| 7254 | ResultLocPeer *this_peer_result_loc = create_peer_result(peer_parent); |
| 7255 | |
| 6550 | 7256 | IrBasicBlock *prong_block = ir_create_basic_block(irb, scope, "SwitchProng"); |
| 6551 | 7257 | IrInstruction **items = allocate<IrInstruction *>(prong_item_count); |
| 6552 | 7258 | |
| ... | ... | @@ -6570,10 +7276,14 @@ static IrInstruction *ir_gen_switch_expr(IrBuilder *irb, Scope *scope, AstNode * |
| 6570 | 7276 | } |
| 6571 | 7277 | |
| 6572 | 7278 | IrBasicBlock *prev_block = irb->current_basic_block; |
| 7279 | if (peer_parent->peers.length > 0) { |
| 7280 | peer_parent->peers.last()->next_bb = prong_block; |
| 7281 | } |
| 7282 | peer_parent->peers.append(this_peer_result_loc); |
| 6573 | 7283 | ir_set_cursor_at_end_and_append_block(irb, prong_block); |
| 6574 | 7284 | if (!ir_gen_switch_prong_expr(irb, subexpr_scope, node, prong_node, end_block, |
| 6575 | 7285 | is_comptime, var_is_comptime, target_value_ptr, items, prong_item_count, |
| 6576 | | &incoming_blocks, &incoming_values, nullptr)) |
| 7286 | &incoming_blocks, &incoming_values, nullptr, LValNone, &this_peer_result_loc->base)) |
| 6577 | 7287 | { |
| 6578 | 7288 | return irb->codegen->invalid_instruction; |
| 6579 | 7289 | } |
| ... | ... | @@ -6582,38 +7292,57 @@ static IrInstruction *ir_gen_switch_expr(IrBuilder *irb, Scope *scope, AstNode * |
| 6582 | 7292 | |
| 6583 | 7293 | } |
| 6584 | 7294 | |
| 6585 | | IrInstruction *switch_prongs_void = ir_build_check_switch_prongs(irb, scope, node, target_value, check_ranges.items, check_ranges.length, |
| 6586 | | else_prong != nullptr); |
| 7295 | IrInstruction *switch_prongs_void = ir_build_check_switch_prongs(irb, scope, node, target_value, |
| 7296 | check_ranges.items, check_ranges.length, else_prong != nullptr); |
| 6587 | 7297 | |
| 7298 | IrInstruction *br_instruction; |
| 6588 | 7299 | if (cases.length == 0) { |
| 6589 | | ir_build_br(irb, scope, node, else_block, is_comptime); |
| 7300 | br_instruction = ir_build_br(irb, scope, node, else_block, is_comptime); |
| 6590 | 7301 | } else { |
| 6591 | 7302 | IrInstructionSwitchBr *switch_br = ir_build_switch_br(irb, scope, node, target_value, else_block, |
| 6592 | 7303 | cases.length, cases.items, is_comptime, switch_prongs_void); |
| 6593 | 7304 | if (switch_else_var != nullptr) { |
| 6594 | 7305 | switch_else_var->switch_br = switch_br; |
| 6595 | 7306 | } |
| 7307 | br_instruction = &switch_br->base; |
| 7308 | } |
| 7309 | if (peer_parent->base.source_instruction == nullptr) { |
| 7310 | peer_parent->base.source_instruction = br_instruction; |
| 7311 | } |
| 7312 | for (size_t i = 0; i < peer_parent->peers.length; i += 1) { |
| 7313 | peer_parent->peers.at(i)->base.source_instruction = peer_parent->base.source_instruction; |
| 6596 | 7314 | } |
| 6597 | 7315 | |
| 6598 | 7316 | if (!else_prong) { |
| 7317 | if (peer_parent->peers.length != 0) { |
| 7318 | peer_parent->peers.last()->next_bb = else_block; |
| 7319 | } |
| 6599 | 7320 | ir_set_cursor_at_end_and_append_block(irb, else_block); |
| 6600 | 7321 | ir_build_unreachable(irb, scope, node); |
| 7322 | } else { |
| 7323 | if (peer_parent->peers.length != 0) { |
| 7324 | peer_parent->peers.last()->next_bb = end_block; |
| 7325 | } |
| 6601 | 7326 | } |
| 6602 | 7327 | |
| 6603 | 7328 | ir_set_cursor_at_end_and_append_block(irb, end_block); |
| 6604 | 7329 | assert(incoming_blocks.length == incoming_values.length); |
| 7330 | IrInstruction *result_instruction; |
| 6605 | 7331 | if (incoming_blocks.length == 0) { |
| 6606 | | return ir_build_const_void(irb, scope, node); |
| 7332 | result_instruction = ir_build_const_void(irb, scope, node); |
| 6607 | 7333 | } else { |
| 6608 | | return ir_build_phi(irb, scope, node, incoming_blocks.length, incoming_blocks.items, incoming_values.items); |
| 7334 | result_instruction = ir_build_phi(irb, scope, node, incoming_blocks.length, |
| 7335 | incoming_blocks.items, incoming_values.items, peer_parent); |
| 6609 | 7336 | } |
| 7337 | return ir_lval_wrap(irb, scope, result_instruction, lval, result_loc); |
| 6610 | 7338 | } |
| 6611 | 7339 | |
| 6612 | 7340 | static IrInstruction *ir_gen_comptime(IrBuilder *irb, Scope *parent_scope, AstNode *node, LVal lval) { |
| 6613 | 7341 | assert(node->type == NodeTypeCompTime); |
| 6614 | 7342 | |
| 6615 | 7343 | Scope *child_scope = create_comptime_scope(irb->codegen, node, parent_scope); |
| 6616 | | return ir_gen_node_extra(irb, node->data.comptime_expr.expr, child_scope, lval); |
| 7344 | // purposefully pass null for result_loc and let EndExpr handle it |
| 7345 | return ir_gen_node_extra(irb, node->data.comptime_expr.expr, child_scope, lval, nullptr); |
| 6617 | 7346 | } |
| 6618 | 7347 | |
| 6619 | 7348 | static IrInstruction *ir_gen_return_from_block(IrBuilder *irb, Scope *break_scope, AstNode *node, ScopeBlock *block_scope) { |
| ... | ... | @@ -6626,7 +7355,11 @@ static IrInstruction *ir_gen_return_from_block(IrBuilder *irb, Scope *break_scop |
| 6626 | 7355 | |
| 6627 | 7356 | IrInstruction *result_value; |
| 6628 | 7357 | if (node->data.break_expr.expr) { |
| 6629 | | result_value = ir_gen_node(irb, node->data.break_expr.expr, break_scope); |
| 7358 | ResultLocPeer *peer_result = create_peer_result(block_scope->peer_parent); |
| 7359 | block_scope->peer_parent->peers.append(peer_result); |
| 7360 | |
| 7361 | result_value = ir_gen_node_extra(irb, node->data.break_expr.expr, break_scope, block_scope->lval, |
| 7362 | &peer_result->base); |
| 6630 | 7363 | if (result_value == irb->codegen->invalid_instruction) |
| 6631 | 7364 | return irb->codegen->invalid_instruction; |
| 6632 | 7365 | } else { |
| ... | ... | @@ -6696,7 +7429,11 @@ static IrInstruction *ir_gen_break(IrBuilder *irb, Scope *break_scope, AstNode * |
| 6696 | 7429 | |
| 6697 | 7430 | IrInstruction *result_value; |
| 6698 | 7431 | if (node->data.break_expr.expr) { |
| 6699 | | result_value = ir_gen_node(irb, node->data.break_expr.expr, break_scope); |
| 7432 | ResultLocPeer *peer_result = create_peer_result(loop_scope->peer_parent); |
| 7433 | loop_scope->peer_parent->peers.append(peer_result); |
| 7434 | |
| 7435 | result_value = ir_gen_node_extra(irb, node->data.break_expr.expr, break_scope, |
| 7436 | loop_scope->lval, &peer_result->base); |
| 6700 | 7437 | if (result_value == irb->codegen->invalid_instruction) |
| 6701 | 7438 | return irb->codegen->invalid_instruction; |
| 6702 | 7439 | } else { |
| ... | ... | @@ -6784,7 +7521,7 @@ static IrInstruction *ir_gen_defer(IrBuilder *irb, Scope *parent_scope, AstNode |
| 6784 | 7521 | return ir_build_const_void(irb, parent_scope, node); |
| 6785 | 7522 | } |
| 6786 | 7523 | |
| 6787 | | static IrInstruction *ir_gen_slice(IrBuilder *irb, Scope *scope, AstNode *node) { |
| 7524 | static IrInstruction *ir_gen_slice(IrBuilder *irb, Scope *scope, AstNode *node, LVal lval, ResultLoc *result_loc) { |
| 6788 | 7525 | assert(node->type == NodeTypeSliceExpr); |
| 6789 | 7526 | |
| 6790 | 7527 | AstNodeSliceExpr *slice_expr = &node->data.slice_expr; |
| ... | ... | @@ -6792,7 +7529,7 @@ static IrInstruction *ir_gen_slice(IrBuilder *irb, Scope *scope, AstNode *node) |
| 6792 | 7529 | AstNode *start_node = slice_expr->start; |
| 6793 | 7530 | AstNode *end_node = slice_expr->end; |
| 6794 | 7531 | |
| 6795 | | IrInstruction *ptr_value = ir_gen_node_extra(irb, array_node, scope, LValPtr); |
| 7532 | IrInstruction *ptr_value = ir_gen_node_extra(irb, array_node, scope, LValPtr, nullptr); |
| 6796 | 7533 | if (ptr_value == irb->codegen->invalid_instruction) |
| 6797 | 7534 | return irb->codegen->invalid_instruction; |
| 6798 | 7535 | |
| ... | ... | @@ -6809,11 +7546,14 @@ static IrInstruction *ir_gen_slice(IrBuilder *irb, Scope *scope, AstNode *node) |
| 6809 | 7546 | end_value = nullptr; |
| 6810 | 7547 | } |
| 6811 | 7548 | |
| 6812 | | return ir_build_slice(irb, scope, node, ptr_value, start_value, end_value, true); |
| 7549 | IrInstruction *slice = ir_build_slice_src(irb, scope, node, ptr_value, start_value, end_value, true, result_loc); |
| 7550 | return ir_lval_wrap(irb, scope, slice, lval, result_loc); |
| 6813 | 7551 | } |
| 6814 | 7552 | |
| 6815 | | static IrInstruction *ir_gen_catch(IrBuilder *irb, Scope *parent_scope, AstNode *node) { |
| 6816 | | assert(node->type == NodeTypeUnwrapErrorExpr); |
| 7553 | static IrInstruction *ir_gen_catch(IrBuilder *irb, Scope *parent_scope, AstNode *node, LVal lval, |
| 7554 | ResultLoc *result_loc) |
| 7555 | { |
| 7556 | assert(node->type == NodeTypeCatchExpr); |
| 6817 | 7557 | |
| 6818 | 7558 | AstNode *op1_node = node->data.unwrap_err_expr.op1; |
| 6819 | 7559 | AstNode *op2_node = node->data.unwrap_err_expr.op2; |
| ... | ... | @@ -6826,16 +7566,15 @@ static IrInstruction *ir_gen_catch(IrBuilder *irb, Scope *parent_scope, AstNode |
| 6826 | 7566 | add_node_error(irb->codegen, var_node, buf_sprintf("unused variable: '%s'", buf_ptr(var_name))); |
| 6827 | 7567 | return irb->codegen->invalid_instruction; |
| 6828 | 7568 | } |
| 6829 | | return ir_gen_catch_unreachable(irb, parent_scope, node, op1_node, LValNone); |
| 7569 | return ir_gen_catch_unreachable(irb, parent_scope, node, op1_node, lval, result_loc); |
| 6830 | 7570 | } |
| 6831 | 7571 | |
| 6832 | 7572 | |
| 6833 | | IrInstruction *err_union_ptr = ir_gen_node_extra(irb, op1_node, parent_scope, LValPtr); |
| 7573 | IrInstruction *err_union_ptr = ir_gen_node_extra(irb, op1_node, parent_scope, LValPtr, nullptr); |
| 6834 | 7574 | if (err_union_ptr == irb->codegen->invalid_instruction) |
| 6835 | 7575 | return irb->codegen->invalid_instruction; |
| 6836 | 7576 | |
| 6837 | | IrInstruction *err_union_val = ir_build_load_ptr(irb, parent_scope, node, err_union_ptr); |
| 6838 | | IrInstruction *is_err = ir_build_test_err(irb, parent_scope, node, err_union_val); |
| 7577 | IrInstruction *is_err = ir_build_test_err_src(irb, parent_scope, node, err_union_ptr, true); |
| 6839 | 7578 | |
| 6840 | 7579 | IrInstruction *is_comptime; |
| 6841 | 7580 | if (ir_should_inline(irb->exec, parent_scope)) { |
| ... | ... | @@ -6847,7 +7586,10 @@ static IrInstruction *ir_gen_catch(IrBuilder *irb, Scope *parent_scope, AstNode |
| 6847 | 7586 | IrBasicBlock *ok_block = ir_create_basic_block(irb, parent_scope, "UnwrapErrOk"); |
| 6848 | 7587 | IrBasicBlock *err_block = ir_create_basic_block(irb, parent_scope, "UnwrapErrError"); |
| 6849 | 7588 | IrBasicBlock *end_block = ir_create_basic_block(irb, parent_scope, "UnwrapErrEnd"); |
| 6850 | | ir_build_cond_br(irb, parent_scope, node, is_err, err_block, ok_block, is_comptime); |
| 7589 | IrInstruction *cond_br_inst = ir_build_cond_br(irb, parent_scope, node, is_err, err_block, ok_block, is_comptime); |
| 7590 | |
| 7591 | ResultLocPeerParent *peer_parent = ir_build_binary_result_peers(irb, cond_br_inst, ok_block, end_block, result_loc, |
| 7592 | is_comptime); |
| 6851 | 7593 | |
| 6852 | 7594 | ir_set_cursor_at_end_and_append_block(irb, err_block); |
| 6853 | 7595 | Scope *err_scope; |
| ... | ... | @@ -6859,12 +7601,12 @@ static IrInstruction *ir_gen_catch(IrBuilder *irb, Scope *parent_scope, AstNode |
| 6859 | 7601 | ZigVar *var = ir_create_var(irb, node, parent_scope, var_name, |
| 6860 | 7602 | is_const, is_const, is_shadowable, is_comptime); |
| 6861 | 7603 | err_scope = var->child_scope; |
| 6862 | | IrInstruction *err_val = ir_build_unwrap_err_code(irb, err_scope, node, err_union_ptr); |
| 6863 | | ir_build_var_decl_src(irb, err_scope, var_node, var, nullptr, nullptr, err_val); |
| 7604 | IrInstruction *err_ptr = ir_build_unwrap_err_code(irb, err_scope, node, err_union_ptr); |
| 7605 | ir_build_var_decl_src(irb, err_scope, var_node, var, nullptr, err_ptr); |
| 6864 | 7606 | } else { |
| 6865 | 7607 | err_scope = parent_scope; |
| 6866 | 7608 | } |
| 6867 | | IrInstruction *err_result = ir_gen_node(irb, op2_node, err_scope); |
| 7609 | IrInstruction *err_result = ir_gen_node_extra(irb, op2_node, err_scope, LValNone, &peer_parent->peers.at(0)->base); |
| 6868 | 7610 | if (err_result == irb->codegen->invalid_instruction) |
| 6869 | 7611 | return irb->codegen->invalid_instruction; |
| 6870 | 7612 | IrBasicBlock *after_err_block = irb->current_basic_block; |
| ... | ... | @@ -6872,8 +7614,9 @@ static IrInstruction *ir_gen_catch(IrBuilder *irb, Scope *parent_scope, AstNode |
| 6872 | 7614 | ir_mark_gen(ir_build_br(irb, err_scope, node, end_block, is_comptime)); |
| 6873 | 7615 | |
| 6874 | 7616 | ir_set_cursor_at_end_and_append_block(irb, ok_block); |
| 6875 | | IrInstruction *unwrapped_ptr = ir_build_unwrap_err_payload(irb, parent_scope, node, err_union_ptr, false); |
| 7617 | IrInstruction *unwrapped_ptr = ir_build_unwrap_err_payload(irb, parent_scope, node, err_union_ptr, false, false); |
| 6876 | 7618 | IrInstruction *unwrapped_payload = ir_build_load_ptr(irb, parent_scope, node, unwrapped_ptr); |
| 7619 | ir_build_end_expr(irb, parent_scope, node, unwrapped_payload, &peer_parent->peers.at(1)->base); |
| 6877 | 7620 | IrBasicBlock *after_ok_block = irb->current_basic_block; |
| 6878 | 7621 | ir_build_br(irb, parent_scope, node, end_block, is_comptime); |
| 6879 | 7622 | |
| ... | ... | @@ -6884,7 +7627,8 @@ static IrInstruction *ir_gen_catch(IrBuilder *irb, Scope *parent_scope, AstNode |
| 6884 | 7627 | IrBasicBlock **incoming_blocks = allocate<IrBasicBlock *>(2); |
| 6885 | 7628 | incoming_blocks[0] = after_err_block; |
| 6886 | 7629 | incoming_blocks[1] = after_ok_block; |
| 6887 | | return ir_build_phi(irb, parent_scope, node, 2, incoming_blocks, incoming_values); |
| 7630 | IrInstruction *phi = ir_build_phi(irb, parent_scope, node, 2, incoming_blocks, incoming_values, peer_parent); |
| 7631 | return ir_lval_wrap(irb, parent_scope, phi, lval, result_loc); |
| 6888 | 7632 | } |
| 6889 | 7633 | |
| 6890 | 7634 | static bool render_instance_name_recursive(CodeGen *codegen, Buf *name, Scope *outer_scope, Scope *inner_scope) { |
| ... | ... | @@ -7160,7 +7904,7 @@ static IrInstruction *ir_gen_cancel_target(IrBuilder *irb, Scope *scope, AstNode |
| 7160 | 7904 | IrInstruction *coro_promise_ptr = ir_build_coro_promise(irb, scope, node, casted_target_inst); |
| 7161 | 7905 | Buf *atomic_state_field_name = buf_create_from_str(ATOMIC_STATE_FIELD_NAME); |
| 7162 | 7906 | IrInstruction *atomic_state_ptr = ir_build_field_ptr(irb, scope, node, coro_promise_ptr, |
| 7163 | | atomic_state_field_name); |
| 7907 | atomic_state_field_name, false); |
| 7164 | 7908 | |
| 7165 | 7909 | // set the is_canceled bit |
| 7166 | 7910 | IrInstruction *prev_atomic_value = ir_build_atomic_rmw(irb, scope, node, |
| ... | ... | @@ -7239,7 +7983,7 @@ static IrInstruction *ir_gen_resume_target(IrBuilder *irb, Scope *scope, AstNode |
| 7239 | 7983 | IrInstruction *coro_promise_ptr = ir_build_coro_promise(irb, scope, node, casted_target_inst); |
| 7240 | 7984 | Buf *atomic_state_field_name = buf_create_from_str(ATOMIC_STATE_FIELD_NAME); |
| 7241 | 7985 | IrInstruction *atomic_state_ptr = ir_build_field_ptr(irb, scope, node, coro_promise_ptr, |
| 7242 | | atomic_state_field_name); |
| 7986 | atomic_state_field_name, false); |
| 7243 | 7987 | |
| 7244 | 7988 | // clear the is_suspended bit |
| 7245 | 7989 | IrInstruction *prev_atomic_value = ir_build_atomic_rmw(irb, scope, node, |
| ... | ... | @@ -7306,12 +8050,12 @@ static IrInstruction *ir_gen_await_expr(IrBuilder *irb, Scope *scope, AstNode *n |
| 7306 | 8050 | |
| 7307 | 8051 | IrInstruction *coro_promise_ptr = ir_build_coro_promise(irb, scope, node, target_inst); |
| 7308 | 8052 | Buf *result_ptr_field_name = buf_create_from_str(RESULT_PTR_FIELD_NAME); |
| 7309 | | IrInstruction *result_ptr_field_ptr = ir_build_field_ptr(irb, scope, node, coro_promise_ptr, result_ptr_field_name); |
| 8053 | IrInstruction *result_ptr_field_ptr = ir_build_field_ptr(irb, scope, node, coro_promise_ptr, result_ptr_field_name, false); |
| 7310 | 8054 | |
| 7311 | 8055 | if (irb->codegen->have_err_ret_tracing) { |
| 7312 | 8056 | IrInstruction *err_ret_trace_ptr = ir_build_error_return_trace(irb, scope, node, IrInstructionErrorReturnTrace::NonNull); |
| 7313 | 8057 | Buf *err_ret_trace_ptr_field_name = buf_create_from_str(ERR_RET_TRACE_PTR_FIELD_NAME); |
| 7314 | | IrInstruction *err_ret_trace_ptr_field_ptr = ir_build_field_ptr(irb, scope, node, coro_promise_ptr, err_ret_trace_ptr_field_name); |
| 8058 | IrInstruction *err_ret_trace_ptr_field_ptr = ir_build_field_ptr(irb, scope, node, coro_promise_ptr, err_ret_trace_ptr_field_name, false); |
| 7315 | 8059 | ir_build_store_ptr(irb, scope, node, err_ret_trace_ptr_field_ptr, err_ret_trace_ptr); |
| 7316 | 8060 | } |
| 7317 | 8061 | |
| ... | ... | @@ -7333,11 +8077,11 @@ static IrInstruction *ir_gen_await_expr(IrBuilder *irb, Scope *scope, AstNode *n |
| 7333 | 8077 | |
| 7334 | 8078 | Buf *atomic_state_field_name = buf_create_from_str(ATOMIC_STATE_FIELD_NAME); |
| 7335 | 8079 | IrInstruction *atomic_state_ptr = ir_build_field_ptr(irb, scope, node, coro_promise_ptr, |
| 7336 | | atomic_state_field_name); |
| 8080 | atomic_state_field_name, false); |
| 7337 | 8081 | |
| 7338 | 8082 | IrInstruction *promise_type_val = ir_build_const_type(irb, scope, node, irb->codegen->builtin_types.entry_promise); |
| 7339 | 8083 | IrInstruction *const_bool_false = ir_build_const_bool(irb, scope, node, false); |
| 7340 | | IrInstruction *undefined_value = ir_build_const_undefined(irb, scope, node); |
| 8084 | IrInstruction *undef = ir_build_const_undefined(irb, scope, node); |
| 7341 | 8085 | IrInstruction *usize_type_val = ir_build_const_type(irb, scope, node, irb->codegen->builtin_types.entry_usize); |
| 7342 | 8086 | IrInstruction *zero = ir_build_const_usize(irb, scope, node, 0); |
| 7343 | 8087 | IrInstruction *inverted_ptr_mask = ir_build_const_usize(irb, scope, node, 0x7); // 0b111 |
| ... | ... | @@ -7351,7 +8095,8 @@ static IrInstruction *ir_gen_await_expr(IrBuilder *irb, Scope *scope, AstNode *n |
| 7351 | 8095 | IrInstruction *target_promise_type = ir_build_typeof(irb, scope, node, target_inst); |
| 7352 | 8096 | IrInstruction *promise_result_type = ir_build_promise_result_type(irb, scope, node, target_promise_type); |
| 7353 | 8097 | ir_build_await_bookkeeping(irb, scope, node, promise_result_type); |
| 7354 | | ir_build_var_decl_src(irb, scope, node, result_var, promise_result_type, nullptr, undefined_value); |
| 8098 | IrInstruction *undef_promise_result = ir_build_implicit_cast(irb, scope, node, promise_result_type, undef, nullptr); |
| 8099 | build_decl_var_and_init(irb, scope, node, result_var, undef_promise_result, "result", const_bool_false); |
| 7355 | 8100 | IrInstruction *my_result_var_ptr = ir_build_var_ptr(irb, scope, node, result_var); |
| 7356 | 8101 | ir_build_store_ptr(irb, scope, node, result_ptr_field_ptr, my_result_var_ptr); |
| 7357 | 8102 | IrInstruction *save_token = ir_build_coro_save(irb, scope, node, irb->exec->coro_handle); |
| ... | ... | @@ -7386,12 +8131,12 @@ static IrInstruction *ir_gen_await_expr(IrBuilder *irb, Scope *scope, AstNode *n |
| 7386 | 8131 | ir_set_cursor_at_end_and_append_block(irb, no_suspend_block); |
| 7387 | 8132 | if (irb->codegen->have_err_ret_tracing) { |
| 7388 | 8133 | Buf *err_ret_trace_field_name = buf_create_from_str(ERR_RET_TRACE_FIELD_NAME); |
| 7389 | | IrInstruction *src_err_ret_trace_ptr = ir_build_field_ptr(irb, scope, node, coro_promise_ptr, err_ret_trace_field_name); |
| 8134 | IrInstruction *src_err_ret_trace_ptr = ir_build_field_ptr(irb, scope, node, coro_promise_ptr, err_ret_trace_field_name, false); |
| 7390 | 8135 | IrInstruction *dest_err_ret_trace_ptr = ir_build_error_return_trace(irb, scope, node, IrInstructionErrorReturnTrace::NonNull); |
| 7391 | 8136 | ir_build_merge_err_ret_traces(irb, scope, node, coro_promise_ptr, src_err_ret_trace_ptr, dest_err_ret_trace_ptr); |
| 7392 | 8137 | } |
| 7393 | 8138 | Buf *result_field_name = buf_create_from_str(RESULT_FIELD_NAME); |
| 7394 | | IrInstruction *promise_result_ptr = ir_build_field_ptr(irb, scope, node, coro_promise_ptr, result_field_name); |
| 8139 | IrInstruction *promise_result_ptr = ir_build_field_ptr(irb, scope, node, coro_promise_ptr, result_field_name, false); |
| 7395 | 8140 | // If the type of the result handle_is_ptr then this does not actually perform a load. But we need it to, |
| 7396 | 8141 | // because we're about to destroy the memory. So we store it into our result variable. |
| 7397 | 8142 | IrInstruction *no_suspend_result = ir_build_load_ptr(irb, scope, node, promise_result_ptr); |
| ... | ... | @@ -7567,7 +8312,8 @@ static IrInstruction *ir_gen_suspend(IrBuilder *irb, Scope *parent_scope, AstNod |
| 7567 | 8312 | incoming_values[0] = const_bool_true; |
| 7568 | 8313 | incoming_blocks[1] = post_cancel_awaiter_block; |
| 7569 | 8314 | incoming_values[1] = const_bool_false; |
| 7570 | | IrInstruction *destroy_ourselves = ir_build_phi(irb, parent_scope, node, 2, incoming_blocks, incoming_values); |
| 8315 | IrInstruction *destroy_ourselves = ir_build_phi(irb, parent_scope, node, 2, incoming_blocks, incoming_values, |
| 8316 | nullptr); |
| 7571 | 8317 | ir_gen_defers_for_block(irb, parent_scope, outer_scope, true); |
| 7572 | 8318 | ir_mark_gen(ir_build_cond_br(irb, parent_scope, node, destroy_ourselves, irb->exec->coro_final_cleanup_block, irb->exec->coro_early_final, const_bool_false)); |
| 7573 | 8319 | |
| ... | ... | @@ -7576,7 +8322,7 @@ static IrInstruction *ir_gen_suspend(IrBuilder *irb, Scope *parent_scope, AstNod |
| 7576 | 8322 | } |
| 7577 | 8323 | |
| 7578 | 8324 | static IrInstruction *ir_gen_node_raw(IrBuilder *irb, AstNode *node, Scope *scope, |
| 7579 | | LVal lval) |
| 8325 | LVal lval, ResultLoc *result_loc) |
| 7580 | 8326 | { |
| 7581 | 8327 | assert(scope); |
| 7582 | 8328 | switch (node->type) { |
| ... | ... | @@ -7590,37 +8336,37 @@ static IrInstruction *ir_gen_node_raw(IrBuilder *irb, AstNode *node, Scope *scop |
| 7590 | 8336 | case NodeTypeTestDecl: |
| 7591 | 8337 | zig_unreachable(); |
| 7592 | 8338 | case NodeTypeBlock: |
| 7593 | | return ir_lval_wrap(irb, scope, ir_gen_block(irb, scope, node), lval); |
| 8339 | return ir_gen_block(irb, scope, node, lval, result_loc); |
| 7594 | 8340 | case NodeTypeGroupedExpr: |
| 7595 | | return ir_gen_node_raw(irb, node->data.grouped_expr, scope, lval); |
| 8341 | return ir_gen_node_raw(irb, node->data.grouped_expr, scope, lval, result_loc); |
| 7596 | 8342 | case NodeTypeBinOpExpr: |
| 7597 | | return ir_lval_wrap(irb, scope, ir_gen_bin_op(irb, scope, node), lval); |
| 8343 | return ir_gen_bin_op(irb, scope, node, lval, result_loc); |
| 7598 | 8344 | case NodeTypeIntLiteral: |
| 7599 | | return ir_lval_wrap(irb, scope, ir_gen_int_lit(irb, scope, node), lval); |
| 8345 | return ir_lval_wrap(irb, scope, ir_gen_int_lit(irb, scope, node), lval, result_loc); |
| 7600 | 8346 | case NodeTypeFloatLiteral: |
| 7601 | | return ir_lval_wrap(irb, scope, ir_gen_float_lit(irb, scope, node), lval); |
| 8347 | return ir_lval_wrap(irb, scope, ir_gen_float_lit(irb, scope, node), lval, result_loc); |
| 7602 | 8348 | case NodeTypeCharLiteral: |
| 7603 | | return ir_lval_wrap(irb, scope, ir_gen_char_lit(irb, scope, node), lval); |
| 8349 | return ir_lval_wrap(irb, scope, ir_gen_char_lit(irb, scope, node), lval, result_loc); |
| 7604 | 8350 | case NodeTypeSymbol: |
| 7605 | | return ir_gen_symbol(irb, scope, node, lval); |
| 8351 | return ir_gen_symbol(irb, scope, node, lval, result_loc); |
| 7606 | 8352 | case NodeTypeFnCallExpr: |
| 7607 | | return ir_gen_fn_call(irb, scope, node, lval); |
| 8353 | return ir_gen_fn_call(irb, scope, node, lval, result_loc); |
| 7608 | 8354 | case NodeTypeIfBoolExpr: |
| 7609 | | return ir_lval_wrap(irb, scope, ir_gen_if_bool_expr(irb, scope, node), lval); |
| 8355 | return ir_gen_if_bool_expr(irb, scope, node, lval, result_loc); |
| 7610 | 8356 | case NodeTypePrefixOpExpr: |
| 7611 | | return ir_gen_prefix_op_expr(irb, scope, node, lval); |
| 8357 | return ir_gen_prefix_op_expr(irb, scope, node, lval, result_loc); |
| 7612 | 8358 | case NodeTypeContainerInitExpr: |
| 7613 | | return ir_lval_wrap(irb, scope, ir_gen_container_init_expr(irb, scope, node), lval); |
| 8359 | return ir_gen_container_init_expr(irb, scope, node, lval, result_loc); |
| 7614 | 8360 | case NodeTypeVariableDeclaration: |
| 7615 | | return ir_lval_wrap(irb, scope, ir_gen_var_decl(irb, scope, node), lval); |
| 8361 | return ir_gen_var_decl(irb, scope, node); |
| 7616 | 8362 | case NodeTypeWhileExpr: |
| 7617 | | return ir_lval_wrap(irb, scope, ir_gen_while_expr(irb, scope, node), lval); |
| 8363 | return ir_gen_while_expr(irb, scope, node, lval, result_loc); |
| 7618 | 8364 | case NodeTypeForExpr: |
| 7619 | | return ir_lval_wrap(irb, scope, ir_gen_for_expr(irb, scope, node), lval); |
| 8365 | return ir_gen_for_expr(irb, scope, node, lval, result_loc); |
| 7620 | 8366 | case NodeTypeArrayAccessExpr: |
| 7621 | | return ir_gen_array_access(irb, scope, node, lval); |
| 8367 | return ir_gen_array_access(irb, scope, node, lval, result_loc); |
| 7622 | 8368 | case NodeTypeReturnExpr: |
| 7623 | | return ir_gen_return(irb, scope, node, lval); |
| 8369 | return ir_gen_return(irb, scope, node, lval, result_loc); |
| 7624 | 8370 | case NodeTypeFieldAccessExpr: |
| 7625 | 8371 | { |
| 7626 | 8372 | IrInstruction *ptr_instruction = ir_gen_field_access(irb, scope, node); |
| ... | ... | @@ -7629,86 +8375,89 @@ static IrInstruction *ir_gen_node_raw(IrBuilder *irb, AstNode *node, Scope *scop |
| 7629 | 8375 | if (lval == LValPtr) |
| 7630 | 8376 | return ptr_instruction; |
| 7631 | 8377 | |
| 7632 | | return ir_build_load_ptr(irb, scope, node, ptr_instruction); |
| 8378 | IrInstruction *load_ptr = ir_build_load_ptr(irb, scope, node, ptr_instruction); |
| 8379 | return ir_expr_wrap(irb, scope, load_ptr, result_loc); |
| 7633 | 8380 | } |
| 7634 | 8381 | case NodeTypePtrDeref: { |
| 7635 | 8382 | AstNode *expr_node = node->data.ptr_deref_expr.target; |
| 7636 | | IrInstruction *value = ir_gen_node_extra(irb, expr_node, scope, lval); |
| 8383 | IrInstruction *value = ir_gen_node_extra(irb, expr_node, scope, lval, nullptr); |
| 7637 | 8384 | if (value == irb->codegen->invalid_instruction) |
| 7638 | 8385 | return value; |
| 7639 | 8386 | |
| 7640 | 8387 | // We essentially just converted any lvalue from &(x.*) to (&x).*; |
| 7641 | 8388 | // this inhibits checking that x is a pointer later, so we directly |
| 7642 | 8389 | // record whether the pointer check is needed |
| 7643 | | return ir_build_un_op_lval(irb, scope, node, IrUnOpDereference, value, lval); |
| 8390 | IrInstruction *un_op = ir_build_un_op_lval(irb, scope, node, IrUnOpDereference, value, lval, result_loc); |
| 8391 | return ir_expr_wrap(irb, scope, un_op, result_loc); |
| 7644 | 8392 | } |
| 7645 | 8393 | case NodeTypeUnwrapOptional: { |
| 7646 | 8394 | AstNode *expr_node = node->data.unwrap_optional.expr; |
| 7647 | 8395 | |
| 7648 | | IrInstruction *maybe_ptr = ir_gen_node_extra(irb, expr_node, scope, LValPtr); |
| 8396 | IrInstruction *maybe_ptr = ir_gen_node_extra(irb, expr_node, scope, LValPtr, nullptr); |
| 7649 | 8397 | if (maybe_ptr == irb->codegen->invalid_instruction) |
| 7650 | 8398 | return irb->codegen->invalid_instruction; |
| 7651 | 8399 | |
| 7652 | | IrInstruction *unwrapped_ptr = ir_build_optional_unwrap_ptr(irb, scope, node, maybe_ptr, true); |
| 8400 | IrInstruction *unwrapped_ptr = ir_build_optional_unwrap_ptr(irb, scope, node, maybe_ptr, true, false); |
| 7653 | 8401 | if (lval == LValPtr) |
| 7654 | 8402 | return unwrapped_ptr; |
| 7655 | 8403 | |
| 7656 | | return ir_build_load_ptr(irb, scope, node, unwrapped_ptr); |
| 8404 | IrInstruction *load_ptr = ir_build_load_ptr(irb, scope, node, unwrapped_ptr); |
| 8405 | return ir_expr_wrap(irb, scope, load_ptr, result_loc); |
| 7657 | 8406 | } |
| 7658 | 8407 | case NodeTypeBoolLiteral: |
| 7659 | | return ir_lval_wrap(irb, scope, ir_gen_bool_literal(irb, scope, node), lval); |
| 8408 | return ir_lval_wrap(irb, scope, ir_gen_bool_literal(irb, scope, node), lval, result_loc); |
| 7660 | 8409 | case NodeTypeArrayType: |
| 7661 | | return ir_lval_wrap(irb, scope, ir_gen_array_type(irb, scope, node), lval); |
| 8410 | return ir_lval_wrap(irb, scope, ir_gen_array_type(irb, scope, node), lval, result_loc); |
| 7662 | 8411 | case NodeTypePointerType: |
| 7663 | | return ir_lval_wrap(irb, scope, ir_gen_pointer_type(irb, scope, node), lval); |
| 8412 | return ir_lval_wrap(irb, scope, ir_gen_pointer_type(irb, scope, node), lval, result_loc); |
| 7664 | 8413 | case NodeTypePromiseType: |
| 7665 | | return ir_lval_wrap(irb, scope, ir_gen_promise_type(irb, scope, node), lval); |
| 8414 | return ir_lval_wrap(irb, scope, ir_gen_promise_type(irb, scope, node), lval, result_loc); |
| 7666 | 8415 | case NodeTypeStringLiteral: |
| 7667 | | return ir_lval_wrap(irb, scope, ir_gen_string_literal(irb, scope, node), lval); |
| 8416 | return ir_lval_wrap(irb, scope, ir_gen_string_literal(irb, scope, node), lval, result_loc); |
| 7668 | 8417 | case NodeTypeUndefinedLiteral: |
| 7669 | | return ir_lval_wrap(irb, scope, ir_gen_undefined_literal(irb, scope, node), lval); |
| 8418 | return ir_lval_wrap(irb, scope, ir_gen_undefined_literal(irb, scope, node), lval, result_loc); |
| 7670 | 8419 | case NodeTypeAsmExpr: |
| 7671 | | return ir_lval_wrap(irb, scope, ir_gen_asm_expr(irb, scope, node), lval); |
| 8420 | return ir_lval_wrap(irb, scope, ir_gen_asm_expr(irb, scope, node), lval, result_loc); |
| 7672 | 8421 | case NodeTypeNullLiteral: |
| 7673 | | return ir_lval_wrap(irb, scope, ir_gen_null_literal(irb, scope, node), lval); |
| 8422 | return ir_lval_wrap(irb, scope, ir_gen_null_literal(irb, scope, node), lval, result_loc); |
| 7674 | 8423 | case NodeTypeIfErrorExpr: |
| 7675 | | return ir_lval_wrap(irb, scope, ir_gen_if_err_expr(irb, scope, node), lval); |
| 8424 | return ir_gen_if_err_expr(irb, scope, node, lval, result_loc); |
| 7676 | 8425 | case NodeTypeIfOptional: |
| 7677 | | return ir_lval_wrap(irb, scope, ir_gen_if_optional_expr(irb, scope, node), lval); |
| 8426 | return ir_gen_if_optional_expr(irb, scope, node, lval, result_loc); |
| 7678 | 8427 | case NodeTypeSwitchExpr: |
| 7679 | | return ir_lval_wrap(irb, scope, ir_gen_switch_expr(irb, scope, node), lval); |
| 8428 | return ir_gen_switch_expr(irb, scope, node, lval, result_loc); |
| 7680 | 8429 | case NodeTypeCompTime: |
| 7681 | | return ir_gen_comptime(irb, scope, node, lval); |
| 8430 | return ir_expr_wrap(irb, scope, ir_gen_comptime(irb, scope, node, lval), result_loc); |
| 7682 | 8431 | case NodeTypeErrorType: |
| 7683 | | return ir_lval_wrap(irb, scope, ir_gen_error_type(irb, scope, node), lval); |
| 8432 | return ir_lval_wrap(irb, scope, ir_gen_error_type(irb, scope, node), lval, result_loc); |
| 7684 | 8433 | case NodeTypeBreak: |
| 7685 | | return ir_lval_wrap(irb, scope, ir_gen_break(irb, scope, node), lval); |
| 8434 | return ir_lval_wrap(irb, scope, ir_gen_break(irb, scope, node), lval, result_loc); |
| 7686 | 8435 | case NodeTypeContinue: |
| 7687 | | return ir_lval_wrap(irb, scope, ir_gen_continue(irb, scope, node), lval); |
| 8436 | return ir_lval_wrap(irb, scope, ir_gen_continue(irb, scope, node), lval, result_loc); |
| 7688 | 8437 | case NodeTypeUnreachable: |
| 7689 | | return ir_lval_wrap(irb, scope, ir_build_unreachable(irb, scope, node), lval); |
| 8438 | return ir_build_unreachable(irb, scope, node); |
| 7690 | 8439 | case NodeTypeDefer: |
| 7691 | | return ir_lval_wrap(irb, scope, ir_gen_defer(irb, scope, node), lval); |
| 8440 | return ir_lval_wrap(irb, scope, ir_gen_defer(irb, scope, node), lval, result_loc); |
| 7692 | 8441 | case NodeTypeSliceExpr: |
| 7693 | | return ir_lval_wrap(irb, scope, ir_gen_slice(irb, scope, node), lval); |
| 7694 | | case NodeTypeUnwrapErrorExpr: |
| 7695 | | return ir_lval_wrap(irb, scope, ir_gen_catch(irb, scope, node), lval); |
| 8442 | return ir_gen_slice(irb, scope, node, lval, result_loc); |
| 8443 | case NodeTypeCatchExpr: |
| 8444 | return ir_gen_catch(irb, scope, node, lval, result_loc); |
| 7696 | 8445 | case NodeTypeContainerDecl: |
| 7697 | | return ir_lval_wrap(irb, scope, ir_gen_container_decl(irb, scope, node), lval); |
| 8446 | return ir_lval_wrap(irb, scope, ir_gen_container_decl(irb, scope, node), lval, result_loc); |
| 7698 | 8447 | case NodeTypeFnProto: |
| 7699 | | return ir_lval_wrap(irb, scope, ir_gen_fn_proto(irb, scope, node), lval); |
| 8448 | return ir_lval_wrap(irb, scope, ir_gen_fn_proto(irb, scope, node), lval, result_loc); |
| 7700 | 8449 | case NodeTypeErrorSetDecl: |
| 7701 | | return ir_lval_wrap(irb, scope, ir_gen_err_set_decl(irb, scope, node), lval); |
| 8450 | return ir_lval_wrap(irb, scope, ir_gen_err_set_decl(irb, scope, node), lval, result_loc); |
| 7702 | 8451 | case NodeTypeCancel: |
| 7703 | | return ir_lval_wrap(irb, scope, ir_gen_cancel(irb, scope, node), lval); |
| 8452 | return ir_lval_wrap(irb, scope, ir_gen_cancel(irb, scope, node), lval, result_loc); |
| 7704 | 8453 | case NodeTypeResume: |
| 7705 | | return ir_lval_wrap(irb, scope, ir_gen_resume(irb, scope, node), lval); |
| 8454 | return ir_lval_wrap(irb, scope, ir_gen_resume(irb, scope, node), lval, result_loc); |
| 7706 | 8455 | case NodeTypeAwaitExpr: |
| 7707 | | return ir_lval_wrap(irb, scope, ir_gen_await_expr(irb, scope, node), lval); |
| 8456 | return ir_lval_wrap(irb, scope, ir_gen_await_expr(irb, scope, node), lval, result_loc); |
| 7708 | 8457 | case NodeTypeSuspend: |
| 7709 | | return ir_lval_wrap(irb, scope, ir_gen_suspend(irb, scope, node), lval); |
| 8458 | return ir_lval_wrap(irb, scope, ir_gen_suspend(irb, scope, node), lval, result_loc); |
| 7710 | 8459 | case NodeTypeEnumLiteral: |
| 7711 | | return ir_lval_wrap(irb, scope, ir_gen_enum_literal(irb, scope, node), lval); |
| 8460 | return ir_lval_wrap(irb, scope, ir_gen_enum_literal(irb, scope, node), lval, result_loc); |
| 7712 | 8461 | case NodeTypeInferredArrayType: |
| 7713 | 8462 | add_node_error(irb->codegen, node, |
| 7714 | 8463 | buf_sprintf("inferred array size invalid here")); |
| ... | ... | @@ -7717,14 +8466,28 @@ static IrInstruction *ir_gen_node_raw(IrBuilder *irb, AstNode *node, Scope *scop |
| 7717 | 8466 | zig_unreachable(); |
| 7718 | 8467 | } |
| 7719 | 8468 | |
| 7720 | | static IrInstruction *ir_gen_node_extra(IrBuilder *irb, AstNode *node, Scope *scope, LVal lval) { |
| 7721 | | IrInstruction *result = ir_gen_node_raw(irb, node, scope, lval); |
| 8469 | static ResultLoc *no_result_loc(void) { |
| 8470 | ResultLocNone *result_loc_none = allocate<ResultLocNone>(1); |
| 8471 | result_loc_none->base.id = ResultLocIdNone; |
| 8472 | return &result_loc_none->base; |
| 8473 | } |
| 8474 | |
| 8475 | static IrInstruction *ir_gen_node_extra(IrBuilder *irb, AstNode *node, Scope *scope, LVal lval, |
| 8476 | ResultLoc *result_loc) |
| 8477 | { |
| 8478 | if (result_loc == nullptr) { |
| 8479 | // Create a result location indicating there is none - but if one gets created |
| 8480 | // it will be properly distributed. |
| 8481 | result_loc = no_result_loc(); |
| 8482 | ir_build_reset_result(irb, scope, node, result_loc); |
| 8483 | } |
| 8484 | IrInstruction *result = ir_gen_node_raw(irb, node, scope, lval, result_loc); |
| 7722 | 8485 | irb->exec->invalid = irb->exec->invalid || (result == irb->codegen->invalid_instruction); |
| 7723 | 8486 | return result; |
| 7724 | 8487 | } |
| 7725 | 8488 | |
| 7726 | 8489 | static IrInstruction *ir_gen_node(IrBuilder *irb, AstNode *node, Scope *scope) { |
| 7727 | | return ir_gen_node_extra(irb, node, scope, LValNone); |
| 8490 | return ir_gen_node_extra(irb, node, scope, LValNone, nullptr); |
| 7728 | 8491 | } |
| 7729 | 8492 | |
| 7730 | 8493 | static void invalidate_exec(IrExecutable *exec) { |
| ... | ... | @@ -7775,17 +8538,19 @@ bool ir_gen(CodeGen *codegen, AstNode *node, Scope *scope, IrExecutable *ir_exec |
| 7775 | 8538 | |
| 7776 | 8539 | return_type = fn_entry->type_entry->data.fn.fn_type_id.return_type; |
| 7777 | 8540 | IrInstruction *undef = ir_build_const_undefined(irb, coro_scope, node); |
| 8541 | // TODO mark this var decl as "no safety" e.g. disable initializing the undef value to 0xaa |
| 7778 | 8542 | ZigType *coro_frame_type = get_promise_frame_type(irb->codegen, return_type); |
| 7779 | 8543 | IrInstruction *coro_frame_type_value = ir_build_const_type(irb, coro_scope, node, coro_frame_type); |
| 7780 | | // TODO mark this var decl as "no safety" e.g. disable initializing the undef value to 0xaa |
| 7781 | | ir_build_var_decl_src(irb, coro_scope, node, promise_var, coro_frame_type_value, nullptr, undef); |
| 8544 | IrInstruction *undef_coro_frame = ir_build_implicit_cast(irb, coro_scope, node, coro_frame_type_value, undef, nullptr); |
| 8545 | build_decl_var_and_init(irb, coro_scope, node, promise_var, undef_coro_frame, "promise", const_bool_false); |
| 7782 | 8546 | coro_promise_ptr = ir_build_var_ptr(irb, coro_scope, node, promise_var); |
| 7783 | 8547 | |
| 7784 | 8548 | ZigVar *await_handle_var = ir_create_var(irb, node, coro_scope, nullptr, false, false, true, const_bool_false); |
| 7785 | 8549 | IrInstruction *null_value = ir_build_const_null(irb, coro_scope, node); |
| 7786 | 8550 | IrInstruction *await_handle_type_val = ir_build_const_type(irb, coro_scope, node, |
| 7787 | 8551 | get_optional_type(irb->codegen, irb->codegen->builtin_types.entry_promise)); |
| 7788 | | ir_build_var_decl_src(irb, coro_scope, node, await_handle_var, await_handle_type_val, nullptr, null_value); |
| 8552 | IrInstruction *null_await_handle = ir_build_implicit_cast(irb, coro_scope, node, await_handle_type_val, null_value, nullptr); |
| 8553 | build_decl_var_and_init(irb, coro_scope, node, await_handle_var, null_await_handle, "await_handle", const_bool_false); |
| 7789 | 8554 | irb->exec->await_handle_var_ptr = ir_build_var_ptr(irb, coro_scope, node, await_handle_var); |
| 7790 | 8555 | |
| 7791 | 8556 | u8_ptr_type = ir_build_const_type(irb, coro_scope, node, |
| ... | ... | @@ -7795,13 +8560,14 @@ bool ir_gen(CodeGen *codegen, AstNode *node, Scope *scope, IrExecutable *ir_exec |
| 7795 | 8560 | coro_id = ir_build_coro_id(irb, coro_scope, node, promise_as_u8_ptr); |
| 7796 | 8561 | coro_size_var = ir_create_var(irb, node, coro_scope, nullptr, false, false, true, const_bool_false); |
| 7797 | 8562 | IrInstruction *coro_size = ir_build_coro_size(irb, coro_scope, node); |
| 7798 | | ir_build_var_decl_src(irb, coro_scope, node, coro_size_var, nullptr, nullptr, coro_size); |
| 8563 | build_decl_var_and_init(irb, coro_scope, node, coro_size_var, coro_size, "coro_size", const_bool_false); |
| 7799 | 8564 | IrInstruction *implicit_allocator_ptr = ir_build_get_implicit_allocator(irb, coro_scope, node, |
| 7800 | 8565 | ImplicitAllocatorIdArg); |
| 7801 | 8566 | irb->exec->coro_allocator_var = ir_create_var(irb, node, coro_scope, nullptr, true, true, true, const_bool_false); |
| 7802 | | ir_build_var_decl_src(irb, coro_scope, node, irb->exec->coro_allocator_var, nullptr, nullptr, implicit_allocator_ptr); |
| 8567 | build_decl_var_and_init(irb, coro_scope, node, irb->exec->coro_allocator_var, implicit_allocator_ptr, |
| 8568 | "allocator", const_bool_false); |
| 7803 | 8569 | Buf *realloc_field_name = buf_create_from_str(ASYNC_REALLOC_FIELD_NAME); |
| 7804 | | IrInstruction *realloc_fn_ptr = ir_build_field_ptr(irb, coro_scope, node, implicit_allocator_ptr, realloc_field_name); |
| 8570 | IrInstruction *realloc_fn_ptr = ir_build_field_ptr(irb, coro_scope, node, implicit_allocator_ptr, realloc_field_name, false); |
| 7805 | 8571 | IrInstruction *realloc_fn = ir_build_load_ptr(irb, coro_scope, node, realloc_fn_ptr); |
| 7806 | 8572 | IrInstruction *maybe_coro_mem_ptr = ir_build_coro_alloc_helper(irb, coro_scope, node, realloc_fn, coro_size); |
| 7807 | 8573 | IrInstruction *alloc_result_is_ok = ir_build_test_nonnull(irb, coro_scope, node, maybe_coro_mem_ptr); |
| ... | ... | @@ -7821,32 +8587,32 @@ bool ir_gen(CodeGen *codegen, AstNode *node, Scope *scope, IrExecutable *ir_exec |
| 7821 | 8587 | |
| 7822 | 8588 | Buf *atomic_state_field_name = buf_create_from_str(ATOMIC_STATE_FIELD_NAME); |
| 7823 | 8589 | irb->exec->atomic_state_field_ptr = ir_build_field_ptr(irb, scope, node, coro_promise_ptr, |
| 7824 | | atomic_state_field_name); |
| 8590 | atomic_state_field_name, false); |
| 7825 | 8591 | IrInstruction *zero = ir_build_const_usize(irb, scope, node, 0); |
| 7826 | 8592 | ir_build_store_ptr(irb, scope, node, irb->exec->atomic_state_field_ptr, zero); |
| 7827 | 8593 | Buf *result_field_name = buf_create_from_str(RESULT_FIELD_NAME); |
| 7828 | | irb->exec->coro_result_field_ptr = ir_build_field_ptr(irb, scope, node, coro_promise_ptr, result_field_name); |
| 8594 | irb->exec->coro_result_field_ptr = ir_build_field_ptr(irb, scope, node, coro_promise_ptr, result_field_name, false); |
| 7829 | 8595 | result_ptr_field_name = buf_create_from_str(RESULT_PTR_FIELD_NAME); |
| 7830 | | irb->exec->coro_result_ptr_field_ptr = ir_build_field_ptr(irb, scope, node, coro_promise_ptr, result_ptr_field_name); |
| 8596 | irb->exec->coro_result_ptr_field_ptr = ir_build_field_ptr(irb, scope, node, coro_promise_ptr, result_ptr_field_name, false); |
| 7831 | 8597 | ir_build_store_ptr(irb, scope, node, irb->exec->coro_result_ptr_field_ptr, irb->exec->coro_result_field_ptr); |
| 7832 | 8598 | if (irb->codegen->have_err_ret_tracing) { |
| 7833 | 8599 | // initialize the error return trace |
| 7834 | 8600 | Buf *return_addresses_field_name = buf_create_from_str(RETURN_ADDRESSES_FIELD_NAME); |
| 7835 | | IrInstruction *return_addresses_ptr = ir_build_field_ptr(irb, scope, node, coro_promise_ptr, return_addresses_field_name); |
| 8601 | IrInstruction *return_addresses_ptr = ir_build_field_ptr(irb, scope, node, coro_promise_ptr, return_addresses_field_name, false); |
| 7836 | 8602 | |
| 7837 | 8603 | Buf *err_ret_trace_field_name = buf_create_from_str(ERR_RET_TRACE_FIELD_NAME); |
| 7838 | | err_ret_trace_ptr = ir_build_field_ptr(irb, scope, node, coro_promise_ptr, err_ret_trace_field_name); |
| 8604 | err_ret_trace_ptr = ir_build_field_ptr(irb, scope, node, coro_promise_ptr, err_ret_trace_field_name, false); |
| 7839 | 8605 | ir_build_mark_err_ret_trace_ptr(irb, scope, node, err_ret_trace_ptr); |
| 7840 | 8606 | |
| 7841 | 8607 | // coordinate with builtin.zig |
| 7842 | 8608 | Buf *index_name = buf_create_from_str("index"); |
| 7843 | | IrInstruction *index_ptr = ir_build_field_ptr(irb, scope, node, err_ret_trace_ptr, index_name); |
| 8609 | IrInstruction *index_ptr = ir_build_field_ptr(irb, scope, node, err_ret_trace_ptr, index_name, false); |
| 7844 | 8610 | ir_build_store_ptr(irb, scope, node, index_ptr, zero); |
| 7845 | 8611 | |
| 7846 | 8612 | Buf *instruction_addresses_name = buf_create_from_str("instruction_addresses"); |
| 7847 | | IrInstruction *addrs_slice_ptr = ir_build_field_ptr(irb, scope, node, err_ret_trace_ptr, instruction_addresses_name); |
| 8613 | IrInstruction *addrs_slice_ptr = ir_build_field_ptr(irb, scope, node, err_ret_trace_ptr, instruction_addresses_name, false); |
| 7848 | 8614 | |
| 7849 | | IrInstruction *slice_value = ir_build_slice(irb, scope, node, return_addresses_ptr, zero, nullptr, false); |
| 8615 | IrInstruction *slice_value = ir_build_slice_src(irb, scope, node, return_addresses_ptr, zero, nullptr, false, no_result_loc()); |
| 7850 | 8616 | ir_build_store_ptr(irb, scope, node, addrs_slice_ptr, slice_value); |
| 7851 | 8617 | } |
| 7852 | 8618 | |
| ... | ... | @@ -7857,7 +8623,7 @@ bool ir_gen(CodeGen *codegen, AstNode *node, Scope *scope, IrExecutable *ir_exec |
| 7857 | 8623 | irb->exec->coro_final_cleanup_block = ir_create_basic_block(irb, scope, "FinalCleanup"); |
| 7858 | 8624 | } |
| 7859 | 8625 | |
| 7860 | | IrInstruction *result = ir_gen_node_extra(irb, node, scope, LValNone); |
| 8626 | IrInstruction *result = ir_gen_node_extra(irb, node, scope, LValNone, nullptr); |
| 7861 | 8627 | assert(result); |
| 7862 | 8628 | if (irb->exec->invalid) |
| 7863 | 8629 | return false; |
| ... | ... | @@ -7905,7 +8671,7 @@ bool ir_gen(CodeGen *codegen, AstNode *node, Scope *scope, IrExecutable *ir_exec |
| 7905 | 8671 | } |
| 7906 | 8672 | if (irb->codegen->have_err_ret_tracing) { |
| 7907 | 8673 | Buf *err_ret_trace_ptr_field_name = buf_create_from_str(ERR_RET_TRACE_PTR_FIELD_NAME); |
| 7908 | | IrInstruction *err_ret_trace_ptr_field_ptr = ir_build_field_ptr(irb, scope, node, coro_promise_ptr, err_ret_trace_ptr_field_name); |
| 8674 | IrInstruction *err_ret_trace_ptr_field_ptr = ir_build_field_ptr(irb, scope, node, coro_promise_ptr, err_ret_trace_ptr_field_name, false); |
| 7909 | 8675 | IrInstruction *dest_err_ret_trace_ptr = ir_build_load_ptr(irb, scope, node, err_ret_trace_ptr_field_ptr); |
| 7910 | 8676 | ir_build_merge_err_ret_traces(irb, scope, node, coro_promise_ptr, err_ret_trace_ptr, dest_err_ret_trace_ptr); |
| 7911 | 8677 | } |
| ... | ... | @@ -7913,7 +8679,7 @@ bool ir_gen(CodeGen *codegen, AstNode *node, Scope *scope, IrExecutable *ir_exec |
| 7913 | 8679 | // a register or local variable which does not get spilled into the frame, |
| 7914 | 8680 | // otherwise llvm tries to access memory inside the destroyed frame. |
| 7915 | 8681 | IrInstruction *unwrapped_await_handle_ptr = ir_build_optional_unwrap_ptr(irb, scope, node, |
| 7916 | | irb->exec->await_handle_var_ptr, false); |
| 8682 | irb->exec->await_handle_var_ptr, false, false); |
| 7917 | 8683 | IrInstruction *await_handle_in_block = ir_build_load_ptr(irb, scope, node, unwrapped_await_handle_ptr); |
| 7918 | 8684 | ir_build_br(irb, scope, node, check_free_block, const_bool_false); |
| 7919 | 8685 | |
| ... | ... | @@ -7927,7 +8693,7 @@ bool ir_gen(CodeGen *codegen, AstNode *node, Scope *scope, IrExecutable *ir_exec |
| 7927 | 8693 | incoming_values[0] = const_bool_false; |
| 7928 | 8694 | incoming_blocks[1] = irb->exec->coro_normal_final; |
| 7929 | 8695 | incoming_values[1] = const_bool_true; |
| 7930 | | IrInstruction *resume_awaiter = ir_build_phi(irb, scope, node, 2, incoming_blocks, incoming_values); |
| 8696 | IrInstruction *resume_awaiter = ir_build_phi(irb, scope, node, 2, incoming_blocks, incoming_values, nullptr); |
| 7931 | 8697 | |
| 7932 | 8698 | IrBasicBlock **merge_incoming_blocks = allocate<IrBasicBlock *>(2); |
| 7933 | 8699 | IrInstruction **merge_incoming_values = allocate<IrInstruction *>(2); |
| ... | ... | @@ -7935,12 +8701,12 @@ bool ir_gen(CodeGen *codegen, AstNode *node, Scope *scope, IrExecutable *ir_exec |
| 7935 | 8701 | merge_incoming_values[0] = ir_build_const_undefined(irb, scope, node); |
| 7936 | 8702 | merge_incoming_blocks[1] = irb->exec->coro_normal_final; |
| 7937 | 8703 | merge_incoming_values[1] = await_handle_in_block; |
| 7938 | | IrInstruction *awaiter_handle = ir_build_phi(irb, scope, node, 2, merge_incoming_blocks, merge_incoming_values); |
| 8704 | IrInstruction *awaiter_handle = ir_build_phi(irb, scope, node, 2, merge_incoming_blocks, merge_incoming_values, nullptr); |
| 7939 | 8705 | |
| 7940 | 8706 | Buf *shrink_field_name = buf_create_from_str(ASYNC_SHRINK_FIELD_NAME); |
| 7941 | 8707 | IrInstruction *implicit_allocator_ptr = ir_build_get_implicit_allocator(irb, scope, node, |
| 7942 | 8708 | ImplicitAllocatorIdLocalVar); |
| 7943 | | IrInstruction *shrink_fn_ptr = ir_build_field_ptr(irb, scope, node, implicit_allocator_ptr, shrink_field_name); |
| 8709 | IrInstruction *shrink_fn_ptr = ir_build_field_ptr(irb, scope, node, implicit_allocator_ptr, shrink_field_name, false); |
| 7944 | 8710 | IrInstruction *shrink_fn = ir_build_load_ptr(irb, scope, node, shrink_fn_ptr); |
| 7945 | 8711 | IrInstruction *zero = ir_build_const_usize(irb, scope, node, 0); |
| 7946 | 8712 | IrInstruction *coro_mem_ptr_maybe = ir_build_coro_free(irb, scope, node, coro_id, irb->exec->coro_handle); |
| ... | ... | @@ -7952,7 +8718,8 @@ bool ir_gen(CodeGen *codegen, AstNode *node, Scope *scope, IrExecutable *ir_exec |
| 7952 | 8718 | IrInstruction *coro_mem_ptr_ref = ir_build_ref(irb, scope, node, coro_mem_ptr, true, false); |
| 7953 | 8719 | IrInstruction *coro_size_ptr = ir_build_var_ptr(irb, scope, node, coro_size_var); |
| 7954 | 8720 | IrInstruction *coro_size = ir_build_load_ptr(irb, scope, node, coro_size_ptr); |
| 7955 | | IrInstruction *mem_slice = ir_build_slice(irb, scope, node, coro_mem_ptr_ref, zero, coro_size, false); |
| 8721 | IrInstruction *mem_slice = ir_build_slice_src(irb, scope, node, coro_mem_ptr_ref, zero, coro_size, false, |
| 8722 | no_result_loc()); |
| 7956 | 8723 | size_t arg_count = 5; |
| 7957 | 8724 | IrInstruction **args = allocate<IrInstruction *>(arg_count); |
| 7958 | 8725 | args[0] = implicit_allocator_ptr; // self |
| ... | ... | @@ -7966,7 +8733,8 @@ bool ir_gen(CodeGen *codegen, AstNode *node, Scope *scope, IrExecutable *ir_exec |
| 7966 | 8733 | // non-allocating. Basically coroutines are not supported right now until they are reworked. |
| 7967 | 8734 | args[3] = ir_build_const_usize(irb, scope, node, 1); // new_size |
| 7968 | 8735 | args[4] = ir_build_const_usize(irb, scope, node, 1); // new_align |
| 7969 | | ir_build_call(irb, scope, node, nullptr, shrink_fn, arg_count, args, false, FnInlineAuto, false, nullptr, nullptr); |
| 8736 | ir_build_call_src(irb, scope, node, nullptr, shrink_fn, arg_count, args, false, FnInlineAuto, false, nullptr, |
| 8737 | nullptr, no_result_loc()); |
| 7970 | 8738 | |
| 7971 | 8739 | IrBasicBlock *resume_block = ir_create_basic_block(irb, scope, "Resume"); |
| 7972 | 8740 | ir_build_cond_br(irb, scope, node, resume_awaiter, resume_block, irb->exec->coro_suspend_block, const_bool_false); |
| ... | ... | @@ -8073,6 +8841,15 @@ static ConstExprValue *ir_exec_const_result(CodeGen *codegen, IrExecutable *exec |
| 8073 | 8841 | } |
| 8074 | 8842 | return &value->value; |
| 8075 | 8843 | } else if (ir_has_side_effects(instruction)) { |
| 8844 | if (instr_is_comptime(instruction)) { |
| 8845 | switch (instruction->id) { |
| 8846 | case IrInstructionIdUnwrapErrPayload: |
| 8847 | case IrInstructionIdUnionFieldPtr: |
| 8848 | continue; |
| 8849 | default: |
| 8850 | break; |
| 8851 | } |
| 8852 | } |
| 8076 | 8853 | exec_add_error_node(codegen, exec, instruction->source_node, |
| 8077 | 8854 | buf_sprintf("unable to evaluate constant expression")); |
| 8078 | 8855 | return &codegen->invalid_instruction->value; |
| ... | ... | @@ -9050,15 +9827,6 @@ static bool ir_num_lit_fits_in_other_type(IrAnalyze *ira, IrInstruction *instruc |
| 9050 | 9827 | return false; |
| 9051 | 9828 | } |
| 9052 | 9829 | |
| 9053 | | static bool is_slice(ZigType *type) { |
| 9054 | | return type->id == ZigTypeIdStruct && type->data.structure.is_slice; |
| 9055 | | } |
| 9056 | | |
| 9057 | | static bool slice_is_const(ZigType *type) { |
| 9058 | | assert(is_slice(type)); |
| 9059 | | return type->data.structure.fields[slice_ptr_index].type_entry->data.pointer.is_const; |
| 9060 | | } |
| 9061 | | |
| 9062 | 9830 | static bool is_tagged_union(ZigType *type) { |
| 9063 | 9831 | if (type->id != ZigTypeIdUnion) |
| 9064 | 9832 | return false; |
| ... | ... | @@ -9429,9 +10197,21 @@ static ZigType *ir_resolve_peer_types(IrAnalyze *ira, AstNode *source_node, ZigT |
| 9429 | 10197 | { |
| 9430 | 10198 | Error err; |
| 9431 | 10199 | assert(instruction_count >= 1); |
| 9432 | | IrInstruction *prev_inst = instructions[0]; |
| 9433 | | if (type_is_invalid(prev_inst->value.type)) { |
| 9434 | | return ira->codegen->builtin_types.entry_invalid; |
| 10200 | IrInstruction *prev_inst; |
| 10201 | size_t i = 0; |
| 10202 | for (;;) { |
| 10203 | prev_inst = instructions[i]; |
| 10204 | if (type_is_invalid(prev_inst->value.type)) { |
| 10205 | return ira->codegen->builtin_types.entry_invalid; |
| 10206 | } |
| 10207 | if (prev_inst->value.type->id == ZigTypeIdUnreachable) { |
| 10208 | i += 1; |
| 10209 | if (i == instruction_count) { |
| 10210 | return prev_inst->value.type; |
| 10211 | } |
| 10212 | continue; |
| 10213 | } |
| 10214 | break; |
| 9435 | 10215 | } |
| 9436 | 10216 | ErrorTableEntry **errors = nullptr; |
| 9437 | 10217 | size_t errors_count = 0; |
| ... | ... | @@ -9456,7 +10236,7 @@ static ZigType *ir_resolve_peer_types(IrAnalyze *ira, AstNode *source_node, ZigT |
| 9456 | 10236 | |
| 9457 | 10237 | bool any_are_null = (prev_inst->value.type->id == ZigTypeIdNull); |
| 9458 | 10238 | bool convert_to_const_slice = false; |
| 9459 | | for (size_t i = 1; i < instruction_count; i += 1) { |
| 10239 | for (; i < instruction_count; i += 1) { |
| 9460 | 10240 | IrInstruction *cur_inst = instructions[i]; |
| 9461 | 10241 | ZigType *cur_type = cur_inst->value.type; |
| 9462 | 10242 | ZigType *prev_type = prev_inst->value.type; |
| ... | ... | @@ -9475,7 +10255,7 @@ static ZigType *ir_resolve_peer_types(IrAnalyze *ira, AstNode *source_node, ZigT |
| 9475 | 10255 | } |
| 9476 | 10256 | |
| 9477 | 10257 | if (prev_type->id == ZigTypeIdErrorSet) { |
| 9478 | | assert(err_set_type != nullptr); |
| 10258 | ir_assert(err_set_type != nullptr, prev_inst); |
| 9479 | 10259 | if (cur_type->id == ZigTypeIdErrorSet) { |
| 9480 | 10260 | if (type_is_global_error_set(err_set_type)) { |
| 9481 | 10261 | continue; |
| ... | ... | @@ -9735,6 +10515,7 @@ static ZigType *ir_resolve_peer_types(IrAnalyze *ira, AstNode *source_node, ZigT |
| 9735 | 10515 | |
| 9736 | 10516 | if (prev_type->id == ZigTypeIdNull) { |
| 9737 | 10517 | prev_inst = cur_inst; |
| 10518 | any_are_null = true; |
| 9738 | 10519 | continue; |
| 9739 | 10520 | } |
| 9740 | 10521 | |
| ... | ... | @@ -10049,6 +10830,8 @@ static ZigType *ir_resolve_peer_types(IrAnalyze *ira, AstNode *source_node, ZigT |
| 10049 | 10830 | } else if (prev_inst->value.type->id == ZigTypeIdOptional) { |
| 10050 | 10831 | return prev_inst->value.type; |
| 10051 | 10832 | } else { |
| 10833 | if ((err = type_resolve(ira->codegen, prev_inst->value.type, ResolveStatusSizeKnown))) |
| 10834 | return ira->codegen->builtin_types.entry_invalid; |
| 10052 | 10835 | return get_optional_type(ira->codegen, prev_inst->value.type); |
| 10053 | 10836 | } |
| 10054 | 10837 | } else { |
| ... | ... | @@ -10056,24 +10839,18 @@ static ZigType *ir_resolve_peer_types(IrAnalyze *ira, AstNode *source_node, ZigT |
| 10056 | 10839 | } |
| 10057 | 10840 | } |
| 10058 | 10841 | |
| 10059 | | static void ir_add_alloca(IrAnalyze *ira, IrInstruction *instruction, ZigType *type_entry) { |
| 10060 | | if (type_has_bits(type_entry) && handle_is_ptr(type_entry)) { |
| 10061 | | ZigFn *fn_entry = exec_fn_entry(ira->new_irb.exec); |
| 10062 | | if (fn_entry != nullptr) { |
| 10063 | | fn_entry->alloca_list.append(instruction); |
| 10064 | | } |
| 10065 | | } |
| 10066 | | } |
| 10067 | | |
| 10068 | 10842 | static void copy_const_val(ConstExprValue *dest, ConstExprValue *src, bool same_global_refs) { |
| 10069 | 10843 | ConstGlobalRefs *global_refs = dest->global_refs; |
| 10070 | | assert(!same_global_refs || src->global_refs != nullptr); |
| 10071 | | *dest = *src; |
| 10844 | memcpy(dest, src, sizeof(ConstExprValue)); |
| 10072 | 10845 | if (!same_global_refs) { |
| 10073 | 10846 | dest->global_refs = global_refs; |
| 10847 | if (src->special == ConstValSpecialUndef) |
| 10848 | return; |
| 10074 | 10849 | if (dest->type->id == ZigTypeIdStruct) { |
| 10075 | | dest->data.x_struct.fields = allocate_nonzero<ConstExprValue>(dest->type->data.structure.src_field_count); |
| 10076 | | memcpy(dest->data.x_struct.fields, src->data.x_struct.fields, sizeof(ConstExprValue) * dest->type->data.structure.src_field_count); |
| 10850 | dest->data.x_struct.fields = create_const_vals(dest->type->data.structure.src_field_count); |
| 10851 | for (size_t i = 0; i < dest->type->data.structure.src_field_count; i += 1) { |
| 10852 | copy_const_val(&dest->data.x_struct.fields[i], &src->data.x_struct.fields[i], false); |
| 10853 | } |
| 10077 | 10854 | } |
| 10078 | 10855 | } |
| 10079 | 10856 | } |
| ... | ... | @@ -10091,7 +10868,6 @@ static bool eval_const_expr_implicit_cast(IrAnalyze *ira, IrInstruction *source_ |
| 10091 | 10868 | zig_unreachable(); |
| 10092 | 10869 | case CastOpErrSet: |
| 10093 | 10870 | case CastOpBitCast: |
| 10094 | | case CastOpPtrOfArrayToSlice: |
| 10095 | 10871 | zig_panic("TODO"); |
| 10096 | 10872 | case CastOpNoop: |
| 10097 | 10873 | { |
| ... | ... | @@ -10191,7 +10967,7 @@ static IrInstruction *ir_const(IrAnalyze *ira, IrInstruction *old_instruction, Z |
| 10191 | 10967 | } |
| 10192 | 10968 | |
| 10193 | 10969 | static IrInstruction *ir_resolve_cast(IrAnalyze *ira, IrInstruction *source_instr, IrInstruction *value, |
| 10194 | | ZigType *wanted_type, CastOp cast_op, bool need_alloca) |
| 10970 | ZigType *wanted_type, CastOp cast_op) |
| 10195 | 10971 | { |
| 10196 | 10972 | if (instr_is_comptime(value) || !type_has_bits(wanted_type)) { |
| 10197 | 10973 | IrInstruction *result = ir_const(ira, source_instr, wanted_type); |
| ... | ... | @@ -10204,9 +10980,6 @@ static IrInstruction *ir_resolve_cast(IrAnalyze *ira, IrInstruction *source_inst |
| 10204 | 10980 | } else { |
| 10205 | 10981 | IrInstruction *result = ir_build_cast(&ira->new_irb, source_instr->scope, source_instr->source_node, wanted_type, value, cast_op); |
| 10206 | 10982 | result->value.type = wanted_type; |
| 10207 | | if (need_alloca) { |
| 10208 | | ir_add_alloca(ira, result, wanted_type); |
| 10209 | | } |
| 10210 | 10983 | return result; |
| 10211 | 10984 | } |
| 10212 | 10985 | } |
| ... | ... | @@ -10248,7 +11021,7 @@ static IrInstruction *ir_resolve_ptr_of_array_to_unknown_len_ptr(IrAnalyze *ira, |
| 10248 | 11021 | } |
| 10249 | 11022 | |
| 10250 | 11023 | static IrInstruction *ir_resolve_ptr_of_array_to_slice(IrAnalyze *ira, IrInstruction *source_instr, |
| 10251 | | IrInstruction *value, ZigType *wanted_type) |
| 11024 | IrInstruction *value, ZigType *wanted_type, ResultLoc *result_loc) |
| 10252 | 11025 | { |
| 10253 | 11026 | Error err; |
| 10254 | 11027 | |
| ... | ... | @@ -10279,11 +11052,12 @@ static IrInstruction *ir_resolve_ptr_of_array_to_slice(IrAnalyze *ira, IrInstruc |
| 10279 | 11052 | } |
| 10280 | 11053 | } |
| 10281 | 11054 | |
| 10282 | | IrInstruction *result = ir_build_cast(&ira->new_irb, source_instr->scope, source_instr->source_node, |
| 10283 | | wanted_type, value, CastOpPtrOfArrayToSlice); |
| 10284 | | result->value.type = wanted_type; |
| 10285 | | ir_add_alloca(ira, result, wanted_type); |
| 10286 | | return result; |
| 11055 | if (result_loc == nullptr) result_loc = no_result_loc(); |
| 11056 | IrInstruction *result_loc_inst = ir_resolve_result(ira, source_instr, result_loc, wanted_type, nullptr, true, false); |
| 11057 | if (type_is_invalid(result_loc_inst->value.type) || instr_is_unreachable(result_loc_inst)) { |
| 11058 | return result_loc_inst; |
| 11059 | } |
| 11060 | return ir_build_ptr_of_array_to_slice(ira, source_instr, wanted_type, value, result_loc_inst); |
| 10287 | 11061 | } |
| 10288 | 11062 | |
| 10289 | 11063 | static IrBasicBlock *ir_get_new_bb(IrAnalyze *ira, IrBasicBlock *old_bb, IrInstruction *ref_old_instruction) { |
| ... | ... | @@ -10315,51 +11089,136 @@ static IrBasicBlock *ir_get_new_bb_runtime(IrAnalyze *ira, IrBasicBlock *old_bb, |
| 10315 | 11089 | } |
| 10316 | 11090 | |
| 10317 | 11091 | static void ir_start_bb(IrAnalyze *ira, IrBasicBlock *old_bb, IrBasicBlock *const_predecessor_bb) { |
| 11092 | assert(!old_bb->suspended); |
| 10318 | 11093 | ira->instruction_index = 0; |
| 10319 | 11094 | ira->old_irb.current_basic_block = old_bb; |
| 10320 | 11095 | ira->const_predecessor_bb = const_predecessor_bb; |
| 11096 | ira->old_bb_index = old_bb->index; |
| 10321 | 11097 | } |
| 10322 | 11098 | |
| 10323 | | static void ir_finish_bb(IrAnalyze *ira) { |
| 10324 | | ira->new_irb.exec->basic_block_list.append(ira->new_irb.current_basic_block); |
| 10325 | | ira->instruction_index += 1; |
| 10326 | | while (ira->instruction_index < ira->old_irb.current_basic_block->instruction_list.length) { |
| 10327 | | IrInstruction *next_instruction = ira->old_irb.current_basic_block->instruction_list.at(ira->instruction_index); |
| 10328 | | if (!next_instruction->is_gen) { |
| 10329 | | ir_add_error(ira, next_instruction, buf_sprintf("unreachable code")); |
| 10330 | | break; |
| 10331 | | } |
| 10332 | | ira->instruction_index += 1; |
| 11099 | static IrInstruction *ira_suspend(IrAnalyze *ira, IrInstruction *old_instruction, IrBasicBlock *next_bb, |
| 11100 | IrSuspendPosition *suspend_pos) |
| 11101 | { |
| 11102 | if (ira->codegen->verbose_ir) { |
| 11103 | fprintf(stderr, "suspend %s_%zu %s_%zu #%zu (%zu,%zu)\n", ira->old_irb.current_basic_block->name_hint, |
| 11104 | ira->old_irb.current_basic_block->debug_id, |
| 11105 | ira->old_irb.exec->basic_block_list.at(ira->old_bb_index)->name_hint, |
| 11106 | ira->old_irb.exec->basic_block_list.at(ira->old_bb_index)->debug_id, |
| 11107 | ira->old_irb.current_basic_block->instruction_list.at(ira->instruction_index)->debug_id, |
| 11108 | ira->old_bb_index, ira->instruction_index); |
| 11109 | } |
| 11110 | suspend_pos->basic_block_index = ira->old_bb_index; |
| 11111 | suspend_pos->instruction_index = ira->instruction_index; |
| 11112 | |
| 11113 | ira->old_irb.current_basic_block->suspended = true; |
| 11114 | |
| 11115 | // null next_bb means that the caller plans to call ira_resume before returning |
| 11116 | if (next_bb != nullptr) { |
| 11117 | ira->old_bb_index = next_bb->index; |
| 11118 | ira->old_irb.current_basic_block = ira->old_irb.exec->basic_block_list.at(ira->old_bb_index); |
| 11119 | assert(ira->old_irb.current_basic_block == next_bb); |
| 11120 | ira->instruction_index = 0; |
| 11121 | ira->const_predecessor_bb = nullptr; |
| 11122 | next_bb->other = ir_get_new_bb_runtime(ira, next_bb, old_instruction); |
| 11123 | ira->new_irb.current_basic_block = next_bb->other; |
| 10333 | 11124 | } |
| 11125 | return ira->codegen->unreach_instruction; |
| 11126 | } |
| 11127 | |
| 11128 | static IrInstruction *ira_resume(IrAnalyze *ira) { |
| 11129 | IrSuspendPosition pos = ira->resume_stack.pop(); |
| 11130 | if (ira->codegen->verbose_ir) { |
| 11131 | fprintf(stderr, "resume (%zu,%zu) ", pos.basic_block_index, pos.instruction_index); |
| 11132 | } |
| 11133 | ira->old_bb_index = pos.basic_block_index; |
| 11134 | ira->old_irb.current_basic_block = ira->old_irb.exec->basic_block_list.at(ira->old_bb_index); |
| 11135 | assert(ira->old_irb.current_basic_block->in_resume_stack); |
| 11136 | ira->old_irb.current_basic_block->in_resume_stack = false; |
| 11137 | ira->old_irb.current_basic_block->suspended = false; |
| 11138 | ira->instruction_index = pos.instruction_index; |
| 11139 | assert(pos.instruction_index < ira->old_irb.current_basic_block->instruction_list.length); |
| 11140 | if (ira->codegen->verbose_ir) { |
| 11141 | fprintf(stderr, "%s_%zu #%zu\n", ira->old_irb.current_basic_block->name_hint, |
| 11142 | ira->old_irb.current_basic_block->debug_id, |
| 11143 | ira->old_irb.current_basic_block->instruction_list.at(pos.instruction_index)->debug_id); |
| 11144 | } |
| 11145 | ira->const_predecessor_bb = nullptr; |
| 11146 | ira->new_irb.current_basic_block = ira->old_irb.current_basic_block->other; |
| 11147 | assert(ira->new_irb.current_basic_block != nullptr); |
| 11148 | return ira->codegen->unreach_instruction; |
| 11149 | } |
| 10334 | 11150 | |
| 10335 | | size_t my_old_bb_index = ira->old_bb_index; |
| 11151 | static void ir_start_next_bb(IrAnalyze *ira) { |
| 10336 | 11152 | ira->old_bb_index += 1; |
| 10337 | 11153 | |
| 10338 | 11154 | bool need_repeat = true; |
| 10339 | 11155 | for (;;) { |
| 10340 | 11156 | while (ira->old_bb_index < ira->old_irb.exec->basic_block_list.length) { |
| 10341 | 11157 | IrBasicBlock *old_bb = ira->old_irb.exec->basic_block_list.at(ira->old_bb_index); |
| 10342 | | if (old_bb->other == nullptr) { |
| 11158 | if (old_bb->other == nullptr && old_bb->suspend_instruction_ref == nullptr) { |
| 10343 | 11159 | ira->old_bb_index += 1; |
| 10344 | 11160 | continue; |
| 10345 | 11161 | } |
| 10346 | | if (old_bb->other->instruction_list.length != 0 || ira->old_bb_index == my_old_bb_index) { |
| 11162 | // if it's already started, or |
| 11163 | // if it's a suspended block, |
| 11164 | // then skip it |
| 11165 | if (old_bb->suspended || |
| 11166 | (old_bb->other != nullptr && old_bb->other->instruction_list.length != 0) || |
| 11167 | (old_bb->other != nullptr && old_bb->other->already_appended)) |
| 11168 | { |
| 10347 | 11169 | ira->old_bb_index += 1; |
| 10348 | 11170 | continue; |
| 10349 | 11171 | } |
| 10350 | | ira->new_irb.current_basic_block = old_bb->other; |
| 10351 | 11172 | |
| 11173 | // if there is a resume_stack, pop one from there rather than moving on. |
| 11174 | // the last item of the resume stack will be a basic block that will |
| 11175 | // move on to the next one below |
| 11176 | if (ira->resume_stack.length != 0) { |
| 11177 | ira_resume(ira); |
| 11178 | return; |
| 11179 | } |
| 11180 | |
| 11181 | if (old_bb->other == nullptr) { |
| 11182 | old_bb->other = ir_get_new_bb_runtime(ira, old_bb, old_bb->suspend_instruction_ref); |
| 11183 | } |
| 11184 | ira->new_irb.current_basic_block = old_bb->other; |
| 10352 | 11185 | ir_start_bb(ira, old_bb, nullptr); |
| 10353 | 11186 | return; |
| 10354 | 11187 | } |
| 10355 | | if (!need_repeat) |
| 11188 | if (!need_repeat) { |
| 11189 | if (ira->resume_stack.length != 0) { |
| 11190 | ira_resume(ira); |
| 11191 | } |
| 10356 | 11192 | return; |
| 11193 | } |
| 10357 | 11194 | need_repeat = false; |
| 10358 | 11195 | ira->old_bb_index = 0; |
| 10359 | 11196 | continue; |
| 10360 | 11197 | } |
| 10361 | 11198 | } |
| 10362 | 11199 | |
| 11200 | static void ir_finish_bb(IrAnalyze *ira) { |
| 11201 | if (!ira->new_irb.current_basic_block->already_appended) { |
| 11202 | ira->new_irb.current_basic_block->already_appended = true; |
| 11203 | if (ira->codegen->verbose_ir) { |
| 11204 | fprintf(stderr, "append new bb %s_%zu\n", ira->new_irb.current_basic_block->name_hint, |
| 11205 | ira->new_irb.current_basic_block->debug_id); |
| 11206 | } |
| 11207 | ira->new_irb.exec->basic_block_list.append(ira->new_irb.current_basic_block); |
| 11208 | } |
| 11209 | ira->instruction_index += 1; |
| 11210 | while (ira->instruction_index < ira->old_irb.current_basic_block->instruction_list.length) { |
| 11211 | IrInstruction *next_instruction = ira->old_irb.current_basic_block->instruction_list.at(ira->instruction_index); |
| 11212 | if (!next_instruction->is_gen) { |
| 11213 | ir_add_error(ira, next_instruction, buf_sprintf("unreachable code")); |
| 11214 | break; |
| 11215 | } |
| 11216 | ira->instruction_index += 1; |
| 11217 | } |
| 11218 | |
| 11219 | ir_start_next_bb(ira); |
| 11220 | } |
| 11221 | |
| 10363 | 11222 | static IrInstruction *ir_unreach_error(IrAnalyze *ira) { |
| 10364 | 11223 | ira->old_bb_index = SIZE_MAX; |
| 10365 | 11224 | ira->new_irb.exec->invalid = true; |
| ... | ... | @@ -10420,6 +11279,12 @@ static IrInstruction *ir_const_undef(IrAnalyze *ira, IrInstruction *source_instr |
| 10420 | 11279 | return result; |
| 10421 | 11280 | } |
| 10422 | 11281 | |
| 11282 | static IrInstruction *ir_const_unreachable(IrAnalyze *ira, IrInstruction *source_instruction) { |
| 11283 | IrInstruction *result = ir_const(ira, source_instruction, ira->codegen->builtin_types.entry_unreachable); |
| 11284 | result->value.special = ConstValSpecialStatic; |
| 11285 | return result; |
| 11286 | } |
| 11287 | |
| 10423 | 11288 | static IrInstruction *ir_const_void(IrAnalyze *ira, IrInstruction *source_instruction) { |
| 10424 | 11289 | return ir_const(ira, source_instruction, ira->codegen->builtin_types.entry_void); |
| 10425 | 11290 | } |
| ... | ... | @@ -10617,7 +11482,7 @@ static ZigFn *ir_resolve_fn(IrAnalyze *ira, IrInstruction *fn_value) { |
| 10617 | 11482 | } |
| 10618 | 11483 | |
| 10619 | 11484 | static IrInstruction *ir_analyze_optional_wrap(IrAnalyze *ira, IrInstruction *source_instr, IrInstruction *value, |
| 10620 | | ZigType *wanted_type) |
| 11485 | ZigType *wanted_type, ResultLoc *result_loc) |
| 10621 | 11486 | { |
| 10622 | 11487 | assert(wanted_type->id == ZigTypeIdOptional); |
| 10623 | 11488 | |
| ... | ... | @@ -10643,20 +11508,29 @@ static IrInstruction *ir_analyze_optional_wrap(IrAnalyze *ira, IrInstruction *so |
| 10643 | 11508 | return &const_instruction->base; |
| 10644 | 11509 | } |
| 10645 | 11510 | |
| 10646 | | IrInstruction *result = ir_build_maybe_wrap(&ira->new_irb, source_instr->scope, source_instr->source_node, value); |
| 10647 | | result->value.type = wanted_type; |
| 11511 | if (result_loc == nullptr && handle_is_ptr(wanted_type)) { |
| 11512 | result_loc = no_result_loc(); |
| 11513 | } |
| 11514 | IrInstruction *result_loc_inst = nullptr; |
| 11515 | if (result_loc != nullptr) { |
| 11516 | result_loc_inst = ir_resolve_result(ira, source_instr, result_loc, wanted_type, nullptr, true, false); |
| 11517 | if (type_is_invalid(result_loc_inst->value.type) || instr_is_unreachable(result_loc_inst)) { |
| 11518 | return result_loc_inst; |
| 11519 | } |
| 11520 | } |
| 11521 | IrInstruction *result = ir_build_optional_wrap(ira, source_instr, wanted_type, value, result_loc_inst); |
| 10648 | 11522 | result->value.data.rh_maybe = RuntimeHintOptionalNonNull; |
| 10649 | | ir_add_alloca(ira, result, wanted_type); |
| 10650 | 11523 | return result; |
| 10651 | 11524 | } |
| 10652 | 11525 | |
| 10653 | 11526 | static IrInstruction *ir_analyze_err_wrap_payload(IrAnalyze *ira, IrInstruction *source_instr, |
| 10654 | | IrInstruction *value, ZigType *wanted_type) |
| 11527 | IrInstruction *value, ZigType *wanted_type, ResultLoc *result_loc) |
| 10655 | 11528 | { |
| 10656 | 11529 | assert(wanted_type->id == ZigTypeIdErrorUnion); |
| 10657 | 11530 | |
| 11531 | ZigType *payload_type = wanted_type->data.error_union.payload_type; |
| 11532 | ZigType *err_set_type = wanted_type->data.error_union.err_set_type; |
| 10658 | 11533 | if (instr_is_comptime(value)) { |
| 10659 | | ZigType *payload_type = wanted_type->data.error_union.payload_type; |
| 10660 | 11534 | IrInstruction *casted_payload = ir_implicit_cast(ira, value, payload_type); |
| 10661 | 11535 | if (type_is_invalid(casted_payload->value.type)) |
| 10662 | 11536 | return ira->codegen->invalid_instruction; |
| ... | ... | @@ -10666,7 +11540,7 @@ static IrInstruction *ir_analyze_err_wrap_payload(IrAnalyze *ira, IrInstruction |
| 10666 | 11540 | return ira->codegen->invalid_instruction; |
| 10667 | 11541 | |
| 10668 | 11542 | ConstExprValue *err_set_val = create_const_vals(1); |
| 10669 | | err_set_val->type = wanted_type->data.error_union.err_set_type; |
| 11543 | err_set_val->type = err_set_type; |
| 10670 | 11544 | err_set_val->special = ConstValSpecialStatic; |
| 10671 | 11545 | err_set_val->data.x_err_set = nullptr; |
| 10672 | 11546 | |
| ... | ... | @@ -10679,10 +11553,19 @@ static IrInstruction *ir_analyze_err_wrap_payload(IrAnalyze *ira, IrInstruction |
| 10679 | 11553 | return &const_instruction->base; |
| 10680 | 11554 | } |
| 10681 | 11555 | |
| 10682 | | IrInstruction *result = ir_build_err_wrap_payload(&ira->new_irb, source_instr->scope, source_instr->source_node, value); |
| 10683 | | result->value.type = wanted_type; |
| 11556 | IrInstruction *result_loc_inst; |
| 11557 | if (handle_is_ptr(wanted_type)) { |
| 11558 | if (result_loc == nullptr) result_loc = no_result_loc(); |
| 11559 | result_loc_inst = ir_resolve_result(ira, source_instr, result_loc, wanted_type, nullptr, true, false); |
| 11560 | if (type_is_invalid(result_loc_inst->value.type) || instr_is_unreachable(result_loc_inst)) { |
| 11561 | return result_loc_inst; |
| 11562 | } |
| 11563 | } else { |
| 11564 | result_loc_inst = nullptr; |
| 11565 | } |
| 11566 | |
| 11567 | IrInstruction *result = ir_build_err_wrap_payload(ira, source_instr, wanted_type, value, result_loc_inst); |
| 10684 | 11568 | result->value.data.rh_error_union = RuntimeHintErrorUnionNonError; |
| 10685 | | ir_add_alloca(ira, result, wanted_type); |
| 10686 | 11569 | return result; |
| 10687 | 11570 | } |
| 10688 | 11571 | |
| ... | ... | @@ -10729,7 +11612,9 @@ static IrInstruction *ir_analyze_err_set_cast(IrAnalyze *ira, IrInstruction *sou |
| 10729 | 11612 | return result; |
| 10730 | 11613 | } |
| 10731 | 11614 | |
| 10732 | | static IrInstruction *ir_analyze_err_wrap_code(IrAnalyze *ira, IrInstruction *source_instr, IrInstruction *value, ZigType *wanted_type) { |
| 11615 | static IrInstruction *ir_analyze_err_wrap_code(IrAnalyze *ira, IrInstruction *source_instr, IrInstruction *value, |
| 11616 | ZigType *wanted_type, ResultLoc *result_loc) |
| 11617 | { |
| 10733 | 11618 | assert(wanted_type->id == ZigTypeIdErrorUnion); |
| 10734 | 11619 | |
| 10735 | 11620 | IrInstruction *casted_value = ir_implicit_cast(ira, value, wanted_type->data.error_union.err_set_type); |
| ... | ... | @@ -10753,10 +11638,20 @@ static IrInstruction *ir_analyze_err_wrap_code(IrAnalyze *ira, IrInstruction *so |
| 10753 | 11638 | return &const_instruction->base; |
| 10754 | 11639 | } |
| 10755 | 11640 | |
| 10756 | | IrInstruction *result = ir_build_err_wrap_code(&ira->new_irb, source_instr->scope, source_instr->source_node, value); |
| 10757 | | result->value.type = wanted_type; |
| 11641 | IrInstruction *result_loc_inst; |
| 11642 | if (handle_is_ptr(wanted_type)) { |
| 11643 | if (result_loc == nullptr) result_loc = no_result_loc(); |
| 11644 | result_loc_inst = ir_resolve_result(ira, source_instr, result_loc, wanted_type, nullptr, true, false); |
| 11645 | if (type_is_invalid(result_loc_inst->value.type) || instr_is_unreachable(result_loc_inst)) { |
| 11646 | return result_loc_inst; |
| 11647 | } |
| 11648 | } else { |
| 11649 | result_loc_inst = nullptr; |
| 11650 | } |
| 11651 | |
| 11652 | |
| 11653 | IrInstruction *result = ir_build_err_wrap_code(ira, source_instr, wanted_type, value, result_loc_inst); |
| 10758 | 11654 | result->value.data.rh_error_union = RuntimeHintErrorUnionError; |
| 10759 | | ir_add_alloca(ira, result, wanted_type); |
| 10760 | 11655 | return result; |
| 10761 | 11656 | } |
| 10762 | 11657 | |
| ... | ... | @@ -10816,20 +11711,21 @@ static IrInstruction *ir_get_ref(IrAnalyze *ira, IrInstruction *source_instructi |
| 10816 | 11711 | |
| 10817 | 11712 | ZigType *ptr_type = get_pointer_to_type_extra(ira->codegen, value->value.type, |
| 10818 | 11713 | is_const, is_volatile, PtrLenSingle, 0, 0, 0, false); |
| 10819 | | IrInstruction *new_instruction = ir_build_ref(&ira->new_irb, source_instruction->scope, |
| 10820 | | source_instruction->source_node, value, is_const, is_volatile); |
| 10821 | | new_instruction->value.type = ptr_type; |
| 10822 | | new_instruction->value.data.rh_ptr = RuntimeHintPtrStack; |
| 11714 | |
| 11715 | IrInstruction *result_loc; |
| 10823 | 11716 | if (type_has_bits(ptr_type) && !handle_is_ptr(value->value.type)) { |
| 10824 | | ZigFn *fn_entry = exec_fn_entry(ira->new_irb.exec); |
| 10825 | | assert(fn_entry); |
| 10826 | | fn_entry->alloca_list.append(new_instruction); |
| 11717 | result_loc = ir_resolve_result(ira, source_instruction, no_result_loc(), value->value.type, nullptr, true, false); |
| 11718 | } else { |
| 11719 | result_loc = nullptr; |
| 10827 | 11720 | } |
| 11721 | |
| 11722 | IrInstruction *new_instruction = ir_build_ref_gen(ira, source_instruction, ptr_type, value, result_loc); |
| 11723 | new_instruction->value.data.rh_ptr = RuntimeHintPtrStack; |
| 10828 | 11724 | return new_instruction; |
| 10829 | 11725 | } |
| 10830 | 11726 | |
| 10831 | 11727 | static IrInstruction *ir_analyze_array_to_slice(IrAnalyze *ira, IrInstruction *source_instr, |
| 10832 | | IrInstruction *array_arg, ZigType *wanted_type) |
| 11728 | IrInstruction *array_arg, ZigType *wanted_type, ResultLoc *result_loc) |
| 10833 | 11729 | { |
| 10834 | 11730 | assert(is_slice(wanted_type)); |
| 10835 | 11731 | // In this function we honor the const-ness of wanted_type, because |
| ... | ... | @@ -10838,7 +11734,7 @@ static IrInstruction *ir_analyze_array_to_slice(IrAnalyze *ira, IrInstruction *s |
| 10838 | 11734 | IrInstruction *array_ptr = nullptr; |
| 10839 | 11735 | IrInstruction *array; |
| 10840 | 11736 | if (array_arg->value.type->id == ZigTypeIdPointer) { |
| 10841 | | array = ir_get_deref(ira, source_instr, array_arg); |
| 11737 | array = ir_get_deref(ira, source_instr, array_arg, nullptr); |
| 10842 | 11738 | array_ptr = array_arg; |
| 10843 | 11739 | } else { |
| 10844 | 11740 | array = array_arg; |
| ... | ... | @@ -10861,12 +11757,14 @@ static IrInstruction *ir_analyze_array_to_slice(IrAnalyze *ira, IrInstruction *s |
| 10861 | 11757 | |
| 10862 | 11758 | if (!array_ptr) array_ptr = ir_get_ref(ira, source_instr, array, true, false); |
| 10863 | 11759 | |
| 10864 | | IrInstruction *result = ir_build_slice(&ira->new_irb, source_instr->scope, |
| 10865 | | source_instr->source_node, array_ptr, start, end, false); |
| 10866 | | result->value.type = wanted_type; |
| 11760 | if (result_loc == nullptr) result_loc = no_result_loc(); |
| 11761 | IrInstruction *result_loc_inst = ir_resolve_result(ira, source_instr, result_loc, wanted_type, nullptr, true, false); |
| 11762 | if (type_is_invalid(result_loc_inst->value.type) || instr_is_unreachable(result_loc_inst)) { |
| 11763 | return result_loc_inst; |
| 11764 | } |
| 11765 | IrInstruction *result = ir_build_slice_gen(ira, source_instr, wanted_type, array_ptr, start, end, false, result_loc_inst); |
| 10867 | 11766 | result->value.data.rh_slice.id = RuntimeHintSliceIdLen; |
| 10868 | 11767 | result->value.data.rh_slice.len = array_type->data.array.len; |
| 10869 | | ir_add_alloca(ira, result, result->value.type); |
| 10870 | 11768 | |
| 10871 | 11769 | return result; |
| 10872 | 11770 | } |
| ... | ... | @@ -11504,7 +12402,7 @@ static IrInstruction *ir_analyze_array_to_vector(IrAnalyze *ira, IrInstruction * |
| 11504 | 12402 | } |
| 11505 | 12403 | |
| 11506 | 12404 | static IrInstruction *ir_analyze_vector_to_array(IrAnalyze *ira, IrInstruction *source_instr, |
| 11507 | | IrInstruction *vector, ZigType *array_type) |
| 12405 | IrInstruction *vector, ZigType *array_type, ResultLoc *result_loc) |
| 11508 | 12406 | { |
| 11509 | 12407 | if (instr_is_comptime(vector)) { |
| 11510 | 12408 | // arrays and vectors have the same ConstExprValue representation |
| ... | ... | @@ -11513,7 +12411,14 @@ static IrInstruction *ir_analyze_vector_to_array(IrAnalyze *ira, IrInstruction * |
| 11513 | 12411 | result->value.type = array_type; |
| 11514 | 12412 | return result; |
| 11515 | 12413 | } |
| 11516 | | return ir_build_vector_to_array(ira, source_instr, vector, array_type); |
| 12414 | if (result_loc == nullptr) { |
| 12415 | result_loc = no_result_loc(); |
| 12416 | } |
| 12417 | IrInstruction *result_loc_inst = ir_resolve_result(ira, source_instr, result_loc, array_type, nullptr, true, false); |
| 12418 | if (type_is_invalid(result_loc_inst->value.type) || instr_is_unreachable(result_loc_inst)) { |
| 12419 | return result_loc_inst; |
| 12420 | } |
| 12421 | return ir_build_vector_to_array(ira, source_instr, array_type, vector, result_loc_inst); |
| 11517 | 12422 | } |
| 11518 | 12423 | |
| 11519 | 12424 | static IrInstruction *ir_analyze_int_to_c_ptr(IrAnalyze *ira, IrInstruction *source_instr, |
| ... | ... | @@ -11563,7 +12468,7 @@ static bool is_pointery_and_elem_is_not_pointery(ZigType *ty) { |
| 11563 | 12468 | } |
| 11564 | 12469 | |
| 11565 | 12470 | static IrInstruction *ir_analyze_cast(IrAnalyze *ira, IrInstruction *source_instr, |
| 11566 | | ZigType *wanted_type, IrInstruction *value) |
| 12471 | ZigType *wanted_type, IrInstruction *value, ResultLoc *result_loc) |
| 11567 | 12472 | { |
| 11568 | 12473 | Error err; |
| 11569 | 12474 | ZigType *actual_type = value->value.type; |
| ... | ... | @@ -11579,7 +12484,7 @@ static IrInstruction *ir_analyze_cast(IrAnalyze *ira, IrInstruction *source_inst |
| 11579 | 12484 | if (const_cast_result.id == ConstCastResultIdInvalid) |
| 11580 | 12485 | return ira->codegen->invalid_instruction; |
| 11581 | 12486 | if (const_cast_result.id == ConstCastResultIdOk) { |
| 11582 | | return ir_resolve_cast(ira, source_instr, value, wanted_type, CastOpNoop, false); |
| 12487 | return ir_resolve_cast(ira, source_instr, value, wanted_type, CastOpNoop); |
| 11583 | 12488 | } |
| 11584 | 12489 | |
| 11585 | 12490 | // cast from T to ?T |
| ... | ... | @@ -11589,12 +12494,12 @@ static IrInstruction *ir_analyze_cast(IrAnalyze *ira, IrInstruction *source_inst |
| 11589 | 12494 | if (types_match_const_cast_only(ira, wanted_child_type, actual_type, source_node, |
| 11590 | 12495 | false).id == ConstCastResultIdOk) |
| 11591 | 12496 | { |
| 11592 | | return ir_analyze_optional_wrap(ira, source_instr, value, wanted_type); |
| 12497 | return ir_analyze_optional_wrap(ira, source_instr, value, wanted_type, result_loc); |
| 11593 | 12498 | } else if (actual_type->id == ZigTypeIdComptimeInt || |
| 11594 | 12499 | actual_type->id == ZigTypeIdComptimeFloat) |
| 11595 | 12500 | { |
| 11596 | 12501 | if (ir_num_lit_fits_in_other_type(ira, value, wanted_child_type, true)) { |
| 11597 | | return ir_analyze_optional_wrap(ira, source_instr, value, wanted_type); |
| 12502 | return ir_analyze_optional_wrap(ira, source_instr, value, wanted_type, result_loc); |
| 11598 | 12503 | } else { |
| 11599 | 12504 | return ira->codegen->invalid_instruction; |
| 11600 | 12505 | } |
| ... | ... | @@ -11618,7 +12523,7 @@ static IrInstruction *ir_analyze_cast(IrAnalyze *ira, IrInstruction *source_inst |
| 11618 | 12523 | wanted_child_type); |
| 11619 | 12524 | if (type_is_invalid(cast1->value.type)) |
| 11620 | 12525 | return ira->codegen->invalid_instruction; |
| 11621 | | return ir_analyze_optional_wrap(ira, source_instr, cast1, wanted_type); |
| 12526 | return ir_analyze_optional_wrap(ira, source_instr, cast1, wanted_type, result_loc); |
| 11622 | 12527 | } |
| 11623 | 12528 | } |
| 11624 | 12529 | } |
| ... | ... | @@ -11628,12 +12533,12 @@ static IrInstruction *ir_analyze_cast(IrAnalyze *ira, IrInstruction *source_inst |
| 11628 | 12533 | if (types_match_const_cast_only(ira, wanted_type->data.error_union.payload_type, actual_type, |
| 11629 | 12534 | source_node, false).id == ConstCastResultIdOk) |
| 11630 | 12535 | { |
| 11631 | | return ir_analyze_err_wrap_payload(ira, source_instr, value, wanted_type); |
| 12536 | return ir_analyze_err_wrap_payload(ira, source_instr, value, wanted_type, result_loc); |
| 11632 | 12537 | } else if (actual_type->id == ZigTypeIdComptimeInt || |
| 11633 | 12538 | actual_type->id == ZigTypeIdComptimeFloat) |
| 11634 | 12539 | { |
| 11635 | 12540 | if (ir_num_lit_fits_in_other_type(ira, value, wanted_type->data.error_union.payload_type, true)) { |
| 11636 | | return ir_analyze_err_wrap_payload(ira, source_instr, value, wanted_type); |
| 12541 | return ir_analyze_err_wrap_payload(ira, source_instr, value, wanted_type, result_loc); |
| 11637 | 12542 | } else { |
| 11638 | 12543 | return ira->codegen->invalid_instruction; |
| 11639 | 12544 | } |
| ... | ... | @@ -11651,11 +12556,11 @@ static IrInstruction *ir_analyze_cast(IrAnalyze *ira, IrInstruction *source_inst |
| 11651 | 12556 | actual_type->id == ZigTypeIdComptimeInt || |
| 11652 | 12557 | actual_type->id == ZigTypeIdComptimeFloat) |
| 11653 | 12558 | { |
| 11654 | | IrInstruction *cast1 = ir_analyze_cast(ira, source_instr, wanted_type->data.error_union.payload_type, value); |
| 12559 | IrInstruction *cast1 = ir_analyze_cast(ira, source_instr, wanted_type->data.error_union.payload_type, value, nullptr); |
| 11655 | 12560 | if (type_is_invalid(cast1->value.type)) |
| 11656 | 12561 | return ira->codegen->invalid_instruction; |
| 11657 | 12562 | |
| 11658 | | IrInstruction *cast2 = ir_analyze_cast(ira, source_instr, wanted_type, cast1); |
| 12563 | IrInstruction *cast2 = ir_analyze_cast(ira, source_instr, wanted_type, cast1, result_loc); |
| 11659 | 12564 | if (type_is_invalid(cast2->value.type)) |
| 11660 | 12565 | return ira->codegen->invalid_instruction; |
| 11661 | 12566 | |
| ... | ... | @@ -11737,7 +12642,7 @@ static IrInstruction *ir_analyze_cast(IrAnalyze *ira, IrInstruction *source_inst |
| 11737 | 12642 | types_match_const_cast_only(ira, ptr_type->data.pointer.child_type, actual_type->data.array.child_type, |
| 11738 | 12643 | source_node, false).id == ConstCastResultIdOk) |
| 11739 | 12644 | { |
| 11740 | | return ir_analyze_array_to_slice(ira, source_instr, value, wanted_type); |
| 12645 | return ir_analyze_array_to_slice(ira, source_instr, value, wanted_type, result_loc); |
| 11741 | 12646 | } |
| 11742 | 12647 | } |
| 11743 | 12648 | |
| ... | ... | @@ -11754,11 +12659,11 @@ static IrInstruction *ir_analyze_cast(IrAnalyze *ira, IrInstruction *source_inst |
| 11754 | 12659 | types_match_const_cast_only(ira, ptr_type->data.pointer.child_type, actual_type->data.array.child_type, |
| 11755 | 12660 | source_node, false).id == ConstCastResultIdOk) |
| 11756 | 12661 | { |
| 11757 | | IrInstruction *cast1 = ir_analyze_cast(ira, source_instr, wanted_type->data.maybe.child_type, value); |
| 12662 | IrInstruction *cast1 = ir_analyze_cast(ira, source_instr, wanted_type->data.maybe.child_type, value, nullptr); |
| 11758 | 12663 | if (type_is_invalid(cast1->value.type)) |
| 11759 | 12664 | return ira->codegen->invalid_instruction; |
| 11760 | 12665 | |
| 11761 | | IrInstruction *cast2 = ir_analyze_cast(ira, source_instr, wanted_type, cast1); |
| 12666 | IrInstruction *cast2 = ir_analyze_cast(ira, source_instr, wanted_type, cast1, result_loc); |
| 11762 | 12667 | if (type_is_invalid(cast2->value.type)) |
| 11763 | 12668 | return ira->codegen->invalid_instruction; |
| 11764 | 12669 | |
| ... | ... | @@ -11801,7 +12706,7 @@ static IrInstruction *ir_analyze_cast(IrAnalyze *ira, IrInstruction *source_inst |
| 11801 | 12706 | array_type->data.array.child_type, source_node, |
| 11802 | 12707 | !slice_ptr_type->data.pointer.is_const).id == ConstCastResultIdOk) |
| 11803 | 12708 | { |
| 11804 | | return ir_resolve_ptr_of_array_to_slice(ira, source_instr, value, wanted_type); |
| 12709 | return ir_resolve_ptr_of_array_to_slice(ira, source_instr, value, wanted_type, result_loc); |
| 11805 | 12710 | } |
| 11806 | 12711 | } |
| 11807 | 12712 | |
| ... | ... | @@ -11832,11 +12737,11 @@ static IrInstruction *ir_analyze_cast(IrAnalyze *ira, IrInstruction *source_inst |
| 11832 | 12737 | types_match_const_cast_only(ira, ptr_type->data.pointer.child_type, actual_type->data.array.child_type, |
| 11833 | 12738 | source_node, false).id == ConstCastResultIdOk) |
| 11834 | 12739 | { |
| 11835 | | IrInstruction *cast1 = ir_analyze_cast(ira, source_instr, wanted_type->data.error_union.payload_type, value); |
| 12740 | IrInstruction *cast1 = ir_analyze_cast(ira, source_instr, wanted_type->data.error_union.payload_type, value, nullptr); |
| 11836 | 12741 | if (type_is_invalid(cast1->value.type)) |
| 11837 | 12742 | return ira->codegen->invalid_instruction; |
| 11838 | 12743 | |
| 11839 | | IrInstruction *cast2 = ir_analyze_cast(ira, source_instr, wanted_type, cast1); |
| 12744 | IrInstruction *cast2 = ir_analyze_cast(ira, source_instr, wanted_type, cast1, result_loc); |
| 11840 | 12745 | if (type_is_invalid(cast2->value.type)) |
| 11841 | 12746 | return ira->codegen->invalid_instruction; |
| 11842 | 12747 | |
| ... | ... | @@ -11848,7 +12753,7 @@ static IrInstruction *ir_analyze_cast(IrAnalyze *ira, IrInstruction *source_inst |
| 11848 | 12753 | if (wanted_type->id == ZigTypeIdErrorUnion && |
| 11849 | 12754 | actual_type->id == ZigTypeIdErrorSet) |
| 11850 | 12755 | { |
| 11851 | | return ir_analyze_err_wrap_code(ira, source_instr, value, wanted_type); |
| 12756 | return ir_analyze_err_wrap_code(ira, source_instr, value, wanted_type, result_loc); |
| 11852 | 12757 | } |
| 11853 | 12758 | |
| 11854 | 12759 | // cast from typed number to integer or float literal. |
| ... | ... | @@ -11972,7 +12877,7 @@ static IrInstruction *ir_analyze_cast(IrAnalyze *ira, IrInstruction *source_inst |
| 11972 | 12877 | types_match_const_cast_only(ira, wanted_type->data.array.child_type, |
| 11973 | 12878 | actual_type->data.vector.elem_type, source_node, false).id == ConstCastResultIdOk) |
| 11974 | 12879 | { |
| 11975 | | return ir_analyze_vector_to_array(ira, source_instr, value, wanted_type); |
| 12880 | return ir_analyze_vector_to_array(ira, source_instr, value, wanted_type, result_loc); |
| 11976 | 12881 | } |
| 11977 | 12882 | |
| 11978 | 12883 | // cast from [N]T to @Vector(N, T) |
| ... | ... | @@ -12014,7 +12919,9 @@ static IrInstruction *ir_analyze_cast(IrAnalyze *ira, IrInstruction *source_inst |
| 12014 | 12919 | return ira->codegen->invalid_instruction; |
| 12015 | 12920 | } |
| 12016 | 12921 | |
| 12017 | | static IrInstruction *ir_implicit_cast(IrAnalyze *ira, IrInstruction *value, ZigType *expected_type) { |
| 12922 | static IrInstruction *ir_implicit_cast_with_result(IrAnalyze *ira, IrInstruction *value, ZigType *expected_type, |
| 12923 | ResultLoc *result_loc) |
| 12924 | { |
| 12018 | 12925 | assert(value); |
| 12019 | 12926 | assert(value != ira->codegen->invalid_instruction); |
| 12020 | 12927 | assert(!expected_type || !type_is_invalid(expected_type)); |
| ... | ... | @@ -12027,63 +12934,76 @@ static IrInstruction *ir_implicit_cast(IrAnalyze *ira, IrInstruction *value, Zig |
| 12027 | 12934 | if (value->value.type->id == ZigTypeIdUnreachable) |
| 12028 | 12935 | return value; |
| 12029 | 12936 | |
| 12030 | | return ir_analyze_cast(ira, value, expected_type, value); |
| 12937 | return ir_analyze_cast(ira, value, expected_type, value, result_loc); |
| 12938 | } |
| 12939 | |
| 12940 | static IrInstruction *ir_implicit_cast(IrAnalyze *ira, IrInstruction *value, ZigType *expected_type) { |
| 12941 | return ir_implicit_cast_with_result(ira, value, expected_type, nullptr); |
| 12031 | 12942 | } |
| 12032 | 12943 | |
| 12033 | | static IrInstruction *ir_get_deref(IrAnalyze *ira, IrInstruction *source_instruction, IrInstruction *ptr) { |
| 12944 | static IrInstruction *ir_get_deref(IrAnalyze *ira, IrInstruction *source_instruction, IrInstruction *ptr, |
| 12945 | ResultLoc *result_loc) |
| 12946 | { |
| 12034 | 12947 | Error err; |
| 12035 | 12948 | ZigType *type_entry = ptr->value.type; |
| 12036 | | if (type_is_invalid(type_entry)) { |
| 12949 | if (type_is_invalid(type_entry)) |
| 12037 | 12950 | return ira->codegen->invalid_instruction; |
| 12038 | | } else if (type_entry->id == ZigTypeIdPointer) { |
| 12039 | | ZigType *child_type = type_entry->data.pointer.child_type; |
| 12040 | | // if the child type has one possible value, the deref is comptime |
| 12041 | | switch (type_has_one_possible_value(ira->codegen, child_type)) { |
| 12042 | | case OnePossibleValueInvalid: |
| 12043 | | return ira->codegen->invalid_instruction; |
| 12044 | | case OnePossibleValueYes: |
| 12045 | | return ir_const(ira, source_instruction, child_type); |
| 12046 | | case OnePossibleValueNo: |
| 12047 | | break; |
| 12951 | |
| 12952 | if (type_entry->id != ZigTypeIdPointer) { |
| 12953 | ir_add_error_node(ira, source_instruction->source_node, |
| 12954 | buf_sprintf("attempt to dereference non-pointer type '%s'", |
| 12955 | buf_ptr(&type_entry->name))); |
| 12956 | return ira->codegen->invalid_instruction; |
| 12957 | } |
| 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; |
| 12048 | 12973 | } |
| 12049 | | if (instr_is_comptime(ptr)) { |
| 12050 | | if (ptr->value.special == ConstValSpecialUndef) { |
| 12051 | | ir_add_error(ira, ptr, buf_sprintf("attempt to dereference undefined value")); |
| 12052 | | return ira->codegen->invalid_instruction; |
| 12053 | | } |
| 12054 | | if (ptr->value.data.x_ptr.mut == ConstPtrMutComptimeConst || |
| 12055 | | ptr->value.data.x_ptr.mut == ConstPtrMutComptimeVar) |
| 12056 | | { |
| 12057 | | ConstExprValue *pointee = const_ptr_pointee_unchecked(ira->codegen, &ptr->value); |
| 12058 | | if (pointee->special != ConstValSpecialRuntime) { |
| 12059 | | IrInstruction *result = ir_const(ira, source_instruction, child_type); |
| 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); |
| 12060 | 12978 | |
| 12061 | | if ((err = ir_read_const_ptr(ira, ira->codegen, source_instruction->source_node, &result->value, |
| 12062 | | &ptr->value))) |
| 12063 | | { |
| 12064 | | return ira->codegen->invalid_instruction; |
| 12065 | | } |
| 12066 | | result->value.type = child_type; |
| 12067 | | return result; |
| 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; |
| 12068 | 12983 | } |
| 12984 | result->value.type = child_type; |
| 12985 | return result; |
| 12069 | 12986 | } |
| 12070 | 12987 | } |
| 12071 | | // if the instruction is a const ref instruction we can skip it |
| 12072 | | if (ptr->id == IrInstructionIdRef) { |
| 12073 | | IrInstructionRef *ref_inst = reinterpret_cast<IrInstructionRef *>(ptr); |
| 12074 | | return ref_inst->value; |
| 12075 | | } |
| 12076 | | IrInstruction *result = ir_build_load_ptr_gen(ira, source_instruction, ptr, child_type); |
| 12077 | | if (type_entry->data.pointer.host_int_bytes != 0 && handle_is_ptr(child_type)) { |
| 12078 | | ir_add_alloca(ira, result, child_type); |
| 12988 | } |
| 12989 | // if the instruction is a const ref instruction we can skip it |
| 12990 | if (ptr->id == IrInstructionIdRef) { |
| 12991 | IrInstructionRef *ref_inst = reinterpret_cast<IrInstructionRef *>(ptr); |
| 12992 | return ref_inst->value; |
| 12993 | } |
| 12994 | |
| 12995 | IrInstruction *result_loc_inst; |
| 12996 | if (type_entry->data.pointer.host_int_bytes != 0 && handle_is_ptr(child_type)) { |
| 12997 | if (result_loc == nullptr) result_loc = no_result_loc(); |
| 12998 | result_loc_inst = ir_resolve_result(ira, source_instruction, result_loc, child_type, nullptr, true, false); |
| 12999 | if (type_is_invalid(result_loc_inst->value.type) || instr_is_unreachable(result_loc_inst)) { |
| 13000 | return result_loc_inst; |
| 12079 | 13001 | } |
| 12080 | | return result; |
| 12081 | 13002 | } else { |
| 12082 | | ir_add_error_node(ira, source_instruction->source_node, |
| 12083 | | buf_sprintf("attempt to dereference non-pointer type '%s'", |
| 12084 | | buf_ptr(&type_entry->name))); |
| 12085 | | return ira->codegen->invalid_instruction; |
| 13003 | result_loc_inst = nullptr; |
| 12086 | 13004 | } |
| 13005 | |
| 13006 | return ir_build_load_ptr_gen(ira, source_instruction, ptr, child_type, result_loc_inst); |
| 12087 | 13007 | } |
| 12088 | 13008 | |
| 12089 | 13009 | static bool ir_resolve_align(IrAnalyze *ira, IrInstruction *value, uint32_t *out) { |
| ... | ... | @@ -12297,6 +13217,14 @@ static IrInstruction *ir_analyze_instruction_return(IrAnalyze *ira, IrInstructio |
| 12297 | 13217 | if (type_is_invalid(value->value.type)) |
| 12298 | 13218 | return ir_unreach_error(ira); |
| 12299 | 13219 | |
| 13220 | if (!instr_is_comptime(value) && handle_is_ptr(ira->explicit_return_type)) { |
| 13221 | // result location mechanism took care of it. |
| 13222 | IrInstruction *result = ir_build_return(&ira->new_irb, instruction->base.scope, |
| 13223 | instruction->base.source_node, nullptr); |
| 13224 | result->value.type = ira->codegen->builtin_types.entry_unreachable; |
| 13225 | return ir_finish_anal(ira, result); |
| 13226 | } |
| 13227 | |
| 12300 | 13228 | IrInstruction *casted_value = ir_implicit_cast(ira, value, ira->explicit_return_type); |
| 12301 | 13229 | if (type_is_invalid(casted_value->value.type)) { |
| 12302 | 13230 | AstNode *source_node = ira->explicit_return_type_source_node; |
| ... | ... | @@ -12459,7 +13387,7 @@ static IrInstruction *ir_analyze_bin_op_cmp(IrAnalyze *ira, IrInstructionBinOp * |
| 12459 | 13387 | } else { |
| 12460 | 13388 | return is_non_null; |
| 12461 | 13389 | } |
| 12462 | | } else if (is_equality_cmp && |
| 13390 | } else if (is_equality_cmp && |
| 12463 | 13391 | ((op1->value.type->id == ZigTypeIdNull && op2->value.type->id == ZigTypeIdPointer && |
| 12464 | 13392 | op2->value.type->data.pointer.ptr_len == PtrLenC) || |
| 12465 | 13393 | (op2->value.type->id == ZigTypeIdNull && op1->value.type->id == ZigTypeIdPointer && |
| ... | ... | @@ -12901,7 +13829,7 @@ static ErrorMsg *ir_eval_math_op_scalar(IrAnalyze *ira, IrInstruction *source_in |
| 12901 | 13829 | } |
| 12902 | 13830 | } else { |
| 12903 | 13831 | float_div_trunc(out_val, op1_val, op2_val); |
| 12904 | | ConstExprValue remainder; |
| 13832 | ConstExprValue remainder = {}; |
| 12905 | 13833 | float_rem(&remainder, op1_val, op2_val); |
| 12906 | 13834 | if (float_cmp_zero(&remainder) != CmpEQ) { |
| 12907 | 13835 | return ir_add_error(ira, source_instr, buf_sprintf("exact division had a remainder")); |
| ... | ... | @@ -13276,8 +14204,8 @@ static IrInstruction *ir_analyze_bin_op_math(IrAnalyze *ira, IrInstructionBinOp |
| 13276 | 14204 | // have a remainder function ambiguity problem |
| 13277 | 14205 | ok = true; |
| 13278 | 14206 | } else { |
| 13279 | | ConstExprValue rem_result; |
| 13280 | | ConstExprValue mod_result; |
| 14207 | ConstExprValue rem_result = {}; |
| 14208 | ConstExprValue mod_result = {}; |
| 13281 | 14209 | float_rem(&rem_result, op1_val, op2_val); |
| 13282 | 14210 | float_mod(&mod_result, op1_val, op2_val); |
| 13283 | 14211 | ok = float_cmp(&rem_result, &mod_result) == CmpEQ; |
| ... | ... | @@ -13500,10 +14428,12 @@ static IrInstruction *ir_analyze_array_cat(IrAnalyze *ira, IrInstructionBinOp *i |
| 13500 | 14428 | |
| 13501 | 14429 | size_t next_index = 0; |
| 13502 | 14430 | for (size_t i = op1_array_index; i < op1_array_end; i += 1, next_index += 1) { |
| 13503 | | out_array_val->data.x_array.data.s_none.elements[next_index] = op1_array_val->data.x_array.data.s_none.elements[i]; |
| 14431 | copy_const_val(&out_array_val->data.x_array.data.s_none.elements[next_index], |
| 14432 | &op1_array_val->data.x_array.data.s_none.elements[i], true); |
| 13504 | 14433 | } |
| 13505 | 14434 | for (size_t i = op2_array_index; i < op2_array_end; i += 1, next_index += 1) { |
| 13506 | | out_array_val->data.x_array.data.s_none.elements[next_index] = op2_array_val->data.x_array.data.s_none.elements[i]; |
| 14435 | copy_const_val(&out_array_val->data.x_array.data.s_none.elements[next_index], |
| 14436 | &op2_array_val->data.x_array.data.s_none.elements[i], true); |
| 13507 | 14437 | } |
| 13508 | 14438 | if (next_index < new_len) { |
| 13509 | 14439 | ConstExprValue *null_byte = &out_array_val->data.x_array.data.s_none.elements[next_index]; |
| ... | ... | @@ -13564,7 +14494,8 @@ static IrInstruction *ir_analyze_array_mult(IrAnalyze *ira, IrInstructionBinOp * |
| 13564 | 14494 | uint64_t i = 0; |
| 13565 | 14495 | for (uint64_t x = 0; x < mult_amt; x += 1) { |
| 13566 | 14496 | for (uint64_t y = 0; y < old_array_len; y += 1) { |
| 13567 | | out_val->data.x_array.data.s_none.elements[i] = array_val->data.x_array.data.s_none.elements[y]; |
| 14497 | copy_const_val(&out_val->data.x_array.data.s_none.elements[i], |
| 14498 | &array_val->data.x_array.data.s_none.elements[y], true); |
| 13568 | 14499 | i += 1; |
| 13569 | 14500 | } |
| 13570 | 14501 | } |
| ... | ... | @@ -13661,12 +14592,6 @@ static IrInstruction *ir_analyze_instruction_decl_var(IrAnalyze *ira, |
| 13661 | 14592 | Error err; |
| 13662 | 14593 | ZigVar *var = decl_var_instruction->var; |
| 13663 | 14594 | |
| 13664 | | IrInstruction *init_value = decl_var_instruction->init_value->child; |
| 13665 | | if (type_is_invalid(init_value->value.type)) { |
| 13666 | | var->var_type = ira->codegen->builtin_types.entry_invalid; |
| 13667 | | return ira->codegen->invalid_instruction; |
| 13668 | | } |
| 13669 | | |
| 13670 | 14595 | ZigType *explicit_type = nullptr; |
| 13671 | 14596 | IrInstruction *var_type = nullptr; |
| 13672 | 14597 | if (decl_var_instruction->var_type != nullptr) { |
| ... | ... | @@ -13681,18 +14606,40 @@ static IrInstruction *ir_analyze_instruction_decl_var(IrAnalyze *ira, |
| 13681 | 14606 | |
| 13682 | 14607 | AstNode *source_node = decl_var_instruction->base.source_node; |
| 13683 | 14608 | |
| 13684 | | IrInstruction *casted_init_value = ir_implicit_cast(ira, init_value, explicit_type); |
| 13685 | 14609 | bool is_comptime_var = ir_get_var_is_comptime(var); |
| 13686 | 14610 | |
| 13687 | 14611 | bool var_class_requires_const = false; |
| 13688 | 14612 | |
| 13689 | | ZigType *result_type = casted_init_value->value.type; |
| 14613 | IrInstruction *var_ptr = decl_var_instruction->ptr->child; |
| 14614 | // if this is null, a compiler error happened and did not initialize the variable. |
| 14615 | // if there are no compile errors there may be a missing ir_expr_wrap in pass1 IR generation. |
| 14616 | if (var_ptr == nullptr || type_is_invalid(var_ptr->value.type)) { |
| 14617 | ir_assert(var_ptr != nullptr || ira->codegen->errors.length != 0, &decl_var_instruction->base); |
| 14618 | var->var_type = ira->codegen->builtin_types.entry_invalid; |
| 14619 | return ira->codegen->invalid_instruction; |
| 14620 | } |
| 14621 | |
| 14622 | // The ir_build_var_decl_src call is supposed to pass a pointer to the allocation, not an initialization value. |
| 14623 | ir_assert(var_ptr->value.type->id == ZigTypeIdPointer, &decl_var_instruction->base); |
| 14624 | |
| 14625 | ZigType *result_type = var_ptr->value.type->data.pointer.child_type; |
| 13690 | 14626 | if (type_is_invalid(result_type)) { |
| 13691 | 14627 | result_type = ira->codegen->builtin_types.entry_invalid; |
| 13692 | 14628 | } else if (result_type->id == ZigTypeIdUnreachable || result_type->id == ZigTypeIdOpaque) { |
| 13693 | | ir_add_error_node(ira, source_node, |
| 13694 | | buf_sprintf("variable of type '%s' not allowed", buf_ptr(&result_type->name))); |
| 13695 | | result_type = ira->codegen->builtin_types.entry_invalid; |
| 14629 | zig_unreachable(); |
| 14630 | } |
| 14631 | |
| 14632 | ConstExprValue *init_val = nullptr; |
| 14633 | if (instr_is_comptime(var_ptr) && var_ptr->value.data.x_ptr.mut != ConstPtrMutRuntimeVar) { |
| 14634 | init_val = const_ptr_pointee(ira, ira->codegen, &var_ptr->value, decl_var_instruction->base.source_node); |
| 14635 | if (is_comptime_var) { |
| 14636 | if (var->gen_is_const) { |
| 14637 | var->const_value = init_val; |
| 14638 | } else { |
| 14639 | var->const_value = create_const_vals(1); |
| 14640 | copy_const_val(var->const_value, init_val, false); |
| 14641 | } |
| 14642 | } |
| 13696 | 14643 | } |
| 13697 | 14644 | |
| 13698 | 14645 | switch (type_requires_comptime(ira->codegen, result_type)) { |
| ... | ... | @@ -13709,18 +14656,20 @@ static IrInstruction *ir_analyze_instruction_decl_var(IrAnalyze *ira, |
| 13709 | 14656 | } |
| 13710 | 14657 | break; |
| 13711 | 14658 | case ReqCompTimeNo: |
| 13712 | | if (casted_init_value->value.special == ConstValSpecialStatic && |
| 13713 | | casted_init_value->value.type->id == ZigTypeIdFn && |
| 13714 | | casted_init_value->value.data.x_ptr.special != ConstPtrSpecialHardCodedAddr && |
| 13715 | | casted_init_value->value.data.x_ptr.data.fn.fn_entry->fn_inline == FnInlineAlways) |
| 13716 | | { |
| 13717 | | var_class_requires_const = true; |
| 13718 | | if (!var->src_is_const && !is_comptime_var) { |
| 13719 | | ErrorMsg *msg = ir_add_error_node(ira, source_node, |
| 13720 | | buf_sprintf("functions marked inline must be stored in const or comptime var")); |
| 13721 | | AstNode *proto_node = casted_init_value->value.data.x_ptr.data.fn.fn_entry->proto_node; |
| 13722 | | add_error_note(ira->codegen, msg, proto_node, buf_sprintf("declared here")); |
| 13723 | | result_type = ira->codegen->builtin_types.entry_invalid; |
| 14659 | if (init_val != nullptr) { |
| 14660 | if (init_val->special == ConstValSpecialStatic && |
| 14661 | init_val->type->id == ZigTypeIdFn && |
| 14662 | init_val->data.x_ptr.special != ConstPtrSpecialHardCodedAddr && |
| 14663 | init_val->data.x_ptr.data.fn.fn_entry->fn_inline == FnInlineAlways) |
| 14664 | { |
| 14665 | var_class_requires_const = true; |
| 14666 | if (!var->src_is_const && !is_comptime_var) { |
| 14667 | ErrorMsg *msg = ir_add_error_node(ira, source_node, |
| 14668 | buf_sprintf("functions marked inline must be stored in const or comptime var")); |
| 14669 | AstNode *proto_node = init_val->data.x_ptr.data.fn.fn_entry->proto_node; |
| 14670 | add_error_note(ira->codegen, msg, proto_node, buf_sprintf("declared here")); |
| 14671 | result_type = ira->codegen->builtin_types.entry_invalid; |
| 14672 | } |
| 13724 | 14673 | } |
| 13725 | 14674 | } |
| 13726 | 14675 | break; |
| ... | ... | @@ -13767,11 +14716,29 @@ static IrInstruction *ir_analyze_instruction_decl_var(IrAnalyze *ira, |
| 13767 | 14716 | } |
| 13768 | 14717 | } |
| 13769 | 14718 | |
| 13770 | | if (casted_init_value->value.special != ConstValSpecialRuntime) { |
| 13771 | | if (var->mem_slot_index != SIZE_MAX) { |
| 14719 | if (init_val != nullptr && init_val->special != ConstValSpecialRuntime) { |
| 14720 | // Resolve ConstPtrMutInfer |
| 14721 | if (var->gen_is_const) { |
| 14722 | var_ptr->value.data.x_ptr.mut = ConstPtrMutComptimeConst; |
| 14723 | } else if (is_comptime_var) { |
| 14724 | var_ptr->value.data.x_ptr.mut = ConstPtrMutComptimeVar; |
| 14725 | } else { |
| 14726 | // we need a runtime ptr but we have a comptime val. |
| 14727 | // since it's a comptime val there are no instructions for it. |
| 14728 | // we memcpy the init value here |
| 14729 | IrInstruction *deref = ir_get_deref(ira, var_ptr, var_ptr, nullptr); |
| 14730 | // If this assertion trips, something is wrong with the IR instructions, because |
| 14731 | // we expected the above deref to return a constant value, but it created a runtime |
| 14732 | // instruction. |
| 14733 | assert(deref->value.special != ConstValSpecialRuntime); |
| 14734 | var_ptr->value.special = ConstValSpecialRuntime; |
| 14735 | ir_analyze_store_ptr(ira, var_ptr, var_ptr, deref); |
| 14736 | } |
| 14737 | |
| 14738 | if (var_ptr->value.special == ConstValSpecialStatic && var->mem_slot_index != SIZE_MAX) { |
| 13772 | 14739 | assert(var->mem_slot_index < ira->exec_context.mem_slot_list.length); |
| 13773 | 14740 | ConstExprValue *mem_slot = ira->exec_context.mem_slot_list.at(var->mem_slot_index); |
| 13774 | | copy_const_val(mem_slot, &casted_init_value->value, !is_comptime_var || var->gen_is_const); |
| 14741 | copy_const_val(mem_slot, init_val, !is_comptime_var || var->gen_is_const); |
| 13775 | 14742 | |
| 13776 | 14743 | if (is_comptime_var || (var_class_requires_const && var->gen_is_const)) { |
| 13777 | 14744 | return ir_const_void(ira, &decl_var_instruction->base); |
| ... | ... | @@ -13788,7 +14755,7 @@ static IrInstruction *ir_analyze_instruction_decl_var(IrAnalyze *ira, |
| 13788 | 14755 | if (fn_entry) |
| 13789 | 14756 | fn_entry->variable_list.append(var); |
| 13790 | 14757 | |
| 13791 | | return ir_build_var_decl_gen(ira, &decl_var_instruction->base, var, casted_init_value); |
| 14758 | return ir_build_var_decl_gen(ira, &decl_var_instruction->base, var, var_ptr); |
| 13792 | 14759 | } |
| 13793 | 14760 | |
| 13794 | 14761 | static IrInstruction *ir_analyze_instruction_export(IrAnalyze *ira, IrInstructionExport *instruction) { |
| ... | ... | @@ -14082,7 +15049,7 @@ IrInstruction *ir_get_implicit_allocator(IrAnalyze *ira, IrInstruction *source_i |
| 14082 | 15049 | ZigVar *coro_allocator_var = ira->old_irb.exec->coro_allocator_var; |
| 14083 | 15050 | assert(coro_allocator_var != nullptr); |
| 14084 | 15051 | IrInstruction *var_ptr_inst = ir_get_var_ptr(ira, source_instr, coro_allocator_var); |
| 14085 | | IrInstruction *result = ir_get_deref(ira, source_instr, var_ptr_inst); |
| 15052 | IrInstruction *result = ir_get_deref(ira, source_instr, var_ptr_inst, nullptr); |
| 14086 | 15053 | assert(result->value.type != nullptr); |
| 14087 | 15054 | return result; |
| 14088 | 15055 | } |
| ... | ... | @@ -14090,109 +15057,543 @@ IrInstruction *ir_get_implicit_allocator(IrAnalyze *ira, IrInstruction *source_i |
| 14090 | 15057 | zig_unreachable(); |
| 14091 | 15058 | } |
| 14092 | 15059 | |
| 14093 | | static IrInstruction *ir_analyze_async_call(IrAnalyze *ira, IrInstructionCall *call_instruction, ZigFn *fn_entry, |
| 14094 | | ZigType *fn_type, IrInstruction *fn_ref, IrInstruction **casted_args, size_t arg_count, |
| 14095 | | IrInstruction *async_allocator_inst) |
| 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) |
| 14096 | 15062 | { |
| 14097 | | Buf *realloc_field_name = buf_create_from_str(ASYNC_REALLOC_FIELD_NAME); |
| 14098 | | ir_assert(async_allocator_inst->value.type->id == ZigTypeIdPointer, &call_instruction->base); |
| 14099 | | ZigType *container_type = async_allocator_inst->value.type->data.pointer.child_type; |
| 14100 | | IrInstruction *field_ptr_inst = ir_analyze_container_field_ptr(ira, realloc_field_name, &call_instruction->base, |
| 14101 | | async_allocator_inst, container_type); |
| 14102 | | if (type_is_invalid(field_ptr_inst->value.type)) { |
| 14103 | | return ira->codegen->invalid_instruction; |
| 14104 | | } |
| 14105 | | ZigType *ptr_to_realloc_fn_type = field_ptr_inst->value.type; |
| 14106 | | ir_assert(ptr_to_realloc_fn_type->id == ZigTypeIdPointer, &call_instruction->base); |
| 15063 | Error err; |
| 14107 | 15064 | |
| 14108 | | ZigType *realloc_fn_type = ptr_to_realloc_fn_type->data.pointer.child_type; |
| 14109 | | if (realloc_fn_type->id != ZigTypeIdFn) { |
| 14110 | | ir_add_error(ira, &call_instruction->base, |
| 14111 | | buf_sprintf("expected reallocation function, found '%s'", buf_ptr(&realloc_fn_type->name))); |
| 14112 | | return ira->codegen->invalid_instruction; |
| 14113 | | } |
| 15065 | ConstExprValue *pointee = create_const_vals(1); |
| 15066 | pointee->special = ConstValSpecialUndef; |
| 14114 | 15067 | |
| 14115 | | ZigType *realloc_fn_return_type = realloc_fn_type->data.fn.fn_type_id.return_type; |
| 14116 | | if (realloc_fn_return_type->id != ZigTypeIdErrorUnion) { |
| 14117 | | ir_add_error(ira, fn_ref, |
| 14118 | | buf_sprintf("expected allocation function to return error union, but it returns '%s'", buf_ptr(&realloc_fn_return_type->name))); |
| 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))) |
| 14119 | 15075 | return ira->codegen->invalid_instruction; |
| 14120 | | } |
| 14121 | | ZigType *alloc_fn_error_set_type = realloc_fn_return_type->data.error_union.err_set_type; |
| 14122 | | ZigType *return_type = fn_type->data.fn.fn_type_id.return_type; |
| 14123 | | ZigType *promise_type = get_promise_type(ira->codegen, return_type); |
| 14124 | | ZigType *async_return_type = get_error_union_type(ira->codegen, alloc_fn_error_set_type, promise_type); |
| 15076 | assert(result->base.value.data.x_ptr.special != ConstPtrSpecialInvalid); |
| 14125 | 15077 | |
| 14126 | | IrInstruction *result = ir_build_call(&ira->new_irb, call_instruction->base.scope, call_instruction->base.source_node, |
| 14127 | | fn_entry, fn_ref, arg_count, casted_args, false, FnInlineAuto, true, async_allocator_inst, nullptr); |
| 14128 | | result->value.type = async_return_type; |
| 14129 | | return result; |
| 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; |
| 14130 | 15088 | } |
| 14131 | 15089 | |
| 14132 | | static bool ir_analyze_fn_call_inline_arg(IrAnalyze *ira, AstNode *fn_proto_node, |
| 14133 | | IrInstruction *arg, Scope **exec_scope, size_t *next_proto_i) |
| 15090 | static ZigType *ir_result_loc_expected_type(IrAnalyze *ira, IrInstruction *suspend_source_instr, |
| 15091 | ResultLoc *result_loc) |
| 14134 | 15092 | { |
| 14135 | | AstNode *param_decl_node = fn_proto_node->data.fn_proto.params.at(*next_proto_i); |
| 14136 | | assert(param_decl_node->type == NodeTypeParamDecl); |
| 14137 | | |
| 14138 | | IrInstruction *casted_arg; |
| 14139 | | if (param_decl_node->data.param_decl.var_token == nullptr) { |
| 14140 | | AstNode *param_type_node = param_decl_node->data.param_decl.type; |
| 14141 | | ZigType *param_type = ir_analyze_type_expr(ira, *exec_scope, param_type_node); |
| 14142 | | if (type_is_invalid(param_type)) |
| 14143 | | return false; |
| 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 | } |
| 14144 | 15110 | |
| 14145 | | casted_arg = ir_implicit_cast(ira, arg, param_type); |
| 14146 | | if (type_is_invalid(casted_arg->value.type)) |
| 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: |
| 14147 | 15126 | return false; |
| 14148 | | } else { |
| 14149 | | casted_arg = arg; |
| 15127 | default: |
| 15128 | // TODO list these types out explicitly, there are probably some other invalid ones here |
| 15129 | return true; |
| 14150 | 15130 | } |
| 15131 | } |
| 14151 | 15132 | |
| 14152 | | ConstExprValue *arg_val = ir_resolve_const(ira, casted_arg, UndefBad); |
| 14153 | | if (!arg_val) |
| 14154 | | return false; |
| 14155 | | |
| 14156 | | Buf *param_name = param_decl_node->data.param_decl.name; |
| 14157 | | ZigVar *var = add_variable(ira->codegen, param_decl_node, |
| 14158 | | *exec_scope, param_name, true, arg_val, nullptr, arg_val->type); |
| 14159 | | *exec_scope = var->child_scope; |
| 14160 | | *next_proto_i += 1; |
| 14161 | | |
| 14162 | | return true; |
| 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; |
| 14163 | 15141 | } |
| 14164 | 15142 | |
| 14165 | | static bool ir_analyze_fn_call_generic_arg(IrAnalyze *ira, AstNode *fn_proto_node, |
| 14166 | | IrInstruction *arg, Scope **child_scope, size_t *next_proto_i, |
| 14167 | | GenericFnTypeId *generic_id, FnTypeId *fn_type_id, IrInstruction **casted_args, |
| 14168 | | ZigFn *impl_fn) |
| 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) |
| 14169 | 15146 | { |
| 14170 | | AstNode *param_decl_node = fn_proto_node->data.fn_proto.params.at(*next_proto_i); |
| 14171 | | assert(param_decl_node->type == NodeTypeParamDecl); |
| 14172 | | bool is_var_args = param_decl_node->data.param_decl.is_var_args; |
| 14173 | | bool arg_part_of_generic_id = false; |
| 14174 | | IrInstruction *casted_arg; |
| 14175 | | if (is_var_args) { |
| 14176 | | arg_part_of_generic_id = true; |
| 14177 | | casted_arg = arg; |
| 14178 | | } else { |
| 14179 | | if (param_decl_node->data.param_decl.var_token == nullptr) { |
| 14180 | | AstNode *param_type_node = param_decl_node->data.param_decl.type; |
| 14181 | | ZigType *param_type = ir_analyze_type_expr(ira, *child_scope, param_type_node); |
| 14182 | | if (type_is_invalid(param_type)) |
| 14183 | | return false; |
| 14184 | | |
| 14185 | | casted_arg = ir_implicit_cast(ira, arg, param_type); |
| 14186 | | if (type_is_invalid(casted_arg->value.type)) |
| 14187 | | return false; |
| 14188 | | } else { |
| 14189 | | arg_part_of_generic_id = true; |
| 14190 | | casted_arg = arg; |
| 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; |
| 14191 | 15152 | } |
| 14192 | 15153 | } |
| 15154 | result_loc->gen_instruction = value; |
| 15155 | result_loc->implicit_elem_type = value_type; |
| 15156 | switch (result_loc->id) { |
| 15157 | case ResultLocIdInvalid: |
| 15158 | case ResultLocIdPeerParent: |
| 15159 | zig_unreachable(); |
| 15160 | case ResultLocIdNone: { |
| 15161 | if (value != nullptr) { |
| 15162 | return nullptr; |
| 15163 | } |
| 15164 | // need to return a result location and don't have one. use a stack allocation |
| 15165 | IrInstructionAllocaGen *alloca_gen = ir_create_alloca_gen(ira, suspend_source_instr, 0, ""); |
| 15166 | if ((err = type_resolve(ira->codegen, value_type, ResolveStatusZeroBitsKnown))) |
| 15167 | return ira->codegen->invalid_instruction; |
| 15168 | alloca_gen->base.value.type = get_pointer_to_type_extra(ira->codegen, value_type, false, false, |
| 15169 | PtrLenSingle, 0, 0, 0, false); |
| 15170 | set_up_result_loc_for_inferred_comptime(&alloca_gen->base); |
| 15171 | ZigFn *fn_entry = exec_fn_entry(ira->new_irb.exec); |
| 15172 | if (fn_entry != nullptr) { |
| 15173 | fn_entry->alloca_gen_list.append(alloca_gen); |
| 15174 | } |
| 15175 | result_loc->written = true; |
| 15176 | result_loc->resolved_loc = &alloca_gen->base; |
| 15177 | return result_loc->resolved_loc; |
| 15178 | } |
| 15179 | case ResultLocIdVar: { |
| 15180 | ResultLocVar *result_loc_var = reinterpret_cast<ResultLocVar *>(result_loc); |
| 15181 | assert(result_loc->source_instruction->id == IrInstructionIdAllocaSrc); |
| 15182 | |
| 15183 | if (value_type->id == ZigTypeIdUnreachable || value_type->id == ZigTypeIdOpaque) { |
| 15184 | ir_add_error(ira, result_loc->source_instruction, |
| 15185 | buf_sprintf("variable of type '%s' not allowed", buf_ptr(&value_type->name))); |
| 15186 | return ira->codegen->invalid_instruction; |
| 15187 | } |
| 14193 | 15188 | |
| 14194 | | bool comptime_arg = param_decl_node->data.param_decl.is_inline || |
| 14195 | | casted_arg->value.type->id == ZigTypeIdComptimeInt || casted_arg->value.type->id == ZigTypeIdComptimeFloat; |
| 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, |
| 15490 | ZigType *fn_type, IrInstruction *fn_ref, IrInstruction **casted_args, size_t arg_count, |
| 15491 | IrInstruction *async_allocator_inst) |
| 15492 | { |
| 15493 | Buf *realloc_field_name = buf_create_from_str(ASYNC_REALLOC_FIELD_NAME); |
| 15494 | ir_assert(async_allocator_inst->value.type->id == ZigTypeIdPointer, &call_instruction->base); |
| 15495 | ZigType *container_type = async_allocator_inst->value.type->data.pointer.child_type; |
| 15496 | IrInstruction *field_ptr_inst = ir_analyze_container_field_ptr(ira, realloc_field_name, &call_instruction->base, |
| 15497 | async_allocator_inst, container_type, false); |
| 15498 | if (type_is_invalid(field_ptr_inst->value.type)) { |
| 15499 | return ira->codegen->invalid_instruction; |
| 15500 | } |
| 15501 | ZigType *ptr_to_realloc_fn_type = field_ptr_inst->value.type; |
| 15502 | ir_assert(ptr_to_realloc_fn_type->id == ZigTypeIdPointer, &call_instruction->base); |
| 15503 | |
| 15504 | ZigType *realloc_fn_type = ptr_to_realloc_fn_type->data.pointer.child_type; |
| 15505 | if (realloc_fn_type->id != ZigTypeIdFn) { |
| 15506 | ir_add_error(ira, &call_instruction->base, |
| 15507 | buf_sprintf("expected reallocation function, found '%s'", buf_ptr(&realloc_fn_type->name))); |
| 15508 | return ira->codegen->invalid_instruction; |
| 15509 | } |
| 15510 | |
| 15511 | ZigType *realloc_fn_return_type = realloc_fn_type->data.fn.fn_type_id.return_type; |
| 15512 | if (realloc_fn_return_type->id != ZigTypeIdErrorUnion) { |
| 15513 | ir_add_error(ira, fn_ref, |
| 15514 | buf_sprintf("expected allocation function to return error union, but it returns '%s'", buf_ptr(&realloc_fn_return_type->name))); |
| 15515 | return ira->codegen->invalid_instruction; |
| 15516 | } |
| 15517 | ZigType *alloc_fn_error_set_type = realloc_fn_return_type->data.error_union.err_set_type; |
| 15518 | ZigType *return_type = fn_type->data.fn.fn_type_id.return_type; |
| 15519 | ZigType *promise_type = get_promise_type(ira->codegen, return_type); |
| 15520 | ZigType *async_return_type = get_error_union_type(ira->codegen, alloc_fn_error_set_type, promise_type); |
| 15521 | |
| 15522 | IrInstruction *result_loc = ir_resolve_result(ira, &call_instruction->base, no_result_loc(), |
| 15523 | async_return_type, nullptr, true, true); |
| 15524 | if (type_is_invalid(result_loc->value.type) || instr_is_unreachable(result_loc)) { |
| 15525 | return result_loc; |
| 15526 | } |
| 15527 | |
| 15528 | return ir_build_call_gen(ira, &call_instruction->base, fn_entry, fn_ref, arg_count, |
| 15529 | casted_args, FnInlineAuto, true, async_allocator_inst, nullptr, result_loc, |
| 15530 | async_return_type); |
| 15531 | } |
| 15532 | |
| 15533 | static bool ir_analyze_fn_call_inline_arg(IrAnalyze *ira, AstNode *fn_proto_node, |
| 15534 | IrInstruction *arg, Scope **exec_scope, size_t *next_proto_i) |
| 15535 | { |
| 15536 | AstNode *param_decl_node = fn_proto_node->data.fn_proto.params.at(*next_proto_i); |
| 15537 | assert(param_decl_node->type == NodeTypeParamDecl); |
| 15538 | |
| 15539 | IrInstruction *casted_arg; |
| 15540 | if (param_decl_node->data.param_decl.var_token == nullptr) { |
| 15541 | AstNode *param_type_node = param_decl_node->data.param_decl.type; |
| 15542 | ZigType *param_type = ir_analyze_type_expr(ira, *exec_scope, param_type_node); |
| 15543 | if (type_is_invalid(param_type)) |
| 15544 | return false; |
| 15545 | |
| 15546 | casted_arg = ir_implicit_cast(ira, arg, param_type); |
| 15547 | if (type_is_invalid(casted_arg->value.type)) |
| 15548 | return false; |
| 15549 | } else { |
| 15550 | casted_arg = arg; |
| 15551 | } |
| 15552 | |
| 15553 | ConstExprValue *arg_val = ir_resolve_const(ira, casted_arg, UndefOk); |
| 15554 | if (!arg_val) |
| 15555 | return false; |
| 15556 | |
| 15557 | Buf *param_name = param_decl_node->data.param_decl.name; |
| 15558 | ZigVar *var = add_variable(ira->codegen, param_decl_node, |
| 15559 | *exec_scope, param_name, true, arg_val, nullptr, arg_val->type); |
| 15560 | *exec_scope = var->child_scope; |
| 15561 | *next_proto_i += 1; |
| 15562 | |
| 15563 | return true; |
| 15564 | } |
| 15565 | |
| 15566 | static bool ir_analyze_fn_call_generic_arg(IrAnalyze *ira, AstNode *fn_proto_node, |
| 15567 | IrInstruction *arg, Scope **child_scope, size_t *next_proto_i, |
| 15568 | GenericFnTypeId *generic_id, FnTypeId *fn_type_id, IrInstruction **casted_args, |
| 15569 | ZigFn *impl_fn) |
| 15570 | { |
| 15571 | AstNode *param_decl_node = fn_proto_node->data.fn_proto.params.at(*next_proto_i); |
| 15572 | assert(param_decl_node->type == NodeTypeParamDecl); |
| 15573 | bool is_var_args = param_decl_node->data.param_decl.is_var_args; |
| 15574 | bool arg_part_of_generic_id = false; |
| 15575 | IrInstruction *casted_arg; |
| 15576 | if (is_var_args) { |
| 15577 | arg_part_of_generic_id = true; |
| 15578 | casted_arg = arg; |
| 15579 | } else { |
| 15580 | if (param_decl_node->data.param_decl.var_token == nullptr) { |
| 15581 | AstNode *param_type_node = param_decl_node->data.param_decl.type; |
| 15582 | ZigType *param_type = ir_analyze_type_expr(ira, *child_scope, param_type_node); |
| 15583 | if (type_is_invalid(param_type)) |
| 15584 | return false; |
| 15585 | |
| 15586 | casted_arg = ir_implicit_cast(ira, arg, param_type); |
| 15587 | if (type_is_invalid(casted_arg->value.type)) |
| 15588 | return false; |
| 15589 | } else { |
| 15590 | arg_part_of_generic_id = true; |
| 15591 | casted_arg = arg; |
| 15592 | } |
| 15593 | } |
| 15594 | |
| 15595 | bool comptime_arg = param_decl_node->data.param_decl.is_inline || |
| 15596 | casted_arg->value.type->id == ZigTypeIdComptimeInt || casted_arg->value.type->id == ZigTypeIdComptimeFloat; |
| 14196 | 15597 | |
| 14197 | 15598 | ConstExprValue *arg_val; |
| 14198 | 15599 | |
| ... | ... | @@ -14205,7 +15606,7 @@ static bool ir_analyze_fn_call_generic_arg(IrAnalyze *ira, AstNode *fn_proto_nod |
| 14205 | 15606 | arg_val = create_const_runtime(casted_arg->value.type); |
| 14206 | 15607 | } |
| 14207 | 15608 | if (arg_part_of_generic_id) { |
| 14208 | | generic_id->params[generic_id->param_count] = *arg_val; |
| 15609 | copy_const_val(&generic_id->params[generic_id->param_count], arg_val, true); |
| 14209 | 15610 | generic_id->param_count += 1; |
| 14210 | 15611 | } |
| 14211 | 15612 | |
| ... | ... | @@ -14376,7 +15777,9 @@ static IrInstruction *ir_analyze_store_ptr(IrAnalyze *ira, IrInstruction *source |
| 14376 | 15777 | ir_add_error(ira, source_instr, buf_sprintf("cannot assign to constant")); |
| 14377 | 15778 | return ira->codegen->invalid_instruction; |
| 14378 | 15779 | } |
| 14379 | | if (ptr->value.data.x_ptr.mut == ConstPtrMutComptimeVar) { |
| 15780 | if (ptr->value.data.x_ptr.mut == ConstPtrMutComptimeVar || |
| 15781 | ptr->value.data.x_ptr.mut == ConstPtrMutInfer) |
| 15782 | { |
| 14380 | 15783 | if (instr_is_comptime(value)) { |
| 14381 | 15784 | ConstExprValue *dest_val = const_ptr_pointee(ira, ira->codegen, &ptr->value, source_instr->source_node); |
| 14382 | 15785 | if (dest_val == nullptr) |
| ... | ... | @@ -14390,18 +15793,24 @@ static IrInstruction *ir_analyze_store_ptr(IrAnalyze *ira, IrInstruction *source |
| 14390 | 15793 | // ConstPtrMutComptimeVar, thus defeating the logic below. |
| 14391 | 15794 | bool same_global_refs = ptr->value.data.x_ptr.mut != ConstPtrMutComptimeVar; |
| 14392 | 15795 | copy_const_val(dest_val, &value->value, same_global_refs); |
| 14393 | | if (!ira->new_irb.current_basic_block->must_be_comptime_source_instr) { |
| 15796 | if (ptr->value.data.x_ptr.mut == ConstPtrMutComptimeVar && |
| 15797 | !ira->new_irb.current_basic_block->must_be_comptime_source_instr) |
| 15798 | { |
| 14394 | 15799 | ira->new_irb.current_basic_block->must_be_comptime_source_instr = source_instr; |
| 14395 | 15800 | } |
| 14396 | 15801 | return ir_const_void(ira, source_instr); |
| 14397 | 15802 | } |
| 14398 | 15803 | } |
| 14399 | | ir_add_error(ira, source_instr, |
| 14400 | | buf_sprintf("cannot store runtime value in compile time variable")); |
| 14401 | | ConstExprValue *dest_val = const_ptr_pointee_unchecked(ira->codegen, &ptr->value); |
| 14402 | | dest_val->type = ira->codegen->builtin_types.entry_invalid; |
| 15804 | if (ptr->value.data.x_ptr.mut == ConstPtrMutInfer) { |
| 15805 | ptr->value.special = ConstValSpecialRuntime; |
| 15806 | } else { |
| 15807 | ir_add_error(ira, source_instr, |
| 15808 | buf_sprintf("cannot store runtime value in compile time variable")); |
| 15809 | ConstExprValue *dest_val = const_ptr_pointee_unchecked(ira->codegen, &ptr->value); |
| 15810 | dest_val->type = ira->codegen->builtin_types.entry_invalid; |
| 14403 | 15811 | |
| 14404 | | return ira->codegen->invalid_instruction; |
| 15812 | return ira->codegen->invalid_instruction; |
| 15813 | } |
| 14405 | 15814 | } |
| 14406 | 15815 | } |
| 14407 | 15816 | |
| ... | ... | @@ -14430,7 +15839,7 @@ static IrInstruction *ir_analyze_store_ptr(IrAnalyze *ira, IrInstruction *source |
| 14430 | 15839 | return result; |
| 14431 | 15840 | } |
| 14432 | 15841 | |
| 14433 | | static IrInstruction *ir_analyze_fn_call(IrAnalyze *ira, IrInstructionCall *call_instruction, |
| 15842 | static IrInstruction *ir_analyze_fn_call(IrAnalyze *ira, IrInstructionCallSrc *call_instruction, |
| 14434 | 15843 | ZigFn *fn_entry, ZigType *fn_type, IrInstruction *fn_ref, |
| 14435 | 15844 | IrInstruction *first_arg_ptr, bool comptime_fn_call, FnInline fn_inline) |
| 14436 | 15845 | { |
| ... | ... | @@ -14533,7 +15942,7 @@ static IrInstruction *ir_analyze_fn_call(IrAnalyze *ira, IrInstructionCall *call |
| 14533 | 15942 | if (!first_arg_known_bare && handle_is_ptr(first_arg_ptr->value.type->data.pointer.child_type)) { |
| 14534 | 15943 | first_arg = first_arg_ptr; |
| 14535 | 15944 | } else { |
| 14536 | | first_arg = ir_get_deref(ira, first_arg_ptr, first_arg_ptr); |
| 15945 | first_arg = ir_get_deref(ira, first_arg_ptr, first_arg_ptr, nullptr); |
| 14537 | 15946 | if (type_is_invalid(first_arg->value.type)) |
| 14538 | 15947 | return ira->codegen->invalid_instruction; |
| 14539 | 15948 | } |
| ... | ... | @@ -14692,7 +16101,7 @@ static IrInstruction *ir_analyze_fn_call(IrAnalyze *ira, IrInstructionCall *call |
| 14692 | 16101 | if (!first_arg_known_bare && handle_is_ptr(first_arg_ptr->value.type->data.pointer.child_type)) { |
| 14693 | 16102 | first_arg = first_arg_ptr; |
| 14694 | 16103 | } else { |
| 14695 | | first_arg = ir_get_deref(ira, first_arg_ptr, first_arg_ptr); |
| 16104 | first_arg = ir_get_deref(ira, first_arg_ptr, first_arg_ptr, nullptr); |
| 14696 | 16105 | if (type_is_invalid(first_arg->value.type)) |
| 14697 | 16106 | return ira->codegen->invalid_instruction; |
| 14698 | 16107 | } |
| ... | ... | @@ -14736,7 +16145,7 @@ static IrInstruction *ir_analyze_fn_call(IrAnalyze *ira, IrInstructionCall *call |
| 14736 | 16145 | if (type_is_invalid(arg_var_ptr_inst->value.type)) |
| 14737 | 16146 | return ira->codegen->invalid_instruction; |
| 14738 | 16147 | |
| 14739 | | IrInstruction *arg_tuple_arg = ir_get_deref(ira, arg, arg_var_ptr_inst); |
| 16148 | IrInstruction *arg_tuple_arg = ir_get_deref(ira, arg, arg_var_ptr_inst, nullptr); |
| 14740 | 16149 | if (type_is_invalid(arg_tuple_arg->value.type)) |
| 14741 | 16150 | return ira->codegen->invalid_instruction; |
| 14742 | 16151 | |
| ... | ... | @@ -14785,7 +16194,7 @@ static IrInstruction *ir_analyze_fn_call(IrAnalyze *ira, IrInstructionCall *call |
| 14785 | 16194 | nullptr, nullptr, fn_proto_node->data.fn_proto.align_expr, nullptr, ira->new_irb.exec, nullptr); |
| 14786 | 16195 | IrInstructionConst *const_instruction = ir_create_instruction<IrInstructionConst>(&ira->new_irb, |
| 14787 | 16196 | impl_fn->child_scope, fn_proto_node->data.fn_proto.align_expr); |
| 14788 | | const_instruction->base.value = *align_result; |
| 16197 | copy_const_val(&const_instruction->base.value, align_result, true); |
| 14789 | 16198 | |
| 14790 | 16199 | uint32_t align_bytes = 0; |
| 14791 | 16200 | ir_resolve_align(ira, &const_instruction->base, &align_bytes); |
| ... | ... | @@ -14867,6 +16276,19 @@ static IrInstruction *ir_analyze_fn_call(IrAnalyze *ira, IrInstructionCall *call |
| 14867 | 16276 | } |
| 14868 | 16277 | |
| 14869 | 16278 | FnTypeId *impl_fn_type_id = &impl_fn->type_entry->data.fn.fn_type_id; |
| 16279 | IrInstruction *result_loc; |
| 16280 | if (handle_is_ptr(impl_fn_type_id->return_type)) { |
| 16281 | result_loc = ir_resolve_result(ira, &call_instruction->base, call_instruction->result_loc, |
| 16282 | impl_fn_type_id->return_type, nullptr, true, true); |
| 16283 | if (result_loc != nullptr && (type_is_invalid(result_loc->value.type) || |
| 16284 | instr_is_unreachable(result_loc))) |
| 16285 | { |
| 16286 | return result_loc; |
| 16287 | } |
| 16288 | } else { |
| 16289 | result_loc = nullptr; |
| 16290 | } |
| 16291 | |
| 14870 | 16292 | if (fn_type_can_fail(impl_fn_type_id)) { |
| 14871 | 16293 | parent_fn_entry->calls_or_awaits_errorable_fn = true; |
| 14872 | 16294 | } |
| ... | ... | @@ -14875,18 +16297,14 @@ static IrInstruction *ir_analyze_fn_call(IrAnalyze *ira, IrInstructionCall *call |
| 14875 | 16297 | if (call_instruction->is_async) { |
| 14876 | 16298 | IrInstruction *result = ir_analyze_async_call(ira, call_instruction, impl_fn, impl_fn->type_entry, |
| 14877 | 16299 | fn_ref, casted_args, impl_param_count, async_allocator_inst); |
| 14878 | | ir_add_alloca(ira, result, result->value.type); |
| 14879 | 16300 | return ir_finish_anal(ira, result); |
| 14880 | 16301 | } |
| 14881 | 16302 | |
| 14882 | 16303 | assert(async_allocator_inst == nullptr); |
| 14883 | | IrInstruction *new_call_instruction = ir_build_call(&ira->new_irb, |
| 14884 | | call_instruction->base.scope, call_instruction->base.source_node, |
| 14885 | | impl_fn, nullptr, impl_param_count, casted_args, false, fn_inline, |
| 14886 | | call_instruction->is_async, nullptr, casted_new_stack); |
| 14887 | | new_call_instruction->value.type = impl_fn_type_id->return_type; |
| 14888 | | |
| 14889 | | ir_add_alloca(ira, new_call_instruction, impl_fn_type_id->return_type); |
| 16304 | IrInstruction *new_call_instruction = ir_build_call_gen(ira, &call_instruction->base, |
| 16305 | impl_fn, nullptr, impl_param_count, casted_args, fn_inline, |
| 16306 | call_instruction->is_async, nullptr, casted_new_stack, result_loc, |
| 16307 | impl_fn_type_id->return_type); |
| 14890 | 16308 | |
| 14891 | 16309 | return ir_finish_anal(ira, new_call_instruction); |
| 14892 | 16310 | } |
| ... | ... | @@ -14914,7 +16332,7 @@ static IrInstruction *ir_analyze_fn_call(IrAnalyze *ira, IrInstructionCall *call |
| 14914 | 16332 | { |
| 14915 | 16333 | first_arg = first_arg_ptr; |
| 14916 | 16334 | } else { |
| 14917 | | first_arg = ir_get_deref(ira, first_arg_ptr, first_arg_ptr); |
| 16335 | first_arg = ir_get_deref(ira, first_arg_ptr, first_arg_ptr, nullptr); |
| 14918 | 16336 | if (type_is_invalid(first_arg->value.type)) |
| 14919 | 16337 | return ira->codegen->invalid_instruction; |
| 14920 | 16338 | } |
| ... | ... | @@ -14971,7 +16389,6 @@ static IrInstruction *ir_analyze_fn_call(IrAnalyze *ira, IrInstructionCall *call |
| 14971 | 16389 | |
| 14972 | 16390 | IrInstruction *result = ir_analyze_async_call(ira, call_instruction, fn_entry, fn_type, fn_ref, |
| 14973 | 16391 | casted_args, call_param_count, async_allocator_inst); |
| 14974 | | ir_add_alloca(ira, result, result->value.type); |
| 14975 | 16392 | return ir_finish_anal(ira, result); |
| 14976 | 16393 | } |
| 14977 | 16394 | |
| ... | ... | @@ -14981,15 +16398,24 @@ static IrInstruction *ir_analyze_fn_call(IrAnalyze *ira, IrInstructionCall *call |
| 14981 | 16398 | return ira->codegen->invalid_instruction; |
| 14982 | 16399 | } |
| 14983 | 16400 | |
| 14984 | | IrInstruction *new_call_instruction = ir_build_call(&ira->new_irb, |
| 14985 | | call_instruction->base.scope, call_instruction->base.source_node, |
| 14986 | | fn_entry, fn_ref, call_param_count, casted_args, false, fn_inline, false, nullptr, casted_new_stack); |
| 14987 | | new_call_instruction->value.type = return_type; |
| 14988 | | ir_add_alloca(ira, new_call_instruction, return_type); |
| 16401 | IrInstruction *result_loc; |
| 16402 | if (handle_is_ptr(return_type)) { |
| 16403 | result_loc = ir_resolve_result(ira, &call_instruction->base, call_instruction->result_loc, |
| 16404 | return_type, nullptr, true, true); |
| 16405 | if (result_loc != nullptr && (type_is_invalid(result_loc->value.type) || instr_is_unreachable(result_loc))) { |
| 16406 | return result_loc; |
| 16407 | } |
| 16408 | } else { |
| 16409 | result_loc = nullptr; |
| 16410 | } |
| 16411 | |
| 16412 | IrInstruction *new_call_instruction = ir_build_call_gen(ira, &call_instruction->base, fn_entry, fn_ref, |
| 16413 | call_param_count, casted_args, fn_inline, false, nullptr, casted_new_stack, |
| 16414 | result_loc, return_type); |
| 14989 | 16415 | return ir_finish_anal(ira, new_call_instruction); |
| 14990 | 16416 | } |
| 14991 | 16417 | |
| 14992 | | static IrInstruction *ir_analyze_instruction_call(IrAnalyze *ira, IrInstructionCall *call_instruction) { |
| 16418 | static IrInstruction *ir_analyze_instruction_call(IrAnalyze *ira, IrInstructionCallSrc *call_instruction) { |
| 14993 | 16419 | IrInstruction *fn_ref = call_instruction->fn_ref->child; |
| 14994 | 16420 | if (type_is_invalid(fn_ref->value.type)) |
| 14995 | 16421 | return ira->codegen->invalid_instruction; |
| ... | ... | @@ -15013,7 +16439,8 @@ static IrInstruction *ir_analyze_instruction_call(IrAnalyze *ira, IrInstructionC |
| 15013 | 16439 | |
| 15014 | 16440 | IrInstruction *arg = call_instruction->args[0]->child; |
| 15015 | 16441 | |
| 15016 | | IrInstruction *cast_instruction = ir_analyze_cast(ira, &call_instruction->base, dest_type, arg); |
| 16442 | IrInstruction *cast_instruction = ir_analyze_cast(ira, &call_instruction->base, dest_type, arg, |
| 16443 | call_instruction->result_loc); |
| 15017 | 16444 | if (type_is_invalid(cast_instruction->value.type)) |
| 15018 | 16445 | return ira->codegen->invalid_instruction; |
| 15019 | 16446 | return ir_finish_anal(ira, cast_instruction); |
| ... | ... | @@ -15066,7 +16493,7 @@ static Error ir_read_const_ptr(IrAnalyze *ira, CodeGen *codegen, AstNode *source |
| 15066 | 16493 | |
| 15067 | 16494 | if (dst_size <= src_size) { |
| 15068 | 16495 | if (src_size == dst_size && types_have_same_zig_comptime_repr(pointee->type, out_val->type)) { |
| 15069 | | copy_const_val(out_val, pointee, ptr_val->data.x_ptr.mut == ConstPtrMutComptimeConst); |
| 16496 | copy_const_val(out_val, pointee, ptr_val->data.x_ptr.mut != ConstPtrMutComptimeVar); |
| 15070 | 16497 | return ErrorNone; |
| 15071 | 16498 | } |
| 15072 | 16499 | Buf buf = BUF_INIT; |
| ... | ... | @@ -15315,7 +16742,7 @@ static IrInstruction *ir_analyze_instruction_un_op(IrAnalyze *ira, IrInstruction |
| 15315 | 16742 | return ira->codegen->invalid_instruction; |
| 15316 | 16743 | } |
| 15317 | 16744 | |
| 15318 | | IrInstruction *result = ir_get_deref(ira, &instruction->base, ptr); |
| 16745 | IrInstruction *result = ir_get_deref(ira, &instruction->base, ptr, instruction->result_loc); |
| 15319 | 16746 | if (result == ira->codegen->invalid_instruction) |
| 15320 | 16747 | return ira->codegen->invalid_instruction; |
| 15321 | 16748 | |
| ... | ... | @@ -15334,6 +16761,19 @@ static IrInstruction *ir_analyze_instruction_un_op(IrAnalyze *ira, IrInstruction |
| 15334 | 16761 | zig_unreachable(); |
| 15335 | 16762 | } |
| 15336 | 16763 | |
| 16764 | static void ir_push_resume(IrAnalyze *ira, IrSuspendPosition pos) { |
| 16765 | IrBasicBlock *old_bb = ira->old_irb.exec->basic_block_list.at(pos.basic_block_index); |
| 16766 | if (old_bb->in_resume_stack) return; |
| 16767 | ira->resume_stack.append(pos); |
| 16768 | old_bb->in_resume_stack = true; |
| 16769 | } |
| 16770 | |
| 16771 | static void ir_push_resume_block(IrAnalyze *ira, IrBasicBlock *old_bb) { |
| 16772 | if (ira->resume_stack.length != 0) { |
| 16773 | ir_push_resume(ira, {old_bb->index, 0}); |
| 16774 | } |
| 16775 | } |
| 16776 | |
| 15337 | 16777 | static IrInstruction *ir_analyze_instruction_br(IrAnalyze *ira, IrInstructionBr *br_instruction) { |
| 15338 | 16778 | IrBasicBlock *old_dest_block = br_instruction->dest_block; |
| 15339 | 16779 | |
| ... | ... | @@ -15341,13 +16781,15 @@ static IrInstruction *ir_analyze_instruction_br(IrAnalyze *ira, IrInstructionBr |
| 15341 | 16781 | if (!ir_resolve_comptime(ira, br_instruction->is_comptime->child, &is_comptime)) |
| 15342 | 16782 | return ir_unreach_error(ira); |
| 15343 | 16783 | |
| 15344 | | if (is_comptime || old_dest_block->ref_count == 1) |
| 16784 | if (is_comptime || (old_dest_block->ref_count == 1 && old_dest_block->suspend_instruction_ref == nullptr)) |
| 15345 | 16785 | return ir_inline_bb(ira, &br_instruction->base, old_dest_block); |
| 15346 | 16786 | |
| 15347 | 16787 | IrBasicBlock *new_bb = ir_get_new_bb_runtime(ira, old_dest_block, &br_instruction->base); |
| 15348 | 16788 | if (new_bb == nullptr) |
| 15349 | 16789 | return ir_unreach_error(ira); |
| 15350 | 16790 | |
| 16791 | ir_push_resume_block(ira, old_dest_block); |
| 16792 | |
| 15351 | 16793 | IrInstruction *result = ir_build_br(&ira->new_irb, |
| 15352 | 16794 | br_instruction->base.scope, br_instruction->base.source_node, new_bb, nullptr); |
| 15353 | 16795 | result->value.type = ira->codegen->builtin_types.entry_unreachable; |
| ... | ... | @@ -15376,13 +16818,15 @@ static IrInstruction *ir_analyze_instruction_cond_br(IrAnalyze *ira, IrInstructi |
| 15376 | 16818 | IrBasicBlock *old_dest_block = cond_is_true ? |
| 15377 | 16819 | cond_br_instruction->then_block : cond_br_instruction->else_block; |
| 15378 | 16820 | |
| 15379 | | if (is_comptime || old_dest_block->ref_count == 1) |
| 16821 | if (is_comptime || (old_dest_block->ref_count == 1 && old_dest_block->suspend_instruction_ref == nullptr)) |
| 15380 | 16822 | return ir_inline_bb(ira, &cond_br_instruction->base, old_dest_block); |
| 15381 | 16823 | |
| 15382 | 16824 | IrBasicBlock *new_dest_block = ir_get_new_bb_runtime(ira, old_dest_block, &cond_br_instruction->base); |
| 15383 | 16825 | if (new_dest_block == nullptr) |
| 15384 | 16826 | return ir_unreach_error(ira); |
| 15385 | 16827 | |
| 16828 | ir_push_resume_block(ira, old_dest_block); |
| 16829 | |
| 15386 | 16830 | IrInstruction *result = ir_build_br(&ira->new_irb, |
| 15387 | 16831 | cond_br_instruction->base.scope, cond_br_instruction->base.source_node, new_dest_block, nullptr); |
| 15388 | 16832 | result->value.type = ira->codegen->builtin_types.entry_unreachable; |
| ... | ... | @@ -15398,6 +16842,9 @@ static IrInstruction *ir_analyze_instruction_cond_br(IrAnalyze *ira, IrInstructi |
| 15398 | 16842 | if (new_else_block == nullptr) |
| 15399 | 16843 | return ir_unreach_error(ira); |
| 15400 | 16844 | |
| 16845 | ir_push_resume_block(ira, cond_br_instruction->else_block); |
| 16846 | ir_push_resume_block(ira, cond_br_instruction->then_block); |
| 16847 | |
| 15401 | 16848 | IrInstruction *result = ir_build_cond_br(&ira->new_irb, |
| 15402 | 16849 | cond_br_instruction->base.scope, cond_br_instruction->base.source_node, |
| 15403 | 16850 | casted_condition, new_then_block, new_else_block, nullptr); |
| ... | ... | @@ -15436,6 +16883,80 @@ static IrInstruction *ir_analyze_instruction_phi(IrAnalyze *ira, IrInstructionPh |
| 15436 | 16883 | zig_unreachable(); |
| 15437 | 16884 | } |
| 15438 | 16885 | |
| 16886 | ResultLocPeerParent *peer_parent = phi_instruction->peer_parent; |
| 16887 | if (peer_parent != nullptr && !peer_parent->skipped && !peer_parent->done_resuming && |
| 16888 | peer_parent->peers.length >= 2) |
| 16889 | { |
| 16890 | if (peer_parent->resolved_type == nullptr) { |
| 16891 | IrInstruction **instructions = allocate<IrInstruction *>(peer_parent->peers.length); |
| 16892 | for (size_t i = 0; i < peer_parent->peers.length; i += 1) { |
| 16893 | ResultLocPeer *this_peer = peer_parent->peers.at(i); |
| 16894 | |
| 16895 | IrInstruction *gen_instruction = this_peer->base.gen_instruction; |
| 16896 | if (gen_instruction == nullptr) { |
| 16897 | // unreachable instructions will cause implicit_elem_type to be null |
| 16898 | if (this_peer->base.implicit_elem_type == nullptr) { |
| 16899 | instructions[i] = ir_const_unreachable(ira, this_peer->base.source_instruction); |
| 16900 | } else { |
| 16901 | instructions[i] = ir_const(ira, this_peer->base.source_instruction, |
| 16902 | this_peer->base.implicit_elem_type); |
| 16903 | instructions[i]->value.special = ConstValSpecialRuntime; |
| 16904 | } |
| 16905 | } else { |
| 16906 | instructions[i] = gen_instruction; |
| 16907 | } |
| 16908 | |
| 16909 | } |
| 16910 | ZigType *expected_type = ir_result_loc_expected_type(ira, &phi_instruction->base, peer_parent->parent); |
| 16911 | peer_parent->resolved_type = ir_resolve_peer_types(ira, |
| 16912 | peer_parent->base.source_instruction->source_node, expected_type, instructions, |
| 16913 | peer_parent->peers.length); |
| 16914 | |
| 16915 | // the logic below assumes there are no instructions in the new current basic block yet |
| 16916 | ir_assert(ira->new_irb.current_basic_block->instruction_list.length == 0, &phi_instruction->base); |
| 16917 | |
| 16918 | // In case resolving the parent activates a suspend, do it now |
| 16919 | IrInstruction *parent_result_loc = ir_resolve_result(ira, &phi_instruction->base, peer_parent->parent, |
| 16920 | peer_parent->resolved_type, nullptr, false, false); |
| 16921 | if (parent_result_loc != nullptr && |
| 16922 | (type_is_invalid(parent_result_loc->value.type) || instr_is_unreachable(parent_result_loc))) |
| 16923 | { |
| 16924 | return parent_result_loc; |
| 16925 | } |
| 16926 | // If the above code generated any instructions in the current basic block, we need |
| 16927 | // to move them to the peer parent predecessor. |
| 16928 | ZigList<IrInstruction *> instrs_to_move = {}; |
| 16929 | while (ira->new_irb.current_basic_block->instruction_list.length != 0) { |
| 16930 | instrs_to_move.append(ira->new_irb.current_basic_block->instruction_list.pop()); |
| 16931 | } |
| 16932 | if (instrs_to_move.length != 0) { |
| 16933 | IrBasicBlock *predecessor = peer_parent->base.source_instruction->child->owner_bb; |
| 16934 | IrInstruction *branch_instruction = predecessor->instruction_list.pop(); |
| 16935 | ir_assert(branch_instruction->value.type->id == ZigTypeIdUnreachable, &phi_instruction->base); |
| 16936 | while (instrs_to_move.length != 0) { |
| 16937 | predecessor->instruction_list.append(instrs_to_move.pop()); |
| 16938 | } |
| 16939 | predecessor->instruction_list.append(branch_instruction); |
| 16940 | } |
| 16941 | } |
| 16942 | |
| 16943 | IrSuspendPosition suspend_pos; |
| 16944 | ira_suspend(ira, &phi_instruction->base, nullptr, &suspend_pos); |
| 16945 | ir_push_resume(ira, suspend_pos); |
| 16946 | |
| 16947 | for (size_t i = 0; i < peer_parent->peers.length; i += 1) { |
| 16948 | ResultLocPeer *opposite_peer = peer_parent->peers.at(peer_parent->peers.length - i - 1); |
| 16949 | if (opposite_peer->base.implicit_elem_type != nullptr && |
| 16950 | opposite_peer->base.implicit_elem_type->id != ZigTypeIdUnreachable) |
| 16951 | { |
| 16952 | ir_push_resume(ira, opposite_peer->suspend_pos); |
| 16953 | } |
| 16954 | } |
| 16955 | |
| 16956 | peer_parent->done_resuming = true; |
| 16957 | return ira_resume(ira); |
| 16958 | } |
| 16959 | |
| 15439 | 16960 | ZigList<IrBasicBlock*> new_incoming_blocks = {0}; |
| 15440 | 16961 | ZigList<IrInstruction*> new_incoming_values = {0}; |
| 15441 | 16962 | |
| ... | ... | @@ -15508,7 +17029,7 @@ static IrInstruction *ir_analyze_instruction_phi(IrAnalyze *ira, IrInstructionPh |
| 15508 | 17029 | IrInstruction *branch_instruction = predecessor->instruction_list.pop(); |
| 15509 | 17030 | ir_set_cursor_at_end(&ira->new_irb, predecessor); |
| 15510 | 17031 | IrInstruction *casted_value = ir_implicit_cast(ira, new_value, resolved_type); |
| 15511 | | if (casted_value == ira->codegen->invalid_instruction) { |
| 17032 | if (type_is_invalid(casted_value->value.type)) { |
| 15512 | 17033 | return ira->codegen->invalid_instruction; |
| 15513 | 17034 | } |
| 15514 | 17035 | new_incoming_values.items[i] = casted_value; |
| ... | ... | @@ -15524,7 +17045,7 @@ static IrInstruction *ir_analyze_instruction_phi(IrAnalyze *ira, IrInstructionPh |
| 15524 | 17045 | |
| 15525 | 17046 | IrInstruction *result = ir_build_phi(&ira->new_irb, |
| 15526 | 17047 | phi_instruction->base.scope, phi_instruction->base.source_node, |
| 15527 | | new_incoming_blocks.length, new_incoming_blocks.items, new_incoming_values.items); |
| 17048 | new_incoming_blocks.length, new_incoming_blocks.items, new_incoming_values.items, nullptr); |
| 15528 | 17049 | result->value.type = resolved_type; |
| 15529 | 17050 | |
| 15530 | 17051 | if (all_stack_ptrs) { |
| ... | ... | @@ -15742,6 +17263,52 @@ static IrInstruction *ir_analyze_instruction_elem_ptr(IrAnalyze *ira, IrInstruct |
| 15742 | 17263 | if (array_ptr_val == nullptr) |
| 15743 | 17264 | return ira->codegen->invalid_instruction; |
| 15744 | 17265 | |
| 17266 | if (array_ptr_val->special == ConstValSpecialUndef && elem_ptr_instruction->init_array_type != nullptr) { |
| 17267 | if (array_type->id == ZigTypeIdArray) { |
| 17268 | array_ptr_val->data.x_array.special = ConstArraySpecialNone; |
| 17269 | array_ptr_val->data.x_array.data.s_none.elements = create_const_vals(array_type->data.array.len); |
| 17270 | array_ptr_val->special = ConstValSpecialStatic; |
| 17271 | for (size_t i = 0; i < array_type->data.array.len; i += 1) { |
| 17272 | ConstExprValue *elem_val = &array_ptr_val->data.x_array.data.s_none.elements[i]; |
| 17273 | elem_val->special = ConstValSpecialUndef; |
| 17274 | elem_val->type = array_type->data.array.child_type; |
| 17275 | elem_val->parent.id = ConstParentIdArray; |
| 17276 | elem_val->parent.data.p_array.array_val = array_ptr_val; |
| 17277 | elem_val->parent.data.p_array.elem_index = i; |
| 17278 | } |
| 17279 | } else if (is_slice(array_type)) { |
| 17280 | ZigType *actual_array_type = ir_resolve_type(ira, elem_ptr_instruction->init_array_type->child); |
| 17281 | if (type_is_invalid(actual_array_type)) |
| 17282 | return ira->codegen->invalid_instruction; |
| 17283 | if (actual_array_type->id != ZigTypeIdArray) { |
| 17284 | ir_add_error(ira, elem_ptr_instruction->init_array_type, |
| 17285 | buf_sprintf("expected array type or [_], found slice")); |
| 17286 | return ira->codegen->invalid_instruction; |
| 17287 | } |
| 17288 | |
| 17289 | ConstExprValue *array_init_val = create_const_vals(1); |
| 17290 | array_init_val->special = ConstValSpecialStatic; |
| 17291 | array_init_val->type = actual_array_type; |
| 17292 | array_init_val->data.x_array.special = ConstArraySpecialNone; |
| 17293 | array_init_val->data.x_array.data.s_none.elements = create_const_vals(actual_array_type->data.array.len); |
| 17294 | array_init_val->special = ConstValSpecialStatic; |
| 17295 | for (size_t i = 0; i < actual_array_type->data.array.len; i += 1) { |
| 17296 | ConstExprValue *elem_val = &array_init_val->data.x_array.data.s_none.elements[i]; |
| 17297 | elem_val->special = ConstValSpecialUndef; |
| 17298 | elem_val->type = actual_array_type->data.array.child_type; |
| 17299 | elem_val->parent.id = ConstParentIdArray; |
| 17300 | elem_val->parent.data.p_array.array_val = array_init_val; |
| 17301 | elem_val->parent.data.p_array.elem_index = i; |
| 17302 | } |
| 17303 | |
| 17304 | init_const_slice(ira->codegen, array_ptr_val, array_init_val, 0, actual_array_type->data.array.len, |
| 17305 | false); |
| 17306 | array_ptr_val->data.x_struct.fields[slice_ptr_index].data.x_ptr.mut = ConstPtrMutInfer; |
| 17307 | } else { |
| 17308 | zig_unreachable(); |
| 17309 | } |
| 17310 | } |
| 17311 | |
| 15745 | 17312 | if (array_ptr_val->special != ConstValSpecialRuntime && |
| 15746 | 17313 | (array_type->id != ZigTypeIdPointer || |
| 15747 | 17314 | array_ptr_val->data.x_ptr.special != ConstPtrSpecialHardCodedAddr)) |
| ... | ... | @@ -15807,8 +17374,9 @@ static IrInstruction *ir_analyze_instruction_elem_ptr(IrAnalyze *ira, IrInstruct |
| 15807 | 17374 | } else if (is_slice(array_type)) { |
| 15808 | 17375 | ConstExprValue *ptr_field = &array_ptr_val->data.x_struct.fields[slice_ptr_index]; |
| 15809 | 17376 | if (ptr_field->data.x_ptr.special == ConstPtrSpecialHardCodedAddr) { |
| 15810 | | IrInstruction *result = ir_build_elem_ptr(&ira->new_irb, elem_ptr_instruction->base.scope, elem_ptr_instruction->base.source_node, |
| 15811 | | array_ptr, casted_elem_index, false, elem_ptr_instruction->ptr_len); |
| 17377 | IrInstruction *result = ir_build_elem_ptr(&ira->new_irb, elem_ptr_instruction->base.scope, |
| 17378 | elem_ptr_instruction->base.source_node, array_ptr, casted_elem_index, false, |
| 17379 | elem_ptr_instruction->ptr_len, nullptr); |
| 15812 | 17380 | result->value.type = return_type; |
| 15813 | 17381 | return result; |
| 15814 | 17382 | } |
| ... | ... | @@ -15861,7 +17429,16 @@ static IrInstruction *ir_analyze_instruction_elem_ptr(IrAnalyze *ira, IrInstruct |
| 15861 | 17429 | } |
| 15862 | 17430 | return result; |
| 15863 | 17431 | } else if (array_type->id == ZigTypeIdArray) { |
| 15864 | | IrInstruction *result = ir_const(ira, &elem_ptr_instruction->base, return_type); |
| 17432 | IrInstruction *result; |
| 17433 | if (orig_array_ptr_val->data.x_ptr.mut == ConstPtrMutInfer) { |
| 17434 | result = ir_build_elem_ptr(&ira->new_irb, elem_ptr_instruction->base.scope, |
| 17435 | elem_ptr_instruction->base.source_node, array_ptr, casted_elem_index, |
| 17436 | false, elem_ptr_instruction->ptr_len, elem_ptr_instruction->init_array_type); |
| 17437 | result->value.type = return_type; |
| 17438 | result->value.special = ConstValSpecialStatic; |
| 17439 | } else { |
| 17440 | result = ir_const(ira, &elem_ptr_instruction->base, return_type); |
| 17441 | } |
| 15865 | 17442 | ConstExprValue *out_val = &result->value; |
| 15866 | 17443 | out_val->data.x_ptr.special = ConstPtrSpecialBaseArray; |
| 15867 | 17444 | out_val->data.x_ptr.mut = orig_array_ptr_val->data.x_ptr.mut; |
| ... | ... | @@ -15873,7 +17450,6 @@ static IrInstruction *ir_analyze_instruction_elem_ptr(IrAnalyze *ira, IrInstruct |
| 15873 | 17450 | } |
| 15874 | 17451 | } |
| 15875 | 17452 | } |
| 15876 | | |
| 15877 | 17453 | } else { |
| 15878 | 17454 | // runtime known element index |
| 15879 | 17455 | switch (type_requires_comptime(ira->codegen, return_type)) { |
| ... | ... | @@ -15899,8 +17475,9 @@ static IrInstruction *ir_analyze_instruction_elem_ptr(IrAnalyze *ira, IrInstruct |
| 15899 | 17475 | } |
| 15900 | 17476 | } |
| 15901 | 17477 | |
| 15902 | | IrInstruction *result = ir_build_elem_ptr(&ira->new_irb, elem_ptr_instruction->base.scope, elem_ptr_instruction->base.source_node, |
| 15903 | | array_ptr, casted_elem_index, safety_check_on, elem_ptr_instruction->ptr_len); |
| 17478 | IrInstruction *result = ir_build_elem_ptr(&ira->new_irb, elem_ptr_instruction->base.scope, |
| 17479 | elem_ptr_instruction->base.source_node, array_ptr, casted_elem_index, safety_check_on, |
| 17480 | elem_ptr_instruction->ptr_len, elem_ptr_instruction->init_array_type); |
| 15904 | 17481 | result->value.type = return_type; |
| 15905 | 17482 | return result; |
| 15906 | 17483 | } |
| ... | ... | @@ -15945,8 +17522,80 @@ static IrInstruction *ir_analyze_container_member_access_inner(IrAnalyze *ira, |
| 15945 | 17522 | return ira->codegen->invalid_instruction; |
| 15946 | 17523 | } |
| 15947 | 17524 | |
| 17525 | static IrInstruction *ir_analyze_struct_field_ptr(IrAnalyze *ira, IrInstruction *source_instr, |
| 17526 | TypeStructField *field, IrInstruction *struct_ptr, ZigType *struct_type, bool initializing) |
| 17527 | { |
| 17528 | switch (type_has_one_possible_value(ira->codegen, field->type_entry)) { |
| 17529 | case OnePossibleValueInvalid: |
| 17530 | return ira->codegen->invalid_instruction; |
| 17531 | case OnePossibleValueYes: { |
| 17532 | IrInstruction *elem = ir_const(ira, source_instr, field->type_entry); |
| 17533 | return ir_get_ref(ira, source_instr, elem, false, false); |
| 17534 | } |
| 17535 | case OnePossibleValueNo: |
| 17536 | break; |
| 17537 | } |
| 17538 | assert(struct_ptr->value.type->id == ZigTypeIdPointer); |
| 17539 | bool is_packed = (struct_type->data.structure.layout == ContainerLayoutPacked); |
| 17540 | uint32_t align_bytes = is_packed ? 1 : get_abi_alignment(ira->codegen, field->type_entry); |
| 17541 | uint32_t ptr_bit_offset = struct_ptr->value.type->data.pointer.bit_offset_in_host; |
| 17542 | uint32_t ptr_host_int_bytes = struct_ptr->value.type->data.pointer.host_int_bytes; |
| 17543 | uint32_t host_int_bytes_for_result_type = (ptr_host_int_bytes == 0) ? |
| 17544 | get_host_int_bytes(ira->codegen, struct_type, field) : ptr_host_int_bytes; |
| 17545 | bool is_const = struct_ptr->value.type->data.pointer.is_const; |
| 17546 | bool is_volatile = struct_ptr->value.type->data.pointer.is_volatile; |
| 17547 | ZigType *ptr_type = get_pointer_to_type_extra(ira->codegen, field->type_entry, |
| 17548 | is_const, is_volatile, PtrLenSingle, align_bytes, |
| 17549 | (uint32_t)(ptr_bit_offset + field->bit_offset_in_host), |
| 17550 | (uint32_t)host_int_bytes_for_result_type, false); |
| 17551 | if (instr_is_comptime(struct_ptr)) { |
| 17552 | ConstExprValue *ptr_val = ir_resolve_const(ira, struct_ptr, UndefBad); |
| 17553 | if (!ptr_val) |
| 17554 | return ira->codegen->invalid_instruction; |
| 17555 | |
| 17556 | if (ptr_val->data.x_ptr.special != ConstPtrSpecialHardCodedAddr) { |
| 17557 | ConstExprValue *struct_val = const_ptr_pointee(ira, ira->codegen, ptr_val, source_instr->source_node); |
| 17558 | if (struct_val == nullptr) |
| 17559 | return ira->codegen->invalid_instruction; |
| 17560 | if (type_is_invalid(struct_val->type)) |
| 17561 | return ira->codegen->invalid_instruction; |
| 17562 | if (struct_val->special == ConstValSpecialUndef && initializing) { |
| 17563 | struct_val->data.x_struct.fields = create_const_vals(struct_type->data.structure.src_field_count); |
| 17564 | struct_val->special = ConstValSpecialStatic; |
| 17565 | for (size_t i = 0; i < struct_type->data.structure.src_field_count; i += 1) { |
| 17566 | ConstExprValue *field_val = &struct_val->data.x_struct.fields[i]; |
| 17567 | field_val->special = ConstValSpecialUndef; |
| 17568 | field_val->type = struct_type->data.structure.fields[i].type_entry; |
| 17569 | field_val->parent.id = ConstParentIdStruct; |
| 17570 | field_val->parent.data.p_struct.struct_val = struct_val; |
| 17571 | field_val->parent.data.p_struct.field_index = i; |
| 17572 | } |
| 17573 | } |
| 17574 | IrInstruction *result; |
| 17575 | if (ptr_val->data.x_ptr.mut == ConstPtrMutInfer) { |
| 17576 | result = ir_build_struct_field_ptr(&ira->new_irb, source_instr->scope, |
| 17577 | source_instr->source_node, struct_ptr, field); |
| 17578 | result->value.type = ptr_type; |
| 17579 | result->value.special = ConstValSpecialStatic; |
| 17580 | } else { |
| 17581 | result = ir_const(ira, source_instr, ptr_type); |
| 17582 | } |
| 17583 | ConstExprValue *const_val = &result->value; |
| 17584 | const_val->data.x_ptr.special = ConstPtrSpecialBaseStruct; |
| 17585 | const_val->data.x_ptr.mut = ptr_val->data.x_ptr.mut; |
| 17586 | const_val->data.x_ptr.data.base_struct.struct_val = struct_val; |
| 17587 | const_val->data.x_ptr.data.base_struct.field_index = field->src_index; |
| 17588 | return result; |
| 17589 | } |
| 17590 | } |
| 17591 | IrInstruction *result = ir_build_struct_field_ptr(&ira->new_irb, source_instr->scope, source_instr->source_node, |
| 17592 | struct_ptr, field); |
| 17593 | result->value.type = ptr_type; |
| 17594 | return result; |
| 17595 | } |
| 17596 | |
| 15948 | 17597 | static IrInstruction *ir_analyze_container_field_ptr(IrAnalyze *ira, Buf *field_name, |
| 15949 | | IrInstruction *source_instr, IrInstruction *container_ptr, ZigType *container_type) |
| 17598 | IrInstruction *source_instr, IrInstruction *container_ptr, ZigType *container_type, bool initializing) |
| 15950 | 17599 | { |
| 15951 | 17600 | Error err; |
| 15952 | 17601 | |
| ... | ... | @@ -15955,81 +17604,55 @@ static IrInstruction *ir_analyze_container_field_ptr(IrAnalyze *ira, Buf *field_ |
| 15955 | 17604 | return ira->codegen->invalid_instruction; |
| 15956 | 17605 | |
| 15957 | 17606 | assert(container_ptr->value.type->id == ZigTypeIdPointer); |
| 15958 | | bool is_const = container_ptr->value.type->data.pointer.is_const; |
| 15959 | | bool is_volatile = container_ptr->value.type->data.pointer.is_volatile; |
| 15960 | 17607 | if (bare_type->id == ZigTypeIdStruct) { |
| 15961 | 17608 | TypeStructField *field = find_struct_type_field(bare_type, field_name); |
| 15962 | | if (field) { |
| 15963 | | switch (type_has_one_possible_value(ira->codegen, field->type_entry)) { |
| 15964 | | case OnePossibleValueInvalid: |
| 15965 | | return ira->codegen->invalid_instruction; |
| 15966 | | case OnePossibleValueYes: { |
| 15967 | | IrInstruction *elem = ir_const(ira, source_instr, field->type_entry); |
| 15968 | | return ir_get_ref(ira, source_instr, elem, false, false); |
| 15969 | | } |
| 15970 | | case OnePossibleValueNo: |
| 15971 | | break; |
| 15972 | | } |
| 15973 | | bool is_packed = (bare_type->data.structure.layout == ContainerLayoutPacked); |
| 15974 | | uint32_t align_bytes = is_packed ? 1 : get_abi_alignment(ira->codegen, field->type_entry); |
| 15975 | | uint32_t ptr_bit_offset = container_ptr->value.type->data.pointer.bit_offset_in_host; |
| 15976 | | uint32_t ptr_host_int_bytes = container_ptr->value.type->data.pointer.host_int_bytes; |
| 15977 | | uint32_t host_int_bytes_for_result_type = (ptr_host_int_bytes == 0) ? |
| 15978 | | get_host_int_bytes(ira->codegen, bare_type, field) : ptr_host_int_bytes; |
| 15979 | | if (instr_is_comptime(container_ptr)) { |
| 15980 | | ConstExprValue *ptr_val = ir_resolve_const(ira, container_ptr, UndefBad); |
| 15981 | | if (!ptr_val) |
| 15982 | | return ira->codegen->invalid_instruction; |
| 15983 | | |
| 15984 | | if (ptr_val->data.x_ptr.special != ConstPtrSpecialHardCodedAddr) { |
| 15985 | | ConstExprValue *struct_val = const_ptr_pointee(ira, ira->codegen, ptr_val, source_instr->source_node); |
| 15986 | | if (struct_val == nullptr) |
| 15987 | | return ira->codegen->invalid_instruction; |
| 15988 | | if (type_is_invalid(struct_val->type)) |
| 15989 | | return ira->codegen->invalid_instruction; |
| 15990 | | ZigType *ptr_type = get_pointer_to_type_extra(ira->codegen, field->type_entry, |
| 15991 | | is_const, is_volatile, PtrLenSingle, align_bytes, |
| 15992 | | (uint32_t)(ptr_bit_offset + field->bit_offset_in_host), |
| 15993 | | (uint32_t)host_int_bytes_for_result_type, false); |
| 15994 | | IrInstruction *result = ir_const(ira, source_instr, ptr_type); |
| 15995 | | ConstExprValue *const_val = &result->value; |
| 15996 | | const_val->data.x_ptr.special = ConstPtrSpecialBaseStruct; |
| 15997 | | const_val->data.x_ptr.mut = container_ptr->value.data.x_ptr.mut; |
| 15998 | | const_val->data.x_ptr.data.base_struct.struct_val = struct_val; |
| 15999 | | const_val->data.x_ptr.data.base_struct.field_index = field->src_index; |
| 16000 | | return result; |
| 16001 | | } |
| 16002 | | } |
| 16003 | | IrInstruction *result = ir_build_struct_field_ptr(&ira->new_irb, source_instr->scope, source_instr->source_node, |
| 16004 | | container_ptr, field); |
| 16005 | | result->value.type = get_pointer_to_type_extra(ira->codegen, field->type_entry, is_const, is_volatile, |
| 16006 | | PtrLenSingle, |
| 16007 | | align_bytes, |
| 16008 | | (uint32_t)(ptr_bit_offset + field->bit_offset_in_host), |
| 16009 | | host_int_bytes_for_result_type, false); |
| 16010 | | return result; |
| 17609 | if (field != nullptr) { |
| 17610 | return ir_analyze_struct_field_ptr(ira, source_instr, field, container_ptr, bare_type, initializing); |
| 16011 | 17611 | } else { |
| 16012 | 17612 | return ir_analyze_container_member_access_inner(ira, bare_type, field_name, |
| 16013 | 17613 | source_instr, container_ptr, container_type); |
| 16014 | 17614 | } |
| 16015 | | } else if (bare_type->id == ZigTypeIdEnum) { |
| 17615 | } |
| 17616 | |
| 17617 | if (bare_type->id == ZigTypeIdEnum) { |
| 16016 | 17618 | return ir_analyze_container_member_access_inner(ira, bare_type, field_name, |
| 16017 | 17619 | source_instr, container_ptr, container_type); |
| 16018 | | } else if (bare_type->id == ZigTypeIdUnion) { |
| 17620 | } |
| 17621 | |
| 17622 | if (bare_type->id == ZigTypeIdUnion) { |
| 17623 | bool is_const = container_ptr->value.type->data.pointer.is_const; |
| 17624 | bool is_volatile = container_ptr->value.type->data.pointer.is_volatile; |
| 17625 | |
| 16019 | 17626 | TypeUnionField *field = find_union_type_field(bare_type, field_name); |
| 16020 | | if (field) { |
| 16021 | | if (instr_is_comptime(container_ptr)) { |
| 16022 | | ConstExprValue *ptr_val = ir_resolve_const(ira, container_ptr, UndefBad); |
| 16023 | | if (!ptr_val) |
| 17627 | if (field == nullptr) { |
| 17628 | return ir_analyze_container_member_access_inner(ira, bare_type, field_name, |
| 17629 | source_instr, container_ptr, container_type); |
| 17630 | } |
| 17631 | ZigType *ptr_type = get_pointer_to_type_extra(ira->codegen, field->type_entry, |
| 17632 | is_const, is_volatile, PtrLenSingle, 0, 0, 0, false); |
| 17633 | if (instr_is_comptime(container_ptr)) { |
| 17634 | ConstExprValue *ptr_val = ir_resolve_const(ira, container_ptr, UndefBad); |
| 17635 | if (!ptr_val) |
| 17636 | return ira->codegen->invalid_instruction; |
| 17637 | |
| 17638 | if (ptr_val->data.x_ptr.special != ConstPtrSpecialHardCodedAddr) { |
| 17639 | ConstExprValue *union_val = const_ptr_pointee(ira, ira->codegen, ptr_val, source_instr->source_node); |
| 17640 | if (union_val == nullptr) |
| 17641 | return ira->codegen->invalid_instruction; |
| 17642 | if (type_is_invalid(union_val->type)) |
| 16024 | 17643 | return ira->codegen->invalid_instruction; |
| 16025 | 17644 | |
| 16026 | | if (ptr_val->data.x_ptr.special != ConstPtrSpecialHardCodedAddr) { |
| 16027 | | ConstExprValue *union_val = const_ptr_pointee(ira, ira->codegen, ptr_val, source_instr->source_node); |
| 16028 | | if (union_val == nullptr) |
| 16029 | | return ira->codegen->invalid_instruction; |
| 16030 | | if (type_is_invalid(union_val->type)) |
| 16031 | | return ira->codegen->invalid_instruction; |
| 17645 | if (initializing) { |
| 17646 | ConstExprValue *payload_val = create_const_vals(1); |
| 17647 | payload_val->special = ConstValSpecialUndef; |
| 17648 | payload_val->type = field->type_entry; |
| 17649 | payload_val->parent.id = ConstParentIdUnion; |
| 17650 | payload_val->parent.data.p_union.union_val = union_val; |
| 16032 | 17651 | |
| 17652 | union_val->special = ConstValSpecialStatic; |
| 17653 | bigint_init_bigint(&union_val->data.x_union.tag, &field->enum_field->value); |
| 17654 | union_val->data.x_union.payload = payload_val; |
| 17655 | } else { |
| 16033 | 17656 | TypeUnionField *actual_field = find_union_field_by_tag(bare_type, &union_val->data.x_union.tag); |
| 16034 | 17657 | if (actual_field == nullptr) |
| 16035 | 17658 | zig_unreachable(); |
| ... | ... | @@ -16040,33 +17663,35 @@ static IrInstruction *ir_analyze_container_field_ptr(IrAnalyze *ira, Buf *field_ |
| 16040 | 17663 | buf_ptr(actual_field->name))); |
| 16041 | 17664 | return ira->codegen->invalid_instruction; |
| 16042 | 17665 | } |
| 17666 | } |
| 16043 | 17667 | |
| 16044 | | ConstExprValue *payload_val = union_val->data.x_union.payload; |
| 17668 | ConstExprValue *payload_val = union_val->data.x_union.payload; |
| 16045 | 17669 | |
| 16046 | | ZigType *field_type = field->type_entry; |
| 16047 | | ZigType *ptr_type = get_pointer_to_type_extra(ira->codegen, field_type, |
| 16048 | | is_const, is_volatile, PtrLenSingle, 0, 0, 0, false); |
| 16049 | 17670 | |
| 16050 | | IrInstruction *result = ir_const(ira, source_instr, ptr_type); |
| 16051 | | ConstExprValue *const_val = &result->value; |
| 16052 | | const_val->data.x_ptr.special = ConstPtrSpecialRef; |
| 16053 | | const_val->data.x_ptr.mut = container_ptr->value.data.x_ptr.mut; |
| 16054 | | const_val->data.x_ptr.data.ref.pointee = payload_val; |
| 16055 | | return result; |
| 17671 | IrInstruction *result; |
| 17672 | if (ptr_val->data.x_ptr.mut == ConstPtrMutInfer) { |
| 17673 | result = ir_build_union_field_ptr(&ira->new_irb, source_instr->scope, |
| 17674 | source_instr->source_node, container_ptr, field, true, initializing); |
| 17675 | result->value.type = ptr_type; |
| 17676 | result->value.special = ConstValSpecialStatic; |
| 17677 | } else { |
| 17678 | result = ir_const(ira, source_instr, ptr_type); |
| 16056 | 17679 | } |
| 17680 | ConstExprValue *const_val = &result->value; |
| 17681 | const_val->data.x_ptr.special = ConstPtrSpecialRef; |
| 17682 | const_val->data.x_ptr.mut = container_ptr->value.data.x_ptr.mut; |
| 17683 | const_val->data.x_ptr.data.ref.pointee = payload_val; |
| 17684 | return result; |
| 16057 | 17685 | } |
| 16058 | | |
| 16059 | | IrInstruction *result = ir_build_union_field_ptr(&ira->new_irb, source_instr->scope, source_instr->source_node, container_ptr, field); |
| 16060 | | result->value.type = get_pointer_to_type_extra(ira->codegen, field->type_entry, is_const, is_volatile, |
| 16061 | | PtrLenSingle, 0, 0, 0, false); |
| 16062 | | return result; |
| 16063 | | } else { |
| 16064 | | return ir_analyze_container_member_access_inner(ira, bare_type, field_name, |
| 16065 | | source_instr, container_ptr, container_type); |
| 16066 | 17686 | } |
| 16067 | | } else { |
| 16068 | | zig_unreachable(); |
| 17687 | |
| 17688 | IrInstruction *result = ir_build_union_field_ptr(&ira->new_irb, source_instr->scope, |
| 17689 | source_instr->source_node, container_ptr, field, true, initializing); |
| 17690 | result->value.type = ptr_type; |
| 17691 | return result; |
| 16069 | 17692 | } |
| 17693 | |
| 17694 | zig_unreachable(); |
| 16070 | 17695 | } |
| 16071 | 17696 | |
| 16072 | 17697 | static void add_link_lib_symbol(IrAnalyze *ira, Buf *lib_name, Buf *symbol_name, AstNode *source_node) { |
| ... | ... | @@ -16104,6 +17729,11 @@ static void add_link_lib_symbol(IrAnalyze *ira, Buf *lib_name, Buf *symbol_name, |
| 16104 | 17729 | link_lib->symbols.append(symbol_name); |
| 16105 | 17730 | } |
| 16106 | 17731 | |
| 17732 | static IrInstruction *ir_error_dependency_loop(IrAnalyze *ira, IrInstruction *source_instr) { |
| 17733 | ErrorMsg *msg = ir_add_error(ira, source_instr, buf_sprintf("dependency loop detected")); |
| 17734 | emit_error_notes_for_ref_stack(ira->codegen, msg); |
| 17735 | return ira->codegen->invalid_instruction; |
| 17736 | } |
| 16107 | 17737 | |
| 16108 | 17738 | static IrInstruction *ir_analyze_decl_ref(IrAnalyze *ira, IrInstruction *source_instruction, Tld *tld) { |
| 16109 | 17739 | resolve_top_level_decl(ira->codegen, tld, source_instruction->source_node); |
| ... | ... | @@ -16118,6 +17748,9 @@ static IrInstruction *ir_analyze_decl_ref(IrAnalyze *ira, IrInstruction *source_ |
| 16118 | 17748 | { |
| 16119 | 17749 | TldVar *tld_var = (TldVar *)tld; |
| 16120 | 17750 | ZigVar *var = tld_var->var; |
| 17751 | if (var == nullptr) { |
| 17752 | return ir_error_dependency_loop(ira, source_instruction); |
| 17753 | } |
| 16121 | 17754 | if (tld_var->extern_lib_name != nullptr) { |
| 16122 | 17755 | add_link_lib_symbol(ira, tld_var->extern_lib_name, &var->name, source_instruction->source_node); |
| 16123 | 17756 | } |
| ... | ... | @@ -16133,23 +17766,13 @@ static IrInstruction *ir_analyze_decl_ref(IrAnalyze *ira, IrInstruction *source_ |
| 16133 | 17766 | if (type_is_invalid(fn_entry->type_entry)) |
| 16134 | 17767 | return ira->codegen->invalid_instruction; |
| 16135 | 17768 | |
| 16136 | | // TODO instead of allocating this every time, put it in the tld value and we can reference |
| 16137 | | // the same one every time |
| 16138 | | ConstExprValue *const_val = create_const_vals(1); |
| 16139 | | const_val->special = ConstValSpecialStatic; |
| 16140 | | const_val->type = fn_entry->type_entry; |
| 16141 | | const_val->data.x_ptr.data.fn.fn_entry = fn_entry; |
| 16142 | | const_val->data.x_ptr.special = ConstPtrSpecialFunction; |
| 16143 | | const_val->data.x_ptr.mut = ConstPtrMutComptimeConst; |
| 16144 | | |
| 16145 | 17769 | if (tld_fn->extern_lib_name != nullptr) { |
| 16146 | 17770 | add_link_lib_symbol(ira, tld_fn->extern_lib_name, &fn_entry->symbol_name, source_instruction->source_node); |
| 16147 | 17771 | } |
| 16148 | 17772 | |
| 16149 | | bool ptr_is_const = true; |
| 16150 | | bool ptr_is_volatile = false; |
| 16151 | | return ir_get_const_ptr(ira, source_instruction, const_val, fn_entry->type_entry, |
| 16152 | | ConstPtrMutComptimeConst, ptr_is_const, ptr_is_volatile, 0); |
| 17773 | IrInstruction *fn_inst = ir_create_const_fn(&ira->new_irb, source_instruction->scope, |
| 17774 | source_instruction->source_node, fn_entry); |
| 17775 | return ir_get_ref(ira, source_instruction, fn_inst, true, false); |
| 16153 | 17776 | } |
| 16154 | 17777 | } |
| 16155 | 17778 | zig_unreachable(); |
| ... | ... | @@ -16191,14 +17814,14 @@ static IrInstruction *ir_analyze_instruction_field_ptr(IrAnalyze *ira, IrInstruc |
| 16191 | 17814 | assert(container_ptr->value.type->id == ZigTypeIdPointer); |
| 16192 | 17815 | if (container_type->id == ZigTypeIdPointer) { |
| 16193 | 17816 | ZigType *bare_type = container_ref_type(container_type); |
| 16194 | | IrInstruction *container_child = ir_get_deref(ira, &field_ptr_instruction->base, container_ptr); |
| 16195 | | IrInstruction *result = ir_analyze_container_field_ptr(ira, field_name, &field_ptr_instruction->base, container_child, bare_type); |
| 17817 | IrInstruction *container_child = ir_get_deref(ira, &field_ptr_instruction->base, container_ptr, nullptr); |
| 17818 | IrInstruction *result = ir_analyze_container_field_ptr(ira, field_name, &field_ptr_instruction->base, container_child, bare_type, field_ptr_instruction->initializing); |
| 16196 | 17819 | return result; |
| 16197 | 17820 | } else { |
| 16198 | | IrInstruction *result = ir_analyze_container_field_ptr(ira, field_name, &field_ptr_instruction->base, container_ptr, container_type); |
| 17821 | IrInstruction *result = ir_analyze_container_field_ptr(ira, field_name, &field_ptr_instruction->base, container_ptr, container_type, field_ptr_instruction->initializing); |
| 16199 | 17822 | return result; |
| 16200 | 17823 | } |
| 16201 | | } else if (is_array_ref(container_type)) { |
| 17824 | } else if (is_array_ref(container_type) && !field_ptr_instruction->initializing) { |
| 16202 | 17825 | if (buf_eql_str(field_name, "len")) { |
| 16203 | 17826 | ConstExprValue *len_val = create_const_vals(1); |
| 16204 | 17827 | if (container_type->id == ZigTypeIdPointer) { |
| ... | ... | @@ -16513,6 +18136,10 @@ static IrInstruction *ir_analyze_instruction_field_ptr(IrAnalyze *ira, IrInstruc |
| 16513 | 18136 | buf_sprintf("type '%s' does not support field access", buf_ptr(&child_type->name))); |
| 16514 | 18137 | return ira->codegen->invalid_instruction; |
| 16515 | 18138 | } |
| 18139 | } else if (field_ptr_instruction->initializing) { |
| 18140 | ir_add_error(ira, &field_ptr_instruction->base, |
| 18141 | buf_sprintf("type '%s' does not support struct initialization syntax", buf_ptr(&container_type->name))); |
| 18142 | return ira->codegen->invalid_instruction; |
| 16516 | 18143 | } else { |
| 16517 | 18144 | ir_add_error_node(ira, field_ptr_instruction->base.source_node, |
| 16518 | 18145 | buf_sprintf("type '%s' does not support field access", buf_ptr(&container_type->name))); |
| ... | ... | @@ -16536,7 +18163,7 @@ static IrInstruction *ir_analyze_instruction_load_ptr(IrAnalyze *ira, IrInstruct |
| 16536 | 18163 | IrInstruction *ptr = instruction->ptr->child; |
| 16537 | 18164 | if (type_is_invalid(ptr->value.type)) |
| 16538 | 18165 | return ira->codegen->invalid_instruction; |
| 16539 | | return ir_get_deref(ira, &instruction->base, ptr); |
| 18166 | return ir_get_deref(ira, &instruction->base, ptr, nullptr); |
| 16540 | 18167 | } |
| 16541 | 18168 | |
| 16542 | 18169 | static IrInstruction *ir_analyze_instruction_typeof(IrAnalyze *ira, IrInstructionTypeOf *typeof_instruction) { |
| ... | ... | @@ -16547,64 +18174,6 @@ static IrInstruction *ir_analyze_instruction_typeof(IrAnalyze *ira, IrInstructio |
| 16547 | 18174 | return ir_const_type(ira, &typeof_instruction->base, type_entry); |
| 16548 | 18175 | } |
| 16549 | 18176 | |
| 16550 | | static IrInstruction *ir_analyze_instruction_to_ptr_type(IrAnalyze *ira, |
| 16551 | | IrInstructionToPtrType *to_ptr_type_instruction) |
| 16552 | | { |
| 16553 | | Error err; |
| 16554 | | IrInstruction *ptr_ptr = to_ptr_type_instruction->ptr->child; |
| 16555 | | if (type_is_invalid(ptr_ptr->value.type)) |
| 16556 | | return ira->codegen->invalid_instruction; |
| 16557 | | |
| 16558 | | ZigType *ptr_ptr_type = ptr_ptr->value.type; |
| 16559 | | assert(ptr_ptr_type->id == ZigTypeIdPointer); |
| 16560 | | ZigType *type_entry = ptr_ptr_type->data.pointer.child_type; |
| 16561 | | |
| 16562 | | ZigType *ptr_type; |
| 16563 | | if (type_entry->id == ZigTypeIdArray) { |
| 16564 | | ptr_type = get_pointer_to_type(ira->codegen, type_entry->data.array.child_type, ptr_ptr_type->data.pointer.is_const); |
| 16565 | | } else if (is_array_ref(type_entry)) { |
| 16566 | | ptr_type = get_pointer_to_type(ira->codegen, |
| 16567 | | type_entry->data.pointer.child_type->data.array.child_type, type_entry->data.pointer.is_const); |
| 16568 | | } else if (is_slice(type_entry)) { |
| 16569 | | ZigType *slice_ptr_type = type_entry->data.structure.fields[0].type_entry; |
| 16570 | | ptr_type = adjust_ptr_len(ira->codegen, slice_ptr_type, PtrLenSingle); |
| 16571 | | // If the pointer is over-aligned, we may have to reduce it based on the alignment of the element type. |
| 16572 | | if (slice_ptr_type->data.pointer.explicit_alignment != 0) { |
| 16573 | | ZigType *elem_type = slice_ptr_type->data.pointer.child_type; |
| 16574 | | if ((err = type_resolve(ira->codegen, elem_type, ResolveStatusAlignmentKnown))) |
| 16575 | | return ira->codegen->invalid_instruction; |
| 16576 | | uint32_t elem_align = get_abi_alignment(ira->codegen, elem_type); |
| 16577 | | uint32_t reduced_align = min(elem_align, slice_ptr_type->data.pointer.explicit_alignment); |
| 16578 | | ptr_type = adjust_ptr_align(ira->codegen, ptr_type, reduced_align); |
| 16579 | | } |
| 16580 | | } else if (type_entry->id == ZigTypeIdArgTuple) { |
| 16581 | | zig_panic("TODO for loop on var args"); |
| 16582 | | } else { |
| 16583 | | ir_add_error_node(ira, to_ptr_type_instruction->base.source_node, |
| 16584 | | buf_sprintf("expected array type, found '%s'", buf_ptr(&type_entry->name))); |
| 16585 | | return ira->codegen->invalid_instruction; |
| 16586 | | } |
| 16587 | | |
| 16588 | | return ir_const_type(ira, &to_ptr_type_instruction->base, ptr_type); |
| 16589 | | } |
| 16590 | | |
| 16591 | | static IrInstruction *ir_analyze_instruction_ptr_type_child(IrAnalyze *ira, |
| 16592 | | IrInstructionPtrTypeChild *ptr_type_child_instruction) |
| 16593 | | { |
| 16594 | | IrInstruction *type_value = ptr_type_child_instruction->value->child; |
| 16595 | | ZigType *type_entry = ir_resolve_type(ira, type_value); |
| 16596 | | if (type_is_invalid(type_entry)) |
| 16597 | | return ira->codegen->invalid_instruction; |
| 16598 | | |
| 16599 | | if (type_entry->id != ZigTypeIdPointer) { |
| 16600 | | ir_add_error_node(ira, ptr_type_child_instruction->base.source_node, |
| 16601 | | buf_sprintf("expected pointer type, found '%s'", buf_ptr(&type_entry->name))); |
| 16602 | | return ira->codegen->invalid_instruction; |
| 16603 | | } |
| 16604 | | |
| 16605 | | return ir_const_type(ira, &ptr_type_child_instruction->base, type_entry->data.pointer.child_type); |
| 16606 | | } |
| 16607 | | |
| 16608 | 18177 | static IrInstruction *ir_analyze_instruction_set_cold(IrAnalyze *ira, IrInstructionSetCold *instruction) { |
| 16609 | 18178 | if (ira->new_irb.exec->is_inline) { |
| 16610 | 18179 | // ignore setCold when running functions at compile time |
| ... | ... | @@ -17034,7 +18603,7 @@ static IrInstruction *ir_analyze_instruction_test_non_null(IrAnalyze *ira, IrIns |
| 17034 | 18603 | } |
| 17035 | 18604 | |
| 17036 | 18605 | static IrInstruction *ir_analyze_unwrap_optional_payload(IrAnalyze *ira, IrInstruction *source_instr, |
| 17037 | | IrInstruction *base_ptr, bool safety_check_on) |
| 18606 | IrInstruction *base_ptr, bool safety_check_on, bool initializing) |
| 17038 | 18607 | { |
| 17039 | 18608 | ZigType *ptr_type = base_ptr->value.type; |
| 17040 | 18609 | assert(ptr_type->id == ZigTypeIdPointer); |
| ... | ... | @@ -17064,7 +18633,7 @@ static IrInstruction *ir_analyze_unwrap_optional_payload(IrAnalyze *ira, IrInstr |
| 17064 | 18633 | } |
| 17065 | 18634 | if (!safety_check_on) |
| 17066 | 18635 | return base_ptr; |
| 17067 | | IrInstruction *c_ptr_val = ir_get_deref(ira, source_instr, base_ptr); |
| 18636 | IrInstruction *c_ptr_val = ir_get_deref(ira, source_instr, base_ptr, nullptr); |
| 17068 | 18637 | ir_build_assert_non_null(ira, source_instr, c_ptr_val); |
| 17069 | 18638 | return base_ptr; |
| 17070 | 18639 | } |
| ... | ... | @@ -17079,34 +18648,84 @@ static IrInstruction *ir_analyze_unwrap_optional_payload(IrAnalyze *ira, IrInstr |
| 17079 | 18648 | ZigType *result_type = get_pointer_to_type_extra(ira->codegen, child_type, |
| 17080 | 18649 | ptr_type->data.pointer.is_const, ptr_type->data.pointer.is_volatile, PtrLenSingle, 0, 0, 0, false); |
| 17081 | 18650 | |
| 18651 | bool same_comptime_repr = types_have_same_zig_comptime_repr(type_entry, child_type); |
| 18652 | |
| 17082 | 18653 | if (instr_is_comptime(base_ptr)) { |
| 17083 | | ConstExprValue *val = ir_resolve_const(ira, base_ptr, UndefBad); |
| 17084 | | if (!val) |
| 18654 | ConstExprValue *ptr_val = ir_resolve_const(ira, base_ptr, UndefBad); |
| 18655 | if (!ptr_val) |
| 17085 | 18656 | return ira->codegen->invalid_instruction; |
| 17086 | | if (val->data.x_ptr.mut != ConstPtrMutRuntimeVar) { |
| 17087 | | ConstExprValue *maybe_val = const_ptr_pointee(ira, ira->codegen, val, source_instr->source_node); |
| 17088 | | if (maybe_val == nullptr) |
| 18657 | if (ptr_val->data.x_ptr.mut != ConstPtrMutRuntimeVar) { |
| 18658 | ConstExprValue *optional_val = const_ptr_pointee(ira, ira->codegen, ptr_val, source_instr->source_node); |
| 18659 | if (optional_val == nullptr) |
| 17089 | 18660 | return ira->codegen->invalid_instruction; |
| 17090 | 18661 | |
| 17091 | | if (optional_value_is_null(maybe_val)) { |
| 18662 | if (initializing && optional_val->special == ConstValSpecialUndef) { |
| 18663 | switch (type_has_one_possible_value(ira->codegen, child_type)) { |
| 18664 | case OnePossibleValueInvalid: |
| 18665 | return ira->codegen->invalid_instruction; |
| 18666 | case OnePossibleValueNo: |
| 18667 | if (!same_comptime_repr) { |
| 18668 | ConstExprValue *payload_val = create_const_vals(1); |
| 18669 | payload_val->type = child_type; |
| 18670 | payload_val->special = ConstValSpecialUndef; |
| 18671 | payload_val->parent.id = ConstParentIdOptionalPayload; |
| 18672 | payload_val->parent.data.p_optional_payload.optional_val = optional_val; |
| 18673 | |
| 18674 | optional_val->data.x_optional = payload_val; |
| 18675 | optional_val->special = ConstValSpecialStatic; |
| 18676 | } |
| 18677 | break; |
| 18678 | case OnePossibleValueYes: { |
| 18679 | ConstExprValue *pointee = create_const_vals(1); |
| 18680 | pointee->special = ConstValSpecialStatic; |
| 18681 | pointee->type = child_type; |
| 18682 | pointee->parent.id = ConstParentIdOptionalPayload; |
| 18683 | pointee->parent.data.p_optional_payload.optional_val = optional_val; |
| 18684 | |
| 18685 | optional_val->special = ConstValSpecialStatic; |
| 18686 | optional_val->data.x_optional = pointee; |
| 18687 | break; |
| 18688 | } |
| 18689 | } |
| 18690 | } else if (optional_value_is_null(optional_val)) { |
| 17092 | 18691 | ir_add_error(ira, source_instr, buf_sprintf("unable to unwrap null")); |
| 17093 | 18692 | return ira->codegen->invalid_instruction; |
| 17094 | 18693 | } |
| 17095 | | IrInstruction *result = ir_const(ira, source_instr, result_type); |
| 17096 | | ConstExprValue *out_val = &result->value; |
| 17097 | | out_val->data.x_ptr.special = ConstPtrSpecialRef; |
| 17098 | | out_val->data.x_ptr.mut = val->data.x_ptr.mut; |
| 17099 | | if (types_have_same_zig_comptime_repr(type_entry, child_type)) { |
| 17100 | | out_val->data.x_ptr.data.ref.pointee = maybe_val; |
| 18694 | |
| 18695 | IrInstruction *result; |
| 18696 | if (ptr_val->data.x_ptr.mut == ConstPtrMutInfer) { |
| 18697 | result = ir_build_optional_unwrap_ptr(&ira->new_irb, source_instr->scope, |
| 18698 | source_instr->source_node, base_ptr, false, initializing); |
| 18699 | result->value.type = result_type; |
| 18700 | result->value.special = ConstValSpecialStatic; |
| 17101 | 18701 | } else { |
| 17102 | | out_val->data.x_ptr.data.ref.pointee = maybe_val->data.x_optional; |
| 18702 | result = ir_const(ira, source_instr, result_type); |
| 18703 | } |
| 18704 | ConstExprValue *result_val = &result->value; |
| 18705 | result_val->data.x_ptr.special = ConstPtrSpecialRef; |
| 18706 | result_val->data.x_ptr.mut = ptr_val->data.x_ptr.mut; |
| 18707 | switch (type_has_one_possible_value(ira->codegen, child_type)) { |
| 18708 | case OnePossibleValueInvalid: |
| 18709 | return ira->codegen->invalid_instruction; |
| 18710 | case OnePossibleValueNo: |
| 18711 | if (same_comptime_repr) { |
| 18712 | result_val->data.x_ptr.data.ref.pointee = optional_val; |
| 18713 | } else { |
| 18714 | assert(optional_val->data.x_optional != nullptr); |
| 18715 | result_val->data.x_ptr.data.ref.pointee = optional_val->data.x_optional; |
| 18716 | } |
| 18717 | break; |
| 18718 | case OnePossibleValueYes: |
| 18719 | assert(optional_val->data.x_optional != nullptr); |
| 18720 | result_val->data.x_ptr.data.ref.pointee = optional_val->data.x_optional; |
| 18721 | break; |
| 17103 | 18722 | } |
| 17104 | 18723 | return result; |
| 17105 | 18724 | } |
| 17106 | 18725 | } |
| 17107 | 18726 | |
| 17108 | 18727 | IrInstruction *result = ir_build_optional_unwrap_ptr(&ira->new_irb, source_instr->scope, |
| 17109 | | source_instr->source_node, base_ptr, safety_check_on); |
| 18728 | source_instr->source_node, base_ptr, safety_check_on, initializing); |
| 17110 | 18729 | result->value.type = result_type; |
| 17111 | 18730 | return result; |
| 17112 | 18731 | } |
| ... | ... | @@ -17118,7 +18737,8 @@ static IrInstruction *ir_analyze_instruction_optional_unwrap_ptr(IrAnalyze *ira, |
| 17118 | 18737 | if (type_is_invalid(base_ptr->value.type)) |
| 17119 | 18738 | return ira->codegen->invalid_instruction; |
| 17120 | 18739 | |
| 17121 | | return ir_analyze_unwrap_optional_payload(ira, &instruction->base, base_ptr, instruction->safety_check_on); |
| 18740 | return ir_analyze_unwrap_optional_payload(ira, &instruction->base, base_ptr, |
| 18741 | instruction->safety_check_on, false); |
| 17122 | 18742 | } |
| 17123 | 18743 | |
| 17124 | 18744 | static IrInstruction *ir_analyze_instruction_ctz(IrAnalyze *ira, IrInstructionCtz *instruction) { |
| ... | ... | @@ -17419,7 +19039,7 @@ static IrInstruction *ir_analyze_instruction_switch_target(IrAnalyze *ira, |
| 17419 | 19039 | return result; |
| 17420 | 19040 | } |
| 17421 | 19041 | |
| 17422 | | IrInstruction *result = ir_get_deref(ira, &switch_target_instruction->base, target_value_ptr); |
| 19042 | IrInstruction *result = ir_get_deref(ira, &switch_target_instruction->base, target_value_ptr, nullptr); |
| 17423 | 19043 | result->value.type = target_type; |
| 17424 | 19044 | return result; |
| 17425 | 19045 | } |
| ... | ... | @@ -17449,7 +19069,7 @@ static IrInstruction *ir_analyze_instruction_switch_target(IrAnalyze *ira, |
| 17449 | 19069 | return result; |
| 17450 | 19070 | } |
| 17451 | 19071 | |
| 17452 | | IrInstruction *union_value = ir_get_deref(ira, &switch_target_instruction->base, target_value_ptr); |
| 19072 | IrInstruction *union_value = ir_get_deref(ira, &switch_target_instruction->base, target_value_ptr, nullptr); |
| 17453 | 19073 | union_value->value.type = target_type; |
| 17454 | 19074 | |
| 17455 | 19075 | IrInstruction *union_tag_inst = ir_build_union_tag(&ira->new_irb, switch_target_instruction->base.scope, |
| ... | ... | @@ -17473,7 +19093,7 @@ static IrInstruction *ir_analyze_instruction_switch_target(IrAnalyze *ira, |
| 17473 | 19093 | return result; |
| 17474 | 19094 | } |
| 17475 | 19095 | |
| 17476 | | IrInstruction *enum_value = ir_get_deref(ira, &switch_target_instruction->base, target_value_ptr); |
| 19096 | IrInstruction *enum_value = ir_get_deref(ira, &switch_target_instruction->base, target_value_ptr, nullptr); |
| 17477 | 19097 | enum_value->value.type = target_type; |
| 17478 | 19098 | return enum_value; |
| 17479 | 19099 | } |
| ... | ... | @@ -17546,7 +19166,7 @@ static IrInstruction *ir_analyze_instruction_switch_var(IrAnalyze *ira, IrInstru |
| 17546 | 19166 | } |
| 17547 | 19167 | |
| 17548 | 19168 | IrInstruction *result = ir_build_union_field_ptr(&ira->new_irb, |
| 17549 | | instruction->base.scope, instruction->base.source_node, target_value_ptr, field); |
| 19169 | instruction->base.scope, instruction->base.source_node, target_value_ptr, field, false, false); |
| 17550 | 19170 | result->value.type = get_pointer_to_type(ira->codegen, field->type_entry, |
| 17551 | 19171 | target_value_ptr->value.type->data.pointer.is_const); |
| 17552 | 19172 | return result; |
| ... | ... | @@ -17756,7 +19376,8 @@ static IrInstruction *ir_analyze_instruction_ref(IrAnalyze *ira, IrInstructionRe |
| 17756 | 19376 | } |
| 17757 | 19377 | |
| 17758 | 19378 | static IrInstruction *ir_analyze_container_init_fields_union(IrAnalyze *ira, IrInstruction *instruction, |
| 17759 | | ZigType *container_type, size_t instr_field_count, IrInstructionContainerInitFieldsField *fields) |
| 19379 | ZigType *container_type, size_t instr_field_count, IrInstructionContainerInitFieldsField *fields, |
| 19380 | IrInstruction *result_loc) |
| 17760 | 19381 | { |
| 17761 | 19382 | Error err; |
| 17762 | 19383 | assert(container_type->id == ZigTypeIdUnion); |
| ... | ... | @@ -17771,12 +19392,12 @@ static IrInstruction *ir_analyze_container_init_fields_union(IrAnalyze *ira, IrI |
| 17771 | 19392 | } |
| 17772 | 19393 | |
| 17773 | 19394 | IrInstructionContainerInitFieldsField *field = &fields[0]; |
| 17774 | | IrInstruction *field_value = field->value->child; |
| 17775 | | if (type_is_invalid(field_value->value.type)) |
| 19395 | IrInstruction *field_result_loc = field->result_loc->child; |
| 19396 | if (type_is_invalid(field_result_loc->value.type)) |
| 17776 | 19397 | return ira->codegen->invalid_instruction; |
| 17777 | 19398 | |
| 17778 | 19399 | TypeUnionField *type_field = find_union_type_field(container_type, field->name); |
| 17779 | | if (!type_field) { |
| 19400 | if (type_field == nullptr) { |
| 17780 | 19401 | ir_add_error_node(ira, field->source_node, |
| 17781 | 19402 | buf_sprintf("no member named '%s' in union '%s'", |
| 17782 | 19403 | buf_ptr(field->name), buf_ptr(&container_type->name))); |
| ... | ... | @@ -17786,46 +19407,36 @@ static IrInstruction *ir_analyze_container_init_fields_union(IrAnalyze *ira, IrI |
| 17786 | 19407 | if (type_is_invalid(type_field->type_entry)) |
| 17787 | 19408 | return ira->codegen->invalid_instruction; |
| 17788 | 19409 | |
| 17789 | | IrInstruction *casted_field_value = ir_implicit_cast(ira, field_value, type_field->type_entry); |
| 17790 | | if (casted_field_value == ira->codegen->invalid_instruction) |
| 17791 | | return ira->codegen->invalid_instruction; |
| 17792 | | |
| 17793 | | if ((err = type_resolve(ira->codegen, casted_field_value->value.type, ResolveStatusZeroBitsKnown))) |
| 17794 | | return ira->codegen->invalid_instruction; |
| 19410 | if (result_loc->value.data.x_ptr.mut == ConstPtrMutInfer) { |
| 19411 | if (instr_is_comptime(field_result_loc) && |
| 19412 | field_result_loc->value.data.x_ptr.mut != ConstPtrMutRuntimeVar) |
| 19413 | { |
| 19414 | // nothing |
| 19415 | } else { |
| 19416 | result_loc->value.special = ConstValSpecialRuntime; |
| 19417 | } |
| 19418 | } |
| 17795 | 19419 | |
| 17796 | 19420 | bool is_comptime = ir_should_inline(ira->new_irb.exec, instruction->scope) |
| 17797 | 19421 | || type_requires_comptime(ira->codegen, container_type) == ReqCompTimeYes; |
| 17798 | | if (is_comptime || casted_field_value->value.special != ConstValSpecialRuntime || |
| 17799 | | !type_has_bits(casted_field_value->value.type)) |
| 17800 | | { |
| 17801 | | ConstExprValue *field_val = ir_resolve_const(ira, casted_field_value, UndefOk); |
| 17802 | | if (!field_val) |
| 17803 | | return ira->codegen->invalid_instruction; |
| 17804 | | |
| 17805 | | IrInstruction *result = ir_const(ira, instruction, container_type); |
| 17806 | | ConstExprValue *out_val = &result->value; |
| 17807 | | out_val->data.x_union.payload = field_val; |
| 17808 | | out_val->data.x_union.tag = type_field->enum_field->value; |
| 17809 | | out_val->parent.id = ConstParentIdUnion; |
| 17810 | | out_val->parent.data.p_union.union_val = out_val; |
| 17811 | 19422 | |
| 17812 | | return result; |
| 19423 | IrInstruction *result = ir_get_deref(ira, instruction, result_loc, nullptr); |
| 19424 | if (is_comptime && !instr_is_comptime(result)) { |
| 19425 | ir_add_error(ira, field->result_loc, |
| 19426 | buf_sprintf("unable to evaluate constant expression")); |
| 19427 | return ira->codegen->invalid_instruction; |
| 17813 | 19428 | } |
| 17814 | | |
| 17815 | | IrInstruction *new_instruction = ir_build_union_init(&ira->new_irb, |
| 17816 | | instruction->scope, instruction->source_node, |
| 17817 | | container_type, type_field, casted_field_value); |
| 17818 | | new_instruction->value.type = container_type; |
| 17819 | | ir_add_alloca(ira, new_instruction, container_type); |
| 17820 | | return new_instruction; |
| 19429 | return result; |
| 17821 | 19430 | } |
| 17822 | 19431 | |
| 17823 | 19432 | static IrInstruction *ir_analyze_container_init_fields(IrAnalyze *ira, IrInstruction *instruction, |
| 17824 | | ZigType *container_type, size_t instr_field_count, IrInstructionContainerInitFieldsField *fields) |
| 19433 | ZigType *container_type, size_t instr_field_count, IrInstructionContainerInitFieldsField *fields, |
| 19434 | IrInstruction *result_loc) |
| 17825 | 19435 | { |
| 17826 | 19436 | Error err; |
| 17827 | 19437 | if (container_type->id == ZigTypeIdUnion) { |
| 17828 | | return ir_analyze_container_init_fields_union(ira, instruction, container_type, instr_field_count, fields); |
| 19438 | return ir_analyze_container_init_fields_union(ira, instruction, container_type, instr_field_count, |
| 19439 | fields, result_loc); |
| 17829 | 19440 | } |
| 17830 | 19441 | if (container_type->id != ZigTypeIdStruct || is_slice(container_type)) { |
| 17831 | 19442 | ir_add_error(ira, instruction, |
| ... | ... | @@ -17842,22 +19453,28 @@ static IrInstruction *ir_analyze_container_init_fields(IrAnalyze *ira, IrInstruc |
| 17842 | 19453 | IrInstruction *first_non_const_instruction = nullptr; |
| 17843 | 19454 | |
| 17844 | 19455 | AstNode **field_assign_nodes = allocate<AstNode *>(actual_field_count); |
| 17845 | | |
| 17846 | | IrInstructionStructInitField *new_fields = allocate<IrInstructionStructInitField>(actual_field_count); |
| 19456 | ZigList<IrInstruction *> const_ptrs = {}; |
| 17847 | 19457 | |
| 17848 | 19458 | bool is_comptime = ir_should_inline(ira->new_irb.exec, instruction->scope) |
| 17849 | 19459 | || type_requires_comptime(ira->codegen, container_type) == ReqCompTimeYes; |
| 17850 | 19460 | |
| 17851 | | ConstExprValue const_val = {}; |
| 17852 | | const_val.special = ConstValSpecialStatic; |
| 17853 | | const_val.type = container_type; |
| 17854 | | // const_val.global_refs = allocate<ConstGlobalRefs>(1); |
| 17855 | | const_val.data.x_struct.fields = create_const_vals(actual_field_count); |
| 19461 | |
| 19462 | // Here we iterate over the fields that have been initialized, and emit |
| 19463 | // compile errors for missing fields and duplicate fields. |
| 19464 | // It is only now that we find out whether the struct initialization can be a comptime |
| 19465 | // value, but we have already emitted runtime instructions for the fields that |
| 19466 | // were initialized with runtime values, and have omitted instructions that would have |
| 19467 | // initialized fields with comptime values. |
| 19468 | // So now we must clean up this situation. If it turns out the struct initialization can |
| 19469 | // be a comptime value, overwrite ConstPtrMutInfer with ConstPtrMutComptimeConst. |
| 19470 | // Otherwise, we must emit instructions to runtime-initialize the fields that have |
| 19471 | // comptime-known values. |
| 19472 | |
| 17856 | 19473 | for (size_t i = 0; i < instr_field_count; i += 1) { |
| 17857 | 19474 | IrInstructionContainerInitFieldsField *field = &fields[i]; |
| 17858 | 19475 | |
| 17859 | | IrInstruction *field_value = field->value->child; |
| 17860 | | if (type_is_invalid(field_value->value.type)) |
| 19476 | IrInstruction *field_result_loc = field->result_loc->child; |
| 19477 | if (type_is_invalid(field_result_loc->value.type)) |
| 17861 | 19478 | return ira->codegen->invalid_instruction; |
| 17862 | 19479 | |
| 17863 | 19480 | TypeStructField *type_field = find_struct_type_field(container_type, field->name); |
| ... | ... | @@ -17871,10 +19488,6 @@ static IrInstruction *ir_analyze_container_init_fields(IrAnalyze *ira, IrInstruc |
| 17871 | 19488 | if (type_is_invalid(type_field->type_entry)) |
| 17872 | 19489 | return ira->codegen->invalid_instruction; |
| 17873 | 19490 | |
| 17874 | | IrInstruction *casted_field_value = ir_implicit_cast(ira, field_value, type_field->type_entry); |
| 17875 | | if (casted_field_value == ira->codegen->invalid_instruction) |
| 17876 | | return ira->codegen->invalid_instruction; |
| 17877 | | |
| 17878 | 19491 | size_t field_index = type_field->src_index; |
| 17879 | 19492 | AstNode *existing_assign_node = field_assign_nodes[field_index]; |
| 17880 | 19493 | if (existing_assign_node) { |
| ... | ... | @@ -17884,26 +19497,18 @@ static IrInstruction *ir_analyze_container_init_fields(IrAnalyze *ira, IrInstruc |
| 17884 | 19497 | } |
| 17885 | 19498 | field_assign_nodes[field_index] = field->source_node; |
| 17886 | 19499 | |
| 17887 | | new_fields[field_index].value = casted_field_value; |
| 17888 | | new_fields[field_index].type_struct_field = type_field; |
| 17889 | | |
| 17890 | | if (const_val.special == ConstValSpecialStatic) { |
| 17891 | | if (is_comptime || casted_field_value->value.special != ConstValSpecialRuntime) { |
| 17892 | | ConstExprValue *field_val = ir_resolve_const(ira, casted_field_value, UndefOk); |
| 17893 | | if (!field_val) |
| 17894 | | return ira->codegen->invalid_instruction; |
| 17895 | | |
| 17896 | | copy_const_val(&const_val.data.x_struct.fields[field_index], field_val, true); |
| 17897 | | } else { |
| 17898 | | first_non_const_instruction = casted_field_value; |
| 17899 | | const_val.special = ConstValSpecialRuntime; |
| 17900 | | } |
| 19500 | if (instr_is_comptime(field_result_loc) && |
| 19501 | field_result_loc->value.data.x_ptr.mut != ConstPtrMutRuntimeVar) |
| 19502 | { |
| 19503 | const_ptrs.append(field_result_loc); |
| 19504 | } else { |
| 19505 | first_non_const_instruction = field_result_loc; |
| 17901 | 19506 | } |
| 17902 | 19507 | } |
| 17903 | 19508 | |
| 17904 | 19509 | bool any_missing = false; |
| 17905 | 19510 | for (size_t i = 0; i < actual_field_count; i += 1) { |
| 17906 | | if (field_assign_nodes[i]) continue; |
| 19511 | if (field_assign_nodes[i] != nullptr) continue; |
| 17907 | 19512 | |
| 17908 | 19513 | // look for a default field value |
| 17909 | 19514 | TypeStructField *field = &container_type->data.structure.fields[i]; |
| ... | ... | @@ -17929,182 +19534,177 @@ static IrInstruction *ir_analyze_container_init_fields(IrAnalyze *ira, IrInstruc |
| 17929 | 19534 | IrInstruction *runtime_inst = ir_const(ira, instruction, field->init_val->type); |
| 17930 | 19535 | copy_const_val(&runtime_inst->value, field->init_val, true); |
| 17931 | 19536 | |
| 17932 | | new_fields[i].value = runtime_inst; |
| 17933 | | new_fields[i].type_struct_field = field; |
| 17934 | | |
| 17935 | | if (const_val.special == ConstValSpecialStatic) { |
| 17936 | | copy_const_val(&const_val.data.x_struct.fields[i], field->init_val, true); |
| 19537 | IrInstruction *field_ptr = ir_analyze_struct_field_ptr(ira, instruction, field, result_loc, |
| 19538 | container_type, true); |
| 19539 | ir_analyze_store_ptr(ira, instruction, field_ptr, runtime_inst); |
| 19540 | if (instr_is_comptime(field_ptr) && field_ptr->value.data.x_ptr.mut != ConstPtrMutRuntimeVar) { |
| 19541 | const_ptrs.append(field_ptr); |
| 19542 | } else { |
| 19543 | first_non_const_instruction = result_loc; |
| 17937 | 19544 | } |
| 17938 | 19545 | } |
| 17939 | 19546 | if (any_missing) |
| 17940 | 19547 | return ira->codegen->invalid_instruction; |
| 17941 | 19548 | |
| 17942 | | if (const_val.special == ConstValSpecialStatic) { |
| 17943 | | IrInstruction *result = ir_const(ira, instruction, nullptr); |
| 17944 | | ConstExprValue *out_val = &result->value; |
| 17945 | | copy_const_val(out_val, &const_val, false); |
| 17946 | | out_val->type = container_type; |
| 17947 | | |
| 17948 | | for (size_t i = 0; i < instr_field_count; i += 1) { |
| 17949 | | ConstExprValue *field_val = &out_val->data.x_struct.fields[i]; |
| 17950 | | ConstParent *parent = get_const_val_parent(ira->codegen, field_val); |
| 17951 | | if (parent != nullptr) { |
| 17952 | | parent->id = ConstParentIdStruct; |
| 17953 | | parent->data.p_struct.field_index = i; |
| 17954 | | parent->data.p_struct.struct_val = out_val; |
| 19549 | if (result_loc->value.data.x_ptr.mut == ConstPtrMutInfer) { |
| 19550 | if (const_ptrs.length != actual_field_count) { |
| 19551 | result_loc->value.special = ConstValSpecialRuntime; |
| 19552 | for (size_t i = 0; i < const_ptrs.length; i += 1) { |
| 19553 | IrInstruction *field_result_loc = const_ptrs.at(i); |
| 19554 | IrInstruction *deref = ir_get_deref(ira, field_result_loc, field_result_loc, nullptr); |
| 19555 | field_result_loc->value.special = ConstValSpecialRuntime; |
| 19556 | ir_analyze_store_ptr(ira, field_result_loc, field_result_loc, deref); |
| 17955 | 19557 | } |
| 17956 | 19558 | } |
| 17957 | | |
| 17958 | | return result; |
| 17959 | 19559 | } |
| 17960 | 19560 | |
| 17961 | | if (is_comptime) { |
| 19561 | IrInstruction *result = ir_get_deref(ira, instruction, result_loc, nullptr); |
| 19562 | |
| 19563 | if (is_comptime && !instr_is_comptime(result)) { |
| 17962 | 19564 | ir_add_error_node(ira, first_non_const_instruction->source_node, |
| 17963 | 19565 | buf_sprintf("unable to evaluate constant expression")); |
| 17964 | 19566 | return ira->codegen->invalid_instruction; |
| 17965 | 19567 | } |
| 17966 | 19568 | |
| 17967 | | IrInstruction *new_instruction = ir_build_struct_init(&ira->new_irb, |
| 17968 | | instruction->scope, instruction->source_node, |
| 17969 | | container_type, actual_field_count, new_fields); |
| 17970 | | new_instruction->value.type = container_type; |
| 17971 | | ir_add_alloca(ira, new_instruction, container_type); |
| 17972 | | return new_instruction; |
| 19569 | return result; |
| 17973 | 19570 | } |
| 17974 | 19571 | |
| 17975 | 19572 | static IrInstruction *ir_analyze_instruction_container_init_list(IrAnalyze *ira, |
| 17976 | 19573 | IrInstructionContainerInitList *instruction) |
| 17977 | 19574 | { |
| 17978 | | Error err; |
| 19575 | ZigType *container_type = ir_resolve_type(ira, instruction->container_type->child); |
| 19576 | if (type_is_invalid(container_type)) |
| 19577 | return ira->codegen->invalid_instruction; |
| 17979 | 19578 | |
| 17980 | 19579 | size_t elem_count = instruction->item_count; |
| 17981 | 19580 | |
| 17982 | | ZigType *container_type; |
| 17983 | | if (instruction->container_type != nullptr) { |
| 17984 | | container_type = ir_resolve_type(ira, instruction->container_type->child); |
| 17985 | | if (type_is_invalid(container_type)) |
| 17986 | | return ira->codegen->invalid_instruction; |
| 17987 | | } else { |
| 17988 | | ZigType *elem_type = ir_resolve_type(ira, instruction->elem_type->child); |
| 17989 | | if (type_is_invalid(elem_type)) |
| 17990 | | return ira->codegen->invalid_instruction; |
| 17991 | | if ((err = type_resolve(ira->codegen, elem_type, ResolveStatusSizeKnown))) { |
| 17992 | | return ira->codegen->invalid_instruction; |
| 17993 | | } |
| 17994 | | container_type = get_array_type(ira->codegen, elem_type, elem_count); |
| 17995 | | } |
| 17996 | | |
| 17997 | 19581 | if (is_slice(container_type)) { |
| 17998 | | ir_add_error(ira, &instruction->base, |
| 19582 | ir_add_error(ira, instruction->container_type, |
| 17999 | 19583 | buf_sprintf("expected array type or [_], found slice")); |
| 18000 | 19584 | return ira->codegen->invalid_instruction; |
| 18001 | | } else if (container_type->id == ZigTypeIdStruct && !is_slice(container_type) && elem_count == 0) { |
| 18002 | | return ir_analyze_container_init_fields(ira, &instruction->base, container_type, |
| 18003 | | 0, nullptr); |
| 18004 | | } else if (container_type->id == ZigTypeIdArray) { |
| 18005 | | // array is same as slice init but we make a compile error if the length is wrong |
| 18006 | | ZigType *child_type; |
| 18007 | | if (container_type->id == ZigTypeIdArray) { |
| 18008 | | child_type = container_type->data.array.child_type; |
| 18009 | | if (container_type->data.array.len != elem_count) { |
| 18010 | | ZigType *literal_type = get_array_type(ira->codegen, child_type, elem_count); |
| 18011 | | |
| 18012 | | ir_add_error(ira, &instruction->base, |
| 18013 | | buf_sprintf("expected %s literal, found %s literal", |
| 18014 | | buf_ptr(&container_type->name), buf_ptr(&literal_type->name))); |
| 18015 | | return ira->codegen->invalid_instruction; |
| 18016 | | } |
| 18017 | | } else { |
| 18018 | | ZigType *pointer_type = container_type->data.structure.fields[slice_ptr_index].type_entry; |
| 18019 | | assert(pointer_type->id == ZigTypeIdPointer); |
| 18020 | | child_type = pointer_type->data.pointer.child_type; |
| 18021 | | } |
| 19585 | } |
| 18022 | 19586 | |
| 18023 | | if ((err = type_resolve(ira->codegen, child_type, ResolveStatusSizeKnown))) { |
| 19587 | if (container_type->id == ZigTypeIdVoid) { |
| 19588 | if (elem_count != 0) { |
| 19589 | ir_add_error_node(ira, instruction->base.source_node, |
| 19590 | buf_sprintf("void expression expects no arguments")); |
| 18024 | 19591 | return ira->codegen->invalid_instruction; |
| 18025 | 19592 | } |
| 19593 | return ir_const_void(ira, &instruction->base); |
| 19594 | } |
| 18026 | 19595 | |
| 18027 | | ZigType *fixed_size_array_type = get_array_type(ira->codegen, child_type, elem_count); |
| 19596 | if (container_type->id == ZigTypeIdStruct && elem_count == 0) { |
| 19597 | ir_assert(instruction->result_loc != nullptr, &instruction->base); |
| 19598 | IrInstruction *result_loc = instruction->result_loc->child; |
| 19599 | if (type_is_invalid(result_loc->value.type)) |
| 19600 | return result_loc; |
| 19601 | return ir_analyze_container_init_fields(ira, &instruction->base, container_type, 0, nullptr, result_loc); |
| 19602 | } |
| 18028 | 19603 | |
| 18029 | | ConstExprValue const_val = {}; |
| 18030 | | const_val.special = ConstValSpecialStatic; |
| 18031 | | const_val.type = fixed_size_array_type; |
| 18032 | | // const_val.global_refs = allocate<ConstGlobalRefs>(1); |
| 18033 | | const_val.data.x_array.data.s_none.elements = create_const_vals(elem_count); |
| 19604 | if (container_type->id != ZigTypeIdArray) { |
| 19605 | ir_add_error_node(ira, instruction->base.source_node, |
| 19606 | buf_sprintf("type '%s' does not support array initialization", |
| 19607 | buf_ptr(&container_type->name))); |
| 19608 | return ira->codegen->invalid_instruction; |
| 19609 | } |
| 18034 | 19610 | |
| 18035 | | bool is_comptime = ir_should_inline(ira->new_irb.exec, instruction->base.scope); |
| 19611 | ir_assert(instruction->result_loc != nullptr, &instruction->base); |
| 19612 | IrInstruction *result_loc = instruction->result_loc->child; |
| 19613 | if (type_is_invalid(result_loc->value.type)) |
| 19614 | return result_loc; |
| 19615 | ir_assert(result_loc->value.type->id == ZigTypeIdPointer, &instruction->base); |
| 18036 | 19616 | |
| 18037 | | IrInstruction **new_items = allocate<IrInstruction *>(elem_count); |
| 19617 | ZigType *child_type = container_type->data.array.child_type; |
| 19618 | if (container_type->data.array.len != elem_count) { |
| 19619 | ZigType *literal_type = get_array_type(ira->codegen, child_type, elem_count); |
| 18038 | 19620 | |
| 18039 | | IrInstruction *first_non_const_instruction = nullptr; |
| 19621 | ir_add_error(ira, &instruction->base, |
| 19622 | buf_sprintf("expected %s literal, found %s literal", |
| 19623 | buf_ptr(&container_type->name), buf_ptr(&literal_type->name))); |
| 19624 | return ira->codegen->invalid_instruction; |
| 19625 | } |
| 18040 | 19626 | |
| 18041 | | for (size_t i = 0; i < elem_count; i += 1) { |
| 18042 | | IrInstruction *arg_value = instruction->items[i]->child; |
| 18043 | | if (type_is_invalid(arg_value->value.type)) |
| 18044 | | return ira->codegen->invalid_instruction; |
| 19627 | switch (type_has_one_possible_value(ira->codegen, container_type)) { |
| 19628 | case OnePossibleValueInvalid: |
| 19629 | return ira->codegen->invalid_instruction; |
| 19630 | case OnePossibleValueYes: |
| 19631 | return ir_const(ira, &instruction->base, container_type); |
| 19632 | case OnePossibleValueNo: |
| 19633 | break; |
| 19634 | } |
| 18045 | 19635 | |
| 18046 | | IrInstruction *casted_arg = ir_implicit_cast(ira, arg_value, child_type); |
| 18047 | | if (casted_arg == ira->codegen->invalid_instruction) |
| 18048 | | return ira->codegen->invalid_instruction; |
| 19636 | bool is_comptime; |
| 19637 | switch (type_requires_comptime(ira->codegen, container_type)) { |
| 19638 | case ReqCompTimeInvalid: |
| 19639 | return ira->codegen->invalid_instruction; |
| 19640 | case ReqCompTimeNo: |
| 19641 | is_comptime = ir_should_inline(ira->new_irb.exec, instruction->base.scope); |
| 19642 | break; |
| 19643 | case ReqCompTimeYes: |
| 19644 | is_comptime = true; |
| 19645 | break; |
| 19646 | } |
| 18049 | 19647 | |
| 18050 | | new_items[i] = casted_arg; |
| 19648 | IrInstruction *first_non_const_instruction = nullptr; |
| 18051 | 19649 | |
| 18052 | | if (const_val.special == ConstValSpecialStatic) { |
| 18053 | | if (is_comptime || casted_arg->value.special != ConstValSpecialRuntime) { |
| 18054 | | ConstExprValue *elem_val = ir_resolve_const(ira, casted_arg, UndefBad); |
| 18055 | | if (!elem_val) |
| 18056 | | return ira->codegen->invalid_instruction; |
| 19650 | // The Result Location Mechanism has already emitted runtime instructions to |
| 19651 | // initialize runtime elements and has omitted instructions for the comptime |
| 19652 | // elements. However it is only now that we find out whether the array initialization |
| 19653 | // can be a comptime value. So we must clean up the situation. If it turns out |
| 19654 | // array initialization can be a comptime value, overwrite ConstPtrMutInfer with |
| 19655 | // ConstPtrMutComptimeConst. Otherwise, emit instructions to runtime-initialize the |
| 19656 | // elements that have comptime-known values. |
| 19657 | ZigList<IrInstruction *> const_ptrs = {}; |
| 19658 | |
| 19659 | for (size_t i = 0; i < elem_count; i += 1) { |
| 19660 | IrInstruction *elem_result_loc = instruction->elem_result_loc_list[i]->child; |
| 19661 | if (type_is_invalid(elem_result_loc->value.type)) |
| 19662 | return ira->codegen->invalid_instruction; |
| 18057 | 19663 | |
| 18058 | | copy_const_val(&const_val.data.x_array.data.s_none.elements[i], elem_val, true); |
| 18059 | | } else { |
| 18060 | | first_non_const_instruction = casted_arg; |
| 18061 | | const_val.special = ConstValSpecialRuntime; |
| 18062 | | } |
| 18063 | | } |
| 19664 | assert(elem_result_loc->value.type->id == ZigTypeIdPointer); |
| 19665 | |
| 19666 | if (instr_is_comptime(elem_result_loc) && |
| 19667 | elem_result_loc->value.data.x_ptr.mut != ConstPtrMutRuntimeVar) |
| 19668 | { |
| 19669 | const_ptrs.append(elem_result_loc); |
| 19670 | } else { |
| 19671 | first_non_const_instruction = elem_result_loc; |
| 18064 | 19672 | } |
| 19673 | } |
| 18065 | 19674 | |
| 18066 | | if (const_val.special == ConstValSpecialStatic) { |
| 18067 | | IrInstruction *result = ir_const(ira, &instruction->base, nullptr); |
| 18068 | | ConstExprValue *out_val = &result->value; |
| 18069 | | copy_const_val(out_val, &const_val, false); |
| 18070 | | result->value.type = fixed_size_array_type; |
| 18071 | | for (size_t i = 0; i < elem_count; i += 1) { |
| 18072 | | ConstExprValue *elem_val = &out_val->data.x_array.data.s_none.elements[i]; |
| 18073 | | ConstParent *parent = get_const_val_parent(ira->codegen, elem_val); |
| 18074 | | if (parent != nullptr) { |
| 18075 | | parent->id = ConstParentIdArray; |
| 18076 | | parent->data.p_array.array_val = out_val; |
| 18077 | | parent->data.p_array.elem_index = i; |
| 18078 | | } |
| 19675 | if (result_loc->value.data.x_ptr.mut == ConstPtrMutInfer) { |
| 19676 | if (const_ptrs.length != elem_count) { |
| 19677 | result_loc->value.special = ConstValSpecialRuntime; |
| 19678 | for (size_t i = 0; i < const_ptrs.length; i += 1) { |
| 19679 | IrInstruction *elem_result_loc = const_ptrs.at(i); |
| 19680 | assert(elem_result_loc->value.special == ConstValSpecialStatic); |
| 19681 | IrInstruction *deref = ir_get_deref(ira, elem_result_loc, elem_result_loc, nullptr); |
| 19682 | elem_result_loc->value.special = ConstValSpecialRuntime; |
| 19683 | ir_analyze_store_ptr(ira, elem_result_loc, elem_result_loc, deref); |
| 18079 | 19684 | } |
| 18080 | | return result; |
| 18081 | 19685 | } |
| 19686 | } |
| 18082 | 19687 | |
| 18083 | | if (is_comptime) { |
| 18084 | | ir_add_error_node(ira, first_non_const_instruction->source_node, |
| 18085 | | buf_sprintf("unable to evaluate constant expression")); |
| 18086 | | return ira->codegen->invalid_instruction; |
| 18087 | | } |
| 19688 | IrInstruction *result = ir_get_deref(ira, &instruction->base, result_loc, nullptr); |
| 19689 | if (instr_is_comptime(result)) |
| 19690 | return result; |
| 18088 | 19691 | |
| 18089 | | IrInstruction *new_instruction = ir_build_container_init_list(&ira->new_irb, |
| 18090 | | instruction->base.scope, instruction->base.source_node, |
| 18091 | | nullptr, nullptr, elem_count, new_items); |
| 18092 | | new_instruction->value.type = fixed_size_array_type; |
| 18093 | | ir_add_alloca(ira, new_instruction, fixed_size_array_type); |
| 18094 | | return new_instruction; |
| 18095 | | } else if (container_type->id == ZigTypeIdVoid) { |
| 18096 | | if (elem_count != 0) { |
| 18097 | | ir_add_error_node(ira, instruction->base.source_node, |
| 18098 | | buf_sprintf("void expression expects no arguments")); |
| 18099 | | return ira->codegen->invalid_instruction; |
| 18100 | | } |
| 18101 | | return ir_const_void(ira, &instruction->base); |
| 18102 | | } else { |
| 18103 | | ir_add_error_node(ira, instruction->base.source_node, |
| 18104 | | buf_sprintf("type '%s' does not support array initialization", |
| 18105 | | buf_ptr(&container_type->name))); |
| 19692 | if (is_comptime) { |
| 19693 | ir_add_error_node(ira, first_non_const_instruction->source_node, |
| 19694 | buf_sprintf("unable to evaluate constant expression")); |
| 19695 | return ira->codegen->invalid_instruction; |
| 19696 | } |
| 19697 | |
| 19698 | ZigType *result_elem_type = result_loc->value.type->data.pointer.child_type; |
| 19699 | if (is_slice(result_elem_type)) { |
| 19700 | ErrorMsg *msg = ir_add_error(ira, &instruction->base, |
| 19701 | buf_sprintf("runtime-initialized array cannot be casted to slice type '%s'", |
| 19702 | buf_ptr(&result_elem_type->name))); |
| 19703 | add_error_note(ira->codegen, msg, first_non_const_instruction->source_node, |
| 19704 | buf_sprintf("this value is not comptime-known")); |
| 18106 | 19705 | return ira->codegen->invalid_instruction; |
| 18107 | 19706 | } |
| 19707 | return result; |
| 18108 | 19708 | } |
| 18109 | 19709 | |
| 18110 | 19710 | static IrInstruction *ir_analyze_instruction_container_init_fields(IrAnalyze *ira, |
| ... | ... | @@ -18115,8 +19715,13 @@ static IrInstruction *ir_analyze_instruction_container_init_fields(IrAnalyze *ir |
| 18115 | 19715 | if (type_is_invalid(container_type)) |
| 18116 | 19716 | return ira->codegen->invalid_instruction; |
| 18117 | 19717 | |
| 19718 | ir_assert(instruction->result_loc != nullptr, &instruction->base); |
| 19719 | IrInstruction *result_loc = instruction->result_loc->child; |
| 19720 | if (type_is_invalid(result_loc->value.type)) |
| 19721 | return result_loc; |
| 19722 | |
| 18118 | 19723 | return ir_analyze_container_init_fields(ira, &instruction->base, container_type, |
| 18119 | | instruction->field_count, instruction->fields); |
| 19724 | instruction->field_count, instruction->fields, result_loc); |
| 18120 | 19725 | } |
| 18121 | 19726 | |
| 18122 | 19727 | static IrInstruction *ir_analyze_instruction_compile_err(IrAnalyze *ira, |
| ... | ... | @@ -18385,12 +19990,6 @@ static IrInstruction *ir_analyze_instruction_bit_offset_of(IrAnalyze *ira, |
| 18385 | 19990 | return ir_const_unsigned(ira, &instruction->base, bit_offset); |
| 18386 | 19991 | } |
| 18387 | 19992 | |
| 18388 | | static IrInstruction *ir_error_dependency_loop(IrAnalyze *ira, IrInstruction *source_instr) { |
| 18389 | | ErrorMsg *msg = ir_add_error(ira, source_instr, buf_sprintf("dependency loop detected")); |
| 18390 | | emit_error_notes_for_ref_stack(ira->codegen, msg); |
| 18391 | | return ira->codegen->invalid_instruction; |
| 18392 | | } |
| 18393 | | |
| 18394 | 19993 | static void ensure_field_index(ZigType *type, const char *field_name, size_t index) { |
| 18395 | 19994 | Buf *field_name_buf; |
| 18396 | 19995 | |
| ... | ... | @@ -19509,7 +21108,7 @@ static IrInstruction *ir_analyze_instruction_c_import(IrAnalyze *ira, IrInstruct |
| 19509 | 21108 | ir_add_error_node(ira, node, buf_sprintf("C import failed: unable to make dir: %s", err_str(err))); |
| 19510 | 21109 | return ira->codegen->invalid_instruction; |
| 19511 | 21110 | } |
| 19512 | | |
| 21111 | |
| 19513 | 21112 | if ((err = os_write_file(&tmp_c_file_path, &cimport_scope->buf))) { |
| 19514 | 21113 | ir_add_error_node(ira, node, buf_sprintf("C import failed: unable to write .h file: %s", err_str(err))); |
| 19515 | 21114 | return ira->codegen->invalid_instruction; |
| ... | ... | @@ -19796,12 +21395,21 @@ static IrInstruction *ir_analyze_instruction_cmpxchg(IrAnalyze *ira, IrInstructi |
| 19796 | 21395 | zig_panic("TODO compile-time execution of cmpxchg"); |
| 19797 | 21396 | } |
| 19798 | 21397 | |
| 19799 | | IrInstruction *result = ir_build_cmpxchg_gen(ira, &instruction->base, |
| 21398 | ZigType *result_type = get_optional_type(ira->codegen, operand_type); |
| 21399 | IrInstruction *result_loc; |
| 21400 | if (handle_is_ptr(result_type)) { |
| 21401 | result_loc = ir_resolve_result(ira, &instruction->base, instruction->result_loc, |
| 21402 | result_type, nullptr, true, false); |
| 21403 | if (type_is_invalid(result_loc->value.type) || instr_is_unreachable(result_loc)) { |
| 21404 | return result_loc; |
| 21405 | } |
| 21406 | } else { |
| 21407 | result_loc = nullptr; |
| 21408 | } |
| 21409 | |
| 21410 | return ir_build_cmpxchg_gen(ira, &instruction->base, result_type, |
| 19800 | 21411 | casted_ptr, casted_cmp_value, casted_new_value, |
| 19801 | | success_order, failure_order, instruction->is_weak); |
| 19802 | | result->value.type = get_optional_type(ira->codegen, operand_type); |
| 19803 | | ir_add_alloca(ira, result, result->value.type); |
| 19804 | | return result; |
| 21412 | success_order, failure_order, instruction->is_weak, result_loc); |
| 19805 | 21413 | } |
| 19806 | 21414 | |
| 19807 | 21415 | static IrInstruction *ir_analyze_instruction_fence(IrAnalyze *ira, IrInstructionFence *instruction) { |
| ... | ... | @@ -19939,7 +21547,7 @@ static IrInstruction *ir_analyze_instruction_float_cast(IrAnalyze *ira, IrInstru |
| 19939 | 21547 | } else { |
| 19940 | 21548 | op = CastOpNumLitToConcrete; |
| 19941 | 21549 | } |
| 19942 | | return ir_resolve_cast(ira, &instruction->base, target, dest_type, op, false); |
| 21550 | return ir_resolve_cast(ira, &instruction->base, target, dest_type, op); |
| 19943 | 21551 | } else { |
| 19944 | 21552 | return ira->codegen->invalid_instruction; |
| 19945 | 21553 | } |
| ... | ... | @@ -20047,6 +21655,12 @@ static IrInstruction *ir_analyze_instruction_from_bytes(IrAnalyze *ira, IrInstru |
| 20047 | 21655 | } |
| 20048 | 21656 | } |
| 20049 | 21657 | |
| 21658 | IrInstruction *result_loc = ir_resolve_result(ira, &instruction->base, instruction->result_loc, |
| 21659 | dest_slice_type, nullptr, true, false); |
| 21660 | if (result_loc != nullptr && (type_is_invalid(result_loc->value.type) || instr_is_unreachable(result_loc))) { |
| 21661 | return result_loc; |
| 21662 | } |
| 21663 | |
| 20050 | 21664 | if (casted_value->value.data.rh_slice.id == RuntimeHintSliceIdLen) { |
| 20051 | 21665 | known_len = casted_value->value.data.rh_slice.len; |
| 20052 | 21666 | have_known_len = true; |
| ... | ... | @@ -20066,9 +21680,7 @@ static IrInstruction *ir_analyze_instruction_from_bytes(IrAnalyze *ira, IrInstru |
| 20066 | 21680 | } |
| 20067 | 21681 | } |
| 20068 | 21682 | |
| 20069 | | IrInstruction *result = ir_build_resize_slice(ira, &instruction->base, casted_value, dest_slice_type); |
| 20070 | | ir_add_alloca(ira, result, dest_slice_type); |
| 20071 | | return result; |
| 21683 | return ir_build_resize_slice(ira, &instruction->base, casted_value, dest_slice_type, result_loc); |
| 20072 | 21684 | } |
| 20073 | 21685 | |
| 20074 | 21686 | static IrInstruction *ir_analyze_instruction_to_bytes(IrAnalyze *ira, IrInstructionToBytes *instruction) { |
| ... | ... | @@ -20120,9 +21732,13 @@ static IrInstruction *ir_analyze_instruction_to_bytes(IrAnalyze *ira, IrInstruct |
| 20120 | 21732 | return result; |
| 20121 | 21733 | } |
| 20122 | 21734 | |
| 20123 | | IrInstruction *result = ir_build_resize_slice(ira, &instruction->base, target, dest_slice_type); |
| 20124 | | ir_add_alloca(ira, result, dest_slice_type); |
| 20125 | | return result; |
| 21735 | IrInstruction *result_loc = ir_resolve_result(ira, &instruction->base, instruction->result_loc, |
| 21736 | dest_slice_type, nullptr, true, false); |
| 21737 | if (type_is_invalid(result_loc->value.type) || instr_is_unreachable(result_loc)) { |
| 21738 | return result_loc; |
| 21739 | } |
| 21740 | |
| 21741 | return ir_build_resize_slice(ira, &instruction->base, target, dest_slice_type, result_loc); |
| 20126 | 21742 | } |
| 20127 | 21743 | |
| 20128 | 21744 | static Error resolve_ptr_align(IrAnalyze *ira, ZigType *ty, uint32_t *result_align) { |
| ... | ... | @@ -20154,7 +21770,7 @@ static IrInstruction *ir_analyze_instruction_int_to_float(IrAnalyze *ira, IrInst |
| 20154 | 21770 | return ira->codegen->invalid_instruction; |
| 20155 | 21771 | } |
| 20156 | 21772 | |
| 20157 | | return ir_resolve_cast(ira, &instruction->base, target, dest_type, CastOpIntToFloat, false); |
| 21773 | return ir_resolve_cast(ira, &instruction->base, target, dest_type, CastOpIntToFloat); |
| 20158 | 21774 | } |
| 20159 | 21775 | |
| 20160 | 21776 | static IrInstruction *ir_analyze_instruction_float_to_int(IrAnalyze *ira, IrInstructionFloatToInt *instruction) { |
| ... | ... | @@ -20176,7 +21792,7 @@ static IrInstruction *ir_analyze_instruction_float_to_int(IrAnalyze *ira, IrInst |
| 20176 | 21792 | return ira->codegen->invalid_instruction; |
| 20177 | 21793 | } |
| 20178 | 21794 | |
| 20179 | | return ir_resolve_cast(ira, &instruction->base, target, dest_type, CastOpFloatToInt, false); |
| 21795 | return ir_resolve_cast(ira, &instruction->base, target, dest_type, CastOpFloatToInt); |
| 20180 | 21796 | } |
| 20181 | 21797 | |
| 20182 | 21798 | static IrInstruction *ir_analyze_instruction_err_to_int(IrAnalyze *ira, IrInstructionErrToInt *instruction) { |
| ... | ... | @@ -20228,7 +21844,7 @@ static IrInstruction *ir_analyze_instruction_bool_to_int(IrAnalyze *ira, IrInstr |
| 20228 | 21844 | } |
| 20229 | 21845 | |
| 20230 | 21846 | ZigType *u1_type = get_int_type(ira->codegen, false, 1); |
| 20231 | | return ir_resolve_cast(ira, &instruction->base, target, u1_type, CastOpBoolToInt, false); |
| 21847 | return ir_resolve_cast(ira, &instruction->base, target, u1_type, CastOpBoolToInt); |
| 20232 | 21848 | } |
| 20233 | 21849 | |
| 20234 | 21850 | static IrInstruction *ir_analyze_instruction_int_type(IrAnalyze *ira, IrInstructionIntType *instruction) { |
| ... | ... | @@ -20389,7 +22005,7 @@ static IrInstruction *ir_analyze_instruction_memset(IrAnalyze *ira, IrInstructio |
| 20389 | 22005 | |
| 20390 | 22006 | ConstExprValue *byte_val = &casted_byte->value; |
| 20391 | 22007 | for (size_t i = start; i < end; i += 1) { |
| 20392 | | dest_elements[i] = *byte_val; |
| 22008 | copy_const_val(&dest_elements[i], byte_val, true); |
| 20393 | 22009 | } |
| 20394 | 22010 | |
| 20395 | 22011 | return ir_const_void(ira, &instruction->base); |
| ... | ... | @@ -20459,7 +22075,7 @@ static IrInstruction *ir_analyze_instruction_memcpy(IrAnalyze *ira, IrInstructio |
| 20459 | 22075 | return ira->codegen->invalid_instruction; |
| 20460 | 22076 | |
| 20461 | 22077 | // TODO test this at comptime with u8 and non-u8 types |
| 20462 | | // TODO test with dest ptr being a global runtime variable |
| 22078 | // TODO test with dest ptr being a global runtime variable |
| 20463 | 22079 | if (casted_dest_ptr->value.special == ConstValSpecialStatic && |
| 20464 | 22080 | casted_src_ptr->value.special == ConstValSpecialStatic && |
| 20465 | 22081 | casted_count->value.special == ConstValSpecialStatic && |
| ... | ... | @@ -20557,7 +22173,7 @@ static IrInstruction *ir_analyze_instruction_memcpy(IrAnalyze *ira, IrInstructio |
| 20557 | 22173 | // TODO check for noalias violations - this should be generalized to work for any function |
| 20558 | 22174 | |
| 20559 | 22175 | for (size_t i = 0; i < count; i += 1) { |
| 20560 | | dest_elements[dest_start + i] = src_elements[src_start + i]; |
| 22176 | copy_const_val(&dest_elements[dest_start + i], &src_elements[src_start + i], true); |
| 20561 | 22177 | } |
| 20562 | 22178 | |
| 20563 | 22179 | return ir_const_void(ira, &instruction->base); |
| ... | ... | @@ -20569,7 +22185,7 @@ static IrInstruction *ir_analyze_instruction_memcpy(IrAnalyze *ira, IrInstructio |
| 20569 | 22185 | return result; |
| 20570 | 22186 | } |
| 20571 | 22187 | |
| 20572 | | static IrInstruction *ir_analyze_instruction_slice(IrAnalyze *ira, IrInstructionSlice *instruction) { |
| 22188 | static IrInstruction *ir_analyze_instruction_slice(IrAnalyze *ira, IrInstructionSliceSrc *instruction) { |
| 20573 | 22189 | IrInstruction *ptr_ptr = instruction->ptr->child; |
| 20574 | 22190 | if (type_is_invalid(ptr_ptr->value.type)) |
| 20575 | 22191 | return ira->codegen->invalid_instruction; |
| ... | ... | @@ -20858,12 +22474,13 @@ static IrInstruction *ir_analyze_instruction_slice(IrAnalyze *ira, IrInstruction |
| 20858 | 22474 | return result; |
| 20859 | 22475 | } |
| 20860 | 22476 | |
| 20861 | | IrInstruction *new_instruction = ir_build_slice(&ira->new_irb, |
| 20862 | | instruction->base.scope, instruction->base.source_node, |
| 20863 | | ptr_ptr, casted_start, end, instruction->safety_check_on); |
| 20864 | | new_instruction->value.type = return_type; |
| 20865 | | ir_add_alloca(ira, new_instruction, return_type); |
| 20866 | | return new_instruction; |
| 22477 | IrInstruction *result_loc = ir_resolve_result(ira, &instruction->base, instruction->result_loc, |
| 22478 | return_type, nullptr, true, false); |
| 22479 | if (type_is_invalid(result_loc->value.type) || instr_is_unreachable(result_loc)) { |
| 22480 | return result_loc; |
| 22481 | } |
| 22482 | return ir_build_slice_gen(ira, &instruction->base, return_type, |
| 22483 | ptr_ptr, casted_start, end, instruction->safety_check_on, result_loc); |
| 20867 | 22484 | } |
| 20868 | 22485 | |
| 20869 | 22486 | static IrInstruction *ir_analyze_instruction_member_count(IrAnalyze *ira, IrInstructionMemberCount *instruction) { |
| ... | ... | @@ -21187,15 +22804,149 @@ static IrInstruction *ir_analyze_instruction_overflow_op(IrAnalyze *ira, IrInstr |
| 21187 | 22804 | return result; |
| 21188 | 22805 | } |
| 21189 | 22806 | |
| 21190 | | static IrInstruction *ir_analyze_instruction_test_err(IrAnalyze *ira, IrInstructionTestErr *instruction) { |
| 21191 | | IrInstruction *value = instruction->value->child; |
| 21192 | | if (type_is_invalid(value->value.type)) |
| 22807 | static IrInstruction *ir_analyze_instruction_result_ptr(IrAnalyze *ira, IrInstructionResultPtr *instruction) { |
| 22808 | IrInstruction *result = instruction->result->child; |
| 22809 | if (type_is_invalid(result->value.type)) |
| 22810 | return result; |
| 22811 | |
| 22812 | if (instruction->result_loc->written && instruction->result_loc->resolved_loc != nullptr && |
| 22813 | !instr_is_comptime(result)) |
| 22814 | { |
| 22815 | return instruction->result_loc->resolved_loc; |
| 22816 | } |
| 22817 | return ir_get_ref(ira, &instruction->base, result, true, false); |
| 22818 | } |
| 22819 | |
| 22820 | static void ir_eval_mul_add(IrAnalyze *ira, IrInstructionMulAdd *source_instr, ZigType *float_type, |
| 22821 | ConstExprValue *op1, ConstExprValue *op2, ConstExprValue *op3, ConstExprValue *out_val) { |
| 22822 | if (float_type->id == ZigTypeIdComptimeFloat) { |
| 22823 | f128M_mulAdd(&out_val->data.x_bigfloat.value, &op1->data.x_bigfloat.value, &op2->data.x_bigfloat.value, |
| 22824 | &op3->data.x_bigfloat.value); |
| 22825 | } else if (float_type->id == ZigTypeIdFloat) { |
| 22826 | switch (float_type->data.floating.bit_count) { |
| 22827 | case 16: |
| 22828 | out_val->data.x_f16 = f16_mulAdd(op1->data.x_f16, op2->data.x_f16, op3->data.x_f16); |
| 22829 | break; |
| 22830 | case 32: |
| 22831 | out_val->data.x_f32 = fmaf(op1->data.x_f32, op2->data.x_f32, op3->data.x_f32); |
| 22832 | break; |
| 22833 | case 64: |
| 22834 | out_val->data.x_f64 = fma(op1->data.x_f64, op2->data.x_f64, op3->data.x_f64); |
| 22835 | break; |
| 22836 | case 128: |
| 22837 | f128M_mulAdd(&op1->data.x_f128, &op2->data.x_f128, &op3->data.x_f128, &out_val->data.x_f128); |
| 22838 | break; |
| 22839 | default: |
| 22840 | zig_unreachable(); |
| 22841 | } |
| 22842 | } else { |
| 22843 | zig_unreachable(); |
| 22844 | } |
| 22845 | } |
| 22846 | |
| 22847 | static IrInstruction *ir_analyze_instruction_mul_add(IrAnalyze *ira, IrInstructionMulAdd *instruction) { |
| 22848 | IrInstruction *type_value = instruction->type_value->child; |
| 22849 | if (type_is_invalid(type_value->value.type)) |
| 22850 | return ira->codegen->invalid_instruction; |
| 22851 | |
| 22852 | ZigType *expr_type = ir_resolve_type(ira, type_value); |
| 22853 | if (type_is_invalid(expr_type)) |
| 22854 | return ira->codegen->invalid_instruction; |
| 22855 | |
| 22856 | // Only allow float types, and vectors of floats. |
| 22857 | ZigType *float_type = (expr_type->id == ZigTypeIdVector) ? expr_type->data.vector.elem_type : expr_type; |
| 22858 | if (float_type->id != ZigTypeIdFloat) { |
| 22859 | ir_add_error(ira, type_value, |
| 22860 | buf_sprintf("expected float or vector of float type, found '%s'", buf_ptr(&float_type->name))); |
| 22861 | return ira->codegen->invalid_instruction; |
| 22862 | } |
| 22863 | |
| 22864 | IrInstruction *op1 = instruction->op1->child; |
| 22865 | if (type_is_invalid(op1->value.type)) |
| 22866 | return ira->codegen->invalid_instruction; |
| 22867 | |
| 22868 | IrInstruction *casted_op1 = ir_implicit_cast(ira, op1, expr_type); |
| 22869 | if (type_is_invalid(casted_op1->value.type)) |
| 22870 | return ira->codegen->invalid_instruction; |
| 22871 | |
| 22872 | IrInstruction *op2 = instruction->op2->child; |
| 22873 | if (type_is_invalid(op2->value.type)) |
| 22874 | return ira->codegen->invalid_instruction; |
| 22875 | |
| 22876 | IrInstruction *casted_op2 = ir_implicit_cast(ira, op2, expr_type); |
| 22877 | if (type_is_invalid(casted_op2->value.type)) |
| 22878 | return ira->codegen->invalid_instruction; |
| 22879 | |
| 22880 | IrInstruction *op3 = instruction->op3->child; |
| 22881 | if (type_is_invalid(op3->value.type)) |
| 22882 | return ira->codegen->invalid_instruction; |
| 22883 | |
| 22884 | IrInstruction *casted_op3 = ir_implicit_cast(ira, op3, expr_type); |
| 22885 | if (type_is_invalid(casted_op3->value.type)) |
| 22886 | return ira->codegen->invalid_instruction; |
| 22887 | |
| 22888 | if (instr_is_comptime(casted_op1) && |
| 22889 | instr_is_comptime(casted_op2) && |
| 22890 | instr_is_comptime(casted_op3)) { |
| 22891 | ConstExprValue *op1_const = ir_resolve_const(ira, casted_op1, UndefBad); |
| 22892 | if (!op1_const) |
| 22893 | return ira->codegen->invalid_instruction; |
| 22894 | ConstExprValue *op2_const = ir_resolve_const(ira, casted_op2, UndefBad); |
| 22895 | if (!op2_const) |
| 22896 | return ira->codegen->invalid_instruction; |
| 22897 | ConstExprValue *op3_const = ir_resolve_const(ira, casted_op3, UndefBad); |
| 22898 | if (!op3_const) |
| 22899 | return ira->codegen->invalid_instruction; |
| 22900 | |
| 22901 | IrInstruction *result = ir_const(ira, &instruction->base, expr_type); |
| 22902 | ConstExprValue *out_val = &result->value; |
| 22903 | |
| 22904 | if (expr_type->id == ZigTypeIdVector) { |
| 22905 | expand_undef_array(ira->codegen, op1_const); |
| 22906 | expand_undef_array(ira->codegen, op2_const); |
| 22907 | expand_undef_array(ira->codegen, op3_const); |
| 22908 | out_val->special = ConstValSpecialUndef; |
| 22909 | expand_undef_array(ira->codegen, out_val); |
| 22910 | size_t len = expr_type->data.vector.len; |
| 22911 | for (size_t i = 0; i < len; i += 1) { |
| 22912 | ConstExprValue *float_operand_op1 = &op1_const->data.x_array.data.s_none.elements[i]; |
| 22913 | ConstExprValue *float_operand_op2 = &op2_const->data.x_array.data.s_none.elements[i]; |
| 22914 | ConstExprValue *float_operand_op3 = &op3_const->data.x_array.data.s_none.elements[i]; |
| 22915 | ConstExprValue *float_out_val = &out_val->data.x_array.data.s_none.elements[i]; |
| 22916 | assert(float_operand_op1->type == float_type); |
| 22917 | assert(float_operand_op2->type == float_type); |
| 22918 | assert(float_operand_op3->type == float_type); |
| 22919 | assert(float_out_val->type == float_type); |
| 22920 | ir_eval_mul_add(ira, instruction, float_type, |
| 22921 | op1_const, op2_const, op3_const, float_out_val); |
| 22922 | float_out_val->type = float_type; |
| 22923 | } |
| 22924 | out_val->type = expr_type; |
| 22925 | out_val->special = ConstValSpecialStatic; |
| 22926 | } else { |
| 22927 | ir_eval_mul_add(ira, instruction, float_type, op1_const, op2_const, op3_const, out_val); |
| 22928 | } |
| 22929 | return result; |
| 22930 | } |
| 22931 | |
| 22932 | IrInstruction *result = ir_build_mul_add(&ira->new_irb, |
| 22933 | instruction->base.scope, instruction->base.source_node, |
| 22934 | type_value, casted_op1, casted_op2, casted_op3); |
| 22935 | result->value.type = expr_type; |
| 22936 | return result; |
| 22937 | } |
| 22938 | |
| 22939 | static IrInstruction *ir_analyze_instruction_test_err(IrAnalyze *ira, IrInstructionTestErrSrc *instruction) { |
| 22940 | IrInstruction *base_ptr = instruction->base_ptr->child; |
| 22941 | if (type_is_invalid(base_ptr->value.type)) |
| 21193 | 22942 | return ira->codegen->invalid_instruction; |
| 21194 | 22943 | |
| 22944 | IrInstruction *value = ir_get_deref(ira, &instruction->base, base_ptr, nullptr); |
| 21195 | 22945 | ZigType *type_entry = value->value.type; |
| 21196 | | if (type_is_invalid(type_entry)) { |
| 22946 | if (type_is_invalid(type_entry)) |
| 21197 | 22947 | return ira->codegen->invalid_instruction; |
| 21198 | | } else if (type_entry->id == ZigTypeIdErrorUnion) { |
| 22948 | |
| 22949 | if (type_entry->id == ZigTypeIdErrorUnion) { |
| 21199 | 22950 | if (instr_is_comptime(value)) { |
| 21200 | 22951 | ConstExprValue *err_union_val = ir_resolve_const(ira, value, UndefBad); |
| 21201 | 22952 | if (!err_union_val) |
| ... | ... | @@ -21207,21 +22958,20 @@ static IrInstruction *ir_analyze_instruction_test_err(IrAnalyze *ira, IrInstruct |
| 21207 | 22958 | } |
| 21208 | 22959 | } |
| 21209 | 22960 | |
| 21210 | | ZigType *err_set_type = type_entry->data.error_union.err_set_type; |
| 21211 | | if (!resolve_inferred_error_set(ira->codegen, err_set_type, instruction->base.source_node)) { |
| 21212 | | return ira->codegen->invalid_instruction; |
| 21213 | | } |
| 21214 | | if (!type_is_global_error_set(err_set_type) && |
| 21215 | | err_set_type->data.error_set.err_count == 0) |
| 21216 | | { |
| 21217 | | assert(err_set_type->data.error_set.infer_fn == nullptr); |
| 21218 | | return ir_const_bool(ira, &instruction->base, false); |
| 22961 | if (instruction->resolve_err_set) { |
| 22962 | ZigType *err_set_type = type_entry->data.error_union.err_set_type; |
| 22963 | if (!resolve_inferred_error_set(ira->codegen, err_set_type, instruction->base.source_node)) { |
| 22964 | return ira->codegen->invalid_instruction; |
| 22965 | } |
| 22966 | if (!type_is_global_error_set(err_set_type) && |
| 22967 | err_set_type->data.error_set.err_count == 0) |
| 22968 | { |
| 22969 | assert(err_set_type->data.error_set.infer_fn == nullptr); |
| 22970 | return ir_const_bool(ira, &instruction->base, false); |
| 22971 | } |
| 21219 | 22972 | } |
| 21220 | 22973 | |
| 21221 | | IrInstruction *result = ir_build_test_err(&ira->new_irb, |
| 21222 | | instruction->base.scope, instruction->base.source_node, value); |
| 21223 | | result->value.type = ira->codegen->builtin_types.entry_bool; |
| 21224 | | return result; |
| 22974 | return ir_build_test_err_gen(ira, &instruction->base, value); |
| 21225 | 22975 | } else if (type_entry->id == ZigTypeIdErrorSet) { |
| 21226 | 22976 | return ir_const_bool(ira, &instruction->base, true); |
| 21227 | 22977 | } else { |
| ... | ... | @@ -21229,10 +22979,9 @@ static IrInstruction *ir_analyze_instruction_test_err(IrAnalyze *ira, IrInstruct |
| 21229 | 22979 | } |
| 21230 | 22980 | } |
| 21231 | 22981 | |
| 21232 | | static IrInstruction *ir_analyze_instruction_unwrap_err_code(IrAnalyze *ira, IrInstructionUnwrapErrCode *instruction) { |
| 21233 | | IrInstruction *base_ptr = instruction->err_union->child; |
| 21234 | | if (type_is_invalid(base_ptr->value.type)) |
| 21235 | | return ira->codegen->invalid_instruction; |
| 22982 | static IrInstruction *ir_analyze_unwrap_err_code(IrAnalyze *ira, IrInstruction *source_instr, |
| 22983 | IrInstruction *base_ptr, bool initializing) |
| 22984 | { |
| 21236 | 22985 | ZigType *ptr_type = base_ptr->value.type; |
| 21237 | 22986 | |
| 21238 | 22987 | // This will be a pointer type because unwrap err payload IR instruction operates on a pointer to a thing. |
| ... | ... | @@ -21248,40 +22997,79 @@ static IrInstruction *ir_analyze_instruction_unwrap_err_code(IrAnalyze *ira, IrI |
| 21248 | 22997 | return ira->codegen->invalid_instruction; |
| 21249 | 22998 | } |
| 21250 | 22999 | |
| 23000 | ZigType *err_set_type = type_entry->data.error_union.err_set_type; |
| 23001 | ZigType *result_type = get_pointer_to_type_extra(ira->codegen, err_set_type, |
| 23002 | ptr_type->data.pointer.is_const, ptr_type->data.pointer.is_volatile, PtrLenSingle, |
| 23003 | ptr_type->data.pointer.explicit_alignment, 0, 0, false); |
| 23004 | |
| 21251 | 23005 | if (instr_is_comptime(base_ptr)) { |
| 21252 | 23006 | ConstExprValue *ptr_val = ir_resolve_const(ira, base_ptr, UndefBad); |
| 21253 | 23007 | if (!ptr_val) |
| 21254 | 23008 | return ira->codegen->invalid_instruction; |
| 21255 | | if (ptr_val->data.x_ptr.mut != ConstPtrMutRuntimeVar) { |
| 21256 | | ConstExprValue *err_union_val = const_ptr_pointee(ira, ira->codegen, ptr_val, instruction->base.source_node); |
| 23009 | if (ptr_val->data.x_ptr.mut != ConstPtrMutRuntimeVar && |
| 23010 | ptr_val->data.x_ptr.special != ConstPtrSpecialHardCodedAddr) |
| 23011 | { |
| 23012 | ConstExprValue *err_union_val = const_ptr_pointee(ira, ira->codegen, ptr_val, source_instr->source_node); |
| 21257 | 23013 | if (err_union_val == nullptr) |
| 21258 | 23014 | return ira->codegen->invalid_instruction; |
| 21259 | | if (err_union_val->special != ConstValSpecialRuntime) { |
| 21260 | | ErrorTableEntry *err = err_union_val->data.x_err_union.error_set->data.x_err_set; |
| 21261 | | assert(err); |
| 21262 | 23015 | |
| 21263 | | IrInstruction *result = ir_const(ira, &instruction->base, |
| 21264 | | type_entry->data.error_union.err_set_type); |
| 21265 | | result->value.data.x_err_set = err; |
| 21266 | | return result; |
| 23016 | if (initializing && err_union_val->special == ConstValSpecialUndef) { |
| 23017 | ConstExprValue *vals = create_const_vals(2); |
| 23018 | ConstExprValue *err_set_val = &vals[0]; |
| 23019 | ConstExprValue *payload_val = &vals[1]; |
| 23020 | |
| 23021 | err_set_val->special = ConstValSpecialUndef; |
| 23022 | err_set_val->type = err_set_type; |
| 23023 | err_set_val->parent.id = ConstParentIdErrUnionCode; |
| 23024 | err_set_val->parent.data.p_err_union_code.err_union_val = err_union_val; |
| 23025 | |
| 23026 | payload_val->special = ConstValSpecialUndef; |
| 23027 | payload_val->type = type_entry->data.error_union.payload_type; |
| 23028 | payload_val->parent.id = ConstParentIdErrUnionPayload; |
| 23029 | payload_val->parent.data.p_err_union_payload.err_union_val = err_union_val; |
| 23030 | |
| 23031 | err_union_val->special = ConstValSpecialStatic; |
| 23032 | err_union_val->data.x_err_union.error_set = err_set_val; |
| 23033 | err_union_val->data.x_err_union.payload = payload_val; |
| 23034 | } |
| 23035 | ir_assert(err_union_val->special != ConstValSpecialRuntime, source_instr); |
| 23036 | |
| 23037 | IrInstruction *result; |
| 23038 | if (ptr_val->data.x_ptr.mut == ConstPtrMutInfer) { |
| 23039 | result = ir_build_unwrap_err_code(&ira->new_irb, source_instr->scope, |
| 23040 | source_instr->source_node, base_ptr); |
| 23041 | result->value.type = result_type; |
| 23042 | result->value.special = ConstValSpecialStatic; |
| 23043 | } else { |
| 23044 | result = ir_const(ira, source_instr, result_type); |
| 21267 | 23045 | } |
| 23046 | ConstExprValue *const_val = &result->value; |
| 23047 | const_val->data.x_ptr.special = ConstPtrSpecialBaseErrorUnionCode; |
| 23048 | const_val->data.x_ptr.data.base_err_union_code.err_union_val = err_union_val; |
| 23049 | const_val->data.x_ptr.mut = ptr_val->data.x_ptr.mut; |
| 23050 | return result; |
| 21268 | 23051 | } |
| 21269 | 23052 | } |
| 21270 | 23053 | |
| 21271 | 23054 | IrInstruction *result = ir_build_unwrap_err_code(&ira->new_irb, |
| 21272 | | instruction->base.scope, instruction->base.source_node, base_ptr); |
| 21273 | | result->value.type = type_entry->data.error_union.err_set_type; |
| 23055 | source_instr->scope, source_instr->source_node, base_ptr); |
| 23056 | result->value.type = result_type; |
| 21274 | 23057 | return result; |
| 21275 | 23058 | } |
| 21276 | 23059 | |
| 21277 | | static IrInstruction *ir_analyze_instruction_unwrap_err_payload(IrAnalyze *ira, |
| 21278 | | IrInstructionUnwrapErrPayload *instruction) |
| 23060 | static IrInstruction *ir_analyze_instruction_unwrap_err_code(IrAnalyze *ira, |
| 23061 | IrInstructionUnwrapErrCode *instruction) |
| 21279 | 23062 | { |
| 21280 | | assert(instruction->value->child); |
| 21281 | | IrInstruction *value = instruction->value->child; |
| 21282 | | if (type_is_invalid(value->value.type)) |
| 23063 | IrInstruction *base_ptr = instruction->err_union_ptr->child; |
| 23064 | if (type_is_invalid(base_ptr->value.type)) |
| 21283 | 23065 | return ira->codegen->invalid_instruction; |
| 21284 | | ZigType *ptr_type = value->value.type; |
| 23066 | return ir_analyze_unwrap_err_code(ira, &instruction->base, base_ptr, false); |
| 23067 | } |
| 23068 | |
| 23069 | static IrInstruction *ir_analyze_unwrap_error_payload(IrAnalyze *ira, IrInstruction *source_instr, |
| 23070 | IrInstruction *base_ptr, bool safety_check_on, bool initializing) |
| 23071 | { |
| 23072 | ZigType *ptr_type = base_ptr->value.type; |
| 21285 | 23073 | |
| 21286 | 23074 | // This will be a pointer type because unwrap err payload IR instruction operates on a pointer to a thing. |
| 21287 | 23075 | assert(ptr_type->id == ZigTypeIdPointer); |
| ... | ... | @@ -21291,7 +23079,7 @@ static IrInstruction *ir_analyze_instruction_unwrap_err_payload(IrAnalyze *ira, |
| 21291 | 23079 | return ira->codegen->invalid_instruction; |
| 21292 | 23080 | |
| 21293 | 23081 | if (type_entry->id != ZigTypeIdErrorUnion) { |
| 21294 | | ir_add_error(ira, value, |
| 23082 | ir_add_error(ira, base_ptr, |
| 21295 | 23083 | buf_sprintf("expected error union type, found '%s'", buf_ptr(&type_entry->name))); |
| 21296 | 23084 | return ira->codegen->invalid_instruction; |
| 21297 | 23085 | } |
| ... | ... | @@ -21303,36 +23091,73 @@ static IrInstruction *ir_analyze_instruction_unwrap_err_payload(IrAnalyze *ira, |
| 21303 | 23091 | ZigType *result_type = get_pointer_to_type_extra(ira->codegen, payload_type, |
| 21304 | 23092 | ptr_type->data.pointer.is_const, ptr_type->data.pointer.is_volatile, |
| 21305 | 23093 | PtrLenSingle, 0, 0, 0, false); |
| 21306 | | if (instr_is_comptime(value)) { |
| 21307 | | ConstExprValue *ptr_val = ir_resolve_const(ira, value, UndefBad); |
| 23094 | if (instr_is_comptime(base_ptr)) { |
| 23095 | ConstExprValue *ptr_val = ir_resolve_const(ira, base_ptr, UndefBad); |
| 21308 | 23096 | if (!ptr_val) |
| 21309 | 23097 | return ira->codegen->invalid_instruction; |
| 21310 | 23098 | if (ptr_val->data.x_ptr.mut != ConstPtrMutRuntimeVar) { |
| 21311 | | ConstExprValue *err_union_val = const_ptr_pointee(ira, ira->codegen, ptr_val, instruction->base.source_node); |
| 23099 | ConstExprValue *err_union_val = const_ptr_pointee(ira, ira->codegen, ptr_val, source_instr->source_node); |
| 21312 | 23100 | if (err_union_val == nullptr) |
| 21313 | 23101 | return ira->codegen->invalid_instruction; |
| 23102 | if (err_union_val->special == ConstValSpecialUndef && initializing) { |
| 23103 | ConstExprValue *vals = create_const_vals(2); |
| 23104 | ConstExprValue *err_set_val = &vals[0]; |
| 23105 | ConstExprValue *payload_val = &vals[1]; |
| 23106 | |
| 23107 | err_set_val->special = ConstValSpecialStatic; |
| 23108 | err_set_val->type = type_entry->data.error_union.err_set_type; |
| 23109 | err_set_val->data.x_err_set = nullptr; |
| 23110 | |
| 23111 | payload_val->special = ConstValSpecialUndef; |
| 23112 | payload_val->type = payload_type; |
| 23113 | |
| 23114 | err_union_val->special = ConstValSpecialStatic; |
| 23115 | err_union_val->data.x_err_union.error_set = err_set_val; |
| 23116 | err_union_val->data.x_err_union.payload = payload_val; |
| 23117 | } |
| 23118 | |
| 21314 | 23119 | if (err_union_val->special != ConstValSpecialRuntime) { |
| 21315 | 23120 | ErrorTableEntry *err = err_union_val->data.x_err_union.error_set->data.x_err_set; |
| 21316 | 23121 | if (err != nullptr) { |
| 21317 | | ir_add_error(ira, &instruction->base, |
| 23122 | ir_add_error(ira, source_instr, |
| 21318 | 23123 | buf_sprintf("caught unexpected error '%s'", buf_ptr(&err->name))); |
| 21319 | 23124 | return ira->codegen->invalid_instruction; |
| 21320 | 23125 | } |
| 21321 | 23126 | |
| 21322 | | IrInstruction *result = ir_const(ira, &instruction->base, result_type); |
| 23127 | IrInstruction *result; |
| 23128 | if (ptr_val->data.x_ptr.mut == ConstPtrMutInfer) { |
| 23129 | result = ir_build_unwrap_err_payload(&ira->new_irb, source_instr->scope, |
| 23130 | source_instr->source_node, base_ptr, safety_check_on, initializing); |
| 23131 | result->value.type = result_type; |
| 23132 | result->value.special = ConstValSpecialStatic; |
| 23133 | } else { |
| 23134 | result = ir_const(ira, source_instr, result_type); |
| 23135 | } |
| 21323 | 23136 | result->value.data.x_ptr.special = ConstPtrSpecialRef; |
| 21324 | 23137 | result->value.data.x_ptr.data.ref.pointee = err_union_val->data.x_err_union.payload; |
| 23138 | result->value.data.x_ptr.mut = ptr_val->data.x_ptr.mut; |
| 21325 | 23139 | return result; |
| 21326 | 23140 | } |
| 21327 | 23141 | } |
| 21328 | 23142 | } |
| 21329 | 23143 | |
| 21330 | | IrInstruction *result = ir_build_unwrap_err_payload(&ira->new_irb, |
| 21331 | | instruction->base.scope, instruction->base.source_node, value, instruction->safety_check_on); |
| 23144 | IrInstruction *result = ir_build_unwrap_err_payload(&ira->new_irb, source_instr->scope, |
| 23145 | source_instr->source_node, base_ptr, safety_check_on, initializing); |
| 21332 | 23146 | result->value.type = result_type; |
| 21333 | 23147 | return result; |
| 21334 | 23148 | } |
| 21335 | 23149 | |
| 23150 | static IrInstruction *ir_analyze_instruction_unwrap_err_payload(IrAnalyze *ira, |
| 23151 | IrInstructionUnwrapErrPayload *instruction) |
| 23152 | { |
| 23153 | assert(instruction->value->child); |
| 23154 | IrInstruction *value = instruction->value->child; |
| 23155 | if (type_is_invalid(value->value.type)) |
| 23156 | return ira->codegen->invalid_instruction; |
| 23157 | |
| 23158 | return ir_analyze_unwrap_error_payload(ira, &instruction->base, value, instruction->safety_check_on, false); |
| 23159 | } |
| 23160 | |
| 21336 | 23161 | static IrInstruction *ir_analyze_instruction_fn_proto(IrAnalyze *ira, IrInstructionFnProto *instruction) { |
| 21337 | 23162 | AstNode *proto_node = instruction->base.source_node; |
| 21338 | 23163 | assert(proto_node->type == NodeTypeFnProto); |
| ... | ... | @@ -21824,14 +23649,19 @@ static IrInstruction *ir_analyze_ptr_cast(IrAnalyze *ira, IrInstruction *source_ |
| 21824 | 23649 | } |
| 21825 | 23650 | } |
| 21826 | 23651 | |
| 21827 | | IrInstruction *result = ir_const(ira, source_instr, dest_type); |
| 23652 | IrInstruction *result; |
| 23653 | if (ptr->value.data.x_ptr.mut == ConstPtrMutInfer) { |
| 23654 | result = ir_build_ptr_cast_gen(ira, source_instr, dest_type, ptr, safety_check_on); |
| 23655 | } else { |
| 23656 | result = ir_const(ira, source_instr, dest_type); |
| 23657 | } |
| 21828 | 23658 | copy_const_val(&result->value, val, true); |
| 21829 | 23659 | result->value.type = dest_type; |
| 21830 | 23660 | |
| 21831 | 23661 | // Keep the bigger alignment, it can only help- |
| 21832 | 23662 | // unless the target is zero bits. |
| 21833 | 23663 | if (src_align_bytes > dest_align_bytes && type_has_bits(dest_type)) { |
| 21834 | | result = ir_align_cast(ira, result, src_align_bytes, false); |
| 23664 | result = ir_align_cast(ira, result, src_align_bytes, false); |
| 21835 | 23665 | } |
| 21836 | 23666 | |
| 21837 | 23667 | return result; |
| ... | ... | @@ -21915,6 +23745,8 @@ static void buf_write_value_bytes(CodeGen *codegen, uint8_t *buf, ConstExprValue |
| 21915 | 23745 | case ZigTypeIdUndefined: |
| 21916 | 23746 | case ZigTypeIdNull: |
| 21917 | 23747 | case ZigTypeIdPromise: |
| 23748 | case ZigTypeIdErrorUnion: |
| 23749 | case ZigTypeIdErrorSet: |
| 21918 | 23750 | zig_unreachable(); |
| 21919 | 23751 | case ZigTypeIdVoid: |
| 21920 | 23752 | return; |
| ... | ... | @@ -22018,10 +23850,6 @@ static void buf_write_value_bytes(CodeGen *codegen, uint8_t *buf, ConstExprValue |
| 22018 | 23850 | } |
| 22019 | 23851 | case ZigTypeIdOptional: |
| 22020 | 23852 | zig_panic("TODO buf_write_value_bytes maybe type"); |
| 22021 | | case ZigTypeIdErrorUnion: |
| 22022 | | zig_panic("TODO buf_write_value_bytes error union"); |
| 22023 | | case ZigTypeIdErrorSet: |
| 22024 | | zig_panic("TODO buf_write_value_bytes pure error type"); |
| 22025 | 23853 | case ZigTypeIdFn: |
| 22026 | 23854 | zig_panic("TODO buf_write_value_bytes fn type"); |
| 22027 | 23855 | case ZigTypeIdUnion: |
| ... | ... | @@ -22210,28 +24038,6 @@ static Error buf_read_value_bytes(IrAnalyze *ira, CodeGen *codegen, AstNode *sou |
| 22210 | 24038 | zig_unreachable(); |
| 22211 | 24039 | } |
| 22212 | 24040 | |
| 22213 | | static bool type_can_bit_cast(ZigType *t) { |
| 22214 | | switch (t->id) { |
| 22215 | | case ZigTypeIdInvalid: |
| 22216 | | zig_unreachable(); |
| 22217 | | case ZigTypeIdMetaType: |
| 22218 | | case ZigTypeIdOpaque: |
| 22219 | | case ZigTypeIdBoundFn: |
| 22220 | | case ZigTypeIdArgTuple: |
| 22221 | | case ZigTypeIdUnreachable: |
| 22222 | | case ZigTypeIdComptimeFloat: |
| 22223 | | case ZigTypeIdComptimeInt: |
| 22224 | | case ZigTypeIdEnumLiteral: |
| 22225 | | case ZigTypeIdUndefined: |
| 22226 | | case ZigTypeIdNull: |
| 22227 | | case ZigTypeIdPointer: |
| 22228 | | return false; |
| 22229 | | default: |
| 22230 | | // TODO list these types out explicitly, there are probably some other invalid ones here |
| 22231 | | return true; |
| 22232 | | } |
| 22233 | | } |
| 22234 | | |
| 22235 | 24041 | static IrInstruction *ir_analyze_bit_cast(IrAnalyze *ira, IrInstruction *source_instr, IrInstruction *value, |
| 22236 | 24042 | ZigType *dest_type) |
| 22237 | 24043 | { |
| ... | ... | @@ -22283,49 +24089,7 @@ static IrInstruction *ir_analyze_bit_cast(IrAnalyze *ira, IrInstruction *source_ |
| 22283 | 24089 | return result; |
| 22284 | 24090 | } |
| 22285 | 24091 | |
| 22286 | | IrInstruction *result = ir_build_bit_cast_gen(ira, source_instr, value, dest_type); |
| 22287 | | if (handle_is_ptr(dest_type) && !handle_is_ptr(src_type)) { |
| 22288 | | ir_add_alloca(ira, result, dest_type); |
| 22289 | | } |
| 22290 | | return result; |
| 22291 | | } |
| 22292 | | |
| 22293 | | static IrInstruction *ir_analyze_instruction_bit_cast(IrAnalyze *ira, IrInstructionBitCast *instruction) { |
| 22294 | | IrInstruction *dest_type_value = instruction->dest_type->child; |
| 22295 | | ZigType *dest_type = ir_resolve_type(ira, dest_type_value); |
| 22296 | | if (type_is_invalid(dest_type)) |
| 22297 | | return ira->codegen->invalid_instruction; |
| 22298 | | |
| 22299 | | IrInstruction *value = instruction->value->child; |
| 22300 | | ZigType *src_type = value->value.type; |
| 22301 | | if (type_is_invalid(src_type)) |
| 22302 | | return ira->codegen->invalid_instruction; |
| 22303 | | |
| 22304 | | if (get_codegen_ptr_type(src_type) != nullptr) { |
| 22305 | | ir_add_error(ira, value, |
| 22306 | | buf_sprintf("unable to @bitCast from pointer type '%s'", buf_ptr(&src_type->name))); |
| 22307 | | return ira->codegen->invalid_instruction; |
| 22308 | | } |
| 22309 | | |
| 22310 | | if (!type_can_bit_cast(src_type)) { |
| 22311 | | ir_add_error(ira, dest_type_value, |
| 22312 | | buf_sprintf("unable to @bitCast from type '%s'", buf_ptr(&src_type->name))); |
| 22313 | | return ira->codegen->invalid_instruction; |
| 22314 | | } |
| 22315 | | |
| 22316 | | if (get_codegen_ptr_type(dest_type) != nullptr) { |
| 22317 | | ir_add_error(ira, dest_type_value, |
| 22318 | | buf_sprintf("unable to @bitCast to pointer type '%s'", buf_ptr(&dest_type->name))); |
| 22319 | | return ira->codegen->invalid_instruction; |
| 22320 | | } |
| 22321 | | |
| 22322 | | if (!type_can_bit_cast(dest_type)) { |
| 22323 | | ir_add_error(ira, dest_type_value, |
| 22324 | | buf_sprintf("unable to @bitCast to type '%s'", buf_ptr(&dest_type->name))); |
| 22325 | | return ira->codegen->invalid_instruction; |
| 22326 | | } |
| 22327 | | |
| 22328 | | return ir_analyze_bit_cast(ira, &instruction->base, value, dest_type); |
| 24092 | return ir_build_bit_cast_gen(ira, source_instr, value, dest_type); |
| 22329 | 24093 | } |
| 22330 | 24094 | |
| 22331 | 24095 | static IrInstruction *ir_analyze_int_to_ptr(IrAnalyze *ira, IrInstruction *source_instr, IrInstruction *target, |
| ... | ... | @@ -22395,58 +24159,15 @@ static IrInstruction *ir_analyze_instruction_int_to_ptr(IrAnalyze *ira, IrInstru |
| 22395 | 24159 | static IrInstruction *ir_analyze_instruction_decl_ref(IrAnalyze *ira, |
| 22396 | 24160 | IrInstructionDeclRef *instruction) |
| 22397 | 24161 | { |
| 22398 | | Tld *tld = instruction->tld; |
| 22399 | | LVal lval = instruction->lval; |
| 22400 | | |
| 22401 | | resolve_top_level_decl(ira->codegen, tld, instruction->base.source_node); |
| 22402 | | if (tld->resolution == TldResolutionInvalid) |
| 24162 | IrInstruction *ref_instruction = ir_analyze_decl_ref(ira, &instruction->base, instruction->tld); |
| 24163 | if (type_is_invalid(ref_instruction->value.type)) |
| 22403 | 24164 | return ira->codegen->invalid_instruction; |
| 22404 | 24165 | |
| 22405 | | switch (tld->id) { |
| 22406 | | case TldIdContainer: |
| 22407 | | case TldIdCompTime: |
| 22408 | | zig_unreachable(); |
| 22409 | | case TldIdVar: { |
| 22410 | | TldVar *tld_var = (TldVar *)tld; |
| 22411 | | ZigVar *var = tld_var->var; |
| 22412 | | |
| 22413 | | if (var == nullptr) { |
| 22414 | | return ir_error_dependency_loop(ira, &instruction->base); |
| 22415 | | } |
| 22416 | | |
| 22417 | | IrInstruction *var_ptr = ir_get_var_ptr(ira, &instruction->base, var); |
| 22418 | | if (type_is_invalid(var_ptr->value.type)) |
| 22419 | | return ira->codegen->invalid_instruction; |
| 22420 | | |
| 22421 | | if (tld_var->extern_lib_name != nullptr) { |
| 22422 | | add_link_lib_symbol(ira, tld_var->extern_lib_name, &var->name, instruction->base.source_node); |
| 22423 | | } |
| 22424 | | |
| 22425 | | if (lval == LValPtr) { |
| 22426 | | return var_ptr; |
| 22427 | | } else { |
| 22428 | | return ir_get_deref(ira, &instruction->base, var_ptr); |
| 22429 | | } |
| 22430 | | } |
| 22431 | | case TldIdFn: { |
| 22432 | | TldFn *tld_fn = (TldFn *)tld; |
| 22433 | | ZigFn *fn_entry = tld_fn->fn_entry; |
| 22434 | | ir_assert(fn_entry->type_entry, &instruction->base); |
| 22435 | | |
| 22436 | | if (tld_fn->extern_lib_name != nullptr) { |
| 22437 | | add_link_lib_symbol(ira, tld_fn->extern_lib_name, &fn_entry->symbol_name, instruction->base.source_node); |
| 22438 | | } |
| 22439 | | |
| 22440 | | IrInstruction *ref_instruction = ir_create_const_fn(&ira->new_irb, instruction->base.scope, |
| 22441 | | instruction->base.source_node, fn_entry); |
| 22442 | | if (lval == LValPtr) { |
| 22443 | | return ir_get_ref(ira, &instruction->base, ref_instruction, true, false); |
| 22444 | | } else { |
| 22445 | | return ref_instruction; |
| 22446 | | } |
| 22447 | | } |
| 24166 | if (instruction->lval == LValPtr) { |
| 24167 | return ref_instruction; |
| 24168 | } else { |
| 24169 | return ir_get_deref(ira, &instruction->base, ref_instruction, nullptr); |
| 22448 | 24170 | } |
| 22449 | | zig_unreachable(); |
| 22450 | 24171 | } |
| 22451 | 24172 | |
| 22452 | 24173 | static IrInstruction *ir_analyze_instruction_ptr_to_int(IrAnalyze *ira, IrInstructionPtrToInt *instruction) { |
| ... | ... | @@ -22960,7 +24681,7 @@ static IrInstruction *ir_analyze_instruction_atomic_load(IrAnalyze *ira, IrInstr |
| 22960 | 24681 | } |
| 22961 | 24682 | |
| 22962 | 24683 | if (instr_is_comptime(casted_ptr)) { |
| 22963 | | IrInstruction *result = ir_get_deref(ira, &instruction->base, casted_ptr); |
| 24684 | IrInstruction *result = ir_get_deref(ira, &instruction->base, casted_ptr, nullptr); |
| 22964 | 24685 | ir_assert(result->value.type != nullptr, &instruction->base); |
| 22965 | 24686 | return result; |
| 22966 | 24687 | } |
| ... | ... | @@ -23048,70 +24769,254 @@ static IrInstruction *ir_analyze_instruction_mark_err_ret_trace_ptr(IrAnalyze *i |
| 23048 | 24769 | return result; |
| 23049 | 24770 | } |
| 23050 | 24771 | |
| 23051 | | static IrInstruction *ir_analyze_instruction_sqrt(IrAnalyze *ira, IrInstructionSqrt *instruction) { |
| 23052 | | ZigType *float_type = ir_resolve_type(ira, instruction->type->child); |
| 23053 | | if (type_is_invalid(float_type)) |
| 23054 | | return ira->codegen->invalid_instruction; |
| 24772 | static void ir_eval_float_op(IrAnalyze *ira, IrInstructionFloatOp *source_instr, ZigType *float_type, |
| 24773 | ConstExprValue *op, ConstExprValue *out_val) { |
| 24774 | assert(ira && source_instr && float_type && out_val && op); |
| 24775 | assert(float_type->id == ZigTypeIdFloat || |
| 24776 | float_type->id == ZigTypeIdComptimeFloat); |
| 23055 | 24777 | |
| 23056 | | IrInstruction *op = instruction->op->child; |
| 23057 | | if (type_is_invalid(op->value.type)) |
| 24778 | BuiltinFnId fop = source_instr->op; |
| 24779 | unsigned bits; |
| 24780 | |
| 24781 | switch (float_type->id) { |
| 24782 | case ZigTypeIdComptimeFloat: |
| 24783 | bits = 128; |
| 24784 | break; |
| 24785 | case ZigTypeIdFloat: |
| 24786 | bits = float_type->data.floating.bit_count; |
| 24787 | break; |
| 24788 | default: |
| 24789 | zig_unreachable(); |
| 24790 | } |
| 24791 | |
| 24792 | switch (bits) { |
| 24793 | case 16: { |
| 24794 | switch (fop) { |
| 24795 | case BuiltinFnIdSqrt: |
| 24796 | out_val->data.x_f16 = f16_sqrt(op->data.x_f16); |
| 24797 | break; |
| 24798 | case BuiltinFnIdSin: |
| 24799 | case BuiltinFnIdCos: |
| 24800 | case BuiltinFnIdExp: |
| 24801 | case BuiltinFnIdExp2: |
| 24802 | case BuiltinFnIdLn: |
| 24803 | case BuiltinFnIdLog10: |
| 24804 | case BuiltinFnIdLog2: |
| 24805 | case BuiltinFnIdFabs: |
| 24806 | case BuiltinFnIdFloor: |
| 24807 | case BuiltinFnIdCeil: |
| 24808 | case BuiltinFnIdTrunc: |
| 24809 | case BuiltinFnIdNearbyInt: |
| 24810 | case BuiltinFnIdRound: |
| 24811 | zig_panic("unimplemented f16 builtin"); |
| 24812 | default: |
| 24813 | zig_unreachable(); |
| 24814 | }; |
| 24815 | break; |
| 24816 | }; |
| 24817 | case 32: { |
| 24818 | switch (fop) { |
| 24819 | case BuiltinFnIdSqrt: |
| 24820 | out_val->data.x_f32 = sqrtf(op->data.x_f32); |
| 24821 | break; |
| 24822 | case BuiltinFnIdSin: |
| 24823 | out_val->data.x_f32 = sinf(op->data.x_f32); |
| 24824 | break; |
| 24825 | case BuiltinFnIdCos: |
| 24826 | out_val->data.x_f32 = cosf(op->data.x_f32); |
| 24827 | break; |
| 24828 | case BuiltinFnIdExp: |
| 24829 | out_val->data.x_f32 = expf(op->data.x_f32); |
| 24830 | break; |
| 24831 | case BuiltinFnIdExp2: |
| 24832 | out_val->data.x_f32 = exp2f(op->data.x_f32); |
| 24833 | break; |
| 24834 | case BuiltinFnIdLn: |
| 24835 | out_val->data.x_f32 = logf(op->data.x_f32); |
| 24836 | break; |
| 24837 | case BuiltinFnIdLog10: |
| 24838 | out_val->data.x_f32 = log10f(op->data.x_f32); |
| 24839 | break; |
| 24840 | case BuiltinFnIdLog2: |
| 24841 | out_val->data.x_f32 = log2f(op->data.x_f32); |
| 24842 | break; |
| 24843 | case BuiltinFnIdFabs: |
| 24844 | out_val->data.x_f32 = fabsf(op->data.x_f32); |
| 24845 | break; |
| 24846 | case BuiltinFnIdFloor: |
| 24847 | out_val->data.x_f32 = floorf(op->data.x_f32); |
| 24848 | break; |
| 24849 | case BuiltinFnIdCeil: |
| 24850 | out_val->data.x_f32 = ceilf(op->data.x_f32); |
| 24851 | break; |
| 24852 | case BuiltinFnIdTrunc: |
| 24853 | out_val->data.x_f32 = truncf(op->data.x_f32); |
| 24854 | break; |
| 24855 | case BuiltinFnIdNearbyInt: |
| 24856 | out_val->data.x_f32 = nearbyintf(op->data.x_f32); |
| 24857 | break; |
| 24858 | case BuiltinFnIdRound: |
| 24859 | out_val->data.x_f32 = roundf(op->data.x_f32); |
| 24860 | break; |
| 24861 | default: |
| 24862 | zig_unreachable(); |
| 24863 | }; |
| 24864 | break; |
| 24865 | }; |
| 24866 | case 64: { |
| 24867 | switch (fop) { |
| 24868 | case BuiltinFnIdSqrt: |
| 24869 | out_val->data.x_f64 = sqrt(op->data.x_f64); |
| 24870 | break; |
| 24871 | case BuiltinFnIdSin: |
| 24872 | out_val->data.x_f64 = sin(op->data.x_f64); |
| 24873 | break; |
| 24874 | case BuiltinFnIdCos: |
| 24875 | out_val->data.x_f64 = cos(op->data.x_f64); |
| 24876 | break; |
| 24877 | case BuiltinFnIdExp: |
| 24878 | out_val->data.x_f64 = exp(op->data.x_f64); |
| 24879 | break; |
| 24880 | case BuiltinFnIdExp2: |
| 24881 | out_val->data.x_f64 = exp2(op->data.x_f64); |
| 24882 | break; |
| 24883 | case BuiltinFnIdLn: |
| 24884 | out_val->data.x_f64 = log(op->data.x_f64); |
| 24885 | break; |
| 24886 | case BuiltinFnIdLog10: |
| 24887 | out_val->data.x_f64 = log10(op->data.x_f64); |
| 24888 | break; |
| 24889 | case BuiltinFnIdLog2: |
| 24890 | out_val->data.x_f64 = log2(op->data.x_f64); |
| 24891 | break; |
| 24892 | case BuiltinFnIdFabs: |
| 24893 | out_val->data.x_f64 = fabs(op->data.x_f64); |
| 24894 | break; |
| 24895 | case BuiltinFnIdFloor: |
| 24896 | out_val->data.x_f64 = floor(op->data.x_f64); |
| 24897 | break; |
| 24898 | case BuiltinFnIdCeil: |
| 24899 | out_val->data.x_f64 = ceil(op->data.x_f64); |
| 24900 | break; |
| 24901 | case BuiltinFnIdTrunc: |
| 24902 | out_val->data.x_f64 = trunc(op->data.x_f64); |
| 24903 | break; |
| 24904 | case BuiltinFnIdNearbyInt: |
| 24905 | out_val->data.x_f64 = nearbyint(op->data.x_f64); |
| 24906 | break; |
| 24907 | case BuiltinFnIdRound: |
| 24908 | out_val->data.x_f64 = round(op->data.x_f64); |
| 24909 | break; |
| 24910 | default: |
| 24911 | zig_unreachable(); |
| 24912 | } |
| 24913 | break; |
| 24914 | }; |
| 24915 | case 128: { |
| 24916 | float128_t *out, *in; |
| 24917 | if (float_type->id == ZigTypeIdComptimeFloat) { |
| 24918 | out = &out_val->data.x_bigfloat.value; |
| 24919 | in = &op->data.x_bigfloat.value; |
| 24920 | } else { |
| 24921 | out = &out_val->data.x_f128; |
| 24922 | in = &op->data.x_f128; |
| 24923 | } |
| 24924 | switch (fop) { |
| 24925 | case BuiltinFnIdSqrt: |
| 24926 | f128M_sqrt(in, out); |
| 24927 | break; |
| 24928 | case BuiltinFnIdNearbyInt: |
| 24929 | case BuiltinFnIdSin: |
| 24930 | case BuiltinFnIdCos: |
| 24931 | case BuiltinFnIdExp: |
| 24932 | case BuiltinFnIdExp2: |
| 24933 | case BuiltinFnIdLn: |
| 24934 | case BuiltinFnIdLog10: |
| 24935 | case BuiltinFnIdLog2: |
| 24936 | case BuiltinFnIdFabs: |
| 24937 | case BuiltinFnIdFloor: |
| 24938 | case BuiltinFnIdCeil: |
| 24939 | case BuiltinFnIdTrunc: |
| 24940 | case BuiltinFnIdRound: |
| 24941 | zig_panic("unimplemented f128 builtin"); |
| 24942 | default: |
| 24943 | zig_unreachable(); |
| 24944 | } |
| 24945 | break; |
| 24946 | }; |
| 24947 | default: |
| 24948 | zig_unreachable(); |
| 24949 | } |
| 24950 | } |
| 24951 | |
| 24952 | static IrInstruction *ir_analyze_instruction_float_op(IrAnalyze *ira, IrInstructionFloatOp *instruction) { |
| 24953 | IrInstruction *type = instruction->type->child; |
| 24954 | if (type_is_invalid(type->value.type)) |
| 24955 | return ira->codegen->invalid_instruction; |
| 24956 | |
| 24957 | ZigType *expr_type = ir_resolve_type(ira, type); |
| 24958 | if (type_is_invalid(expr_type)) |
| 23058 | 24959 | return ira->codegen->invalid_instruction; |
| 23059 | 24960 | |
| 23060 | | bool ok_type = float_type->id == ZigTypeIdComptimeFloat || float_type->id == ZigTypeIdFloat; |
| 23061 | | if (!ok_type) { |
| 23062 | | ir_add_error(ira, instruction->type, buf_sprintf("@sqrt does not support type '%s'", buf_ptr(&float_type->name))); |
| 24961 | // Only allow float types, and vectors of floats. |
| 24962 | ZigType *float_type = (expr_type->id == ZigTypeIdVector) ? expr_type->data.vector.elem_type : expr_type; |
| 24963 | if (float_type->id != ZigTypeIdFloat && float_type->id != ZigTypeIdComptimeFloat) { |
| 24964 | ir_add_error(ira, instruction->type, buf_sprintf("@%s does not support type '%s'", float_op_to_name(instruction->op, false), buf_ptr(&float_type->name))); |
| 23063 | 24965 | return ira->codegen->invalid_instruction; |
| 23064 | 24966 | } |
| 23065 | 24967 | |
| 23066 | | IrInstruction *casted_op = ir_implicit_cast(ira, op, float_type); |
| 23067 | | if (type_is_invalid(casted_op->value.type)) |
| 24968 | IrInstruction *op1 = instruction->op1->child; |
| 24969 | if (type_is_invalid(op1->value.type)) |
| 24970 | return ira->codegen->invalid_instruction; |
| 24971 | |
| 24972 | IrInstruction *casted_op1 = ir_implicit_cast(ira, op1, float_type); |
| 24973 | if (type_is_invalid(casted_op1->value.type)) |
| 23068 | 24974 | return ira->codegen->invalid_instruction; |
| 23069 | 24975 | |
| 23070 | | if (instr_is_comptime(casted_op)) { |
| 23071 | | ConstExprValue *val = ir_resolve_const(ira, casted_op, UndefBad); |
| 23072 | | if (!val) |
| 24976 | if (instr_is_comptime(casted_op1)) { |
| 24977 | // Our comptime 16-bit and 128-bit support is quite limited. |
| 24978 | if ((float_type->id == ZigTypeIdComptimeFloat || |
| 24979 | float_type->data.floating.bit_count == 16 || |
| 24980 | float_type->data.floating.bit_count == 128) && |
| 24981 | instruction->op != BuiltinFnIdSqrt) { |
| 24982 | ir_add_error(ira, instruction->type, buf_sprintf("@%s does not support type '%s'", float_op_to_name(instruction->op, false), buf_ptr(&float_type->name))); |
| 24983 | return ira->codegen->invalid_instruction; |
| 24984 | } |
| 24985 | |
| 24986 | ConstExprValue *op1_const = ir_resolve_const(ira, casted_op1, UndefBad); |
| 24987 | if (!op1_const) |
| 23073 | 24988 | return ira->codegen->invalid_instruction; |
| 23074 | 24989 | |
| 23075 | | IrInstruction *result = ir_const(ira, &instruction->base, float_type); |
| 24990 | IrInstruction *result = ir_const(ira, &instruction->base, expr_type); |
| 23076 | 24991 | ConstExprValue *out_val = &result->value; |
| 23077 | 24992 | |
| 23078 | | if (float_type->id == ZigTypeIdComptimeFloat) { |
| 23079 | | bigfloat_sqrt(&out_val->data.x_bigfloat, &val->data.x_bigfloat); |
| 23080 | | } else if (float_type->id == ZigTypeIdFloat) { |
| 23081 | | switch (float_type->data.floating.bit_count) { |
| 23082 | | case 16: |
| 23083 | | out_val->data.x_f16 = f16_sqrt(val->data.x_f16); |
| 23084 | | break; |
| 23085 | | case 32: |
| 23086 | | out_val->data.x_f32 = sqrtf(val->data.x_f32); |
| 23087 | | break; |
| 23088 | | case 64: |
| 23089 | | out_val->data.x_f64 = sqrt(val->data.x_f64); |
| 23090 | | break; |
| 23091 | | case 128: |
| 23092 | | f128M_sqrt(&val->data.x_f128, &out_val->data.x_f128); |
| 23093 | | break; |
| 23094 | | default: |
| 23095 | | zig_unreachable(); |
| 24993 | if (expr_type->id == ZigTypeIdVector) { |
| 24994 | expand_undef_array(ira->codegen, op1_const); |
| 24995 | out_val->special = ConstValSpecialUndef; |
| 24996 | expand_undef_array(ira->codegen, out_val); |
| 24997 | size_t len = expr_type->data.vector.len; |
| 24998 | for (size_t i = 0; i < len; i += 1) { |
| 24999 | ConstExprValue *float_operand_op1 = &op1_const->data.x_array.data.s_none.elements[i]; |
| 25000 | ConstExprValue *float_out_val = &out_val->data.x_array.data.s_none.elements[i]; |
| 25001 | assert(float_operand_op1->type == float_type); |
| 25002 | assert(float_out_val->type == float_type); |
| 25003 | ir_eval_float_op(ira, instruction, float_type, |
| 25004 | op1_const, float_out_val); |
| 25005 | float_out_val->type = float_type; |
| 23096 | 25006 | } |
| 25007 | out_val->type = expr_type; |
| 25008 | out_val->special = ConstValSpecialStatic; |
| 23097 | 25009 | } else { |
| 23098 | | zig_unreachable(); |
| 25010 | ir_eval_float_op(ira, instruction, float_type, op1_const, out_val); |
| 23099 | 25011 | } |
| 23100 | | |
| 23101 | 25012 | return result; |
| 23102 | 25013 | } |
| 23103 | 25014 | |
| 23104 | 25015 | ir_assert(float_type->id == ZigTypeIdFloat, &instruction->base); |
| 23105 | | if (float_type->data.floating.bit_count != 16 && |
| 23106 | | float_type->data.floating.bit_count != 32 && |
| 23107 | | float_type->data.floating.bit_count != 64) { |
| 23108 | | ir_add_error(ira, instruction->type, buf_sprintf("compiler TODO: add implementation of sqrt for '%s'", buf_ptr(&float_type->name))); |
| 23109 | | return ira->codegen->invalid_instruction; |
| 23110 | | } |
| 23111 | 25016 | |
| 23112 | | IrInstruction *result = ir_build_sqrt(&ira->new_irb, instruction->base.scope, |
| 23113 | | instruction->base.source_node, nullptr, casted_op); |
| 23114 | | result->value.type = float_type; |
| 25017 | IrInstruction *result = ir_build_float_op(&ira->new_irb, instruction->base.scope, |
| 25018 | instruction->base.source_node, nullptr, casted_op1, instruction->op); |
| 25019 | result->value.type = expr_type; |
| 23115 | 25020 | return result; |
| 23116 | 25021 | } |
| 23117 | 25022 | |
| ... | ... | @@ -23314,12 +25219,56 @@ static IrInstruction *ir_analyze_instruction_undeclared_ident(IrAnalyze *ira, Ir |
| 23314 | 25219 | return ira->codegen->invalid_instruction; |
| 23315 | 25220 | } |
| 23316 | 25221 | |
| 23317 | | static IrInstruction *ir_analyze_instruction_nocast(IrAnalyze *ira, IrInstruction *instruction) { |
| 25222 | static IrInstruction *ir_analyze_instruction_end_expr(IrAnalyze *ira, IrInstructionEndExpr *instruction) { |
| 25223 | IrInstruction *value = instruction->value->child; |
| 25224 | if (type_is_invalid(value->value.type)) |
| 25225 | return ira->codegen->invalid_instruction; |
| 25226 | |
| 25227 | bool was_written = instruction->result_loc->written; |
| 25228 | IrInstruction *result_loc = ir_resolve_result(ira, &instruction->base, instruction->result_loc, |
| 25229 | value->value.type, value, false, false); |
| 25230 | if (result_loc != nullptr) { |
| 25231 | if (type_is_invalid(result_loc->value.type)) |
| 25232 | return ira->codegen->invalid_instruction; |
| 25233 | if (result_loc->value.type->id == ZigTypeIdUnreachable) |
| 25234 | return result_loc; |
| 25235 | |
| 25236 | if (!was_written) { |
| 25237 | IrInstruction *store_ptr = ir_analyze_store_ptr(ira, &instruction->base, result_loc, value); |
| 25238 | if (type_is_invalid(store_ptr->value.type)) { |
| 25239 | return ira->codegen->invalid_instruction; |
| 25240 | } |
| 25241 | } |
| 25242 | |
| 25243 | if (result_loc->value.data.x_ptr.mut == ConstPtrMutInfer) { |
| 25244 | if (instr_is_comptime(value)) { |
| 25245 | result_loc->value.data.x_ptr.mut = ConstPtrMutComptimeConst; |
| 25246 | } else { |
| 25247 | result_loc->value.special = ConstValSpecialRuntime; |
| 25248 | } |
| 25249 | } |
| 25250 | } |
| 25251 | |
| 25252 | return ir_const_void(ira, &instruction->base); |
| 25253 | } |
| 25254 | |
| 25255 | static IrInstruction *ir_analyze_instruction_bit_cast_src(IrAnalyze *ira, IrInstructionBitCastSrc *instruction) { |
| 25256 | IrInstruction *operand = instruction->operand->child; |
| 25257 | if (type_is_invalid(operand->value.type)) |
| 25258 | return operand; |
| 25259 | |
| 25260 | IrInstruction *result_loc = ir_resolve_result(ira, &instruction->base, |
| 25261 | &instruction->result_loc_bit_cast->base, operand->value.type, operand, false, false); |
| 25262 | if (result_loc != nullptr && (type_is_invalid(result_loc->value.type) || instr_is_unreachable(result_loc))) |
| 25263 | return result_loc; |
| 25264 | |
| 25265 | return instruction->result_loc_bit_cast->parent->gen_instruction; |
| 25266 | } |
| 25267 | |
| 25268 | static IrInstruction *ir_analyze_instruction_base(IrAnalyze *ira, IrInstruction *instruction) { |
| 23318 | 25269 | switch (instruction->id) { |
| 23319 | 25270 | case IrInstructionIdInvalid: |
| 23320 | 25271 | case IrInstructionIdWidenOrShorten: |
| 23321 | | case IrInstructionIdStructInit: |
| 23322 | | case IrInstructionIdUnionInit: |
| 23323 | 25272 | case IrInstructionIdStructFieldPtr: |
| 23324 | 25273 | case IrInstructionIdUnionFieldPtr: |
| 23325 | 25274 | case IrInstructionIdOptionalWrap: |
| ... | ... | @@ -23331,11 +25280,18 @@ static IrInstruction *ir_analyze_instruction_nocast(IrAnalyze *ira, IrInstructio |
| 23331 | 25280 | case IrInstructionIdCmpxchgGen: |
| 23332 | 25281 | case IrInstructionIdArrayToVector: |
| 23333 | 25282 | case IrInstructionIdVectorToArray: |
| 25283 | case IrInstructionIdPtrOfArrayToSlice: |
| 23334 | 25284 | case IrInstructionIdAssertZero: |
| 23335 | 25285 | case IrInstructionIdAssertNonNull: |
| 23336 | 25286 | case IrInstructionIdResizeSlice: |
| 23337 | 25287 | case IrInstructionIdLoadPtrGen: |
| 23338 | 25288 | case IrInstructionIdBitCastGen: |
| 25289 | case IrInstructionIdCallGen: |
| 25290 | case IrInstructionIdReturnPtr: |
| 25291 | case IrInstructionIdAllocaGen: |
| 25292 | case IrInstructionIdSliceGen: |
| 25293 | case IrInstructionIdRefGen: |
| 25294 | case IrInstructionIdTestErrGen: |
| 23339 | 25295 | zig_unreachable(); |
| 23340 | 25296 | |
| 23341 | 25297 | case IrInstructionIdReturn: |
| ... | ... | @@ -23358,8 +25314,8 @@ static IrInstruction *ir_analyze_instruction_nocast(IrAnalyze *ira, IrInstructio |
| 23358 | 25314 | return ir_analyze_instruction_var_ptr(ira, (IrInstructionVarPtr *)instruction); |
| 23359 | 25315 | case IrInstructionIdFieldPtr: |
| 23360 | 25316 | return ir_analyze_instruction_field_ptr(ira, (IrInstructionFieldPtr *)instruction); |
| 23361 | | case IrInstructionIdCall: |
| 23362 | | return ir_analyze_instruction_call(ira, (IrInstructionCall *)instruction); |
| 25317 | case IrInstructionIdCallSrc: |
| 25318 | return ir_analyze_instruction_call(ira, (IrInstructionCallSrc *)instruction); |
| 23363 | 25319 | case IrInstructionIdBr: |
| 23364 | 25320 | return ir_analyze_instruction_br(ira, (IrInstructionBr *)instruction); |
| 23365 | 25321 | case IrInstructionIdCondBr: |
| ... | ... | @@ -23370,10 +25326,6 @@ static IrInstruction *ir_analyze_instruction_nocast(IrAnalyze *ira, IrInstructio |
| 23370 | 25326 | return ir_analyze_instruction_phi(ira, (IrInstructionPhi *)instruction); |
| 23371 | 25327 | case IrInstructionIdTypeOf: |
| 23372 | 25328 | return ir_analyze_instruction_typeof(ira, (IrInstructionTypeOf *)instruction); |
| 23373 | | case IrInstructionIdToPtrType: |
| 23374 | | return ir_analyze_instruction_to_ptr_type(ira, (IrInstructionToPtrType *)instruction); |
| 23375 | | case IrInstructionIdPtrTypeChild: |
| 23376 | | return ir_analyze_instruction_ptr_type_child(ira, (IrInstructionPtrTypeChild *)instruction); |
| 23377 | 25329 | case IrInstructionIdSetCold: |
| 23378 | 25330 | return ir_analyze_instruction_set_cold(ira, (IrInstructionSetCold *)instruction); |
| 23379 | 25331 | case IrInstructionIdSetRuntimeSafety: |
| ... | ... | @@ -23474,8 +25426,8 @@ static IrInstruction *ir_analyze_instruction_nocast(IrAnalyze *ira, IrInstructio |
| 23474 | 25426 | return ir_analyze_instruction_memset(ira, (IrInstructionMemset *)instruction); |
| 23475 | 25427 | case IrInstructionIdMemcpy: |
| 23476 | 25428 | return ir_analyze_instruction_memcpy(ira, (IrInstructionMemcpy *)instruction); |
| 23477 | | case IrInstructionIdSlice: |
| 23478 | | return ir_analyze_instruction_slice(ira, (IrInstructionSlice *)instruction); |
| 25429 | case IrInstructionIdSliceSrc: |
| 25430 | return ir_analyze_instruction_slice(ira, (IrInstructionSliceSrc *)instruction); |
| 23479 | 25431 | case IrInstructionIdMemberCount: |
| 23480 | 25432 | return ir_analyze_instruction_member_count(ira, (IrInstructionMemberCount *)instruction); |
| 23481 | 25433 | case IrInstructionIdMemberType: |
| ... | ... | @@ -23494,8 +25446,8 @@ static IrInstruction *ir_analyze_instruction_nocast(IrAnalyze *ira, IrInstructio |
| 23494 | 25446 | return ir_analyze_instruction_align_of(ira, (IrInstructionAlignOf *)instruction); |
| 23495 | 25447 | case IrInstructionIdOverflowOp: |
| 23496 | 25448 | return ir_analyze_instruction_overflow_op(ira, (IrInstructionOverflowOp *)instruction); |
| 23497 | | case IrInstructionIdTestErr: |
| 23498 | | return ir_analyze_instruction_test_err(ira, (IrInstructionTestErr *)instruction); |
| 25449 | case IrInstructionIdTestErrSrc: |
| 25450 | return ir_analyze_instruction_test_err(ira, (IrInstructionTestErrSrc *)instruction); |
| 23499 | 25451 | case IrInstructionIdUnwrapErrCode: |
| 23500 | 25452 | return ir_analyze_instruction_unwrap_err_code(ira, (IrInstructionUnwrapErrCode *)instruction); |
| 23501 | 25453 | case IrInstructionIdUnwrapErrPayload: |
| ... | ... | @@ -23514,8 +25466,6 @@ static IrInstruction *ir_analyze_instruction_nocast(IrAnalyze *ira, IrInstructio |
| 23514 | 25466 | return ir_analyze_instruction_panic(ira, (IrInstructionPanic *)instruction); |
| 23515 | 25467 | case IrInstructionIdPtrCastSrc: |
| 23516 | 25468 | return ir_analyze_instruction_ptr_cast(ira, (IrInstructionPtrCastSrc *)instruction); |
| 23517 | | case IrInstructionIdBitCast: |
| 23518 | | return ir_analyze_instruction_bit_cast(ira, (IrInstructionBitCast *)instruction); |
| 23519 | 25469 | case IrInstructionIdIntToPtr: |
| 23520 | 25470 | return ir_analyze_instruction_int_to_ptr(ira, (IrInstructionIntToPtr *)instruction); |
| 23521 | 25471 | case IrInstructionIdPtrToInt: |
| ... | ... | @@ -23538,6 +25488,14 @@ static IrInstruction *ir_analyze_instruction_nocast(IrAnalyze *ira, IrInstructio |
| 23538 | 25488 | return ir_analyze_instruction_ptr_type(ira, (IrInstructionPtrType *)instruction); |
| 23539 | 25489 | case IrInstructionIdAlignCast: |
| 23540 | 25490 | return ir_analyze_instruction_align_cast(ira, (IrInstructionAlignCast *)instruction); |
| 25491 | case IrInstructionIdImplicitCast: |
| 25492 | return ir_analyze_instruction_implicit_cast(ira, (IrInstructionImplicitCast *)instruction); |
| 25493 | case IrInstructionIdResolveResult: |
| 25494 | return ir_analyze_instruction_resolve_result(ira, (IrInstructionResolveResult *)instruction); |
| 25495 | case IrInstructionIdResetResult: |
| 25496 | return ir_analyze_instruction_reset_result(ira, (IrInstructionResetResult *)instruction); |
| 25497 | case IrInstructionIdResultPtr: |
| 25498 | return ir_analyze_instruction_result_ptr(ira, (IrInstructionResultPtr *)instruction); |
| 23541 | 25499 | case IrInstructionIdOpaqueType: |
| 23542 | 25500 | return ir_analyze_instruction_opaque_type(ira, (IrInstructionOpaqueType *)instruction); |
| 23543 | 25501 | case IrInstructionIdSetAlignStack: |
| ... | ... | @@ -23596,8 +25554,10 @@ static IrInstruction *ir_analyze_instruction_nocast(IrAnalyze *ira, IrInstructio |
| 23596 | 25554 | return ir_analyze_instruction_merge_err_ret_traces(ira, (IrInstructionMergeErrRetTraces *)instruction); |
| 23597 | 25555 | case IrInstructionIdMarkErrRetTracePtr: |
| 23598 | 25556 | return ir_analyze_instruction_mark_err_ret_trace_ptr(ira, (IrInstructionMarkErrRetTracePtr *)instruction); |
| 23599 | | case IrInstructionIdSqrt: |
| 23600 | | return ir_analyze_instruction_sqrt(ira, (IrInstructionSqrt *)instruction); |
| 25557 | case IrInstructionIdFloatOp: |
| 25558 | return ir_analyze_instruction_float_op(ira, (IrInstructionFloatOp *)instruction); |
| 25559 | case IrInstructionIdMulAdd: |
| 25560 | return ir_analyze_instruction_mul_add(ira, (IrInstructionMulAdd *)instruction); |
| 23601 | 25561 | case IrInstructionIdIntToErr: |
| 23602 | 25562 | return ir_analyze_instruction_int_to_err(ira, (IrInstructionIntToErr *)instruction); |
| 23603 | 25563 | case IrInstructionIdErrToInt: |
| ... | ... | @@ -23612,17 +25572,16 @@ static IrInstruction *ir_analyze_instruction_nocast(IrAnalyze *ira, IrInstructio |
| 23612 | 25572 | return ir_analyze_instruction_has_decl(ira, (IrInstructionHasDecl *)instruction); |
| 23613 | 25573 | case IrInstructionIdUndeclaredIdent: |
| 23614 | 25574 | return ir_analyze_instruction_undeclared_ident(ira, (IrInstructionUndeclaredIdent *)instruction); |
| 25575 | case IrInstructionIdAllocaSrc: |
| 25576 | return nullptr; |
| 25577 | case IrInstructionIdEndExpr: |
| 25578 | return ir_analyze_instruction_end_expr(ira, (IrInstructionEndExpr *)instruction); |
| 25579 | case IrInstructionIdBitCastSrc: |
| 25580 | return ir_analyze_instruction_bit_cast_src(ira, (IrInstructionBitCastSrc *)instruction); |
| 23615 | 25581 | } |
| 23616 | 25582 | zig_unreachable(); |
| 23617 | 25583 | } |
| 23618 | 25584 | |
| 23619 | | static IrInstruction *ir_analyze_instruction(IrAnalyze *ira, IrInstruction *old_instruction) { |
| 23620 | | IrInstruction *new_instruction = ir_analyze_instruction_nocast(ira, old_instruction); |
| 23621 | | ir_assert(new_instruction->value.type != nullptr, old_instruction); |
| 23622 | | old_instruction->child = new_instruction; |
| 23623 | | return new_instruction; |
| 23624 | | } |
| 23625 | | |
| 23626 | 25585 | // This function attempts to evaluate IR code while doing type checking and other analysis. |
| 23627 | 25586 | // It emits a new IrExecutable which is partially evaluated IR code. |
| 23628 | 25587 | ZigType *ir_analyze(CodeGen *codegen, IrExecutable *old_exec, IrExecutable *new_exec, |
| ... | ... | @@ -23668,14 +25627,22 @@ ZigType *ir_analyze(CodeGen *codegen, IrExecutable *old_exec, IrExecutable *new_ |
| 23668 | 25627 | continue; |
| 23669 | 25628 | } |
| 23670 | 25629 | |
| 23671 | | IrInstruction *new_instruction = ir_analyze_instruction(ira, old_instruction); |
| 23672 | | if (type_is_invalid(new_instruction->value.type) && ir_should_inline(new_exec, old_instruction->scope)) { |
| 23673 | | return ira->codegen->builtin_types.entry_invalid; |
| 25630 | if (ira->codegen->verbose_ir) { |
| 25631 | fprintf(stderr, "analyze #%zu\n", old_instruction->debug_id); |
| 23674 | 25632 | } |
| 25633 | IrInstruction *new_instruction = ir_analyze_instruction_base(ira, old_instruction); |
| 25634 | if (new_instruction != nullptr) { |
| 25635 | ir_assert(new_instruction->value.type != nullptr || new_instruction->value.type != nullptr, old_instruction); |
| 25636 | old_instruction->child = new_instruction; |
| 23675 | 25637 | |
| 23676 | | // unreachable instructions do their own control flow. |
| 23677 | | if (new_instruction->value.type->id == ZigTypeIdUnreachable) |
| 23678 | | continue; |
| 25638 | if (type_is_invalid(new_instruction->value.type)) { |
| 25639 | return ira->codegen->builtin_types.entry_invalid; |
| 25640 | } |
| 25641 | |
| 25642 | // unreachable instructions do their own control flow. |
| 25643 | if (new_instruction->value.type->id == ZigTypeIdUnreachable) |
| 25644 | continue; |
| 25645 | } |
| 23679 | 25646 | |
| 23680 | 25647 | ira->instruction_index += 1; |
| 23681 | 25648 | } |
| ... | ... | @@ -23700,7 +25667,8 @@ bool ir_has_side_effects(IrInstruction *instruction) { |
| 23700 | 25667 | case IrInstructionIdDeclVarSrc: |
| 23701 | 25668 | case IrInstructionIdDeclVarGen: |
| 23702 | 25669 | case IrInstructionIdStorePtr: |
| 23703 | | case IrInstructionIdCall: |
| 25670 | case IrInstructionIdCallSrc: |
| 25671 | case IrInstructionIdCallGen: |
| 23704 | 25672 | case IrInstructionIdReturn: |
| 23705 | 25673 | case IrInstructionIdUnreachable: |
| 23706 | 25674 | case IrInstructionIdSetCold: |
| ... | ... | @@ -23747,27 +25715,28 @@ bool ir_has_side_effects(IrInstruction *instruction) { |
| 23747 | 25715 | case IrInstructionIdResizeSlice: |
| 23748 | 25716 | case IrInstructionIdGlobalAsm: |
| 23749 | 25717 | case IrInstructionIdUndeclaredIdent: |
| 25718 | case IrInstructionIdEndExpr: |
| 25719 | case IrInstructionIdPtrOfArrayToSlice: |
| 25720 | case IrInstructionIdSliceGen: |
| 25721 | case IrInstructionIdOptionalWrap: |
| 25722 | case IrInstructionIdVectorToArray: |
| 25723 | case IrInstructionIdResetResult: |
| 23750 | 25724 | return true; |
| 23751 | 25725 | |
| 23752 | 25726 | case IrInstructionIdPhi: |
| 23753 | 25727 | case IrInstructionIdUnOp: |
| 23754 | 25728 | case IrInstructionIdBinOp: |
| 23755 | 25729 | case IrInstructionIdLoadPtr: |
| 23756 | | case IrInstructionIdLoadPtrGen: |
| 23757 | 25730 | case IrInstructionIdConst: |
| 23758 | 25731 | case IrInstructionIdCast: |
| 23759 | 25732 | case IrInstructionIdContainerInitList: |
| 23760 | 25733 | case IrInstructionIdContainerInitFields: |
| 23761 | | case IrInstructionIdStructInit: |
| 23762 | | case IrInstructionIdUnionInit: |
| 23763 | 25734 | case IrInstructionIdFieldPtr: |
| 23764 | 25735 | case IrInstructionIdElemPtr: |
| 23765 | 25736 | case IrInstructionIdVarPtr: |
| 25737 | case IrInstructionIdReturnPtr: |
| 23766 | 25738 | case IrInstructionIdTypeOf: |
| 23767 | | case IrInstructionIdToPtrType: |
| 23768 | | case IrInstructionIdPtrTypeChild: |
| 23769 | 25739 | case IrInstructionIdStructFieldPtr: |
| 23770 | | case IrInstructionIdUnionFieldPtr: |
| 23771 | 25740 | case IrInstructionIdArrayType: |
| 23772 | 25741 | case IrInstructionIdPromiseType: |
| 23773 | 25742 | case IrInstructionIdSliceType: |
| ... | ... | @@ -23789,7 +25758,7 @@ bool ir_has_side_effects(IrInstruction *instruction) { |
| 23789 | 25758 | case IrInstructionIdIntType: |
| 23790 | 25759 | case IrInstructionIdVectorType: |
| 23791 | 25760 | case IrInstructionIdBoolNot: |
| 23792 | | case IrInstructionIdSlice: |
| 25761 | case IrInstructionIdSliceSrc: |
| 23793 | 25762 | case IrInstructionIdMemberCount: |
| 23794 | 25763 | case IrInstructionIdMemberType: |
| 23795 | 25764 | case IrInstructionIdMemberName: |
| ... | ... | @@ -23797,16 +25766,13 @@ bool ir_has_side_effects(IrInstruction *instruction) { |
| 23797 | 25766 | case IrInstructionIdReturnAddress: |
| 23798 | 25767 | case IrInstructionIdFrameAddress: |
| 23799 | 25768 | case IrInstructionIdHandle: |
| 23800 | | case IrInstructionIdTestErr: |
| 23801 | | case IrInstructionIdUnwrapErrCode: |
| 23802 | | case IrInstructionIdOptionalWrap: |
| 23803 | | case IrInstructionIdErrWrapCode: |
| 23804 | | case IrInstructionIdErrWrapPayload: |
| 25769 | case IrInstructionIdTestErrSrc: |
| 25770 | case IrInstructionIdTestErrGen: |
| 23805 | 25771 | case IrInstructionIdFnProto: |
| 23806 | 25772 | case IrInstructionIdTestComptime: |
| 23807 | 25773 | case IrInstructionIdPtrCastSrc: |
| 23808 | 25774 | case IrInstructionIdPtrCastGen: |
| 23809 | | case IrInstructionIdBitCast: |
| 25775 | case IrInstructionIdBitCastSrc: |
| 23810 | 25776 | case IrInstructionIdBitCastGen: |
| 23811 | 25777 | case IrInstructionIdWidenOrShorten: |
| 23812 | 25778 | case IrInstructionIdPtrToInt: |
| ... | ... | @@ -23824,6 +25790,8 @@ bool ir_has_side_effects(IrInstruction *instruction) { |
| 23824 | 25790 | case IrInstructionIdTypeInfo: |
| 23825 | 25791 | case IrInstructionIdTypeId: |
| 23826 | 25792 | case IrInstructionIdAlignCast: |
| 25793 | case IrInstructionIdImplicitCast: |
| 25794 | case IrInstructionIdResolveResult: |
| 23827 | 25795 | case IrInstructionIdOpaqueType: |
| 23828 | 25796 | case IrInstructionIdArgType: |
| 23829 | 25797 | case IrInstructionIdTagType: |
| ... | ... | @@ -23836,7 +25804,8 @@ bool ir_has_side_effects(IrInstruction *instruction) { |
| 23836 | 25804 | case IrInstructionIdCoroFree: |
| 23837 | 25805 | case IrInstructionIdCoroPromise: |
| 23838 | 25806 | case IrInstructionIdPromiseResultType: |
| 23839 | | case IrInstructionIdSqrt: |
| 25807 | case IrInstructionIdFloatOp: |
| 25808 | case IrInstructionIdMulAdd: |
| 23840 | 25809 | case IrInstructionIdAtomicLoad: |
| 23841 | 25810 | case IrInstructionIdIntCast: |
| 23842 | 25811 | case IrInstructionIdFloatCast: |
| ... | ... | @@ -23847,9 +25816,11 @@ bool ir_has_side_effects(IrInstruction *instruction) { |
| 23847 | 25816 | case IrInstructionIdFromBytes: |
| 23848 | 25817 | case IrInstructionIdToBytes: |
| 23849 | 25818 | case IrInstructionIdEnumToInt: |
| 23850 | | case IrInstructionIdVectorToArray: |
| 23851 | 25819 | case IrInstructionIdArrayToVector: |
| 23852 | 25820 | case IrInstructionIdHasDecl: |
| 25821 | case IrInstructionIdAllocaSrc: |
| 25822 | case IrInstructionIdAllocaGen: |
| 25823 | case IrInstructionIdResultPtr: |
| 23853 | 25824 | return false; |
| 23854 | 25825 | |
| 23855 | 25826 | case IrInstructionIdAsm: |
| ... | ... | @@ -23861,8 +25832,21 @@ bool ir_has_side_effects(IrInstruction *instruction) { |
| 23861 | 25832 | { |
| 23862 | 25833 | IrInstructionUnwrapErrPayload *unwrap_err_payload_instruction = |
| 23863 | 25834 | (IrInstructionUnwrapErrPayload *)instruction; |
| 23864 | | return unwrap_err_payload_instruction->safety_check_on; |
| 25835 | return unwrap_err_payload_instruction->safety_check_on || |
| 25836 | unwrap_err_payload_instruction->initializing; |
| 23865 | 25837 | } |
| 25838 | case IrInstructionIdUnwrapErrCode: |
| 25839 | return reinterpret_cast<IrInstructionUnwrapErrCode *>(instruction)->initializing; |
| 25840 | case IrInstructionIdUnionFieldPtr: |
| 25841 | return reinterpret_cast<IrInstructionUnionFieldPtr *>(instruction)->initializing; |
| 25842 | case IrInstructionIdErrWrapPayload: |
| 25843 | return reinterpret_cast<IrInstructionErrWrapPayload *>(instruction)->result_loc != nullptr; |
| 25844 | case IrInstructionIdErrWrapCode: |
| 25845 | return reinterpret_cast<IrInstructionErrWrapCode *>(instruction)->result_loc != nullptr; |
| 25846 | case IrInstructionIdLoadPtrGen: |
| 25847 | return reinterpret_cast<IrInstructionLoadPtrGen *>(instruction)->result_loc != nullptr; |
| 25848 | case IrInstructionIdRefGen: |
| 25849 | return reinterpret_cast<IrInstructionRefGen *>(instruction)->result_loc != nullptr; |
| 23866 | 25850 | } |
| 23867 | 25851 | zig_unreachable(); |
| 23868 | 25852 | } |