| ... | ... | @@ -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,12 @@ 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; |
| 748 | 778 | } |
| 749 | 779 | |
| 750 | 780 | static constexpr IrInstructionId ir_instruction_id(IrInstructionMulAdd *) { |
| ... | ... | @@ -787,8 +817,8 @@ static constexpr IrInstructionId ir_instruction_id(IrInstructionPtrCastGen *) { |
| 787 | 817 | return IrInstructionIdPtrCastGen; |
| 788 | 818 | } |
| 789 | 819 | |
| 790 | | static constexpr IrInstructionId ir_instruction_id(IrInstructionBitCast *) { |
| 791 | | return IrInstructionIdBitCast; |
| 820 | static constexpr IrInstructionId ir_instruction_id(IrInstructionBitCastSrc *) { |
| 821 | return IrInstructionIdBitCastSrc; |
| 792 | 822 | } |
| 793 | 823 | |
| 794 | 824 | static constexpr IrInstructionId ir_instruction_id(IrInstructionBitCastGen *) { |
| ... | ... | @@ -883,6 +913,26 @@ static constexpr IrInstructionId ir_instruction_id(IrInstructionAlignCast *) { |
| 883 | 913 | return IrInstructionIdAlignCast; |
| 884 | 914 | } |
| 885 | 915 | |
| 916 | static constexpr IrInstructionId ir_instruction_id(IrInstructionImplicitCast *) { |
| 917 | return IrInstructionIdImplicitCast; |
| 918 | } |
| 919 | |
| 920 | static constexpr IrInstructionId ir_instruction_id(IrInstructionResolveResult *) { |
| 921 | return IrInstructionIdResolveResult; |
| 922 | } |
| 923 | |
| 924 | static constexpr IrInstructionId ir_instruction_id(IrInstructionResetResult *) { |
| 925 | return IrInstructionIdResetResult; |
| 926 | } |
| 927 | |
| 928 | static constexpr IrInstructionId ir_instruction_id(IrInstructionResultPtr *) { |
| 929 | return IrInstructionIdResultPtr; |
| 930 | } |
| 931 | |
| 932 | static constexpr IrInstructionId ir_instruction_id(IrInstructionPtrOfArrayToSlice *) { |
| 933 | return IrInstructionIdPtrOfArrayToSlice; |
| 934 | } |
| 935 | |
| 886 | 936 | static constexpr IrInstructionId ir_instruction_id(IrInstructionOpaqueType *) { |
| 887 | 937 | return IrInstructionIdOpaqueType; |
| 888 | 938 | } |
| ... | ... | @@ -1023,6 +1073,18 @@ static constexpr IrInstructionId ir_instruction_id(IrInstructionUndeclaredIdent |
| 1023 | 1073 | return IrInstructionIdUndeclaredIdent; |
| 1024 | 1074 | } |
| 1025 | 1075 | |
| 1076 | static constexpr IrInstructionId ir_instruction_id(IrInstructionAllocaSrc *) { |
| 1077 | return IrInstructionIdAllocaSrc; |
| 1078 | } |
| 1079 | |
| 1080 | static constexpr IrInstructionId ir_instruction_id(IrInstructionAllocaGen *) { |
| 1081 | return IrInstructionIdAllocaGen; |
| 1082 | } |
| 1083 | |
| 1084 | static constexpr IrInstructionId ir_instruction_id(IrInstructionEndExpr *) { |
| 1085 | return IrInstructionIdEndExpr; |
| 1086 | } |
| 1087 | |
| 1026 | 1088 | template<typename T> |
| 1027 | 1089 | static T *ir_create_instruction(IrBuilder *irb, Scope *scope, AstNode *source_node) { |
| 1028 | 1090 | T *special_instruction = allocate<T>(1); |
| ... | ... | @@ -1074,13 +1136,15 @@ static IrInstruction *ir_build_cond_br(IrBuilder *irb, Scope *scope, AstNode *so |
| 1074 | 1136 | return &cond_br_instruction->base; |
| 1075 | 1137 | } |
| 1076 | 1138 | |
| 1077 | | static IrInstruction *ir_build_return(IrBuilder *irb, Scope *scope, AstNode *source_node, IrInstruction *return_value) { |
| 1139 | static IrInstruction *ir_build_return(IrBuilder *irb, Scope *scope, AstNode *source_node, |
| 1140 | IrInstruction *return_value) |
| 1141 | { |
| 1078 | 1142 | IrInstructionReturn *return_instruction = ir_build_instruction<IrInstructionReturn>(irb, scope, source_node); |
| 1079 | 1143 | return_instruction->base.value.type = irb->codegen->builtin_types.entry_unreachable; |
| 1080 | 1144 | return_instruction->base.value.special = ConstValSpecialStatic; |
| 1081 | 1145 | return_instruction->value = return_value; |
| 1082 | 1146 | |
| 1083 | | ir_ref_instruction(return_value, irb->current_basic_block); |
| 1147 | if (return_value != nullptr) ir_ref_instruction(return_value, irb->current_basic_block); |
| 1084 | 1148 | |
| 1085 | 1149 | return &return_instruction->base; |
| 1086 | 1150 | } |
| ... | ... | @@ -1258,17 +1322,27 @@ static IrInstruction *ir_build_var_ptr(IrBuilder *irb, Scope *scope, AstNode *so |
| 1258 | 1322 | return ir_build_var_ptr_x(irb, scope, source_node, var, nullptr); |
| 1259 | 1323 | } |
| 1260 | 1324 | |
| 1261 | | static IrInstruction *ir_build_elem_ptr(IrBuilder *irb, Scope *scope, AstNode *source_node, IrInstruction *array_ptr, |
| 1262 | | 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) |
| 1263 | 1335 | { |
| 1264 | 1336 | IrInstructionElemPtr *instruction = ir_build_instruction<IrInstructionElemPtr>(irb, scope, source_node); |
| 1265 | 1337 | instruction->array_ptr = array_ptr; |
| 1266 | 1338 | instruction->elem_index = elem_index; |
| 1267 | 1339 | instruction->safety_check_on = safety_check_on; |
| 1268 | 1340 | instruction->ptr_len = ptr_len; |
| 1341 | instruction->init_array_type = init_array_type; |
| 1269 | 1342 | |
| 1270 | 1343 | ir_ref_instruction(array_ptr, irb->current_basic_block); |
| 1271 | 1344 | ir_ref_instruction(elem_index, irb->current_basic_block); |
| 1345 | if (init_array_type != nullptr) ir_ref_instruction(init_array_type, irb->current_basic_block); |
| 1272 | 1346 | |
| 1273 | 1347 | return &instruction->base; |
| 1274 | 1348 | } |
| ... | ... | @@ -1288,12 +1362,13 @@ static IrInstruction *ir_build_field_ptr_instruction(IrBuilder *irb, Scope *scop |
| 1288 | 1362 | } |
| 1289 | 1363 | |
| 1290 | 1364 | static IrInstruction *ir_build_field_ptr(IrBuilder *irb, Scope *scope, AstNode *source_node, |
| 1291 | | IrInstruction *container_ptr, Buf *field_name) |
| 1365 | IrInstruction *container_ptr, Buf *field_name, bool initializing) |
| 1292 | 1366 | { |
| 1293 | 1367 | IrInstructionFieldPtr *instruction = ir_build_instruction<IrInstructionFieldPtr>(irb, scope, source_node); |
| 1294 | 1368 | instruction->container_ptr = container_ptr; |
| 1295 | 1369 | instruction->field_name_buffer = field_name; |
| 1296 | 1370 | instruction->field_name_expr = nullptr; |
| 1371 | instruction->initializing = initializing; |
| 1297 | 1372 | |
| 1298 | 1373 | ir_ref_instruction(container_ptr, irb->current_basic_block); |
| 1299 | 1374 | |
| ... | ... | @@ -1313,9 +1388,11 @@ static IrInstruction *ir_build_struct_field_ptr(IrBuilder *irb, Scope *scope, As |
| 1313 | 1388 | } |
| 1314 | 1389 | |
| 1315 | 1390 | static IrInstruction *ir_build_union_field_ptr(IrBuilder *irb, Scope *scope, AstNode *source_node, |
| 1316 | | IrInstruction *union_ptr, TypeUnionField *field) |
| 1391 | IrInstruction *union_ptr, TypeUnionField *field, bool safety_check_on, bool initializing) |
| 1317 | 1392 | { |
| 1318 | 1393 | IrInstructionUnionFieldPtr *instruction = ir_build_instruction<IrInstructionUnionFieldPtr>(irb, scope, source_node); |
| 1394 | instruction->initializing = initializing; |
| 1395 | instruction->safety_check_on = safety_check_on; |
| 1319 | 1396 | instruction->union_ptr = union_ptr; |
| 1320 | 1397 | instruction->field = field; |
| 1321 | 1398 | |
| ... | ... | @@ -1324,12 +1401,12 @@ static IrInstruction *ir_build_union_field_ptr(IrBuilder *irb, Scope *scope, Ast |
| 1324 | 1401 | return &instruction->base; |
| 1325 | 1402 | } |
| 1326 | 1403 | |
| 1327 | | static IrInstruction *ir_build_call(IrBuilder *irb, Scope *scope, AstNode *source_node, |
| 1404 | static IrInstruction *ir_build_call_src(IrBuilder *irb, Scope *scope, AstNode *source_node, |
| 1328 | 1405 | ZigFn *fn_entry, IrInstruction *fn_ref, size_t arg_count, IrInstruction **args, |
| 1329 | 1406 | bool is_comptime, FnInline fn_inline, bool is_async, IrInstruction *async_allocator, |
| 1330 | | IrInstruction *new_stack) |
| 1407 | IrInstruction *new_stack, ResultLoc *result_loc) |
| 1331 | 1408 | { |
| 1332 | | IrInstructionCall *call_instruction = ir_build_instruction<IrInstructionCall>(irb, scope, source_node); |
| 1409 | IrInstructionCallSrc *call_instruction = ir_build_instruction<IrInstructionCallSrc>(irb, scope, source_node); |
| 1333 | 1410 | call_instruction->fn_entry = fn_entry; |
| 1334 | 1411 | call_instruction->fn_ref = fn_ref; |
| 1335 | 1412 | call_instruction->is_comptime = is_comptime; |
| ... | ... | @@ -1339,6 +1416,7 @@ static IrInstruction *ir_build_call(IrBuilder *irb, Scope *scope, AstNode *sourc |
| 1339 | 1416 | call_instruction->is_async = is_async; |
| 1340 | 1417 | call_instruction->async_allocator = async_allocator; |
| 1341 | 1418 | call_instruction->new_stack = new_stack; |
| 1419 | call_instruction->result_loc = result_loc; |
| 1342 | 1420 | |
| 1343 | 1421 | if (fn_ref != nullptr) ir_ref_instruction(fn_ref, irb->current_basic_block); |
| 1344 | 1422 | for (size_t i = 0; i < arg_count; i += 1) |
| ... | ... | @@ -1349,8 +1427,37 @@ static IrInstruction *ir_build_call(IrBuilder *irb, Scope *scope, AstNode *sourc |
| 1349 | 1427 | return &call_instruction->base; |
| 1350 | 1428 | } |
| 1351 | 1429 | |
| 1430 | static IrInstruction *ir_build_call_gen(IrAnalyze *ira, IrInstruction *source_instruction, |
| 1431 | ZigFn *fn_entry, IrInstruction *fn_ref, size_t arg_count, IrInstruction **args, |
| 1432 | FnInline fn_inline, bool is_async, IrInstruction *async_allocator, IrInstruction *new_stack, |
| 1433 | IrInstruction *result_loc, ZigType *return_type) |
| 1434 | { |
| 1435 | IrInstructionCallGen *call_instruction = ir_build_instruction<IrInstructionCallGen>(&ira->new_irb, |
| 1436 | source_instruction->scope, source_instruction->source_node); |
| 1437 | call_instruction->base.value.type = return_type; |
| 1438 | call_instruction->fn_entry = fn_entry; |
| 1439 | call_instruction->fn_ref = fn_ref; |
| 1440 | call_instruction->fn_inline = fn_inline; |
| 1441 | call_instruction->args = args; |
| 1442 | call_instruction->arg_count = arg_count; |
| 1443 | call_instruction->is_async = is_async; |
| 1444 | call_instruction->async_allocator = async_allocator; |
| 1445 | call_instruction->new_stack = new_stack; |
| 1446 | call_instruction->result_loc = result_loc; |
| 1447 | |
| 1448 | if (fn_ref != nullptr) ir_ref_instruction(fn_ref, ira->new_irb.current_basic_block); |
| 1449 | for (size_t i = 0; i < arg_count; i += 1) |
| 1450 | ir_ref_instruction(args[i], ira->new_irb.current_basic_block); |
| 1451 | if (async_allocator != nullptr) ir_ref_instruction(async_allocator, ira->new_irb.current_basic_block); |
| 1452 | if (new_stack != nullptr) ir_ref_instruction(new_stack, ira->new_irb.current_basic_block); |
| 1453 | if (result_loc != nullptr) ir_ref_instruction(result_loc, ira->new_irb.current_basic_block); |
| 1454 | |
| 1455 | return &call_instruction->base; |
| 1456 | } |
| 1457 | |
| 1352 | 1458 | static IrInstruction *ir_build_phi(IrBuilder *irb, Scope *scope, AstNode *source_node, |
| 1353 | | size_t incoming_count, IrBasicBlock **incoming_blocks, IrInstruction **incoming_values) |
| 1459 | size_t incoming_count, IrBasicBlock **incoming_blocks, IrInstruction **incoming_values, |
| 1460 | ResultLocPeerParent *peer_parent) |
| 1354 | 1461 | { |
| 1355 | 1462 | assert(incoming_count != 0); |
| 1356 | 1463 | assert(incoming_count != SIZE_MAX); |
| ... | ... | @@ -1359,6 +1466,7 @@ static IrInstruction *ir_build_phi(IrBuilder *irb, Scope *scope, AstNode *source |
| 1359 | 1466 | phi_instruction->incoming_count = incoming_count; |
| 1360 | 1467 | phi_instruction->incoming_blocks = incoming_blocks; |
| 1361 | 1468 | phi_instruction->incoming_values = incoming_values; |
| 1469 | phi_instruction->peer_parent = peer_parent; |
| 1362 | 1470 | |
| 1363 | 1471 | for (size_t i = 0; i < incoming_count; i += 1) { |
| 1364 | 1472 | ir_ref_bb(incoming_blocks[i]); |
| ... | ... | @@ -1412,12 +1520,13 @@ static IrInstruction *ir_build_ptr_type(IrBuilder *irb, Scope *scope, AstNode *s |
| 1412 | 1520 | } |
| 1413 | 1521 | |
| 1414 | 1522 | static IrInstruction *ir_build_un_op_lval(IrBuilder *irb, Scope *scope, AstNode *source_node, IrUnOp op_id, |
| 1415 | | IrInstruction *value, LVal lval) |
| 1523 | IrInstruction *value, LVal lval, ResultLoc *result_loc) |
| 1416 | 1524 | { |
| 1417 | 1525 | IrInstructionUnOp *instruction = ir_build_instruction<IrInstructionUnOp>(irb, scope, source_node); |
| 1418 | 1526 | instruction->op_id = op_id; |
| 1419 | 1527 | instruction->value = value; |
| 1420 | 1528 | instruction->lval = lval; |
| 1529 | instruction->result_loc = result_loc; |
| 1421 | 1530 | |
| 1422 | 1531 | ir_ref_instruction(value, irb->current_basic_block); |
| 1423 | 1532 | |
| ... | ... | @@ -1427,72 +1536,49 @@ static IrInstruction *ir_build_un_op_lval(IrBuilder *irb, Scope *scope, AstNode |
| 1427 | 1536 | static IrInstruction *ir_build_un_op(IrBuilder *irb, Scope *scope, AstNode *source_node, IrUnOp op_id, |
| 1428 | 1537 | IrInstruction *value) |
| 1429 | 1538 | { |
| 1430 | | return ir_build_un_op_lval(irb, scope, source_node, op_id, value, LValNone); |
| 1539 | return ir_build_un_op_lval(irb, scope, source_node, op_id, value, LValNone, nullptr); |
| 1431 | 1540 | } |
| 1432 | 1541 | |
| 1433 | 1542 | static IrInstruction *ir_build_container_init_list(IrBuilder *irb, Scope *scope, AstNode *source_node, |
| 1434 | | IrInstruction *container_type, IrInstruction *elem_type, size_t item_count, IrInstruction **items) |
| 1543 | IrInstruction *container_type, size_t item_count, IrInstruction **elem_result_loc_list, |
| 1544 | IrInstruction *result_loc) |
| 1435 | 1545 | { |
| 1436 | 1546 | IrInstructionContainerInitList *container_init_list_instruction = |
| 1437 | 1547 | ir_build_instruction<IrInstructionContainerInitList>(irb, scope, source_node); |
| 1438 | 1548 | container_init_list_instruction->container_type = container_type; |
| 1439 | | container_init_list_instruction->elem_type = elem_type; |
| 1440 | 1549 | container_init_list_instruction->item_count = item_count; |
| 1441 | | container_init_list_instruction->items = items; |
| 1550 | container_init_list_instruction->elem_result_loc_list = elem_result_loc_list; |
| 1551 | container_init_list_instruction->result_loc = result_loc; |
| 1442 | 1552 | |
| 1443 | | if (container_type != nullptr) ir_ref_instruction(container_type, irb->current_basic_block); |
| 1444 | | if (elem_type != nullptr) ir_ref_instruction(elem_type, irb->current_basic_block); |
| 1553 | ir_ref_instruction(container_type, irb->current_basic_block); |
| 1445 | 1554 | for (size_t i = 0; i < item_count; i += 1) { |
| 1446 | | ir_ref_instruction(items[i], irb->current_basic_block); |
| 1555 | ir_ref_instruction(elem_result_loc_list[i], irb->current_basic_block); |
| 1447 | 1556 | } |
| 1557 | if (result_loc != nullptr) ir_ref_instruction(result_loc, irb->current_basic_block); |
| 1448 | 1558 | |
| 1449 | 1559 | return &container_init_list_instruction->base; |
| 1450 | 1560 | } |
| 1451 | 1561 | |
| 1452 | 1562 | static IrInstruction *ir_build_container_init_fields(IrBuilder *irb, Scope *scope, AstNode *source_node, |
| 1453 | | IrInstruction *container_type, size_t field_count, IrInstructionContainerInitFieldsField *fields) |
| 1563 | IrInstruction *container_type, size_t field_count, IrInstructionContainerInitFieldsField *fields, |
| 1564 | IrInstruction *result_loc) |
| 1454 | 1565 | { |
| 1455 | 1566 | IrInstructionContainerInitFields *container_init_fields_instruction = |
| 1456 | 1567 | ir_build_instruction<IrInstructionContainerInitFields>(irb, scope, source_node); |
| 1457 | 1568 | container_init_fields_instruction->container_type = container_type; |
| 1458 | 1569 | container_init_fields_instruction->field_count = field_count; |
| 1459 | 1570 | container_init_fields_instruction->fields = fields; |
| 1571 | container_init_fields_instruction->result_loc = result_loc; |
| 1460 | 1572 | |
| 1461 | 1573 | ir_ref_instruction(container_type, irb->current_basic_block); |
| 1462 | 1574 | for (size_t i = 0; i < field_count; i += 1) { |
| 1463 | | ir_ref_instruction(fields[i].value, irb->current_basic_block); |
| 1575 | ir_ref_instruction(fields[i].result_loc, irb->current_basic_block); |
| 1464 | 1576 | } |
| 1577 | if (result_loc != nullptr) ir_ref_instruction(result_loc, irb->current_basic_block); |
| 1465 | 1578 | |
| 1466 | 1579 | return &container_init_fields_instruction->base; |
| 1467 | 1580 | } |
| 1468 | 1581 | |
| 1469 | | static IrInstruction *ir_build_struct_init(IrBuilder *irb, Scope *scope, AstNode *source_node, |
| 1470 | | ZigType *struct_type, size_t field_count, IrInstructionStructInitField *fields) |
| 1471 | | { |
| 1472 | | IrInstructionStructInit *struct_init_instruction = ir_build_instruction<IrInstructionStructInit>(irb, scope, source_node); |
| 1473 | | struct_init_instruction->struct_type = struct_type; |
| 1474 | | struct_init_instruction->field_count = field_count; |
| 1475 | | struct_init_instruction->fields = fields; |
| 1476 | | |
| 1477 | | for (size_t i = 0; i < field_count; i += 1) |
| 1478 | | ir_ref_instruction(fields[i].value, irb->current_basic_block); |
| 1479 | | |
| 1480 | | return &struct_init_instruction->base; |
| 1481 | | } |
| 1482 | | |
| 1483 | | static IrInstruction *ir_build_union_init(IrBuilder *irb, Scope *scope, AstNode *source_node, |
| 1484 | | ZigType *union_type, TypeUnionField *field, IrInstruction *init_value) |
| 1485 | | { |
| 1486 | | IrInstructionUnionInit *union_init_instruction = ir_build_instruction<IrInstructionUnionInit>(irb, scope, source_node); |
| 1487 | | union_init_instruction->union_type = union_type; |
| 1488 | | union_init_instruction->field = field; |
| 1489 | | union_init_instruction->init_value = init_value; |
| 1490 | | |
| 1491 | | ir_ref_instruction(init_value, irb->current_basic_block); |
| 1492 | | |
| 1493 | | return &union_init_instruction->base; |
| 1494 | | } |
| 1495 | | |
| 1496 | 1582 | static IrInstruction *ir_build_unreachable(IrBuilder *irb, Scope *scope, AstNode *source_node) { |
| 1497 | 1583 | IrInstructionUnreachable *unreachable_instruction = |
| 1498 | 1584 | ir_build_instruction<IrInstructionUnreachable>(irb, scope, source_node); |
| ... | ... | @@ -1517,47 +1603,47 @@ static IrInstruction *ir_build_store_ptr(IrBuilder *irb, Scope *scope, AstNode * |
| 1517 | 1603 | } |
| 1518 | 1604 | |
| 1519 | 1605 | static IrInstruction *ir_build_var_decl_src(IrBuilder *irb, Scope *scope, AstNode *source_node, |
| 1520 | | ZigVar *var, IrInstruction *var_type, IrInstruction *align_value, IrInstruction *init_value) |
| 1606 | ZigVar *var, IrInstruction *align_value, IrInstruction *ptr) |
| 1521 | 1607 | { |
| 1522 | 1608 | IrInstructionDeclVarSrc *decl_var_instruction = ir_build_instruction<IrInstructionDeclVarSrc>(irb, scope, source_node); |
| 1523 | 1609 | decl_var_instruction->base.value.special = ConstValSpecialStatic; |
| 1524 | 1610 | decl_var_instruction->base.value.type = irb->codegen->builtin_types.entry_void; |
| 1525 | 1611 | decl_var_instruction->var = var; |
| 1526 | | decl_var_instruction->var_type = var_type; |
| 1527 | 1612 | decl_var_instruction->align_value = align_value; |
| 1528 | | decl_var_instruction->init_value = init_value; |
| 1613 | decl_var_instruction->ptr = ptr; |
| 1529 | 1614 | |
| 1530 | | if (var_type != nullptr) ir_ref_instruction(var_type, irb->current_basic_block); |
| 1531 | 1615 | if (align_value != nullptr) ir_ref_instruction(align_value, irb->current_basic_block); |
| 1532 | | ir_ref_instruction(init_value, irb->current_basic_block); |
| 1616 | ir_ref_instruction(ptr, irb->current_basic_block); |
| 1533 | 1617 | |
| 1534 | 1618 | return &decl_var_instruction->base; |
| 1535 | 1619 | } |
| 1536 | 1620 | |
| 1537 | 1621 | static IrInstruction *ir_build_var_decl_gen(IrAnalyze *ira, IrInstruction *source_instruction, |
| 1538 | | ZigVar *var, IrInstruction *init_value) |
| 1622 | ZigVar *var, IrInstruction *var_ptr) |
| 1539 | 1623 | { |
| 1540 | 1624 | IrInstructionDeclVarGen *decl_var_instruction = ir_build_instruction<IrInstructionDeclVarGen>(&ira->new_irb, |
| 1541 | 1625 | source_instruction->scope, source_instruction->source_node); |
| 1542 | 1626 | decl_var_instruction->base.value.special = ConstValSpecialStatic; |
| 1543 | 1627 | decl_var_instruction->base.value.type = ira->codegen->builtin_types.entry_void; |
| 1544 | 1628 | decl_var_instruction->var = var; |
| 1545 | | decl_var_instruction->init_value = init_value; |
| 1629 | decl_var_instruction->var_ptr = var_ptr; |
| 1546 | 1630 | |
| 1547 | | ir_ref_instruction(init_value, ira->new_irb.current_basic_block); |
| 1631 | ir_ref_instruction(var_ptr, ira->new_irb.current_basic_block); |
| 1548 | 1632 | |
| 1549 | 1633 | return &decl_var_instruction->base; |
| 1550 | 1634 | } |
| 1551 | 1635 | |
| 1552 | 1636 | static IrInstruction *ir_build_resize_slice(IrAnalyze *ira, IrInstruction *source_instruction, |
| 1553 | | IrInstruction *operand, ZigType *ty) |
| 1637 | IrInstruction *operand, ZigType *ty, IrInstruction *result_loc) |
| 1554 | 1638 | { |
| 1555 | 1639 | IrInstructionResizeSlice *instruction = ir_build_instruction<IrInstructionResizeSlice>(&ira->new_irb, |
| 1556 | 1640 | source_instruction->scope, source_instruction->source_node); |
| 1557 | 1641 | instruction->base.value.type = ty; |
| 1558 | 1642 | instruction->operand = operand; |
| 1643 | instruction->result_loc = result_loc; |
| 1559 | 1644 | |
| 1560 | 1645 | ir_ref_instruction(operand, ira->new_irb.current_basic_block); |
| 1646 | ir_ref_instruction(result_loc, ira->new_irb.current_basic_block); |
| 1561 | 1647 | |
| 1562 | 1648 | return &instruction->base; |
| 1563 | 1649 | } |
| ... | ... | @@ -1598,27 +1684,6 @@ static IrInstruction *ir_build_typeof(IrBuilder *irb, Scope *scope, AstNode *sou |
| 1598 | 1684 | return &instruction->base; |
| 1599 | 1685 | } |
| 1600 | 1686 | |
| 1601 | | static IrInstruction *ir_build_to_ptr_type(IrBuilder *irb, Scope *scope, AstNode *source_node, IrInstruction *ptr) { |
| 1602 | | IrInstructionToPtrType *instruction = ir_build_instruction<IrInstructionToPtrType>(irb, scope, source_node); |
| 1603 | | instruction->ptr = ptr; |
| 1604 | | |
| 1605 | | ir_ref_instruction(ptr, irb->current_basic_block); |
| 1606 | | |
| 1607 | | return &instruction->base; |
| 1608 | | } |
| 1609 | | |
| 1610 | | static IrInstruction *ir_build_ptr_type_child(IrBuilder *irb, Scope *scope, AstNode *source_node, |
| 1611 | | IrInstruction *value) |
| 1612 | | { |
| 1613 | | IrInstructionPtrTypeChild *instruction = ir_build_instruction<IrInstructionPtrTypeChild>( |
| 1614 | | irb, scope, source_node); |
| 1615 | | instruction->value = value; |
| 1616 | | |
| 1617 | | ir_ref_instruction(value, irb->current_basic_block); |
| 1618 | | |
| 1619 | | return &instruction->base; |
| 1620 | | } |
| 1621 | | |
| 1622 | 1687 | static IrInstruction *ir_build_set_cold(IrBuilder *irb, Scope *scope, AstNode *source_node, IrInstruction *is_cold) { |
| 1623 | 1688 | IrInstructionSetCold *instruction = ir_build_instruction<IrInstructionSetCold>(irb, scope, source_node); |
| 1624 | 1689 | instruction->is_cold = is_cold; |
| ... | ... | @@ -1744,40 +1809,59 @@ static IrInstruction *ir_build_test_nonnull(IrBuilder *irb, Scope *scope, AstNod |
| 1744 | 1809 | } |
| 1745 | 1810 | |
| 1746 | 1811 | static IrInstruction *ir_build_optional_unwrap_ptr(IrBuilder *irb, Scope *scope, AstNode *source_node, |
| 1747 | | IrInstruction *base_ptr, bool safety_check_on) |
| 1812 | IrInstruction *base_ptr, bool safety_check_on, bool initializing) |
| 1748 | 1813 | { |
| 1749 | 1814 | IrInstructionOptionalUnwrapPtr *instruction = ir_build_instruction<IrInstructionOptionalUnwrapPtr>(irb, scope, source_node); |
| 1750 | 1815 | instruction->base_ptr = base_ptr; |
| 1751 | 1816 | instruction->safety_check_on = safety_check_on; |
| 1817 | instruction->initializing = initializing; |
| 1752 | 1818 | |
| 1753 | 1819 | ir_ref_instruction(base_ptr, irb->current_basic_block); |
| 1754 | 1820 | |
| 1755 | 1821 | return &instruction->base; |
| 1756 | 1822 | } |
| 1757 | 1823 | |
| 1758 | | static IrInstruction *ir_build_maybe_wrap(IrBuilder *irb, Scope *scope, AstNode *source_node, IrInstruction *value) { |
| 1759 | | IrInstructionOptionalWrap *instruction = ir_build_instruction<IrInstructionOptionalWrap>(irb, scope, source_node); |
| 1760 | | 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; |
| 1761 | 1832 | |
| 1762 | | ir_ref_instruction(value, irb->current_basic_block); |
| 1833 | ir_ref_instruction(operand, ira->new_irb.current_basic_block); |
| 1834 | if (result_loc != nullptr) ir_ref_instruction(result_loc, ira->new_irb.current_basic_block); |
| 1763 | 1835 | |
| 1764 | 1836 | return &instruction->base; |
| 1765 | 1837 | } |
| 1766 | 1838 | |
| 1767 | | static IrInstruction *ir_build_err_wrap_payload(IrBuilder *irb, Scope *scope, AstNode *source_node, IrInstruction *value) { |
| 1768 | | IrInstructionErrWrapPayload *instruction = ir_build_instruction<IrInstructionErrWrapPayload>(irb, scope, source_node); |
| 1769 | | 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; |
| 1770 | 1847 | |
| 1771 | | ir_ref_instruction(value, irb->current_basic_block); |
| 1848 | ir_ref_instruction(operand, ira->new_irb.current_basic_block); |
| 1849 | if (result_loc != nullptr) ir_ref_instruction(result_loc, ira->new_irb.current_basic_block); |
| 1772 | 1850 | |
| 1773 | 1851 | return &instruction->base; |
| 1774 | 1852 | } |
| 1775 | 1853 | |
| 1776 | | static IrInstruction *ir_build_err_wrap_code(IrBuilder *irb, Scope *scope, AstNode *source_node, IrInstruction *value) { |
| 1777 | | IrInstructionErrWrapCode *instruction = ir_build_instruction<IrInstructionErrWrapCode>(irb, scope, source_node); |
| 1778 | | 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; |
| 1779 | 1862 | |
| 1780 | | ir_ref_instruction(value, irb->current_basic_block); |
| 1863 | ir_ref_instruction(operand, ira->new_irb.current_basic_block); |
| 1864 | if (result_loc != nullptr) ir_ref_instruction(result_loc, ira->new_irb.current_basic_block); |
| 1781 | 1865 | |
| 1782 | 1866 | return &instruction->base; |
| 1783 | 1867 | } |
| ... | ... | @@ -1934,6 +2018,21 @@ static IrInstruction *ir_build_ref(IrBuilder *irb, Scope *scope, AstNode *source |
| 1934 | 2018 | return &instruction->base; |
| 1935 | 2019 | } |
| 1936 | 2020 | |
| 2021 | static IrInstruction *ir_build_ref_gen(IrAnalyze *ira, IrInstruction *source_instruction, ZigType *result_type, |
| 2022 | IrInstruction *operand, IrInstruction *result_loc) |
| 2023 | { |
| 2024 | IrInstructionRefGen *instruction = ir_build_instruction<IrInstructionRefGen>(&ira->new_irb, |
| 2025 | source_instruction->scope, source_instruction->source_node); |
| 2026 | instruction->base.value.type = result_type; |
| 2027 | instruction->operand = operand; |
| 2028 | instruction->result_loc = result_loc; |
| 2029 | |
| 2030 | ir_ref_instruction(operand, ira->new_irb.current_basic_block); |
| 2031 | if (result_loc != nullptr) ir_ref_instruction(result_loc, ira->new_irb.current_basic_block); |
| 2032 | |
| 2033 | return &instruction->base; |
| 2034 | } |
| 2035 | |
| 1937 | 2036 | static IrInstruction *ir_build_compile_err(IrBuilder *irb, Scope *scope, AstNode *source_node, IrInstruction *msg) { |
| 1938 | 2037 | IrInstructionCompileErr *instruction = ir_build_instruction<IrInstructionCompileErr>(irb, scope, source_node); |
| 1939 | 2038 | instruction->msg = msg; |
| ... | ... | @@ -2011,8 +2110,7 @@ static IrInstruction *ir_build_embed_file(IrBuilder *irb, Scope *scope, AstNode |
| 2011 | 2110 | |
| 2012 | 2111 | static IrInstruction *ir_build_cmpxchg_src(IrBuilder *irb, Scope *scope, AstNode *source_node, |
| 2013 | 2112 | IrInstruction *type_value, IrInstruction *ptr, IrInstruction *cmp_value, IrInstruction *new_value, |
| 2014 | | IrInstruction *success_order_value, IrInstruction *failure_order_value, |
| 2015 | | bool is_weak) |
| 2113 | IrInstruction *success_order_value, IrInstruction *failure_order_value, bool is_weak, ResultLoc *result_loc) |
| 2016 | 2114 | { |
| 2017 | 2115 | IrInstructionCmpxchgSrc *instruction = ir_build_instruction<IrInstructionCmpxchgSrc>(irb, scope, source_node); |
| 2018 | 2116 | instruction->type_value = type_value; |
| ... | ... | @@ -2022,6 +2120,7 @@ static IrInstruction *ir_build_cmpxchg_src(IrBuilder *irb, Scope *scope, AstNode |
| 2022 | 2120 | instruction->success_order_value = success_order_value; |
| 2023 | 2121 | instruction->failure_order_value = failure_order_value; |
| 2024 | 2122 | instruction->is_weak = is_weak; |
| 2123 | instruction->result_loc = result_loc; |
| 2025 | 2124 | |
| 2026 | 2125 | ir_ref_instruction(type_value, irb->current_basic_block); |
| 2027 | 2126 | ir_ref_instruction(ptr, irb->current_basic_block); |
| ... | ... | @@ -2033,22 +2132,25 @@ static IrInstruction *ir_build_cmpxchg_src(IrBuilder *irb, Scope *scope, AstNode |
| 2033 | 2132 | return &instruction->base; |
| 2034 | 2133 | } |
| 2035 | 2134 | |
| 2036 | | static IrInstruction *ir_build_cmpxchg_gen(IrAnalyze *ira, IrInstruction *source_instruction, |
| 2135 | static IrInstruction *ir_build_cmpxchg_gen(IrAnalyze *ira, IrInstruction *source_instruction, ZigType *result_type, |
| 2037 | 2136 | IrInstruction *ptr, IrInstruction *cmp_value, IrInstruction *new_value, |
| 2038 | | AtomicOrder success_order, AtomicOrder failure_order, bool is_weak) |
| 2137 | AtomicOrder success_order, AtomicOrder failure_order, bool is_weak, IrInstruction *result_loc) |
| 2039 | 2138 | { |
| 2040 | 2139 | IrInstructionCmpxchgGen *instruction = ir_build_instruction<IrInstructionCmpxchgGen>(&ira->new_irb, |
| 2041 | 2140 | source_instruction->scope, source_instruction->source_node); |
| 2141 | instruction->base.value.type = result_type; |
| 2042 | 2142 | instruction->ptr = ptr; |
| 2043 | 2143 | instruction->cmp_value = cmp_value; |
| 2044 | 2144 | instruction->new_value = new_value; |
| 2045 | 2145 | instruction->success_order = success_order; |
| 2046 | 2146 | instruction->failure_order = failure_order; |
| 2047 | 2147 | instruction->is_weak = is_weak; |
| 2148 | instruction->result_loc = result_loc; |
| 2048 | 2149 | |
| 2049 | 2150 | ir_ref_instruction(ptr, ira->new_irb.current_basic_block); |
| 2050 | 2151 | ir_ref_instruction(cmp_value, ira->new_irb.current_basic_block); |
| 2051 | 2152 | ir_ref_instruction(new_value, ira->new_irb.current_basic_block); |
| 2153 | if (result_loc != nullptr) ir_ref_instruction(result_loc, ira->new_irb.current_basic_block); |
| 2052 | 2154 | |
| 2053 | 2155 | return &instruction->base; |
| 2054 | 2156 | } |
| ... | ... | @@ -2107,19 +2209,25 @@ static IrInstruction *ir_build_err_set_cast(IrBuilder *irb, Scope *scope, AstNod |
| 2107 | 2209 | return &instruction->base; |
| 2108 | 2210 | } |
| 2109 | 2211 | |
| 2110 | | static IrInstruction *ir_build_to_bytes(IrBuilder *irb, Scope *scope, AstNode *source_node, IrInstruction *target) { |
| 2212 | static IrInstruction *ir_build_to_bytes(IrBuilder *irb, Scope *scope, AstNode *source_node, IrInstruction *target, |
| 2213 | ResultLoc *result_loc) |
| 2214 | { |
| 2111 | 2215 | IrInstructionToBytes *instruction = ir_build_instruction<IrInstructionToBytes>(irb, scope, source_node); |
| 2112 | 2216 | instruction->target = target; |
| 2217 | instruction->result_loc = result_loc; |
| 2113 | 2218 | |
| 2114 | 2219 | ir_ref_instruction(target, irb->current_basic_block); |
| 2115 | 2220 | |
| 2116 | 2221 | return &instruction->base; |
| 2117 | 2222 | } |
| 2118 | 2223 | |
| 2119 | | static IrInstruction *ir_build_from_bytes(IrBuilder *irb, Scope *scope, AstNode *source_node, IrInstruction *dest_child_type, IrInstruction *target) { |
| 2224 | static IrInstruction *ir_build_from_bytes(IrBuilder *irb, Scope *scope, AstNode *source_node, |
| 2225 | IrInstruction *dest_child_type, IrInstruction *target, ResultLoc *result_loc) |
| 2226 | { |
| 2120 | 2227 | IrInstructionFromBytes *instruction = ir_build_instruction<IrInstructionFromBytes>(irb, scope, source_node); |
| 2121 | 2228 | instruction->dest_child_type = dest_child_type; |
| 2122 | 2229 | instruction->target = target; |
| 2230 | instruction->result_loc = result_loc; |
| 2123 | 2231 | |
| 2124 | 2232 | ir_ref_instruction(dest_child_type, irb->current_basic_block); |
| 2125 | 2233 | ir_ref_instruction(target, irb->current_basic_block); |
| ... | ... | @@ -2221,14 +2329,15 @@ static IrInstruction *ir_build_memcpy(IrBuilder *irb, Scope *scope, AstNode *sou |
| 2221 | 2329 | return &instruction->base; |
| 2222 | 2330 | } |
| 2223 | 2331 | |
| 2224 | | static IrInstruction *ir_build_slice(IrBuilder *irb, Scope *scope, AstNode *source_node, |
| 2225 | | 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) |
| 2226 | 2334 | { |
| 2227 | | IrInstructionSlice *instruction = ir_build_instruction<IrInstructionSlice>(irb, scope, source_node); |
| 2335 | IrInstructionSliceSrc *instruction = ir_build_instruction<IrInstructionSliceSrc>(irb, scope, source_node); |
| 2228 | 2336 | instruction->ptr = ptr; |
| 2229 | 2337 | instruction->start = start; |
| 2230 | 2338 | instruction->end = end; |
| 2231 | 2339 | instruction->safety_check_on = safety_check_on; |
| 2340 | instruction->result_loc = result_loc; |
| 2232 | 2341 | |
| 2233 | 2342 | ir_ref_instruction(ptr, irb->current_basic_block); |
| 2234 | 2343 | ir_ref_instruction(start, irb->current_basic_block); |
| ... | ... | @@ -2237,6 +2346,26 @@ static IrInstruction *ir_build_slice(IrBuilder *irb, Scope *scope, AstNode *sour |
| 2237 | 2346 | return &instruction->base; |
| 2238 | 2347 | } |
| 2239 | 2348 | |
| 2349 | static IrInstruction *ir_build_slice_gen(IrAnalyze *ira, IrInstruction *source_instruction, ZigType *slice_type, |
| 2350 | IrInstruction *ptr, IrInstruction *start, IrInstruction *end, bool safety_check_on, IrInstruction *result_loc) |
| 2351 | { |
| 2352 | IrInstructionSliceGen *instruction = ir_build_instruction<IrInstructionSliceGen>( |
| 2353 | &ira->new_irb, source_instruction->scope, source_instruction->source_node); |
| 2354 | instruction->base.value.type = slice_type; |
| 2355 | instruction->ptr = ptr; |
| 2356 | instruction->start = start; |
| 2357 | instruction->end = end; |
| 2358 | instruction->safety_check_on = safety_check_on; |
| 2359 | instruction->result_loc = result_loc; |
| 2360 | |
| 2361 | ir_ref_instruction(ptr, ira->new_irb.current_basic_block); |
| 2362 | ir_ref_instruction(start, ira->new_irb.current_basic_block); |
| 2363 | if (end) ir_ref_instruction(end, ira->new_irb.current_basic_block); |
| 2364 | ir_ref_instruction(result_loc, ira->new_irb.current_basic_block); |
| 2365 | |
| 2366 | return &instruction->base; |
| 2367 | } |
| 2368 | |
| 2240 | 2369 | static IrInstruction *ir_build_member_count(IrBuilder *irb, Scope *scope, AstNode *source_node, IrInstruction *container) { |
| 2241 | 2370 | IrInstructionMemberCount *instruction = ir_build_instruction<IrInstructionMemberCount>(irb, scope, source_node); |
| 2242 | 2371 | instruction->container = container; |
| ... | ... | @@ -2390,34 +2519,49 @@ static IrInstruction *ir_build_align_of(IrBuilder *irb, Scope *scope, AstNode *s |
| 2390 | 2519 | return &instruction->base; |
| 2391 | 2520 | } |
| 2392 | 2521 | |
| 2393 | | static IrInstruction *ir_build_test_err(IrBuilder *irb, Scope *scope, AstNode *source_node, |
| 2394 | | 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) |
| 2395 | 2524 | { |
| 2396 | | IrInstructionTestErr *instruction = ir_build_instruction<IrInstructionTestErr>(irb, scope, source_node); |
| 2397 | | 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; |
| 2398 | 2528 | |
| 2399 | | ir_ref_instruction(value, irb->current_basic_block); |
| 2529 | ir_ref_instruction(base_ptr, irb->current_basic_block); |
| 2400 | 2530 | |
| 2401 | 2531 | return &instruction->base; |
| 2402 | 2532 | } |
| 2403 | 2533 | |
| 2404 | | static IrInstruction *ir_build_unwrap_err_code(IrBuilder *irb, Scope *scope, AstNode *source_node, |
| 2534 | static IrInstruction *ir_build_test_err_gen(IrAnalyze *ira, IrInstruction *source_instruction, |
| 2405 | 2535 | IrInstruction *err_union) |
| 2406 | 2536 | { |
| 2407 | | IrInstructionUnwrapErrCode *instruction = ir_build_instruction<IrInstructionUnwrapErrCode>(irb, scope, source_node); |
| 2537 | IrInstructionTestErrGen *instruction = ir_build_instruction<IrInstructionTestErrGen>( |
| 2538 | &ira->new_irb, source_instruction->scope, source_instruction->source_node); |
| 2539 | instruction->base.value.type = ira->codegen->builtin_types.entry_bool; |
| 2408 | 2540 | instruction->err_union = err_union; |
| 2409 | 2541 | |
| 2410 | | ir_ref_instruction(err_union, irb->current_basic_block); |
| 2542 | ir_ref_instruction(err_union, ira->new_irb.current_basic_block); |
| 2543 | |
| 2544 | return &instruction->base; |
| 2545 | } |
| 2546 | |
| 2547 | static IrInstruction *ir_build_unwrap_err_code(IrBuilder *irb, Scope *scope, AstNode *source_node, |
| 2548 | IrInstruction *err_union_ptr) |
| 2549 | { |
| 2550 | IrInstructionUnwrapErrCode *instruction = ir_build_instruction<IrInstructionUnwrapErrCode>(irb, scope, source_node); |
| 2551 | instruction->err_union_ptr = err_union_ptr; |
| 2552 | |
| 2553 | ir_ref_instruction(err_union_ptr, irb->current_basic_block); |
| 2411 | 2554 | |
| 2412 | 2555 | return &instruction->base; |
| 2413 | 2556 | } |
| 2414 | 2557 | |
| 2415 | 2558 | static IrInstruction *ir_build_unwrap_err_payload(IrBuilder *irb, Scope *scope, AstNode *source_node, |
| 2416 | | IrInstruction *value, bool safety_check_on) |
| 2559 | IrInstruction *value, bool safety_check_on, bool initializing) |
| 2417 | 2560 | { |
| 2418 | 2561 | IrInstructionUnwrapErrPayload *instruction = ir_build_instruction<IrInstructionUnwrapErrPayload>(irb, scope, source_node); |
| 2419 | 2562 | instruction->value = value; |
| 2420 | 2563 | instruction->safety_check_on = safety_check_on; |
| 2564 | instruction->initializing = initializing; |
| 2421 | 2565 | |
| 2422 | 2566 | ir_ref_instruction(value, irb->current_basic_block); |
| 2423 | 2567 | |
| ... | ... | @@ -2487,28 +2631,28 @@ static IrInstruction *ir_build_ptr_cast_gen(IrAnalyze *ira, IrInstruction *sourc |
| 2487 | 2631 | } |
| 2488 | 2632 | |
| 2489 | 2633 | static IrInstruction *ir_build_load_ptr_gen(IrAnalyze *ira, IrInstruction *source_instruction, |
| 2490 | | IrInstruction *ptr, ZigType *ty) |
| 2634 | IrInstruction *ptr, ZigType *ty, IrInstruction *result_loc) |
| 2491 | 2635 | { |
| 2492 | 2636 | IrInstructionLoadPtrGen *instruction = ir_build_instruction<IrInstructionLoadPtrGen>( |
| 2493 | 2637 | &ira->new_irb, source_instruction->scope, source_instruction->source_node); |
| 2494 | 2638 | instruction->base.value.type = ty; |
| 2495 | 2639 | instruction->ptr = ptr; |
| 2640 | instruction->result_loc = result_loc; |
| 2496 | 2641 | |
| 2497 | 2642 | ir_ref_instruction(ptr, ira->new_irb.current_basic_block); |
| 2643 | if (result_loc != nullptr) ir_ref_instruction(result_loc, ira->new_irb.current_basic_block); |
| 2498 | 2644 | |
| 2499 | 2645 | return &instruction->base; |
| 2500 | 2646 | } |
| 2501 | 2647 | |
| 2502 | | static IrInstruction *ir_build_bit_cast(IrBuilder *irb, Scope *scope, AstNode *source_node, |
| 2503 | | 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) |
| 2504 | 2650 | { |
| 2505 | | IrInstructionBitCast *instruction = ir_build_instruction<IrInstructionBitCast>( |
| 2506 | | irb, scope, source_node); |
| 2507 | | instruction->dest_type = dest_type; |
| 2508 | | 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; |
| 2509 | 2654 | |
| 2510 | | ir_ref_instruction(dest_type, irb->current_basic_block); |
| 2511 | | ir_ref_instruction(value, irb->current_basic_block); |
| 2655 | ir_ref_instruction(operand, irb->current_basic_block); |
| 2512 | 2656 | |
| 2513 | 2657 | return &instruction->base; |
| 2514 | 2658 | } |
| ... | ... | @@ -2660,11 +2804,8 @@ static IrInstruction *ir_build_type_name(IrBuilder *irb, Scope *scope, AstNode * |
| 2660 | 2804 | return &instruction->base; |
| 2661 | 2805 | } |
| 2662 | 2806 | |
| 2663 | | static IrInstruction *ir_build_decl_ref(IrBuilder *irb, Scope *scope, AstNode *source_node, |
| 2664 | | Tld *tld, LVal lval) |
| 2665 | | { |
| 2666 | | IrInstructionDeclRef *instruction = ir_build_instruction<IrInstructionDeclRef>( |
| 2667 | | 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); |
| 2668 | 2809 | instruction->tld = tld; |
| 2669 | 2810 | instruction->lval = lval; |
| 2670 | 2811 | |
| ... | ... | @@ -2792,6 +2933,53 @@ static IrInstruction *ir_build_align_cast(IrBuilder *irb, Scope *scope, AstNode |
| 2792 | 2933 | return &instruction->base; |
| 2793 | 2934 | } |
| 2794 | 2935 | |
| 2936 | static IrInstruction *ir_build_implicit_cast(IrBuilder *irb, Scope *scope, AstNode *source_node, |
| 2937 | IrInstruction *dest_type, IrInstruction *target, ResultLoc *result_loc) |
| 2938 | { |
| 2939 | IrInstructionImplicitCast *instruction = ir_build_instruction<IrInstructionImplicitCast>(irb, scope, source_node); |
| 2940 | instruction->dest_type = dest_type; |
| 2941 | instruction->target = target; |
| 2942 | instruction->result_loc = result_loc; |
| 2943 | |
| 2944 | ir_ref_instruction(dest_type, irb->current_basic_block); |
| 2945 | ir_ref_instruction(target, irb->current_basic_block); |
| 2946 | |
| 2947 | return &instruction->base; |
| 2948 | } |
| 2949 | |
| 2950 | static IrInstruction *ir_build_resolve_result(IrBuilder *irb, Scope *scope, AstNode *source_node, |
| 2951 | ResultLoc *result_loc, IrInstruction *ty) |
| 2952 | { |
| 2953 | IrInstructionResolveResult *instruction = ir_build_instruction<IrInstructionResolveResult>(irb, scope, source_node); |
| 2954 | instruction->result_loc = result_loc; |
| 2955 | instruction->ty = ty; |
| 2956 | |
| 2957 | ir_ref_instruction(ty, irb->current_basic_block); |
| 2958 | |
| 2959 | return &instruction->base; |
| 2960 | } |
| 2961 | |
| 2962 | static IrInstruction *ir_build_reset_result(IrBuilder *irb, Scope *scope, AstNode *source_node, |
| 2963 | ResultLoc *result_loc) |
| 2964 | { |
| 2965 | IrInstructionResetResult *instruction = ir_build_instruction<IrInstructionResetResult>(irb, scope, source_node); |
| 2966 | instruction->result_loc = result_loc; |
| 2967 | |
| 2968 | return &instruction->base; |
| 2969 | } |
| 2970 | |
| 2971 | static IrInstruction *ir_build_result_ptr(IrBuilder *irb, Scope *scope, AstNode *source_node, |
| 2972 | ResultLoc *result_loc, IrInstruction *result) |
| 2973 | { |
| 2974 | IrInstructionResultPtr *instruction = ir_build_instruction<IrInstructionResultPtr>(irb, scope, source_node); |
| 2975 | instruction->result_loc = result_loc; |
| 2976 | instruction->result = result; |
| 2977 | |
| 2978 | ir_ref_instruction(result, irb->current_basic_block); |
| 2979 | |
| 2980 | return &instruction->base; |
| 2981 | } |
| 2982 | |
| 2795 | 2983 | static IrInstruction *ir_build_opaque_type(IrBuilder *irb, Scope *scope, AstNode *source_node) { |
| 2796 | 2984 | IrInstructionOpaqueType *instruction = ir_build_instruction<IrInstructionOpaqueType>(irb, scope, source_node); |
| 2797 | 2985 | |
| ... | ... | @@ -3120,16 +3308,31 @@ static IrInstruction *ir_build_check_runtime_scope(IrBuilder *irb, Scope *scope, |
| 3120 | 3308 | } |
| 3121 | 3309 | |
| 3122 | 3310 | static IrInstruction *ir_build_vector_to_array(IrAnalyze *ira, IrInstruction *source_instruction, |
| 3123 | | IrInstruction *vector, ZigType *result_type) |
| 3311 | ZigType *result_type, IrInstruction *vector, IrInstruction *result_loc) |
| 3124 | 3312 | { |
| 3125 | 3313 | IrInstructionVectorToArray *instruction = ir_build_instruction<IrInstructionVectorToArray>(&ira->new_irb, |
| 3126 | 3314 | source_instruction->scope, source_instruction->source_node); |
| 3127 | 3315 | instruction->base.value.type = result_type; |
| 3128 | 3316 | instruction->vector = vector; |
| 3317 | instruction->result_loc = result_loc; |
| 3129 | 3318 | |
| 3130 | 3319 | ir_ref_instruction(vector, ira->new_irb.current_basic_block); |
| 3320 | ir_ref_instruction(result_loc, ira->new_irb.current_basic_block); |
| 3321 | |
| 3322 | return &instruction->base; |
| 3323 | } |
| 3324 | |
| 3325 | static IrInstruction *ir_build_ptr_of_array_to_slice(IrAnalyze *ira, IrInstruction *source_instruction, |
| 3326 | ZigType *result_type, IrInstruction *operand, IrInstruction *result_loc) |
| 3327 | { |
| 3328 | IrInstructionPtrOfArrayToSlice *instruction = ir_build_instruction<IrInstructionPtrOfArrayToSlice>(&ira->new_irb, |
| 3329 | source_instruction->scope, source_instruction->source_node); |
| 3330 | instruction->base.value.type = result_type; |
| 3331 | instruction->operand = operand; |
| 3332 | instruction->result_loc = result_loc; |
| 3131 | 3333 | |
| 3132 | | ir_add_alloca(ira, &instruction->base, result_type); |
| 3334 | ir_ref_instruction(operand, ira->new_irb.current_basic_block); |
| 3335 | ir_ref_instruction(result_loc, ira->new_irb.current_basic_block); |
| 3133 | 3336 | |
| 3134 | 3337 | return &instruction->base; |
| 3135 | 3338 | } |
| ... | ... | @@ -3173,6 +3376,45 @@ static IrInstruction *ir_build_assert_non_null(IrAnalyze *ira, IrInstruction *so |
| 3173 | 3376 | return &instruction->base; |
| 3174 | 3377 | } |
| 3175 | 3378 | |
| 3379 | static IrInstruction *ir_build_alloca_src(IrBuilder *irb, Scope *scope, AstNode *source_node, |
| 3380 | IrInstruction *align, const char *name_hint, IrInstruction *is_comptime) |
| 3381 | { |
| 3382 | IrInstructionAllocaSrc *instruction = ir_build_instruction<IrInstructionAllocaSrc>(irb, scope, source_node); |
| 3383 | instruction->base.is_gen = true; |
| 3384 | instruction->align = align; |
| 3385 | instruction->name_hint = name_hint; |
| 3386 | instruction->is_comptime = is_comptime; |
| 3387 | |
| 3388 | if (align != nullptr) ir_ref_instruction(align, irb->current_basic_block); |
| 3389 | if (is_comptime != nullptr) ir_ref_instruction(is_comptime, irb->current_basic_block); |
| 3390 | |
| 3391 | return &instruction->base; |
| 3392 | } |
| 3393 | |
| 3394 | static IrInstructionAllocaGen *ir_create_alloca_gen(IrAnalyze *ira, IrInstruction *source_instruction, |
| 3395 | uint32_t align, const char *name_hint) |
| 3396 | { |
| 3397 | IrInstructionAllocaGen *instruction = ir_create_instruction<IrInstructionAllocaGen>(&ira->new_irb, |
| 3398 | source_instruction->scope, source_instruction->source_node); |
| 3399 | instruction->align = align; |
| 3400 | instruction->name_hint = name_hint; |
| 3401 | |
| 3402 | return instruction; |
| 3403 | } |
| 3404 | |
| 3405 | static IrInstruction *ir_build_end_expr(IrBuilder *irb, Scope *scope, AstNode *source_node, |
| 3406 | IrInstruction *value, ResultLoc *result_loc) |
| 3407 | { |
| 3408 | IrInstructionEndExpr *instruction = ir_build_instruction<IrInstructionEndExpr>(irb, scope, source_node); |
| 3409 | instruction->base.is_gen = true; |
| 3410 | instruction->value = value; |
| 3411 | instruction->result_loc = result_loc; |
| 3412 | |
| 3413 | ir_ref_instruction(value, irb->current_basic_block); |
| 3414 | |
| 3415 | return &instruction->base; |
| 3416 | } |
| 3417 | |
| 3176 | 3418 | static void ir_count_defers(IrBuilder *irb, Scope *inner_scope, Scope *outer_scope, size_t *results) { |
| 3177 | 3419 | results[ReturnKindUnconditional] = 0; |
| 3178 | 3420 | results[ReturnKindError] = 0; |
| ... | ... | @@ -3273,6 +3515,7 @@ static void ir_set_cursor_at_end(IrBuilder *irb, IrBasicBlock *basic_block) { |
| 3273 | 3515 | } |
| 3274 | 3516 | |
| 3275 | 3517 | static void ir_set_cursor_at_end_and_append_block(IrBuilder *irb, IrBasicBlock *basic_block) { |
| 3518 | basic_block->index = irb->exec->basic_block_list.length; |
| 3276 | 3519 | irb->exec->basic_block_list.append(basic_block); |
| 3277 | 3520 | ir_set_cursor_at_end(irb, basic_block); |
| 3278 | 3521 | } |
| ... | ... | @@ -3361,7 +3604,7 @@ static IrInstruction *ir_gen_async_return(IrBuilder *irb, Scope *scope, AstNode |
| 3361 | 3604 | return ir_build_cond_br(irb, scope, node, is_canceled_bool, irb->exec->coro_final_cleanup_block, irb->exec->coro_early_final, is_comptime); |
| 3362 | 3605 | } |
| 3363 | 3606 | |
| 3364 | | static IrInstruction *ir_gen_return(IrBuilder *irb, Scope *scope, AstNode *node, LVal lval) { |
| 3607 | static IrInstruction *ir_gen_return(IrBuilder *irb, Scope *scope, AstNode *node, LVal lval, ResultLoc *result_loc) { |
| 3365 | 3608 | assert(node->type == NodeTypeReturnExpr); |
| 3366 | 3609 | |
| 3367 | 3610 | ZigFn *fn_entry = exec_fn_entry(irb->exec); |
| ... | ... | @@ -3385,12 +3628,16 @@ static IrInstruction *ir_gen_return(IrBuilder *irb, Scope *scope, AstNode *node, |
| 3385 | 3628 | switch (node->data.return_expr.kind) { |
| 3386 | 3629 | case ReturnKindUnconditional: |
| 3387 | 3630 | { |
| 3631 | ResultLocReturn *result_loc_ret = allocate<ResultLocReturn>(1); |
| 3632 | result_loc_ret->base.id = ResultLocIdReturn; |
| 3633 | ir_build_reset_result(irb, scope, node, &result_loc_ret->base); |
| 3634 | |
| 3388 | 3635 | IrInstruction *return_value; |
| 3389 | 3636 | if (expr_node) { |
| 3390 | 3637 | // Temporarily set this so that if we return a type it gets the name of the function |
| 3391 | 3638 | ZigFn *prev_name_fn = irb->exec->name_fn; |
| 3392 | 3639 | irb->exec->name_fn = exec_fn_entry(irb->exec); |
| 3393 | | return_value = ir_gen_node(irb, expr_node, scope); |
| 3640 | return_value = ir_gen_node_extra(irb, expr_node, scope, LValNone, &result_loc_ret->base); |
| 3394 | 3641 | irb->exec->name_fn = prev_name_fn; |
| 3395 | 3642 | if (return_value == irb->codegen->invalid_instruction) |
| 3396 | 3643 | return irb->codegen->invalid_instruction; |
| ... | ... | @@ -3408,7 +3655,9 @@ static IrInstruction *ir_gen_return(IrBuilder *irb, Scope *scope, AstNode *node, |
| 3408 | 3655 | ir_gen_defers_for_block(irb, scope, outer_scope, false); |
| 3409 | 3656 | } |
| 3410 | 3657 | |
| 3411 | | IrInstruction *is_err = ir_build_test_err(irb, scope, node, return_value); |
| 3658 | IrInstruction *ret_ptr = ir_build_result_ptr(irb, scope, node, &result_loc_ret->base, |
| 3659 | return_value); |
| 3660 | IrInstruction *is_err = ir_build_test_err_src(irb, scope, node, ret_ptr, false); |
| 3412 | 3661 | |
| 3413 | 3662 | bool should_inline = ir_should_inline(irb->exec, scope); |
| 3414 | 3663 | IrInstruction *is_comptime; |
| ... | ... | @@ -3437,21 +3686,24 @@ static IrInstruction *ir_gen_return(IrBuilder *irb, Scope *scope, AstNode *node, |
| 3437 | 3686 | ir_build_br(irb, scope, node, ret_stmt_block, is_comptime); |
| 3438 | 3687 | |
| 3439 | 3688 | ir_set_cursor_at_end_and_append_block(irb, ret_stmt_block); |
| 3440 | | return ir_gen_async_return(irb, scope, node, return_value, false); |
| 3689 | IrInstruction *result = ir_gen_async_return(irb, scope, node, return_value, false); |
| 3690 | result_loc_ret->base.source_instruction = result; |
| 3691 | return result; |
| 3441 | 3692 | } else { |
| 3442 | 3693 | // generate unconditional defers |
| 3443 | 3694 | ir_gen_defers_for_block(irb, scope, outer_scope, false); |
| 3444 | | return ir_gen_async_return(irb, scope, node, return_value, false); |
| 3695 | IrInstruction *result = ir_gen_async_return(irb, scope, node, return_value, false); |
| 3696 | result_loc_ret->base.source_instruction = result; |
| 3697 | return result; |
| 3445 | 3698 | } |
| 3446 | 3699 | } |
| 3447 | 3700 | case ReturnKindError: |
| 3448 | 3701 | { |
| 3449 | 3702 | assert(expr_node); |
| 3450 | | IrInstruction *err_union_ptr = ir_gen_node_extra(irb, expr_node, scope, LValPtr); |
| 3703 | IrInstruction *err_union_ptr = ir_gen_node_extra(irb, expr_node, scope, LValPtr, nullptr); |
| 3451 | 3704 | if (err_union_ptr == irb->codegen->invalid_instruction) |
| 3452 | 3705 | return irb->codegen->invalid_instruction; |
| 3453 | | IrInstruction *err_union_val = ir_build_load_ptr(irb, scope, node, err_union_ptr); |
| 3454 | | 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); |
| 3455 | 3707 | |
| 3456 | 3708 | IrBasicBlock *return_block = ir_create_basic_block(irb, scope, "ErrRetReturn"); |
| 3457 | 3709 | IrBasicBlock *continue_block = ir_create_basic_block(irb, scope, "ErrRetContinue"); |
| ... | ... | @@ -3466,19 +3718,27 @@ static IrInstruction *ir_gen_return(IrBuilder *irb, Scope *scope, AstNode *node, |
| 3466 | 3718 | |
| 3467 | 3719 | ir_set_cursor_at_end_and_append_block(irb, return_block); |
| 3468 | 3720 | if (!ir_gen_defers_for_block(irb, scope, outer_scope, true)) { |
| 3469 | | IrInstruction *err_val = ir_build_unwrap_err_code(irb, scope, node, err_union_ptr); |
| 3721 | IrInstruction *err_val_ptr = ir_build_unwrap_err_code(irb, scope, node, err_union_ptr); |
| 3722 | IrInstruction *err_val = ir_build_load_ptr(irb, scope, node, err_val_ptr); |
| 3723 | |
| 3724 | ResultLocReturn *result_loc_ret = allocate<ResultLocReturn>(1); |
| 3725 | result_loc_ret->base.id = ResultLocIdReturn; |
| 3726 | ir_build_reset_result(irb, scope, node, &result_loc_ret->base); |
| 3727 | ir_build_end_expr(irb, scope, node, err_val, &result_loc_ret->base); |
| 3728 | |
| 3470 | 3729 | if (irb->codegen->have_err_ret_tracing && !should_inline) { |
| 3471 | 3730 | ir_build_save_err_ret_addr(irb, scope, node); |
| 3472 | 3731 | } |
| 3473 | | ir_gen_async_return(irb, scope, node, err_val, false); |
| 3732 | IrInstruction *ret_inst = ir_gen_async_return(irb, scope, node, err_val, false); |
| 3733 | result_loc_ret->base.source_instruction = ret_inst; |
| 3474 | 3734 | } |
| 3475 | 3735 | |
| 3476 | 3736 | ir_set_cursor_at_end_and_append_block(irb, continue_block); |
| 3477 | | IrInstruction *unwrapped_ptr = ir_build_unwrap_err_payload(irb, scope, node, err_union_ptr, false); |
| 3737 | IrInstruction *unwrapped_ptr = ir_build_unwrap_err_payload(irb, scope, node, err_union_ptr, false, false); |
| 3478 | 3738 | if (lval == LValPtr) |
| 3479 | 3739 | return unwrapped_ptr; |
| 3480 | 3740 | else |
| 3481 | | return ir_build_load_ptr(irb, scope, node, unwrapped_ptr); |
| 3741 | return ir_expr_wrap(irb, scope, ir_build_load_ptr(irb, scope, node, unwrapped_ptr), result_loc); |
| 3482 | 3742 | } |
| 3483 | 3743 | } |
| 3484 | 3744 | zig_unreachable(); |
| ... | ... | @@ -3562,7 +3822,17 @@ static ZigVar *ir_create_var(IrBuilder *irb, AstNode *node, Scope *scope, Buf *n |
| 3562 | 3822 | return var; |
| 3563 | 3823 | } |
| 3564 | 3824 | |
| 3565 | | static IrInstruction *ir_gen_block(IrBuilder *irb, Scope *parent_scope, AstNode *block_node) { |
| 3825 | static ResultLocPeer *create_peer_result(ResultLocPeerParent *peer_parent) { |
| 3826 | ResultLocPeer *result = allocate<ResultLocPeer>(1); |
| 3827 | result->base.id = ResultLocIdPeer; |
| 3828 | result->base.source_instruction = peer_parent->base.source_instruction; |
| 3829 | result->parent = peer_parent; |
| 3830 | return result; |
| 3831 | } |
| 3832 | |
| 3833 | static IrInstruction *ir_gen_block(IrBuilder *irb, Scope *parent_scope, AstNode *block_node, LVal lval, |
| 3834 | ResultLoc *result_loc) |
| 3835 | { |
| 3566 | 3836 | assert(block_node->type == NodeTypeBlock); |
| 3567 | 3837 | |
| 3568 | 3838 | ZigList<IrInstruction *> incoming_values = {0}; |
| ... | ... | @@ -3580,15 +3850,24 @@ static IrInstruction *ir_gen_block(IrBuilder *irb, Scope *parent_scope, AstNode |
| 3580 | 3850 | |
| 3581 | 3851 | if (block_node->data.block.statements.length == 0) { |
| 3582 | 3852 | // {} |
| 3583 | | return ir_build_const_void(irb, child_scope, block_node); |
| 3853 | return ir_lval_wrap(irb, parent_scope, ir_build_const_void(irb, child_scope, block_node), lval, result_loc); |
| 3584 | 3854 | } |
| 3585 | 3855 | |
| 3586 | 3856 | if (block_node->data.block.name != nullptr) { |
| 3857 | scope_block->lval = lval; |
| 3587 | 3858 | scope_block->incoming_blocks = &incoming_blocks; |
| 3588 | 3859 | scope_block->incoming_values = &incoming_values; |
| 3589 | 3860 | scope_block->end_block = ir_create_basic_block(irb, parent_scope, "BlockEnd"); |
| 3590 | 3861 | scope_block->is_comptime = ir_build_const_bool(irb, parent_scope, block_node, |
| 3591 | 3862 | ir_should_inline(irb->exec, parent_scope)); |
| 3863 | |
| 3864 | scope_block->peer_parent = allocate<ResultLocPeerParent>(1); |
| 3865 | scope_block->peer_parent->base.id = ResultLocIdPeerParent; |
| 3866 | scope_block->peer_parent->base.source_instruction = scope_block->is_comptime; |
| 3867 | scope_block->peer_parent->end_bb = scope_block->end_block; |
| 3868 | scope_block->peer_parent->is_comptime = scope_block->is_comptime; |
| 3869 | scope_block->peer_parent->parent = result_loc; |
| 3870 | ir_build_reset_result(irb, parent_scope, block_node, &scope_block->peer_parent->base); |
| 3592 | 3871 | } |
| 3593 | 3872 | |
| 3594 | 3873 | bool is_continuation_unreachable = false; |
| ... | ... | @@ -3602,6 +3881,8 @@ static IrInstruction *ir_gen_block(IrBuilder *irb, Scope *parent_scope, AstNode |
| 3602 | 3881 | // keep the last noreturn statement value around in case we need to return it |
| 3603 | 3882 | noreturn_return_value = statement_value; |
| 3604 | 3883 | } |
| 3884 | // This logic must be kept in sync with |
| 3885 | // [STMT_EXPR_TEST_THING] <--- (search this token) |
| 3605 | 3886 | if (statement_node->type == NodeTypeDefer && statement_value != irb->codegen->invalid_instruction) { |
| 3606 | 3887 | // defer starts a new scope |
| 3607 | 3888 | child_scope = statement_node->data.defer.child_scope; |
| ... | ... | @@ -3622,21 +3903,41 @@ static IrInstruction *ir_gen_block(IrBuilder *irb, Scope *parent_scope, AstNode |
| 3622 | 3903 | return noreturn_return_value; |
| 3623 | 3904 | } |
| 3624 | 3905 | |
| 3906 | if (scope_block->peer_parent != nullptr && scope_block->peer_parent->peers.length != 0) { |
| 3907 | scope_block->peer_parent->peers.last()->next_bb = scope_block->end_block; |
| 3908 | } |
| 3625 | 3909 | ir_set_cursor_at_end_and_append_block(irb, scope_block->end_block); |
| 3626 | | return ir_build_phi(irb, parent_scope, block_node, incoming_blocks.length, incoming_blocks.items, incoming_values.items); |
| 3910 | IrInstruction *phi = ir_build_phi(irb, parent_scope, block_node, incoming_blocks.length, |
| 3911 | incoming_blocks.items, incoming_values.items, scope_block->peer_parent); |
| 3912 | return ir_expr_wrap(irb, parent_scope, phi, result_loc); |
| 3627 | 3913 | } else { |
| 3628 | 3914 | incoming_blocks.append(irb->current_basic_block); |
| 3629 | | incoming_values.append(ir_mark_gen(ir_build_const_void(irb, parent_scope, block_node))); |
| 3915 | IrInstruction *else_expr_result = ir_mark_gen(ir_build_const_void(irb, parent_scope, block_node)); |
| 3916 | |
| 3917 | if (scope_block->peer_parent != nullptr) { |
| 3918 | ResultLocPeer *peer_result = create_peer_result(scope_block->peer_parent); |
| 3919 | scope_block->peer_parent->peers.append(peer_result); |
| 3920 | ir_build_end_expr(irb, parent_scope, block_node, else_expr_result, &peer_result->base); |
| 3921 | |
| 3922 | if (scope_block->peer_parent->peers.length != 0) { |
| 3923 | scope_block->peer_parent->peers.last()->next_bb = scope_block->end_block; |
| 3924 | } |
| 3925 | } |
| 3926 | |
| 3927 | incoming_values.append(else_expr_result); |
| 3630 | 3928 | } |
| 3631 | 3929 | |
| 3632 | 3930 | if (block_node->data.block.name != nullptr) { |
| 3633 | 3931 | ir_gen_defers_for_block(irb, child_scope, outer_block_scope, false); |
| 3634 | 3932 | ir_mark_gen(ir_build_br(irb, parent_scope, block_node, scope_block->end_block, scope_block->is_comptime)); |
| 3635 | 3933 | ir_set_cursor_at_end_and_append_block(irb, scope_block->end_block); |
| 3636 | | return ir_build_phi(irb, parent_scope, block_node, incoming_blocks.length, incoming_blocks.items, incoming_values.items); |
| 3934 | IrInstruction *phi = ir_build_phi(irb, parent_scope, block_node, incoming_blocks.length, |
| 3935 | incoming_blocks.items, incoming_values.items, scope_block->peer_parent); |
| 3936 | return ir_expr_wrap(irb, parent_scope, phi, result_loc); |
| 3637 | 3937 | } else { |
| 3638 | 3938 | ir_gen_defers_for_block(irb, child_scope, outer_block_scope, false); |
| 3639 | | return ir_mark_gen(ir_mark_gen(ir_build_const_void(irb, child_scope, block_node))); |
| 3939 | IrInstruction *void_inst = ir_mark_gen(ir_build_const_void(irb, child_scope, block_node)); |
| 3940 | return ir_lval_wrap(irb, parent_scope, void_inst, lval, result_loc); |
| 3640 | 3941 | } |
| 3641 | 3942 | } |
| 3642 | 3943 | |
| ... | ... | @@ -3656,7 +3957,7 @@ static IrInstruction *ir_gen_bin_op_id(IrBuilder *irb, Scope *scope, AstNode *no |
| 3656 | 3957 | } |
| 3657 | 3958 | |
| 3658 | 3959 | static IrInstruction *ir_gen_assign(IrBuilder *irb, Scope *scope, AstNode *node) { |
| 3659 | | IrInstruction *lvalue = ir_gen_node_extra(irb, node->data.bin_op_expr.op1, scope, LValPtr); |
| 3960 | IrInstruction *lvalue = ir_gen_node_extra(irb, node->data.bin_op_expr.op1, scope, LValPtr, nullptr); |
| 3660 | 3961 | IrInstruction *rvalue = ir_gen_node(irb, node->data.bin_op_expr.op2, scope); |
| 3661 | 3962 | |
| 3662 | 3963 | if (lvalue == irb->codegen->invalid_instruction || rvalue == irb->codegen->invalid_instruction) |
| ... | ... | @@ -3667,7 +3968,7 @@ static IrInstruction *ir_gen_assign(IrBuilder *irb, Scope *scope, AstNode *node) |
| 3667 | 3968 | } |
| 3668 | 3969 | |
| 3669 | 3970 | static IrInstruction *ir_gen_assign_op(IrBuilder *irb, Scope *scope, AstNode *node, IrBinOp op_id) { |
| 3670 | | IrInstruction *lvalue = ir_gen_node_extra(irb, node->data.bin_op_expr.op1, scope, LValPtr); |
| 3971 | IrInstruction *lvalue = ir_gen_node_extra(irb, node->data.bin_op_expr.op1, scope, LValPtr, nullptr); |
| 3671 | 3972 | if (lvalue == irb->codegen->invalid_instruction) |
| 3672 | 3973 | return lvalue; |
| 3673 | 3974 | IrInstruction *op1 = ir_build_load_ptr(irb, scope, node->data.bin_op_expr.op1, lvalue); |
| ... | ... | @@ -3718,7 +4019,7 @@ static IrInstruction *ir_gen_bool_or(IrBuilder *irb, Scope *scope, AstNode *node |
| 3718 | 4019 | incoming_blocks[0] = post_val1_block; |
| 3719 | 4020 | incoming_blocks[1] = post_val2_block; |
| 3720 | 4021 | |
| 3721 | | return ir_build_phi(irb, scope, node, 2, incoming_blocks, incoming_values); |
| 4022 | return ir_build_phi(irb, scope, node, 2, incoming_blocks, incoming_values, nullptr); |
| 3722 | 4023 | } |
| 3723 | 4024 | |
| 3724 | 4025 | static IrInstruction *ir_gen_bool_and(IrBuilder *irb, Scope *scope, AstNode *node) { |
| ... | ... | @@ -3760,16 +4061,51 @@ static IrInstruction *ir_gen_bool_and(IrBuilder *irb, Scope *scope, AstNode *nod |
| 3760 | 4061 | incoming_blocks[0] = post_val1_block; |
| 3761 | 4062 | incoming_blocks[1] = post_val2_block; |
| 3762 | 4063 | |
| 3763 | | return ir_build_phi(irb, scope, node, 2, incoming_blocks, incoming_values); |
| 4064 | return ir_build_phi(irb, scope, node, 2, incoming_blocks, incoming_values, nullptr); |
| 4065 | } |
| 4066 | |
| 4067 | static ResultLocPeerParent *ir_build_result_peers(IrBuilder *irb, IrInstruction *cond_br_inst, |
| 4068 | IrBasicBlock *end_block, ResultLoc *parent, IrInstruction *is_comptime) |
| 4069 | { |
| 4070 | ResultLocPeerParent *peer_parent = allocate<ResultLocPeerParent>(1); |
| 4071 | peer_parent->base.id = ResultLocIdPeerParent; |
| 4072 | peer_parent->base.source_instruction = cond_br_inst; |
| 4073 | peer_parent->end_bb = end_block; |
| 4074 | peer_parent->is_comptime = is_comptime; |
| 4075 | peer_parent->parent = parent; |
| 4076 | |
| 4077 | IrInstruction *popped_inst = irb->current_basic_block->instruction_list.pop(); |
| 4078 | ir_assert(popped_inst == cond_br_inst, cond_br_inst); |
| 4079 | |
| 4080 | ir_build_reset_result(irb, cond_br_inst->scope, cond_br_inst->source_node, &peer_parent->base); |
| 4081 | irb->current_basic_block->instruction_list.append(popped_inst); |
| 4082 | |
| 4083 | return peer_parent; |
| 3764 | 4084 | } |
| 3765 | 4085 | |
| 3766 | | static IrInstruction *ir_gen_orelse(IrBuilder *irb, Scope *parent_scope, AstNode *node) { |
| 4086 | static ResultLocPeerParent *ir_build_binary_result_peers(IrBuilder *irb, IrInstruction *cond_br_inst, |
| 4087 | IrBasicBlock *else_block, IrBasicBlock *end_block, ResultLoc *parent, IrInstruction *is_comptime) |
| 4088 | { |
| 4089 | ResultLocPeerParent *peer_parent = ir_build_result_peers(irb, cond_br_inst, end_block, parent, is_comptime); |
| 4090 | |
| 4091 | peer_parent->peers.append(create_peer_result(peer_parent)); |
| 4092 | peer_parent->peers.last()->next_bb = else_block; |
| 4093 | |
| 4094 | peer_parent->peers.append(create_peer_result(peer_parent)); |
| 4095 | peer_parent->peers.last()->next_bb = end_block; |
| 4096 | |
| 4097 | return peer_parent; |
| 4098 | } |
| 4099 | |
| 4100 | static IrInstruction *ir_gen_orelse(IrBuilder *irb, Scope *parent_scope, AstNode *node, LVal lval, |
| 4101 | ResultLoc *result_loc) |
| 4102 | { |
| 3767 | 4103 | assert(node->type == NodeTypeBinOpExpr); |
| 3768 | 4104 | |
| 3769 | 4105 | AstNode *op1_node = node->data.bin_op_expr.op1; |
| 3770 | 4106 | AstNode *op2_node = node->data.bin_op_expr.op2; |
| 3771 | 4107 | |
| 3772 | | IrInstruction *maybe_ptr = ir_gen_node_extra(irb, op1_node, parent_scope, LValPtr); |
| 4108 | IrInstruction *maybe_ptr = ir_gen_node_extra(irb, op1_node, parent_scope, LValPtr, nullptr); |
| 3773 | 4109 | if (maybe_ptr == irb->codegen->invalid_instruction) |
| 3774 | 4110 | return irb->codegen->invalid_instruction; |
| 3775 | 4111 | |
| ... | ... | @@ -3786,10 +4122,14 @@ static IrInstruction *ir_gen_orelse(IrBuilder *irb, Scope *parent_scope, AstNode |
| 3786 | 4122 | IrBasicBlock *ok_block = ir_create_basic_block(irb, parent_scope, "OptionalNonNull"); |
| 3787 | 4123 | IrBasicBlock *null_block = ir_create_basic_block(irb, parent_scope, "OptionalNull"); |
| 3788 | 4124 | IrBasicBlock *end_block = ir_create_basic_block(irb, parent_scope, "OptionalEnd"); |
| 3789 | | ir_build_cond_br(irb, parent_scope, node, is_non_null, ok_block, null_block, is_comptime); |
| 4125 | IrInstruction *cond_br_inst = ir_build_cond_br(irb, parent_scope, node, is_non_null, ok_block, null_block, is_comptime); |
| 4126 | |
| 4127 | ResultLocPeerParent *peer_parent = ir_build_binary_result_peers(irb, cond_br_inst, ok_block, end_block, |
| 4128 | result_loc, is_comptime); |
| 3790 | 4129 | |
| 3791 | 4130 | ir_set_cursor_at_end_and_append_block(irb, null_block); |
| 3792 | | IrInstruction *null_result = ir_gen_node(irb, op2_node, parent_scope); |
| 4131 | IrInstruction *null_result = ir_gen_node_extra(irb, op2_node, parent_scope, LValNone, |
| 4132 | &peer_parent->peers.at(0)->base); |
| 3793 | 4133 | if (null_result == irb->codegen->invalid_instruction) |
| 3794 | 4134 | return irb->codegen->invalid_instruction; |
| 3795 | 4135 | IrBasicBlock *after_null_block = irb->current_basic_block; |
| ... | ... | @@ -3797,8 +4137,9 @@ static IrInstruction *ir_gen_orelse(IrBuilder *irb, Scope *parent_scope, AstNode |
| 3797 | 4137 | ir_mark_gen(ir_build_br(irb, parent_scope, node, end_block, is_comptime)); |
| 3798 | 4138 | |
| 3799 | 4139 | ir_set_cursor_at_end_and_append_block(irb, ok_block); |
| 3800 | | IrInstruction *unwrapped_ptr = ir_build_optional_unwrap_ptr(irb, parent_scope, node, maybe_ptr, false); |
| 4140 | IrInstruction *unwrapped_ptr = ir_build_optional_unwrap_ptr(irb, parent_scope, node, maybe_ptr, false, false); |
| 3801 | 4141 | IrInstruction *unwrapped_payload = ir_build_load_ptr(irb, parent_scope, node, unwrapped_ptr); |
| 4142 | ir_build_end_expr(irb, parent_scope, node, unwrapped_payload, &peer_parent->peers.at(1)->base); |
| 3802 | 4143 | IrBasicBlock *after_ok_block = irb->current_basic_block; |
| 3803 | 4144 | ir_build_br(irb, parent_scope, node, end_block, is_comptime); |
| 3804 | 4145 | |
| ... | ... | @@ -3809,7 +4150,8 @@ static IrInstruction *ir_gen_orelse(IrBuilder *irb, Scope *parent_scope, AstNode |
| 3809 | 4150 | IrBasicBlock **incoming_blocks = allocate<IrBasicBlock *>(2); |
| 3810 | 4151 | incoming_blocks[0] = after_null_block; |
| 3811 | 4152 | incoming_blocks[1] = after_ok_block; |
| 3812 | | return ir_build_phi(irb, parent_scope, node, 2, incoming_blocks, incoming_values); |
| 4153 | IrInstruction *phi = ir_build_phi(irb, parent_scope, node, 2, incoming_blocks, incoming_values, peer_parent); |
| 4154 | return ir_lval_wrap(irb, parent_scope, phi, lval, result_loc); |
| 3813 | 4155 | } |
| 3814 | 4156 | |
| 3815 | 4157 | static IrInstruction *ir_gen_error_union(IrBuilder *irb, Scope *parent_scope, AstNode *node) { |
| ... | ... | @@ -3829,7 +4171,7 @@ static IrInstruction *ir_gen_error_union(IrBuilder *irb, Scope *parent_scope, As |
| 3829 | 4171 | return ir_build_error_union(irb, parent_scope, node, err_set, payload); |
| 3830 | 4172 | } |
| 3831 | 4173 | |
| 3832 | | static IrInstruction *ir_gen_bin_op(IrBuilder *irb, Scope *scope, AstNode *node) { |
| 4174 | static IrInstruction *ir_gen_bin_op(IrBuilder *irb, Scope *scope, AstNode *node, LVal lval, ResultLoc *result_loc) { |
| 3833 | 4175 | assert(node->type == NodeTypeBinOpExpr); |
| 3834 | 4176 | |
| 3835 | 4177 | BinOpType bin_op_type = node->data.bin_op_expr.bin_op; |
| ... | ... | @@ -3837,87 +4179,87 @@ static IrInstruction *ir_gen_bin_op(IrBuilder *irb, Scope *scope, AstNode *node) |
| 3837 | 4179 | case BinOpTypeInvalid: |
| 3838 | 4180 | zig_unreachable(); |
| 3839 | 4181 | case BinOpTypeAssign: |
| 3840 | | return ir_gen_assign(irb, scope, node); |
| 4182 | return ir_lval_wrap(irb, scope, ir_gen_assign(irb, scope, node), lval, result_loc); |
| 3841 | 4183 | case BinOpTypeAssignTimes: |
| 3842 | | return ir_gen_assign_op(irb, scope, node, IrBinOpMult); |
| 4184 | return ir_lval_wrap(irb, scope, ir_gen_assign_op(irb, scope, node, IrBinOpMult), lval, result_loc); |
| 3843 | 4185 | case BinOpTypeAssignTimesWrap: |
| 3844 | | return ir_gen_assign_op(irb, scope, node, IrBinOpMultWrap); |
| 4186 | return ir_lval_wrap(irb, scope, ir_gen_assign_op(irb, scope, node, IrBinOpMultWrap), lval, result_loc); |
| 3845 | 4187 | case BinOpTypeAssignDiv: |
| 3846 | | return ir_gen_assign_op(irb, scope, node, IrBinOpDivUnspecified); |
| 4188 | return ir_lval_wrap(irb, scope, ir_gen_assign_op(irb, scope, node, IrBinOpDivUnspecified), lval, result_loc); |
| 3847 | 4189 | case BinOpTypeAssignMod: |
| 3848 | | return ir_gen_assign_op(irb, scope, node, IrBinOpRemUnspecified); |
| 4190 | return ir_lval_wrap(irb, scope, ir_gen_assign_op(irb, scope, node, IrBinOpRemUnspecified), lval, result_loc); |
| 3849 | 4191 | case BinOpTypeAssignPlus: |
| 3850 | | return ir_gen_assign_op(irb, scope, node, IrBinOpAdd); |
| 4192 | return ir_lval_wrap(irb, scope, ir_gen_assign_op(irb, scope, node, IrBinOpAdd), lval, result_loc); |
| 3851 | 4193 | case BinOpTypeAssignPlusWrap: |
| 3852 | | return ir_gen_assign_op(irb, scope, node, IrBinOpAddWrap); |
| 4194 | return ir_lval_wrap(irb, scope, ir_gen_assign_op(irb, scope, node, IrBinOpAddWrap), lval, result_loc); |
| 3853 | 4195 | case BinOpTypeAssignMinus: |
| 3854 | | return ir_gen_assign_op(irb, scope, node, IrBinOpSub); |
| 4196 | return ir_lval_wrap(irb, scope, ir_gen_assign_op(irb, scope, node, IrBinOpSub), lval, result_loc); |
| 3855 | 4197 | case BinOpTypeAssignMinusWrap: |
| 3856 | | return ir_gen_assign_op(irb, scope, node, IrBinOpSubWrap); |
| 4198 | return ir_lval_wrap(irb, scope, ir_gen_assign_op(irb, scope, node, IrBinOpSubWrap), lval, result_loc); |
| 3857 | 4199 | case BinOpTypeAssignBitShiftLeft: |
| 3858 | | return ir_gen_assign_op(irb, scope, node, IrBinOpBitShiftLeftLossy); |
| 4200 | return ir_lval_wrap(irb, scope, ir_gen_assign_op(irb, scope, node, IrBinOpBitShiftLeftLossy), lval, result_loc); |
| 3859 | 4201 | case BinOpTypeAssignBitShiftRight: |
| 3860 | | return ir_gen_assign_op(irb, scope, node, IrBinOpBitShiftRightLossy); |
| 4202 | return ir_lval_wrap(irb, scope, ir_gen_assign_op(irb, scope, node, IrBinOpBitShiftRightLossy), lval, result_loc); |
| 3861 | 4203 | case BinOpTypeAssignBitAnd: |
| 3862 | | return ir_gen_assign_op(irb, scope, node, IrBinOpBinAnd); |
| 4204 | return ir_lval_wrap(irb, scope, ir_gen_assign_op(irb, scope, node, IrBinOpBinAnd), lval, result_loc); |
| 3863 | 4205 | case BinOpTypeAssignBitXor: |
| 3864 | | return ir_gen_assign_op(irb, scope, node, IrBinOpBinXor); |
| 4206 | return ir_lval_wrap(irb, scope, ir_gen_assign_op(irb, scope, node, IrBinOpBinXor), lval, result_loc); |
| 3865 | 4207 | case BinOpTypeAssignBitOr: |
| 3866 | | return ir_gen_assign_op(irb, scope, node, IrBinOpBinOr); |
| 4208 | return ir_lval_wrap(irb, scope, ir_gen_assign_op(irb, scope, node, IrBinOpBinOr), lval, result_loc); |
| 3867 | 4209 | case BinOpTypeAssignMergeErrorSets: |
| 3868 | | return ir_gen_assign_op(irb, scope, node, IrBinOpMergeErrorSets); |
| 4210 | return ir_lval_wrap(irb, scope, ir_gen_assign_op(irb, scope, node, IrBinOpMergeErrorSets), lval, result_loc); |
| 3869 | 4211 | case BinOpTypeBoolOr: |
| 3870 | | return ir_gen_bool_or(irb, scope, node); |
| 4212 | return ir_lval_wrap(irb, scope, ir_gen_bool_or(irb, scope, node), lval, result_loc); |
| 3871 | 4213 | case BinOpTypeBoolAnd: |
| 3872 | | return ir_gen_bool_and(irb, scope, node); |
| 4214 | return ir_lval_wrap(irb, scope, ir_gen_bool_and(irb, scope, node), lval, result_loc); |
| 3873 | 4215 | case BinOpTypeCmpEq: |
| 3874 | | return ir_gen_bin_op_id(irb, scope, node, IrBinOpCmpEq); |
| 4216 | return ir_lval_wrap(irb, scope, ir_gen_bin_op_id(irb, scope, node, IrBinOpCmpEq), lval, result_loc); |
| 3875 | 4217 | case BinOpTypeCmpNotEq: |
| 3876 | | return ir_gen_bin_op_id(irb, scope, node, IrBinOpCmpNotEq); |
| 4218 | return ir_lval_wrap(irb, scope, ir_gen_bin_op_id(irb, scope, node, IrBinOpCmpNotEq), lval, result_loc); |
| 3877 | 4219 | case BinOpTypeCmpLessThan: |
| 3878 | | return ir_gen_bin_op_id(irb, scope, node, IrBinOpCmpLessThan); |
| 4220 | return ir_lval_wrap(irb, scope, ir_gen_bin_op_id(irb, scope, node, IrBinOpCmpLessThan), lval, result_loc); |
| 3879 | 4221 | case BinOpTypeCmpGreaterThan: |
| 3880 | | return ir_gen_bin_op_id(irb, scope, node, IrBinOpCmpGreaterThan); |
| 4222 | return ir_lval_wrap(irb, scope, ir_gen_bin_op_id(irb, scope, node, IrBinOpCmpGreaterThan), lval, result_loc); |
| 3881 | 4223 | case BinOpTypeCmpLessOrEq: |
| 3882 | | return ir_gen_bin_op_id(irb, scope, node, IrBinOpCmpLessOrEq); |
| 4224 | return ir_lval_wrap(irb, scope, ir_gen_bin_op_id(irb, scope, node, IrBinOpCmpLessOrEq), lval, result_loc); |
| 3883 | 4225 | case BinOpTypeCmpGreaterOrEq: |
| 3884 | | return ir_gen_bin_op_id(irb, scope, node, IrBinOpCmpGreaterOrEq); |
| 4226 | return ir_lval_wrap(irb, scope, ir_gen_bin_op_id(irb, scope, node, IrBinOpCmpGreaterOrEq), lval, result_loc); |
| 3885 | 4227 | case BinOpTypeBinOr: |
| 3886 | | return ir_gen_bin_op_id(irb, scope, node, IrBinOpBinOr); |
| 4228 | return ir_lval_wrap(irb, scope, ir_gen_bin_op_id(irb, scope, node, IrBinOpBinOr), lval, result_loc); |
| 3887 | 4229 | case BinOpTypeBinXor: |
| 3888 | | return ir_gen_bin_op_id(irb, scope, node, IrBinOpBinXor); |
| 4230 | return ir_lval_wrap(irb, scope, ir_gen_bin_op_id(irb, scope, node, IrBinOpBinXor), lval, result_loc); |
| 3889 | 4231 | case BinOpTypeBinAnd: |
| 3890 | | return ir_gen_bin_op_id(irb, scope, node, IrBinOpBinAnd); |
| 4232 | return ir_lval_wrap(irb, scope, ir_gen_bin_op_id(irb, scope, node, IrBinOpBinAnd), lval, result_loc); |
| 3891 | 4233 | case BinOpTypeBitShiftLeft: |
| 3892 | | return ir_gen_bin_op_id(irb, scope, node, IrBinOpBitShiftLeftLossy); |
| 4234 | return ir_lval_wrap(irb, scope, ir_gen_bin_op_id(irb, scope, node, IrBinOpBitShiftLeftLossy), lval, result_loc); |
| 3893 | 4235 | case BinOpTypeBitShiftRight: |
| 3894 | | return ir_gen_bin_op_id(irb, scope, node, IrBinOpBitShiftRightLossy); |
| 4236 | return ir_lval_wrap(irb, scope, ir_gen_bin_op_id(irb, scope, node, IrBinOpBitShiftRightLossy), lval, result_loc); |
| 3895 | 4237 | case BinOpTypeAdd: |
| 3896 | | return ir_gen_bin_op_id(irb, scope, node, IrBinOpAdd); |
| 4238 | return ir_lval_wrap(irb, scope, ir_gen_bin_op_id(irb, scope, node, IrBinOpAdd), lval, result_loc); |
| 3897 | 4239 | case BinOpTypeAddWrap: |
| 3898 | | return ir_gen_bin_op_id(irb, scope, node, IrBinOpAddWrap); |
| 4240 | return ir_lval_wrap(irb, scope, ir_gen_bin_op_id(irb, scope, node, IrBinOpAddWrap), lval, result_loc); |
| 3899 | 4241 | case BinOpTypeSub: |
| 3900 | | return ir_gen_bin_op_id(irb, scope, node, IrBinOpSub); |
| 4242 | return ir_lval_wrap(irb, scope, ir_gen_bin_op_id(irb, scope, node, IrBinOpSub), lval, result_loc); |
| 3901 | 4243 | case BinOpTypeSubWrap: |
| 3902 | | return ir_gen_bin_op_id(irb, scope, node, IrBinOpSubWrap); |
| 4244 | return ir_lval_wrap(irb, scope, ir_gen_bin_op_id(irb, scope, node, IrBinOpSubWrap), lval, result_loc); |
| 3903 | 4245 | case BinOpTypeMult: |
| 3904 | | return ir_gen_bin_op_id(irb, scope, node, IrBinOpMult); |
| 4246 | return ir_lval_wrap(irb, scope, ir_gen_bin_op_id(irb, scope, node, IrBinOpMult), lval, result_loc); |
| 3905 | 4247 | case BinOpTypeMultWrap: |
| 3906 | | return ir_gen_bin_op_id(irb, scope, node, IrBinOpMultWrap); |
| 4248 | return ir_lval_wrap(irb, scope, ir_gen_bin_op_id(irb, scope, node, IrBinOpMultWrap), lval, result_loc); |
| 3907 | 4249 | case BinOpTypeDiv: |
| 3908 | | return ir_gen_bin_op_id(irb, scope, node, IrBinOpDivUnspecified); |
| 4250 | return ir_lval_wrap(irb, scope, ir_gen_bin_op_id(irb, scope, node, IrBinOpDivUnspecified), lval, result_loc); |
| 3909 | 4251 | case BinOpTypeMod: |
| 3910 | | return ir_gen_bin_op_id(irb, scope, node, IrBinOpRemUnspecified); |
| 4252 | return ir_lval_wrap(irb, scope, ir_gen_bin_op_id(irb, scope, node, IrBinOpRemUnspecified), lval, result_loc); |
| 3911 | 4253 | case BinOpTypeArrayCat: |
| 3912 | | return ir_gen_bin_op_id(irb, scope, node, IrBinOpArrayCat); |
| 4254 | return ir_lval_wrap(irb, scope, ir_gen_bin_op_id(irb, scope, node, IrBinOpArrayCat), lval, result_loc); |
| 3913 | 4255 | case BinOpTypeArrayMult: |
| 3914 | | return ir_gen_bin_op_id(irb, scope, node, IrBinOpArrayMult); |
| 4256 | return ir_lval_wrap(irb, scope, ir_gen_bin_op_id(irb, scope, node, IrBinOpArrayMult), lval, result_loc); |
| 3915 | 4257 | case BinOpTypeMergeErrorSets: |
| 3916 | | return ir_gen_bin_op_id(irb, scope, node, IrBinOpMergeErrorSets); |
| 4258 | return ir_lval_wrap(irb, scope, ir_gen_bin_op_id(irb, scope, node, IrBinOpMergeErrorSets), lval, result_loc); |
| 3917 | 4259 | case BinOpTypeUnwrapOptional: |
| 3918 | | return ir_gen_orelse(irb, scope, node); |
| 4260 | return ir_gen_orelse(irb, scope, node, lval, result_loc); |
| 3919 | 4261 | case BinOpTypeErrorUnion: |
| 3920 | | return ir_gen_error_union(irb, scope, node); |
| 4262 | return ir_lval_wrap(irb, scope, ir_gen_error_union(irb, scope, node), lval, result_loc); |
| 3921 | 4263 | } |
| 3922 | 4264 | zig_unreachable(); |
| 3923 | 4265 | } |
| ... | ... | @@ -3962,12 +4304,12 @@ static void populate_invalid_variable_in_scope(CodeGen *g, Scope *scope, AstNode |
| 3962 | 4304 | TldVar *tld_var = allocate<TldVar>(1); |
| 3963 | 4305 | init_tld(&tld_var->base, TldIdVar, var_name, VisibModPub, node, &scope_decls->base); |
| 3964 | 4306 | tld_var->base.resolution = TldResolutionInvalid; |
| 3965 | | tld_var->var = add_variable(g, node, &scope_decls->base, var_name, false, |
| 4307 | tld_var->var = add_variable(g, node, &scope_decls->base, var_name, false, |
| 3966 | 4308 | &g->invalid_instruction->value, &tld_var->base, g->builtin_types.entry_invalid); |
| 3967 | 4309 | scope_decls->decl_table.put(var_name, &tld_var->base); |
| 3968 | 4310 | } |
| 3969 | 4311 | |
| 3970 | | static IrInstruction *ir_gen_symbol(IrBuilder *irb, Scope *scope, AstNode *node, LVal lval) { |
| 4312 | static IrInstruction *ir_gen_symbol(IrBuilder *irb, Scope *scope, AstNode *node, LVal lval, ResultLoc *result_loc) { |
| 3971 | 4313 | Error err; |
| 3972 | 4314 | assert(node->type == NodeTypeSymbol); |
| 3973 | 4315 | |
| ... | ... | @@ -4001,7 +4343,7 @@ static IrInstruction *ir_gen_symbol(IrBuilder *irb, Scope *scope, AstNode *node, |
| 4001 | 4343 | if (lval == LValPtr) { |
| 4002 | 4344 | return ir_build_ref(irb, scope, node, value, false, false); |
| 4003 | 4345 | } else { |
| 4004 | | return value; |
| 4346 | return ir_expr_wrap(irb, scope, value, result_loc); |
| 4005 | 4347 | } |
| 4006 | 4348 | } |
| 4007 | 4349 | |
| ... | ... | @@ -4009,15 +4351,22 @@ static IrInstruction *ir_gen_symbol(IrBuilder *irb, Scope *scope, AstNode *node, |
| 4009 | 4351 | ZigVar *var = find_variable(irb->codegen, scope, variable_name, &crossed_fndef_scope); |
| 4010 | 4352 | if (var) { |
| 4011 | 4353 | IrInstruction *var_ptr = ir_build_var_ptr_x(irb, scope, node, var, crossed_fndef_scope); |
| 4012 | | if (lval == LValPtr) |
| 4354 | if (lval == LValPtr) { |
| 4013 | 4355 | return var_ptr; |
| 4014 | | else |
| 4015 | | 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 | } |
| 4016 | 4359 | } |
| 4017 | 4360 | |
| 4018 | 4361 | Tld *tld = find_decl(irb->codegen, scope, variable_name); |
| 4019 | | if (tld) |
| 4020 | | 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 | } |
| 4021 | 4370 | |
| 4022 | 4371 | if (get_container_scope(node->owner)->any_imports_failed) { |
| 4023 | 4372 | // skip the error message since we had a failing import in this file |
| ... | ... | @@ -4028,11 +4377,13 @@ static IrInstruction *ir_gen_symbol(IrBuilder *irb, Scope *scope, AstNode *node, |
| 4028 | 4377 | return ir_build_undeclared_identifier(irb, scope, node, variable_name); |
| 4029 | 4378 | } |
| 4030 | 4379 | |
| 4031 | | static IrInstruction *ir_gen_array_access(IrBuilder *irb, Scope *scope, AstNode *node, LVal lval) { |
| 4380 | static IrInstruction *ir_gen_array_access(IrBuilder *irb, Scope *scope, AstNode *node, LVal lval, |
| 4381 | ResultLoc *result_loc) |
| 4382 | { |
| 4032 | 4383 | assert(node->type == NodeTypeArrayAccessExpr); |
| 4033 | 4384 | |
| 4034 | 4385 | AstNode *array_ref_node = node->data.array_access_expr.array_ref_expr; |
| 4035 | | IrInstruction *array_ref_instruction = ir_gen_node_extra(irb, array_ref_node, scope, LValPtr); |
| 4386 | IrInstruction *array_ref_instruction = ir_gen_node_extra(irb, array_ref_node, scope, LValPtr, nullptr); |
| 4036 | 4387 | if (array_ref_instruction == irb->codegen->invalid_instruction) |
| 4037 | 4388 | return array_ref_instruction; |
| 4038 | 4389 | |
| ... | ... | @@ -4042,11 +4393,12 @@ static IrInstruction *ir_gen_array_access(IrBuilder *irb, Scope *scope, AstNode |
| 4042 | 4393 | return subscript_instruction; |
| 4043 | 4394 | |
| 4044 | 4395 | IrInstruction *ptr_instruction = ir_build_elem_ptr(irb, scope, node, array_ref_instruction, |
| 4045 | | subscript_instruction, true, PtrLenSingle); |
| 4396 | subscript_instruction, true, PtrLenSingle, nullptr); |
| 4046 | 4397 | if (lval == LValPtr) |
| 4047 | 4398 | return ptr_instruction; |
| 4048 | 4399 | |
| 4049 | | return ir_build_load_ptr(irb, scope, node, ptr_instruction); |
| 4400 | IrInstruction *load_ptr = ir_build_load_ptr(irb, scope, node, ptr_instruction); |
| 4401 | return ir_expr_wrap(irb, scope, load_ptr, result_loc); |
| 4050 | 4402 | } |
| 4051 | 4403 | |
| 4052 | 4404 | static IrInstruction *ir_gen_field_access(IrBuilder *irb, Scope *scope, AstNode *node) { |
| ... | ... | @@ -4055,11 +4407,11 @@ static IrInstruction *ir_gen_field_access(IrBuilder *irb, Scope *scope, AstNode |
| 4055 | 4407 | AstNode *container_ref_node = node->data.field_access_expr.struct_expr; |
| 4056 | 4408 | Buf *field_name = node->data.field_access_expr.field_name; |
| 4057 | 4409 | |
| 4058 | | IrInstruction *container_ref_instruction = ir_gen_node_extra(irb, container_ref_node, scope, LValPtr); |
| 4410 | IrInstruction *container_ref_instruction = ir_gen_node_extra(irb, container_ref_node, scope, LValPtr, nullptr); |
| 4059 | 4411 | if (container_ref_instruction == irb->codegen->invalid_instruction) |
| 4060 | 4412 | return container_ref_instruction; |
| 4061 | 4413 | |
| 4062 | | return ir_build_field_ptr(irb, scope, node, container_ref_instruction, field_name); |
| 4414 | return ir_build_field_ptr(irb, scope, node, container_ref_instruction, field_name, false); |
| 4063 | 4415 | } |
| 4064 | 4416 | |
| 4065 | 4417 | static IrInstruction *ir_gen_overflow_op(IrBuilder *irb, Scope *scope, AstNode *node, IrOverflowOp op) { |
| ... | ... | @@ -4132,7 +4484,9 @@ static IrInstruction *ir_gen_this(IrBuilder *irb, Scope *orig_scope, AstNode *no |
| 4132 | 4484 | zig_unreachable(); |
| 4133 | 4485 | } |
| 4134 | 4486 | |
| 4135 | | static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNode *node, LVal lval) { |
| 4487 | static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNode *node, LVal lval, |
| 4488 | ResultLoc *result_loc) |
| 4489 | { |
| 4136 | 4490 | assert(node->type == NodeTypeFnCallExpr); |
| 4137 | 4491 | |
| 4138 | 4492 | AstNode *fn_ref_expr = node->data.fn_call_expr.fn_ref_expr; |
| ... | ... | @@ -4168,7 +4522,7 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo |
| 4168 | 4522 | return arg; |
| 4169 | 4523 | |
| 4170 | 4524 | IrInstruction *type_of = ir_build_typeof(irb, scope, node, arg); |
| 4171 | | return ir_lval_wrap(irb, scope, type_of, lval); |
| 4525 | return ir_lval_wrap(irb, scope, type_of, lval, result_loc); |
| 4172 | 4526 | } |
| 4173 | 4527 | case BuiltinFnIdSetCold: |
| 4174 | 4528 | { |
| ... | ... | @@ -4178,7 +4532,7 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo |
| 4178 | 4532 | return arg0_value; |
| 4179 | 4533 | |
| 4180 | 4534 | IrInstruction *set_cold = ir_build_set_cold(irb, scope, node, arg0_value); |
| 4181 | | return ir_lval_wrap(irb, scope, set_cold, lval); |
| 4535 | return ir_lval_wrap(irb, scope, set_cold, lval, result_loc); |
| 4182 | 4536 | } |
| 4183 | 4537 | case BuiltinFnIdSetRuntimeSafety: |
| 4184 | 4538 | { |
| ... | ... | @@ -4188,7 +4542,7 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo |
| 4188 | 4542 | return arg0_value; |
| 4189 | 4543 | |
| 4190 | 4544 | IrInstruction *set_safety = ir_build_set_runtime_safety(irb, scope, node, arg0_value); |
| 4191 | | return ir_lval_wrap(irb, scope, set_safety, lval); |
| 4545 | return ir_lval_wrap(irb, scope, set_safety, lval, result_loc); |
| 4192 | 4546 | } |
| 4193 | 4547 | case BuiltinFnIdSetFloatMode: |
| 4194 | 4548 | { |
| ... | ... | @@ -4198,7 +4552,7 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo |
| 4198 | 4552 | return arg0_value; |
| 4199 | 4553 | |
| 4200 | 4554 | IrInstruction *set_float_mode = ir_build_set_float_mode(irb, scope, node, arg0_value); |
| 4201 | | return ir_lval_wrap(irb, scope, set_float_mode, lval); |
| 4555 | return ir_lval_wrap(irb, scope, set_float_mode, lval, result_loc); |
| 4202 | 4556 | } |
| 4203 | 4557 | case BuiltinFnIdSizeof: |
| 4204 | 4558 | { |
| ... | ... | @@ -4208,7 +4562,7 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo |
| 4208 | 4562 | return arg0_value; |
| 4209 | 4563 | |
| 4210 | 4564 | IrInstruction *size_of = ir_build_size_of(irb, scope, node, arg0_value); |
| 4211 | | return ir_lval_wrap(irb, scope, size_of, lval); |
| 4565 | return ir_lval_wrap(irb, scope, size_of, lval, result_loc); |
| 4212 | 4566 | } |
| 4213 | 4567 | case BuiltinFnIdImport: |
| 4214 | 4568 | { |
| ... | ... | @@ -4218,12 +4572,12 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo |
| 4218 | 4572 | return arg0_value; |
| 4219 | 4573 | |
| 4220 | 4574 | IrInstruction *import = ir_build_import(irb, scope, node, arg0_value); |
| 4221 | | return ir_lval_wrap(irb, scope, import, lval); |
| 4575 | return ir_lval_wrap(irb, scope, import, lval, result_loc); |
| 4222 | 4576 | } |
| 4223 | 4577 | case BuiltinFnIdCImport: |
| 4224 | 4578 | { |
| 4225 | 4579 | IrInstruction *c_import = ir_build_c_import(irb, scope, node); |
| 4226 | | return ir_lval_wrap(irb, scope, c_import, lval); |
| 4580 | return ir_lval_wrap(irb, scope, c_import, lval, result_loc); |
| 4227 | 4581 | } |
| 4228 | 4582 | case BuiltinFnIdCInclude: |
| 4229 | 4583 | { |
| ... | ... | @@ -4238,7 +4592,7 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo |
| 4238 | 4592 | } |
| 4239 | 4593 | |
| 4240 | 4594 | IrInstruction *c_include = ir_build_c_include(irb, scope, node, arg0_value); |
| 4241 | | return ir_lval_wrap(irb, scope, c_include, lval); |
| 4595 | return ir_lval_wrap(irb, scope, c_include, lval, result_loc); |
| 4242 | 4596 | } |
| 4243 | 4597 | case BuiltinFnIdCDefine: |
| 4244 | 4598 | { |
| ... | ... | @@ -4258,7 +4612,7 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo |
| 4258 | 4612 | } |
| 4259 | 4613 | |
| 4260 | 4614 | IrInstruction *c_define = ir_build_c_define(irb, scope, node, arg0_value, arg1_value); |
| 4261 | | return ir_lval_wrap(irb, scope, c_define, lval); |
| 4615 | return ir_lval_wrap(irb, scope, c_define, lval, result_loc); |
| 4262 | 4616 | } |
| 4263 | 4617 | case BuiltinFnIdCUndef: |
| 4264 | 4618 | { |
| ... | ... | @@ -4273,7 +4627,7 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo |
| 4273 | 4627 | } |
| 4274 | 4628 | |
| 4275 | 4629 | IrInstruction *c_undef = ir_build_c_undef(irb, scope, node, arg0_value); |
| 4276 | | return ir_lval_wrap(irb, scope, c_undef, lval); |
| 4630 | return ir_lval_wrap(irb, scope, c_undef, lval, result_loc); |
| 4277 | 4631 | } |
| 4278 | 4632 | case BuiltinFnIdCompileErr: |
| 4279 | 4633 | { |
| ... | ... | @@ -4283,7 +4637,7 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo |
| 4283 | 4637 | return arg0_value; |
| 4284 | 4638 | |
| 4285 | 4639 | IrInstruction *compile_err = ir_build_compile_err(irb, scope, node, arg0_value); |
| 4286 | | return ir_lval_wrap(irb, scope, compile_err, lval); |
| 4640 | return ir_lval_wrap(irb, scope, compile_err, lval, result_loc); |
| 4287 | 4641 | } |
| 4288 | 4642 | case BuiltinFnIdCompileLog: |
| 4289 | 4643 | { |
| ... | ... | @@ -4297,7 +4651,7 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo |
| 4297 | 4651 | } |
| 4298 | 4652 | |
| 4299 | 4653 | IrInstruction *compile_log = ir_build_compile_log(irb, scope, node, actual_param_count, args); |
| 4300 | | return ir_lval_wrap(irb, scope, compile_log, lval); |
| 4654 | return ir_lval_wrap(irb, scope, compile_log, lval, result_loc); |
| 4301 | 4655 | } |
| 4302 | 4656 | case BuiltinFnIdErrName: |
| 4303 | 4657 | { |
| ... | ... | @@ -4307,7 +4661,7 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo |
| 4307 | 4661 | return arg0_value; |
| 4308 | 4662 | |
| 4309 | 4663 | IrInstruction *err_name = ir_build_err_name(irb, scope, node, arg0_value); |
| 4310 | | return ir_lval_wrap(irb, scope, err_name, lval); |
| 4664 | return ir_lval_wrap(irb, scope, err_name, lval, result_loc); |
| 4311 | 4665 | } |
| 4312 | 4666 | case BuiltinFnIdEmbedFile: |
| 4313 | 4667 | { |
| ... | ... | @@ -4317,7 +4671,7 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo |
| 4317 | 4671 | return arg0_value; |
| 4318 | 4672 | |
| 4319 | 4673 | IrInstruction *embed_file = ir_build_embed_file(irb, scope, node, arg0_value); |
| 4320 | | return ir_lval_wrap(irb, scope, embed_file, lval); |
| 4674 | return ir_lval_wrap(irb, scope, embed_file, lval, result_loc); |
| 4321 | 4675 | } |
| 4322 | 4676 | case BuiltinFnIdCmpxchgWeak: |
| 4323 | 4677 | case BuiltinFnIdCmpxchgStrong: |
| ... | ... | @@ -4353,8 +4707,9 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo |
| 4353 | 4707 | return arg5_value; |
| 4354 | 4708 | |
| 4355 | 4709 | IrInstruction *cmpxchg = ir_build_cmpxchg_src(irb, scope, node, arg0_value, arg1_value, |
| 4356 | | arg2_value, arg3_value, arg4_value, arg5_value, (builtin_fn->id == BuiltinFnIdCmpxchgWeak)); |
| 4357 | | 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); |
| 4358 | 4713 | } |
| 4359 | 4714 | case BuiltinFnIdFence: |
| 4360 | 4715 | { |
| ... | ... | @@ -4364,7 +4719,7 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo |
| 4364 | 4719 | return arg0_value; |
| 4365 | 4720 | |
| 4366 | 4721 | IrInstruction *fence = ir_build_fence(irb, scope, node, arg0_value, AtomicOrderUnordered); |
| 4367 | | return ir_lval_wrap(irb, scope, fence, lval); |
| 4722 | return ir_lval_wrap(irb, scope, fence, lval, result_loc); |
| 4368 | 4723 | } |
| 4369 | 4724 | case BuiltinFnIdDivExact: |
| 4370 | 4725 | { |
| ... | ... | @@ -4379,7 +4734,7 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo |
| 4379 | 4734 | return arg1_value; |
| 4380 | 4735 | |
| 4381 | 4736 | IrInstruction *bin_op = ir_build_bin_op(irb, scope, node, IrBinOpDivExact, arg0_value, arg1_value, true); |
| 4382 | | return ir_lval_wrap(irb, scope, bin_op, lval); |
| 4737 | return ir_lval_wrap(irb, scope, bin_op, lval, result_loc); |
| 4383 | 4738 | } |
| 4384 | 4739 | case BuiltinFnIdDivTrunc: |
| 4385 | 4740 | { |
| ... | ... | @@ -4394,7 +4749,7 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo |
| 4394 | 4749 | return arg1_value; |
| 4395 | 4750 | |
| 4396 | 4751 | IrInstruction *bin_op = ir_build_bin_op(irb, scope, node, IrBinOpDivTrunc, arg0_value, arg1_value, true); |
| 4397 | | return ir_lval_wrap(irb, scope, bin_op, lval); |
| 4752 | return ir_lval_wrap(irb, scope, bin_op, lval, result_loc); |
| 4398 | 4753 | } |
| 4399 | 4754 | case BuiltinFnIdDivFloor: |
| 4400 | 4755 | { |
| ... | ... | @@ -4409,7 +4764,7 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo |
| 4409 | 4764 | return arg1_value; |
| 4410 | 4765 | |
| 4411 | 4766 | IrInstruction *bin_op = ir_build_bin_op(irb, scope, node, IrBinOpDivFloor, arg0_value, arg1_value, true); |
| 4412 | | return ir_lval_wrap(irb, scope, bin_op, lval); |
| 4767 | return ir_lval_wrap(irb, scope, bin_op, lval, result_loc); |
| 4413 | 4768 | } |
| 4414 | 4769 | case BuiltinFnIdRem: |
| 4415 | 4770 | { |
| ... | ... | @@ -4424,7 +4779,7 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo |
| 4424 | 4779 | return arg1_value; |
| 4425 | 4780 | |
| 4426 | 4781 | IrInstruction *bin_op = ir_build_bin_op(irb, scope, node, IrBinOpRemRem, arg0_value, arg1_value, true); |
| 4427 | | return ir_lval_wrap(irb, scope, bin_op, lval); |
| 4782 | return ir_lval_wrap(irb, scope, bin_op, lval, result_loc); |
| 4428 | 4783 | } |
| 4429 | 4784 | case BuiltinFnIdMod: |
| 4430 | 4785 | { |
| ... | ... | @@ -4439,7 +4794,7 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo |
| 4439 | 4794 | return arg1_value; |
| 4440 | 4795 | |
| 4441 | 4796 | IrInstruction *bin_op = ir_build_bin_op(irb, scope, node, IrBinOpRemMod, arg0_value, arg1_value, true); |
| 4442 | | return ir_lval_wrap(irb, scope, bin_op, lval); |
| 4797 | return ir_lval_wrap(irb, scope, bin_op, lval, result_loc); |
| 4443 | 4798 | } |
| 4444 | 4799 | case BuiltinFnIdSqrt: |
| 4445 | 4800 | case BuiltinFnIdSin: |
| ... | ... | @@ -4467,7 +4822,7 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo |
| 4467 | 4822 | return arg1_value; |
| 4468 | 4823 | |
| 4469 | 4824 | IrInstruction *ir_sqrt = ir_build_float_op(irb, scope, node, arg0_value, arg1_value, builtin_fn->id); |
| 4470 | | return ir_lval_wrap(irb, scope, ir_sqrt, lval); |
| 4825 | return ir_lval_wrap(irb, scope, ir_sqrt, lval, result_loc); |
| 4471 | 4826 | } |
| 4472 | 4827 | case BuiltinFnIdTruncate: |
| 4473 | 4828 | { |
| ... | ... | @@ -4482,7 +4837,7 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo |
| 4482 | 4837 | return arg1_value; |
| 4483 | 4838 | |
| 4484 | 4839 | IrInstruction *truncate = ir_build_truncate(irb, scope, node, arg0_value, arg1_value); |
| 4485 | | return ir_lval_wrap(irb, scope, truncate, lval); |
| 4840 | return ir_lval_wrap(irb, scope, truncate, lval, result_loc); |
| 4486 | 4841 | } |
| 4487 | 4842 | case BuiltinFnIdIntCast: |
| 4488 | 4843 | { |
| ... | ... | @@ -4497,7 +4852,7 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo |
| 4497 | 4852 | return arg1_value; |
| 4498 | 4853 | |
| 4499 | 4854 | IrInstruction *result = ir_build_int_cast(irb, scope, node, arg0_value, arg1_value); |
| 4500 | | return ir_lval_wrap(irb, scope, result, lval); |
| 4855 | return ir_lval_wrap(irb, scope, result, lval, result_loc); |
| 4501 | 4856 | } |
| 4502 | 4857 | case BuiltinFnIdFloatCast: |
| 4503 | 4858 | { |
| ... | ... | @@ -4512,7 +4867,7 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo |
| 4512 | 4867 | return arg1_value; |
| 4513 | 4868 | |
| 4514 | 4869 | IrInstruction *result = ir_build_float_cast(irb, scope, node, arg0_value, arg1_value); |
| 4515 | | return ir_lval_wrap(irb, scope, result, lval); |
| 4870 | return ir_lval_wrap(irb, scope, result, lval, result_loc); |
| 4516 | 4871 | } |
| 4517 | 4872 | case BuiltinFnIdErrSetCast: |
| 4518 | 4873 | { |
| ... | ... | @@ -4527,7 +4882,7 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo |
| 4527 | 4882 | return arg1_value; |
| 4528 | 4883 | |
| 4529 | 4884 | IrInstruction *result = ir_build_err_set_cast(irb, scope, node, arg0_value, arg1_value); |
| 4530 | | return ir_lval_wrap(irb, scope, result, lval); |
| 4885 | return ir_lval_wrap(irb, scope, result, lval, result_loc); |
| 4531 | 4886 | } |
| 4532 | 4887 | case BuiltinFnIdFromBytes: |
| 4533 | 4888 | { |
| ... | ... | @@ -4541,8 +4896,8 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo |
| 4541 | 4896 | if (arg1_value == irb->codegen->invalid_instruction) |
| 4542 | 4897 | return arg1_value; |
| 4543 | 4898 | |
| 4544 | | IrInstruction *result = ir_build_from_bytes(irb, scope, node, arg0_value, arg1_value); |
| 4545 | | 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); |
| 4546 | 4901 | } |
| 4547 | 4902 | case BuiltinFnIdToBytes: |
| 4548 | 4903 | { |
| ... | ... | @@ -4551,8 +4906,8 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo |
| 4551 | 4906 | if (arg0_value == irb->codegen->invalid_instruction) |
| 4552 | 4907 | return arg0_value; |
| 4553 | 4908 | |
| 4554 | | IrInstruction *result = ir_build_to_bytes(irb, scope, node, arg0_value); |
| 4555 | | 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); |
| 4556 | 4911 | } |
| 4557 | 4912 | case BuiltinFnIdIntToFloat: |
| 4558 | 4913 | { |
| ... | ... | @@ -4567,7 +4922,7 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo |
| 4567 | 4922 | return arg1_value; |
| 4568 | 4923 | |
| 4569 | 4924 | IrInstruction *result = ir_build_int_to_float(irb, scope, node, arg0_value, arg1_value); |
| 4570 | | return ir_lval_wrap(irb, scope, result, lval); |
| 4925 | return ir_lval_wrap(irb, scope, result, lval, result_loc); |
| 4571 | 4926 | } |
| 4572 | 4927 | case BuiltinFnIdFloatToInt: |
| 4573 | 4928 | { |
| ... | ... | @@ -4582,7 +4937,7 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo |
| 4582 | 4937 | return arg1_value; |
| 4583 | 4938 | |
| 4584 | 4939 | IrInstruction *result = ir_build_float_to_int(irb, scope, node, arg0_value, arg1_value); |
| 4585 | | return ir_lval_wrap(irb, scope, result, lval); |
| 4940 | return ir_lval_wrap(irb, scope, result, lval, result_loc); |
| 4586 | 4941 | } |
| 4587 | 4942 | case BuiltinFnIdErrToInt: |
| 4588 | 4943 | { |
| ... | ... | @@ -4592,7 +4947,7 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo |
| 4592 | 4947 | return arg0_value; |
| 4593 | 4948 | |
| 4594 | 4949 | IrInstruction *result = ir_build_err_to_int(irb, scope, node, arg0_value); |
| 4595 | | return ir_lval_wrap(irb, scope, result, lval); |
| 4950 | return ir_lval_wrap(irb, scope, result, lval, result_loc); |
| 4596 | 4951 | } |
| 4597 | 4952 | case BuiltinFnIdIntToErr: |
| 4598 | 4953 | { |
| ... | ... | @@ -4602,7 +4957,7 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo |
| 4602 | 4957 | return arg0_value; |
| 4603 | 4958 | |
| 4604 | 4959 | IrInstruction *result = ir_build_int_to_err(irb, scope, node, arg0_value); |
| 4605 | | return ir_lval_wrap(irb, scope, result, lval); |
| 4960 | return ir_lval_wrap(irb, scope, result, lval, result_loc); |
| 4606 | 4961 | } |
| 4607 | 4962 | case BuiltinFnIdBoolToInt: |
| 4608 | 4963 | { |
| ... | ... | @@ -4612,7 +4967,7 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo |
| 4612 | 4967 | return arg0_value; |
| 4613 | 4968 | |
| 4614 | 4969 | IrInstruction *result = ir_build_bool_to_int(irb, scope, node, arg0_value); |
| 4615 | | return ir_lval_wrap(irb, scope, result, lval); |
| 4970 | return ir_lval_wrap(irb, scope, result, lval, result_loc); |
| 4616 | 4971 | } |
| 4617 | 4972 | case BuiltinFnIdIntType: |
| 4618 | 4973 | { |
| ... | ... | @@ -4627,7 +4982,7 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo |
| 4627 | 4982 | return arg1_value; |
| 4628 | 4983 | |
| 4629 | 4984 | IrInstruction *int_type = ir_build_int_type(irb, scope, node, arg0_value, arg1_value); |
| 4630 | | return ir_lval_wrap(irb, scope, int_type, lval); |
| 4985 | return ir_lval_wrap(irb, scope, int_type, lval, result_loc); |
| 4631 | 4986 | } |
| 4632 | 4987 | case BuiltinFnIdVectorType: |
| 4633 | 4988 | { |
| ... | ... | @@ -4642,7 +4997,7 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo |
| 4642 | 4997 | return arg1_value; |
| 4643 | 4998 | |
| 4644 | 4999 | IrInstruction *vector_type = ir_build_vector_type(irb, scope, node, arg0_value, arg1_value); |
| 4645 | | return ir_lval_wrap(irb, scope, vector_type, lval); |
| 5000 | return ir_lval_wrap(irb, scope, vector_type, lval, result_loc); |
| 4646 | 5001 | } |
| 4647 | 5002 | case BuiltinFnIdMemcpy: |
| 4648 | 5003 | { |
| ... | ... | @@ -4662,7 +5017,7 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo |
| 4662 | 5017 | return arg2_value; |
| 4663 | 5018 | |
| 4664 | 5019 | IrInstruction *ir_memcpy = ir_build_memcpy(irb, scope, node, arg0_value, arg1_value, arg2_value); |
| 4665 | | return ir_lval_wrap(irb, scope, ir_memcpy, lval); |
| 5020 | return ir_lval_wrap(irb, scope, ir_memcpy, lval, result_loc); |
| 4666 | 5021 | } |
| 4667 | 5022 | case BuiltinFnIdMemset: |
| 4668 | 5023 | { |
| ... | ... | @@ -4682,7 +5037,7 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo |
| 4682 | 5037 | return arg2_value; |
| 4683 | 5038 | |
| 4684 | 5039 | IrInstruction *ir_memset = ir_build_memset(irb, scope, node, arg0_value, arg1_value, arg2_value); |
| 4685 | | return ir_lval_wrap(irb, scope, ir_memset, lval); |
| 5040 | return ir_lval_wrap(irb, scope, ir_memset, lval, result_loc); |
| 4686 | 5041 | } |
| 4687 | 5042 | case BuiltinFnIdMemberCount: |
| 4688 | 5043 | { |
| ... | ... | @@ -4692,7 +5047,7 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo |
| 4692 | 5047 | return arg0_value; |
| 4693 | 5048 | |
| 4694 | 5049 | IrInstruction *member_count = ir_build_member_count(irb, scope, node, arg0_value); |
| 4695 | | return ir_lval_wrap(irb, scope, member_count, lval); |
| 5050 | return ir_lval_wrap(irb, scope, member_count, lval, result_loc); |
| 4696 | 5051 | } |
| 4697 | 5052 | case BuiltinFnIdMemberType: |
| 4698 | 5053 | { |
| ... | ... | @@ -4708,7 +5063,7 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo |
| 4708 | 5063 | |
| 4709 | 5064 | |
| 4710 | 5065 | IrInstruction *member_type = ir_build_member_type(irb, scope, node, arg0_value, arg1_value); |
| 4711 | | return ir_lval_wrap(irb, scope, member_type, lval); |
| 5066 | return ir_lval_wrap(irb, scope, member_type, lval, result_loc); |
| 4712 | 5067 | } |
| 4713 | 5068 | case BuiltinFnIdMemberName: |
| 4714 | 5069 | { |
| ... | ... | @@ -4724,12 +5079,12 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo |
| 4724 | 5079 | |
| 4725 | 5080 | |
| 4726 | 5081 | IrInstruction *member_name = ir_build_member_name(irb, scope, node, arg0_value, arg1_value); |
| 4727 | | return ir_lval_wrap(irb, scope, member_name, lval); |
| 5082 | return ir_lval_wrap(irb, scope, member_name, lval, result_loc); |
| 4728 | 5083 | } |
| 4729 | 5084 | case BuiltinFnIdField: |
| 4730 | 5085 | { |
| 4731 | 5086 | AstNode *arg0_node = node->data.fn_call_expr.params.at(0); |
| 4732 | | IrInstruction *arg0_value = ir_gen_node_extra(irb, arg0_node, scope, LValPtr); |
| 5087 | IrInstruction *arg0_value = ir_gen_node_extra(irb, arg0_node, scope, LValPtr, nullptr); |
| 4733 | 5088 | if (arg0_value == irb->codegen->invalid_instruction) |
| 4734 | 5089 | return arg0_value; |
| 4735 | 5090 | |
| ... | ... | @@ -4743,7 +5098,8 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo |
| 4743 | 5098 | if (lval == LValPtr) |
| 4744 | 5099 | return ptr_instruction; |
| 4745 | 5100 | |
| 4746 | | return ir_build_load_ptr(irb, scope, node, ptr_instruction); |
| 5101 | IrInstruction *load_ptr = ir_build_load_ptr(irb, scope, node, ptr_instruction); |
| 5102 | return ir_expr_wrap(irb, scope, load_ptr, result_loc); |
| 4747 | 5103 | } |
| 4748 | 5104 | case BuiltinFnIdTypeInfo: |
| 4749 | 5105 | { |
| ... | ... | @@ -4753,14 +5109,14 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo |
| 4753 | 5109 | return arg0_value; |
| 4754 | 5110 | |
| 4755 | 5111 | IrInstruction *type_info = ir_build_type_info(irb, scope, node, arg0_value); |
| 4756 | | return ir_lval_wrap(irb, scope, type_info, lval); |
| 5112 | return ir_lval_wrap(irb, scope, type_info, lval, result_loc); |
| 4757 | 5113 | } |
| 4758 | 5114 | case BuiltinFnIdBreakpoint: |
| 4759 | | return ir_lval_wrap(irb, scope, ir_build_breakpoint(irb, scope, node), lval); |
| 5115 | return ir_lval_wrap(irb, scope, ir_build_breakpoint(irb, scope, node), lval, result_loc); |
| 4760 | 5116 | case BuiltinFnIdReturnAddress: |
| 4761 | | return ir_lval_wrap(irb, scope, ir_build_return_address(irb, scope, node), lval); |
| 5117 | return ir_lval_wrap(irb, scope, ir_build_return_address(irb, scope, node), lval, result_loc); |
| 4762 | 5118 | case BuiltinFnIdFrameAddress: |
| 4763 | | return ir_lval_wrap(irb, scope, ir_build_frame_address(irb, scope, node), lval); |
| 5119 | return ir_lval_wrap(irb, scope, ir_build_frame_address(irb, scope, node), lval, result_loc); |
| 4764 | 5120 | case BuiltinFnIdHandle: |
| 4765 | 5121 | if (!irb->exec->fn_entry) { |
| 4766 | 5122 | add_node_error(irb->codegen, node, buf_sprintf("@handle() called outside of function definition")); |
| ... | ... | @@ -4770,7 +5126,7 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo |
| 4770 | 5126 | add_node_error(irb->codegen, node, buf_sprintf("@handle() in non-async function")); |
| 4771 | 5127 | return irb->codegen->invalid_instruction; |
| 4772 | 5128 | } |
| 4773 | | return ir_lval_wrap(irb, scope, ir_build_handle(irb, scope, node), lval); |
| 5129 | return ir_lval_wrap(irb, scope, ir_build_handle(irb, scope, node), lval, result_loc); |
| 4774 | 5130 | case BuiltinFnIdAlignOf: |
| 4775 | 5131 | { |
| 4776 | 5132 | AstNode *arg0_node = node->data.fn_call_expr.params.at(0); |
| ... | ... | @@ -4779,18 +5135,18 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo |
| 4779 | 5135 | return arg0_value; |
| 4780 | 5136 | |
| 4781 | 5137 | IrInstruction *align_of = ir_build_align_of(irb, scope, node, arg0_value); |
| 4782 | | return ir_lval_wrap(irb, scope, align_of, lval); |
| 5138 | return ir_lval_wrap(irb, scope, align_of, lval, result_loc); |
| 4783 | 5139 | } |
| 4784 | 5140 | case BuiltinFnIdAddWithOverflow: |
| 4785 | | return ir_lval_wrap(irb, scope, ir_gen_overflow_op(irb, scope, node, IrOverflowOpAdd), lval); |
| 5141 | return ir_lval_wrap(irb, scope, ir_gen_overflow_op(irb, scope, node, IrOverflowOpAdd), lval, result_loc); |
| 4786 | 5142 | case BuiltinFnIdSubWithOverflow: |
| 4787 | | return ir_lval_wrap(irb, scope, ir_gen_overflow_op(irb, scope, node, IrOverflowOpSub), lval); |
| 5143 | return ir_lval_wrap(irb, scope, ir_gen_overflow_op(irb, scope, node, IrOverflowOpSub), lval, result_loc); |
| 4788 | 5144 | case BuiltinFnIdMulWithOverflow: |
| 4789 | | return ir_lval_wrap(irb, scope, ir_gen_overflow_op(irb, scope, node, IrOverflowOpMul), lval); |
| 5145 | return ir_lval_wrap(irb, scope, ir_gen_overflow_op(irb, scope, node, IrOverflowOpMul), lval, result_loc); |
| 4790 | 5146 | case BuiltinFnIdShlWithOverflow: |
| 4791 | | return ir_lval_wrap(irb, scope, ir_gen_overflow_op(irb, scope, node, IrOverflowOpShl), lval); |
| 5147 | return ir_lval_wrap(irb, scope, ir_gen_overflow_op(irb, scope, node, IrOverflowOpShl), lval, result_loc); |
| 4792 | 5148 | case BuiltinFnIdMulAdd: |
| 4793 | | return ir_lval_wrap(irb, scope, ir_gen_mul_add(irb, scope, node), lval); |
| 5149 | return ir_lval_wrap(irb, scope, ir_gen_mul_add(irb, scope, node), lval, result_loc); |
| 4794 | 5150 | case BuiltinFnIdTypeName: |
| 4795 | 5151 | { |
| 4796 | 5152 | AstNode *arg0_node = node->data.fn_call_expr.params.at(0); |
| ... | ... | @@ -4799,7 +5155,7 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo |
| 4799 | 5155 | return arg0_value; |
| 4800 | 5156 | |
| 4801 | 5157 | IrInstruction *type_name = ir_build_type_name(irb, scope, node, arg0_value); |
| 4802 | | return ir_lval_wrap(irb, scope, type_name, lval); |
| 5158 | return ir_lval_wrap(irb, scope, type_name, lval, result_loc); |
| 4803 | 5159 | } |
| 4804 | 5160 | case BuiltinFnIdPanic: |
| 4805 | 5161 | { |
| ... | ... | @@ -4809,7 +5165,7 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo |
| 4809 | 5165 | return arg0_value; |
| 4810 | 5166 | |
| 4811 | 5167 | IrInstruction *panic = ir_build_panic(irb, scope, node, arg0_value); |
| 4812 | | return ir_lval_wrap(irb, scope, panic, lval); |
| 5168 | return ir_lval_wrap(irb, scope, panic, lval, result_loc); |
| 4813 | 5169 | } |
| 4814 | 5170 | case BuiltinFnIdPtrCast: |
| 4815 | 5171 | { |
| ... | ... | @@ -4824,22 +5180,31 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo |
| 4824 | 5180 | return arg1_value; |
| 4825 | 5181 | |
| 4826 | 5182 | IrInstruction *ptr_cast = ir_build_ptr_cast_src(irb, scope, node, arg0_value, arg1_value, true); |
| 4827 | | return ir_lval_wrap(irb, scope, ptr_cast, lval); |
| 5183 | return ir_lval_wrap(irb, scope, ptr_cast, lval, result_loc); |
| 4828 | 5184 | } |
| 4829 | 5185 | case BuiltinFnIdBitCast: |
| 4830 | 5186 | { |
| 4831 | | AstNode *arg0_node = node->data.fn_call_expr.params.at(0); |
| 4832 | | IrInstruction *arg0_value = ir_gen_node(irb, arg0_node, scope); |
| 4833 | | if (arg0_value == irb->codegen->invalid_instruction) |
| 4834 | | 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); |
| 4835 | 5199 | |
| 4836 | 5200 | AstNode *arg1_node = node->data.fn_call_expr.params.at(1); |
| 4837 | | IrInstruction *arg1_value = ir_gen_node(irb, arg1_node, scope); |
| 5201 | IrInstruction *arg1_value = ir_gen_node_extra(irb, arg1_node, scope, LValNone, |
| 5202 | &result_loc_bit_cast->base); |
| 4838 | 5203 | if (arg1_value == irb->codegen->invalid_instruction) |
| 4839 | 5204 | return arg1_value; |
| 4840 | 5205 | |
| 4841 | | IrInstruction *bit_cast = ir_build_bit_cast(irb, scope, node, arg0_value, arg1_value); |
| 4842 | | 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); |
| 4843 | 5208 | } |
| 4844 | 5209 | case BuiltinFnIdIntToPtr: |
| 4845 | 5210 | { |
| ... | ... | @@ -4854,7 +5219,7 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo |
| 4854 | 5219 | return arg1_value; |
| 4855 | 5220 | |
| 4856 | 5221 | IrInstruction *int_to_ptr = ir_build_int_to_ptr(irb, scope, node, arg0_value, arg1_value); |
| 4857 | | return ir_lval_wrap(irb, scope, int_to_ptr, lval); |
| 5222 | return ir_lval_wrap(irb, scope, int_to_ptr, lval, result_loc); |
| 4858 | 5223 | } |
| 4859 | 5224 | case BuiltinFnIdPtrToInt: |
| 4860 | 5225 | { |
| ... | ... | @@ -4864,7 +5229,7 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo |
| 4864 | 5229 | return arg0_value; |
| 4865 | 5230 | |
| 4866 | 5231 | IrInstruction *ptr_to_int = ir_build_ptr_to_int(irb, scope, node, arg0_value); |
| 4867 | | return ir_lval_wrap(irb, scope, ptr_to_int, lval); |
| 5232 | return ir_lval_wrap(irb, scope, ptr_to_int, lval, result_loc); |
| 4868 | 5233 | } |
| 4869 | 5234 | case BuiltinFnIdTagName: |
| 4870 | 5235 | { |
| ... | ... | @@ -4875,7 +5240,7 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo |
| 4875 | 5240 | |
| 4876 | 5241 | IrInstruction *actual_tag = ir_build_union_tag(irb, scope, node, arg0_value); |
| 4877 | 5242 | IrInstruction *tag_name = ir_build_tag_name(irb, scope, node, actual_tag); |
| 4878 | | return ir_lval_wrap(irb, scope, tag_name, lval); |
| 5243 | return ir_lval_wrap(irb, scope, tag_name, lval, result_loc); |
| 4879 | 5244 | } |
| 4880 | 5245 | case BuiltinFnIdTagType: |
| 4881 | 5246 | { |
| ... | ... | @@ -4885,7 +5250,7 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo |
| 4885 | 5250 | return arg0_value; |
| 4886 | 5251 | |
| 4887 | 5252 | IrInstruction *tag_type = ir_build_tag_type(irb, scope, node, arg0_value); |
| 4888 | | return ir_lval_wrap(irb, scope, tag_type, lval); |
| 5253 | return ir_lval_wrap(irb, scope, tag_type, lval, result_loc); |
| 4889 | 5254 | } |
| 4890 | 5255 | case BuiltinFnIdFieldParentPtr: |
| 4891 | 5256 | { |
| ... | ... | @@ -4905,7 +5270,7 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo |
| 4905 | 5270 | return arg2_value; |
| 4906 | 5271 | |
| 4907 | 5272 | IrInstruction *field_parent_ptr = ir_build_field_parent_ptr(irb, scope, node, arg0_value, arg1_value, arg2_value, nullptr); |
| 4908 | | return ir_lval_wrap(irb, scope, field_parent_ptr, lval); |
| 5273 | return ir_lval_wrap(irb, scope, field_parent_ptr, lval, result_loc); |
| 4909 | 5274 | } |
| 4910 | 5275 | case BuiltinFnIdByteOffsetOf: |
| 4911 | 5276 | { |
| ... | ... | @@ -4920,7 +5285,7 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo |
| 4920 | 5285 | return arg1_value; |
| 4921 | 5286 | |
| 4922 | 5287 | IrInstruction *offset_of = ir_build_byte_offset_of(irb, scope, node, arg0_value, arg1_value); |
| 4923 | | return ir_lval_wrap(irb, scope, offset_of, lval); |
| 5288 | return ir_lval_wrap(irb, scope, offset_of, lval, result_loc); |
| 4924 | 5289 | } |
| 4925 | 5290 | case BuiltinFnIdBitOffsetOf: |
| 4926 | 5291 | { |
| ... | ... | @@ -4935,7 +5300,7 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo |
| 4935 | 5300 | return arg1_value; |
| 4936 | 5301 | |
| 4937 | 5302 | IrInstruction *offset_of = ir_build_bit_offset_of(irb, scope, node, arg0_value, arg1_value); |
| 4938 | | return ir_lval_wrap(irb, scope, offset_of, lval); |
| 5303 | return ir_lval_wrap(irb, scope, offset_of, lval, result_loc); |
| 4939 | 5304 | } |
| 4940 | 5305 | case BuiltinFnIdInlineCall: |
| 4941 | 5306 | case BuiltinFnIdNoInlineCall: |
| ... | ... | @@ -4961,8 +5326,9 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo |
| 4961 | 5326 | } |
| 4962 | 5327 | FnInline fn_inline = (builtin_fn->id == BuiltinFnIdInlineCall) ? FnInlineAlways : FnInlineNever; |
| 4963 | 5328 | |
| 4964 | | IrInstruction *call = ir_build_call(irb, scope, node, nullptr, fn_ref, arg_count, args, false, fn_inline, false, nullptr, nullptr); |
| 4965 | | 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); |
| 4966 | 5332 | } |
| 4967 | 5333 | case BuiltinFnIdNewStackCall: |
| 4968 | 5334 | { |
| ... | ... | @@ -4991,8 +5357,9 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo |
| 4991 | 5357 | return args[i]; |
| 4992 | 5358 | } |
| 4993 | 5359 | |
| 4994 | | IrInstruction *call = ir_build_call(irb, scope, node, nullptr, fn_ref, arg_count, args, false, FnInlineAuto, false, nullptr, new_stack); |
| 4995 | | 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); |
| 4996 | 5363 | } |
| 4997 | 5364 | case BuiltinFnIdTypeId: |
| 4998 | 5365 | { |
| ... | ... | @@ -5002,7 +5369,7 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo |
| 5002 | 5369 | return arg0_value; |
| 5003 | 5370 | |
| 5004 | 5371 | IrInstruction *type_id = ir_build_type_id(irb, scope, node, arg0_value); |
| 5005 | | return ir_lval_wrap(irb, scope, type_id, lval); |
| 5372 | return ir_lval_wrap(irb, scope, type_id, lval, result_loc); |
| 5006 | 5373 | } |
| 5007 | 5374 | case BuiltinFnIdShlExact: |
| 5008 | 5375 | { |
| ... | ... | @@ -5017,7 +5384,7 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo |
| 5017 | 5384 | return arg1_value; |
| 5018 | 5385 | |
| 5019 | 5386 | IrInstruction *bin_op = ir_build_bin_op(irb, scope, node, IrBinOpBitShiftLeftExact, arg0_value, arg1_value, true); |
| 5020 | | return ir_lval_wrap(irb, scope, bin_op, lval); |
| 5387 | return ir_lval_wrap(irb, scope, bin_op, lval, result_loc); |
| 5021 | 5388 | } |
| 5022 | 5389 | case BuiltinFnIdShrExact: |
| 5023 | 5390 | { |
| ... | ... | @@ -5032,7 +5399,7 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo |
| 5032 | 5399 | return arg1_value; |
| 5033 | 5400 | |
| 5034 | 5401 | IrInstruction *bin_op = ir_build_bin_op(irb, scope, node, IrBinOpBitShiftRightExact, arg0_value, arg1_value, true); |
| 5035 | | return ir_lval_wrap(irb, scope, bin_op, lval); |
| 5402 | return ir_lval_wrap(irb, scope, bin_op, lval, result_loc); |
| 5036 | 5403 | } |
| 5037 | 5404 | case BuiltinFnIdSetEvalBranchQuota: |
| 5038 | 5405 | { |
| ... | ... | @@ -5042,7 +5409,7 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo |
| 5042 | 5409 | return arg0_value; |
| 5043 | 5410 | |
| 5044 | 5411 | IrInstruction *set_eval_branch_quota = ir_build_set_eval_branch_quota(irb, scope, node, arg0_value); |
| 5045 | | return ir_lval_wrap(irb, scope, set_eval_branch_quota, lval); |
| 5412 | return ir_lval_wrap(irb, scope, set_eval_branch_quota, lval, result_loc); |
| 5046 | 5413 | } |
| 5047 | 5414 | case BuiltinFnIdAlignCast: |
| 5048 | 5415 | { |
| ... | ... | @@ -5057,17 +5424,17 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo |
| 5057 | 5424 | return arg1_value; |
| 5058 | 5425 | |
| 5059 | 5426 | IrInstruction *align_cast = ir_build_align_cast(irb, scope, node, arg0_value, arg1_value); |
| 5060 | | return ir_lval_wrap(irb, scope, align_cast, lval); |
| 5427 | return ir_lval_wrap(irb, scope, align_cast, lval, result_loc); |
| 5061 | 5428 | } |
| 5062 | 5429 | case BuiltinFnIdOpaqueType: |
| 5063 | 5430 | { |
| 5064 | 5431 | IrInstruction *opaque_type = ir_build_opaque_type(irb, scope, node); |
| 5065 | | return ir_lval_wrap(irb, scope, opaque_type, lval); |
| 5432 | return ir_lval_wrap(irb, scope, opaque_type, lval, result_loc); |
| 5066 | 5433 | } |
| 5067 | 5434 | case BuiltinFnIdThis: |
| 5068 | 5435 | { |
| 5069 | 5436 | IrInstruction *this_inst = ir_gen_this(irb, scope, node); |
| 5070 | | return ir_lval_wrap(irb, scope, this_inst, lval); |
| 5437 | return ir_lval_wrap(irb, scope, this_inst, lval, result_loc); |
| 5071 | 5438 | } |
| 5072 | 5439 | case BuiltinFnIdSetAlignStack: |
| 5073 | 5440 | { |
| ... | ... | @@ -5077,7 +5444,7 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo |
| 5077 | 5444 | return arg0_value; |
| 5078 | 5445 | |
| 5079 | 5446 | IrInstruction *set_align_stack = ir_build_set_align_stack(irb, scope, node, arg0_value); |
| 5080 | | return ir_lval_wrap(irb, scope, set_align_stack, lval); |
| 5447 | return ir_lval_wrap(irb, scope, set_align_stack, lval, result_loc); |
| 5081 | 5448 | } |
| 5082 | 5449 | case BuiltinFnIdArgType: |
| 5083 | 5450 | { |
| ... | ... | @@ -5092,7 +5459,7 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo |
| 5092 | 5459 | return arg1_value; |
| 5093 | 5460 | |
| 5094 | 5461 | IrInstruction *arg_type = ir_build_arg_type(irb, scope, node, arg0_value, arg1_value); |
| 5095 | | return ir_lval_wrap(irb, scope, arg_type, lval); |
| 5462 | return ir_lval_wrap(irb, scope, arg_type, lval, result_loc); |
| 5096 | 5463 | } |
| 5097 | 5464 | case BuiltinFnIdExport: |
| 5098 | 5465 | { |
| ... | ... | @@ -5112,12 +5479,12 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo |
| 5112 | 5479 | return arg2_value; |
| 5113 | 5480 | |
| 5114 | 5481 | IrInstruction *ir_export = ir_build_export(irb, scope, node, arg0_value, arg1_value, arg2_value); |
| 5115 | | return ir_lval_wrap(irb, scope, ir_export, lval); |
| 5482 | return ir_lval_wrap(irb, scope, ir_export, lval, result_loc); |
| 5116 | 5483 | } |
| 5117 | 5484 | case BuiltinFnIdErrorReturnTrace: |
| 5118 | 5485 | { |
| 5119 | 5486 | IrInstruction *error_return_trace = ir_build_error_return_trace(irb, scope, node, IrInstructionErrorReturnTrace::Null); |
| 5120 | | return ir_lval_wrap(irb, scope, error_return_trace, lval); |
| 5487 | return ir_lval_wrap(irb, scope, error_return_trace, lval, result_loc); |
| 5121 | 5488 | } |
| 5122 | 5489 | case BuiltinFnIdAtomicRmw: |
| 5123 | 5490 | { |
| ... | ... | @@ -5146,10 +5513,11 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo |
| 5146 | 5513 | if (arg4_value == irb->codegen->invalid_instruction) |
| 5147 | 5514 | return arg4_value; |
| 5148 | 5515 | |
| 5149 | | return ir_build_atomic_rmw(irb, scope, node, arg0_value, arg1_value, arg2_value, arg3_value, |
| 5516 | IrInstruction *inst = ir_build_atomic_rmw(irb, scope, node, arg0_value, arg1_value, arg2_value, arg3_value, |
| 5150 | 5517 | arg4_value, |
| 5151 | 5518 | // these 2 values don't mean anything since we passed non-null values for other args |
| 5152 | 5519 | AtomicRmwOp_xchg, AtomicOrderMonotonic); |
| 5520 | return ir_lval_wrap(irb, scope, inst, lval, result_loc); |
| 5153 | 5521 | } |
| 5154 | 5522 | case BuiltinFnIdAtomicLoad: |
| 5155 | 5523 | { |
| ... | ... | @@ -5168,9 +5536,10 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo |
| 5168 | 5536 | if (arg2_value == irb->codegen->invalid_instruction) |
| 5169 | 5537 | return arg2_value; |
| 5170 | 5538 | |
| 5171 | | return ir_build_atomic_load(irb, scope, node, arg0_value, arg1_value, arg2_value, |
| 5539 | IrInstruction *inst = ir_build_atomic_load(irb, scope, node, arg0_value, arg1_value, arg2_value, |
| 5172 | 5540 | // this value does not mean anything since we passed non-null values for other arg |
| 5173 | 5541 | AtomicOrderMonotonic); |
| 5542 | return ir_lval_wrap(irb, scope, inst, lval, result_loc); |
| 5174 | 5543 | } |
| 5175 | 5544 | case BuiltinFnIdIntToEnum: |
| 5176 | 5545 | { |
| ... | ... | @@ -5185,7 +5554,7 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo |
| 5185 | 5554 | return arg1_value; |
| 5186 | 5555 | |
| 5187 | 5556 | IrInstruction *result = ir_build_int_to_enum(irb, scope, node, arg0_value, arg1_value); |
| 5188 | | return ir_lval_wrap(irb, scope, result, lval); |
| 5557 | return ir_lval_wrap(irb, scope, result, lval, result_loc); |
| 5189 | 5558 | } |
| 5190 | 5559 | case BuiltinFnIdEnumToInt: |
| 5191 | 5560 | { |
| ... | ... | @@ -5195,7 +5564,7 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo |
| 5195 | 5564 | return arg0_value; |
| 5196 | 5565 | |
| 5197 | 5566 | IrInstruction *result = ir_build_enum_to_int(irb, scope, node, arg0_value); |
| 5198 | | return ir_lval_wrap(irb, scope, result, lval); |
| 5567 | return ir_lval_wrap(irb, scope, result, lval, result_loc); |
| 5199 | 5568 | } |
| 5200 | 5569 | case BuiltinFnIdCtz: |
| 5201 | 5570 | case BuiltinFnIdPopCount: |
| ... | ... | @@ -5233,7 +5602,7 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo |
| 5233 | 5602 | default: |
| 5234 | 5603 | zig_unreachable(); |
| 5235 | 5604 | } |
| 5236 | | return ir_lval_wrap(irb, scope, result, lval); |
| 5605 | return ir_lval_wrap(irb, scope, result, lval, result_loc); |
| 5237 | 5606 | } |
| 5238 | 5607 | case BuiltinFnIdHasDecl: |
| 5239 | 5608 | { |
| ... | ... | @@ -5248,17 +5617,19 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo |
| 5248 | 5617 | return arg1_value; |
| 5249 | 5618 | |
| 5250 | 5619 | IrInstruction *has_decl = ir_build_has_decl(irb, scope, node, arg0_value, arg1_value); |
| 5251 | | return ir_lval_wrap(irb, scope, has_decl, lval); |
| 5620 | return ir_lval_wrap(irb, scope, has_decl, lval, result_loc); |
| 5252 | 5621 | } |
| 5253 | 5622 | } |
| 5254 | 5623 | zig_unreachable(); |
| 5255 | 5624 | } |
| 5256 | 5625 | |
| 5257 | | static IrInstruction *ir_gen_fn_call(IrBuilder *irb, Scope *scope, AstNode *node, LVal lval) { |
| 5626 | static IrInstruction *ir_gen_fn_call(IrBuilder *irb, Scope *scope, AstNode *node, LVal lval, |
| 5627 | ResultLoc *result_loc) |
| 5628 | { |
| 5258 | 5629 | assert(node->type == NodeTypeFnCallExpr); |
| 5259 | 5630 | |
| 5260 | 5631 | if (node->data.fn_call_expr.is_builtin) |
| 5261 | | return ir_gen_builtin_fn_call(irb, scope, node, lval); |
| 5632 | return ir_gen_builtin_fn_call(irb, scope, node, lval, result_loc); |
| 5262 | 5633 | |
| 5263 | 5634 | AstNode *fn_ref_node = node->data.fn_call_expr.fn_ref_expr; |
| 5264 | 5635 | IrInstruction *fn_ref = ir_gen_node(irb, fn_ref_node, scope); |
| ... | ... | @@ -5284,12 +5655,14 @@ static IrInstruction *ir_gen_fn_call(IrBuilder *irb, Scope *scope, AstNode *node |
| 5284 | 5655 | } |
| 5285 | 5656 | } |
| 5286 | 5657 | |
| 5287 | | IrInstruction *fn_call = ir_build_call(irb, scope, node, nullptr, fn_ref, arg_count, args, false, FnInlineAuto, |
| 5288 | | is_async, async_allocator, nullptr); |
| 5289 | | 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); |
| 5290 | 5661 | } |
| 5291 | 5662 | |
| 5292 | | static IrInstruction *ir_gen_if_bool_expr(IrBuilder *irb, Scope *scope, AstNode *node) { |
| 5663 | static IrInstruction *ir_gen_if_bool_expr(IrBuilder *irb, Scope *scope, AstNode *node, LVal lval, |
| 5664 | ResultLoc *result_loc) |
| 5665 | { |
| 5293 | 5666 | assert(node->type == NodeTypeIfBoolExpr); |
| 5294 | 5667 | |
| 5295 | 5668 | IrInstruction *condition = ir_gen_node(irb, node->data.if_bool_expr.condition, scope); |
| ... | ... | @@ -5310,12 +5683,16 @@ static IrInstruction *ir_gen_if_bool_expr(IrBuilder *irb, Scope *scope, AstNode |
| 5310 | 5683 | IrBasicBlock *else_block = ir_create_basic_block(irb, scope, "Else"); |
| 5311 | 5684 | IrBasicBlock *endif_block = ir_create_basic_block(irb, scope, "EndIf"); |
| 5312 | 5685 | |
| 5313 | | ir_build_cond_br(irb, scope, condition->source_node, condition, then_block, else_block, is_comptime); |
| 5686 | IrInstruction *cond_br_inst = ir_build_cond_br(irb, scope, node, condition, |
| 5687 | then_block, else_block, is_comptime); |
| 5688 | ResultLocPeerParent *peer_parent = ir_build_binary_result_peers(irb, cond_br_inst, else_block, endif_block, |
| 5689 | result_loc, is_comptime); |
| 5314 | 5690 | |
| 5315 | 5691 | ir_set_cursor_at_end_and_append_block(irb, then_block); |
| 5316 | 5692 | |
| 5317 | 5693 | Scope *subexpr_scope = create_runtime_scope(irb->codegen, node, scope, is_comptime); |
| 5318 | | IrInstruction *then_expr_result = ir_gen_node(irb, then_node, subexpr_scope); |
| 5694 | IrInstruction *then_expr_result = ir_gen_node_extra(irb, then_node, subexpr_scope, lval, |
| 5695 | &peer_parent->peers.at(0)->base); |
| 5319 | 5696 | if (then_expr_result == irb->codegen->invalid_instruction) |
| 5320 | 5697 | return irb->codegen->invalid_instruction; |
| 5321 | 5698 | IrBasicBlock *after_then_block = irb->current_basic_block; |
| ... | ... | @@ -5325,11 +5702,12 @@ static IrInstruction *ir_gen_if_bool_expr(IrBuilder *irb, Scope *scope, AstNode |
| 5325 | 5702 | ir_set_cursor_at_end_and_append_block(irb, else_block); |
| 5326 | 5703 | IrInstruction *else_expr_result; |
| 5327 | 5704 | if (else_node) { |
| 5328 | | else_expr_result = ir_gen_node(irb, else_node, subexpr_scope); |
| 5705 | else_expr_result = ir_gen_node_extra(irb, else_node, subexpr_scope, lval, &peer_parent->peers.at(1)->base); |
| 5329 | 5706 | if (else_expr_result == irb->codegen->invalid_instruction) |
| 5330 | 5707 | return irb->codegen->invalid_instruction; |
| 5331 | 5708 | } else { |
| 5332 | 5709 | else_expr_result = ir_build_const_void(irb, scope, node); |
| 5710 | ir_build_end_expr(irb, scope, node, else_expr_result, &peer_parent->peers.at(1)->base); |
| 5333 | 5711 | } |
| 5334 | 5712 | IrBasicBlock *after_else_block = irb->current_basic_block; |
| 5335 | 5713 | if (!instr_is_unreachable(else_expr_result)) |
| ... | ... | @@ -5343,14 +5721,15 @@ static IrInstruction *ir_gen_if_bool_expr(IrBuilder *irb, Scope *scope, AstNode |
| 5343 | 5721 | incoming_blocks[0] = after_then_block; |
| 5344 | 5722 | incoming_blocks[1] = after_else_block; |
| 5345 | 5723 | |
| 5346 | | return ir_build_phi(irb, scope, node, 2, incoming_blocks, incoming_values); |
| 5724 | IrInstruction *phi = ir_build_phi(irb, scope, node, 2, incoming_blocks, incoming_values, peer_parent); |
| 5725 | return ir_expr_wrap(irb, scope, phi, result_loc); |
| 5347 | 5726 | } |
| 5348 | 5727 | |
| 5349 | 5728 | static IrInstruction *ir_gen_prefix_op_id_lval(IrBuilder *irb, Scope *scope, AstNode *node, IrUnOp op_id, LVal lval) { |
| 5350 | 5729 | assert(node->type == NodeTypePrefixOpExpr); |
| 5351 | 5730 | AstNode *expr_node = node->data.prefix_op_expr.primary_expr; |
| 5352 | 5731 | |
| 5353 | | IrInstruction *value = ir_gen_node_extra(irb, expr_node, scope, lval); |
| 5732 | IrInstruction *value = ir_gen_node_extra(irb, expr_node, scope, lval, nullptr); |
| 5354 | 5733 | if (value == irb->codegen->invalid_instruction) |
| 5355 | 5734 | return value; |
| 5356 | 5735 | |
| ... | ... | @@ -5361,15 +5740,34 @@ static IrInstruction *ir_gen_prefix_op_id(IrBuilder *irb, Scope *scope, AstNode |
| 5361 | 5740 | return ir_gen_prefix_op_id_lval(irb, scope, node, op_id, LValNone); |
| 5362 | 5741 | } |
| 5363 | 5742 | |
| 5364 | | static IrInstruction *ir_lval_wrap(IrBuilder *irb, Scope *scope, IrInstruction *value, LVal lval) { |
| 5365 | | 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 | { |
| 5366 | 5758 | return value; |
| 5367 | | if (value == irb->codegen->invalid_instruction) |
| 5759 | } |
| 5760 | |
| 5761 | if (lval == LValPtr) { |
| 5762 | // We needed a pointer to a value, but we got a value. So we create |
| 5763 | // an instruction which just makes a pointer of it. |
| 5764 | return ir_build_ref(irb, scope, value->source_node, value, false, false); |
| 5765 | } else if (result_loc != nullptr) { |
| 5766 | return ir_expr_wrap(irb, scope, value, result_loc); |
| 5767 | } else { |
| 5368 | 5768 | return value; |
| 5769 | } |
| 5369 | 5770 | |
| 5370 | | // We needed a pointer to a value, but we got a value. So we create |
| 5371 | | // an instruction which just makes a const pointer of it. |
| 5372 | | return ir_build_ref(irb, scope, value->source_node, value, false, false); |
| 5373 | 5771 | } |
| 5374 | 5772 | |
| 5375 | 5773 | static PtrLen star_token_to_ptr_len(TokenId token_id) { |
| ... | ... | @@ -5442,21 +5840,22 @@ static IrInstruction *ir_gen_pointer_type(IrBuilder *irb, Scope *scope, AstNode |
| 5442 | 5840 | ptr_len, align_value, bit_offset_start, host_int_bytes, is_allow_zero); |
| 5443 | 5841 | } |
| 5444 | 5842 | |
| 5445 | | static IrInstruction *ir_gen_catch_unreachable(IrBuilder *irb, Scope *scope, AstNode *source_node, AstNode *expr_node, |
| 5446 | | 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) |
| 5447 | 5845 | { |
| 5448 | | IrInstruction *err_union_ptr = ir_gen_node_extra(irb, expr_node, scope, LValPtr); |
| 5846 | IrInstruction *err_union_ptr = ir_gen_node_extra(irb, expr_node, scope, LValPtr, nullptr); |
| 5449 | 5847 | if (err_union_ptr == irb->codegen->invalid_instruction) |
| 5450 | 5848 | return irb->codegen->invalid_instruction; |
| 5451 | 5849 | |
| 5452 | | IrInstruction *payload_ptr = ir_build_unwrap_err_payload(irb, scope, source_node, err_union_ptr, true); |
| 5850 | IrInstruction *payload_ptr = ir_build_unwrap_err_payload(irb, scope, source_node, err_union_ptr, true, false); |
| 5453 | 5851 | if (payload_ptr == irb->codegen->invalid_instruction) |
| 5454 | 5852 | return irb->codegen->invalid_instruction; |
| 5455 | 5853 | |
| 5456 | 5854 | if (lval == LValPtr) |
| 5457 | 5855 | return payload_ptr; |
| 5458 | 5856 | |
| 5459 | | return ir_build_load_ptr(irb, scope, source_node, payload_ptr); |
| 5857 | IrInstruction *load_ptr = ir_build_load_ptr(irb, scope, source_node, payload_ptr); |
| 5858 | return ir_expr_wrap(irb, scope, load_ptr, result_loc); |
| 5460 | 5859 | } |
| 5461 | 5860 | |
| 5462 | 5861 | static IrInstruction *ir_gen_bool_not(IrBuilder *irb, Scope *scope, AstNode *node) { |
| ... | ... | @@ -5470,7 +5869,9 @@ static IrInstruction *ir_gen_bool_not(IrBuilder *irb, Scope *scope, AstNode *nod |
| 5470 | 5869 | return ir_build_bool_not(irb, scope, node, value); |
| 5471 | 5870 | } |
| 5472 | 5871 | |
| 5473 | | static IrInstruction *ir_gen_prefix_op_expr(IrBuilder *irb, Scope *scope, AstNode *node, LVal lval) { |
| 5872 | static IrInstruction *ir_gen_prefix_op_expr(IrBuilder *irb, Scope *scope, AstNode *node, LVal lval, |
| 5873 | ResultLoc *result_loc) |
| 5874 | { |
| 5474 | 5875 | assert(node->type == NodeTypePrefixOpExpr); |
| 5475 | 5876 | |
| 5476 | 5877 | PrefixOp prefix_op = node->data.prefix_op_expr.prefix_op; |
| ... | ... | @@ -5479,24 +5880,26 @@ static IrInstruction *ir_gen_prefix_op_expr(IrBuilder *irb, Scope *scope, AstNod |
| 5479 | 5880 | case PrefixOpInvalid: |
| 5480 | 5881 | zig_unreachable(); |
| 5481 | 5882 | case PrefixOpBoolNot: |
| 5482 | | return ir_lval_wrap(irb, scope, ir_gen_bool_not(irb, scope, node), lval); |
| 5883 | return ir_lval_wrap(irb, scope, ir_gen_bool_not(irb, scope, node), lval, result_loc); |
| 5483 | 5884 | case PrefixOpBinNot: |
| 5484 | | return ir_lval_wrap(irb, scope, ir_gen_prefix_op_id(irb, scope, node, IrUnOpBinNot), lval); |
| 5885 | return ir_lval_wrap(irb, scope, ir_gen_prefix_op_id(irb, scope, node, IrUnOpBinNot), lval, result_loc); |
| 5485 | 5886 | case PrefixOpNegation: |
| 5486 | | return ir_lval_wrap(irb, scope, ir_gen_prefix_op_id(irb, scope, node, IrUnOpNegation), lval); |
| 5887 | return ir_lval_wrap(irb, scope, ir_gen_prefix_op_id(irb, scope, node, IrUnOpNegation), lval, result_loc); |
| 5487 | 5888 | case PrefixOpNegationWrap: |
| 5488 | | return ir_lval_wrap(irb, scope, ir_gen_prefix_op_id(irb, scope, node, IrUnOpNegationWrap), lval); |
| 5889 | return ir_lval_wrap(irb, scope, ir_gen_prefix_op_id(irb, scope, node, IrUnOpNegationWrap), lval, result_loc); |
| 5489 | 5890 | case PrefixOpOptional: |
| 5490 | | return ir_lval_wrap(irb, scope, ir_gen_prefix_op_id(irb, scope, node, IrUnOpOptional), lval); |
| 5891 | return ir_lval_wrap(irb, scope, ir_gen_prefix_op_id(irb, scope, node, IrUnOpOptional), lval, result_loc); |
| 5491 | 5892 | case PrefixOpAddrOf: { |
| 5492 | 5893 | AstNode *expr_node = node->data.prefix_op_expr.primary_expr; |
| 5493 | | return ir_lval_wrap(irb, scope, ir_gen_node_extra(irb, expr_node, scope, LValPtr), lval); |
| 5894 | return ir_lval_wrap(irb, scope, ir_gen_node_extra(irb, expr_node, scope, LValPtr, nullptr), lval, result_loc); |
| 5494 | 5895 | } |
| 5495 | 5896 | } |
| 5496 | 5897 | zig_unreachable(); |
| 5497 | 5898 | } |
| 5498 | 5899 | |
| 5499 | | static IrInstruction *ir_gen_container_init_expr(IrBuilder *irb, Scope *scope, AstNode *node) { |
| 5900 | static IrInstruction *ir_gen_container_init_expr(IrBuilder *irb, Scope *scope, AstNode *node, LVal lval, |
| 5901 | ResultLoc *parent_result_loc) |
| 5902 | { |
| 5500 | 5903 | assert(node->type == NodeTypeContainerInitExpr); |
| 5501 | 5904 | |
| 5502 | 5905 | AstNodeContainerInitExpr *container_init_expr = &node->data.container_init_expr; |
| ... | ... | @@ -5514,45 +5917,104 @@ static IrInstruction *ir_gen_container_init_expr(IrBuilder *irb, Scope *scope, A |
| 5514 | 5917 | return container_type; |
| 5515 | 5918 | } |
| 5516 | 5919 | |
| 5517 | | if (kind == ContainerInitKindStruct) { |
| 5518 | | if (elem_type != nullptr) { |
| 5519 | | add_node_error(irb->codegen, container_init_expr->type, |
| 5520 | | buf_sprintf("initializing array with struct syntax")); |
| 5521 | | return irb->codegen->invalid_instruction; |
| 5522 | | } |
| 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); |
| 5936 | |
| 5937 | Buf *name = entry_node->data.struct_val_field.name; |
| 5938 | AstNode *expr_node = entry_node->data.struct_val_field.expr; |
| 5523 | 5939 | |
| 5524 | | size_t field_count = container_init_expr->entries.length; |
| 5525 | | IrInstructionContainerInitFieldsField *fields = allocate<IrInstructionContainerInitFieldsField>(field_count); |
| 5526 | | for (size_t i = 0; i < field_count; i += 1) { |
| 5527 | | AstNode *entry_node = container_init_expr->entries.at(i); |
| 5528 | | assert(entry_node->type == NodeTypeStructValueField); |
| 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); |
| 5529 | 5946 | |
| 5530 | | Buf *name = entry_node->data.struct_val_field.name; |
| 5531 | | AstNode *expr_node = entry_node->data.struct_val_field.expr; |
| 5532 | | IrInstruction *expr_value = ir_gen_node(irb, expr_node, scope); |
| 5533 | | if (expr_value == irb->codegen->invalid_instruction) |
| 5534 | | return expr_value; |
| 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; |
| 5535 | 5951 | |
| 5536 | | fields[i].name = name; |
| 5537 | | fields[i].value = expr_value; |
| 5538 | | fields[i].source_node = entry_node; |
| 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); |
| 5539 | 5960 | } |
| 5540 | | return ir_build_container_init_fields(irb, scope, node, container_type, field_count, fields); |
| 5541 | | } else if (kind == ContainerInitKindArray) { |
| 5542 | | size_t item_count = container_init_expr->entries.length; |
| 5543 | | IrInstruction **values = allocate<IrInstruction *>(item_count); |
| 5544 | | for (size_t i = 0; i < item_count; i += 1) { |
| 5545 | | AstNode *expr_node = container_init_expr->entries.at(i); |
| 5546 | | IrInstruction *expr_value = ir_gen_node(irb, expr_node, scope); |
| 5547 | | if (expr_value == irb->codegen->invalid_instruction) |
| 5548 | | 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 | } |
| 5549 | 5968 | |
| 5550 | | values[i] = expr_value; |
| 5969 | IrInstruction *container_ptr = ir_build_resolve_result(irb, scope, node, parent_result_loc, |
| 5970 | container_type); |
| 5971 | |
| 5972 | IrInstruction **result_locs = allocate<IrInstruction *>(item_count); |
| 5973 | for (size_t i = 0; i < item_count; i += 1) { |
| 5974 | AstNode *expr_node = container_init_expr->entries.at(i); |
| 5975 | |
| 5976 | IrInstruction *elem_index = ir_build_const_usize(irb, scope, expr_node, i); |
| 5977 | IrInstruction *elem_ptr = ir_build_elem_ptr(irb, scope, expr_node, container_ptr, elem_index, |
| 5978 | false, PtrLenSingle, container_type); |
| 5979 | ResultLocInstruction *result_loc_inst = allocate<ResultLocInstruction>(1); |
| 5980 | result_loc_inst->base.id = ResultLocIdInstruction; |
| 5981 | result_loc_inst->base.source_instruction = elem_ptr; |
| 5982 | ir_ref_instruction(elem_ptr, irb->current_basic_block); |
| 5983 | ir_build_reset_result(irb, scope, expr_node, &result_loc_inst->base); |
| 5984 | |
| 5985 | IrInstruction *expr_value = ir_gen_node_extra(irb, expr_node, scope, LValNone, |
| 5986 | &result_loc_inst->base); |
| 5987 | if (expr_value == irb->codegen->invalid_instruction) |
| 5988 | return expr_value; |
| 5989 | |
| 5990 | result_locs[i] = elem_ptr; |
| 5991 | } |
| 5992 | IrInstruction *init_list = ir_build_container_init_list(irb, scope, node, container_type, |
| 5993 | item_count, result_locs, container_ptr); |
| 5994 | return ir_lval_wrap(irb, scope, init_list, lval, parent_result_loc); |
| 5551 | 5995 | } |
| 5552 | | return ir_build_container_init_list(irb, scope, node, container_type, elem_type, item_count, values); |
| 5553 | | } else { |
| 5554 | | zig_unreachable(); |
| 5555 | 5996 | } |
| 5997 | zig_unreachable(); |
| 5998 | } |
| 5999 | |
| 6000 | static ResultLocVar *ir_build_var_result_loc(IrBuilder *irb, IrInstruction *alloca, ZigVar *var) { |
| 6001 | ResultLocVar *result_loc_var = allocate<ResultLocVar>(1); |
| 6002 | result_loc_var->base.id = ResultLocIdVar; |
| 6003 | result_loc_var->base.source_instruction = alloca; |
| 6004 | result_loc_var->var = var; |
| 6005 | |
| 6006 | ir_build_reset_result(irb, alloca->scope, alloca->source_node, &result_loc_var->base); |
| 6007 | |
| 6008 | return result_loc_var; |
| 6009 | } |
| 6010 | |
| 6011 | static void build_decl_var_and_init(IrBuilder *irb, Scope *scope, AstNode *source_node, ZigVar *var, |
| 6012 | IrInstruction *init, const char *name_hint, IrInstruction *is_comptime) |
| 6013 | { |
| 6014 | IrInstruction *alloca = ir_build_alloca_src(irb, scope, source_node, nullptr, name_hint, is_comptime); |
| 6015 | ResultLocVar *var_result_loc = ir_build_var_result_loc(irb, alloca, var); |
| 6016 | ir_build_end_expr(irb, scope, source_node, init, &var_result_loc->base); |
| 6017 | ir_build_var_decl_src(irb, scope, source_node, var, nullptr, alloca); |
| 5556 | 6018 | } |
| 5557 | 6019 | |
| 5558 | 6020 | static IrInstruction *ir_gen_var_decl(IrBuilder *irb, Scope *scope, AstNode *node) { |
| ... | ... | @@ -5565,9 +6027,12 @@ static IrInstruction *ir_gen_var_decl(IrBuilder *irb, Scope *scope, AstNode *nod |
| 5565 | 6027 | return irb->codegen->invalid_instruction; |
| 5566 | 6028 | } |
| 5567 | 6029 | |
| 6030 | // Used for the type expr and the align expr |
| 6031 | Scope *comptime_scope = create_comptime_scope(irb->codegen, node, scope); |
| 6032 | |
| 5568 | 6033 | IrInstruction *type_instruction; |
| 5569 | 6034 | if (variable_declaration->type != nullptr) { |
| 5570 | | type_instruction = ir_gen_node(irb, variable_declaration->type, scope); |
| 6035 | type_instruction = ir_gen_node(irb, variable_declaration->type, comptime_scope); |
| 5571 | 6036 | if (type_instruction == irb->codegen->invalid_instruction) |
| 5572 | 6037 | return type_instruction; |
| 5573 | 6038 | } else { |
| ... | ... | @@ -5578,8 +6043,8 @@ static IrInstruction *ir_gen_var_decl(IrBuilder *irb, Scope *scope, AstNode *nod |
| 5578 | 6043 | bool is_const = variable_declaration->is_const; |
| 5579 | 6044 | bool is_extern = variable_declaration->is_extern; |
| 5580 | 6045 | |
| 5581 | | IrInstruction *is_comptime = ir_build_const_bool(irb, scope, node, |
| 5582 | | 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); |
| 5583 | 6048 | ZigVar *var = ir_create_var(irb, node, scope, variable_declaration->symbol, |
| 5584 | 6049 | is_const, is_const, is_shadowable, is_comptime); |
| 5585 | 6050 | // we detect IrInstructionIdDeclVarSrc in gen_block to make sure the next node |
| ... | ... | @@ -5593,7 +6058,7 @@ static IrInstruction *ir_gen_var_decl(IrBuilder *irb, Scope *scope, AstNode *nod |
| 5593 | 6058 | |
| 5594 | 6059 | IrInstruction *align_value = nullptr; |
| 5595 | 6060 | if (variable_declaration->align_expr != nullptr) { |
| 5596 | | align_value = ir_gen_node(irb, variable_declaration->align_expr, scope); |
| 6061 | align_value = ir_gen_node(irb, variable_declaration->align_expr, comptime_scope); |
| 5597 | 6062 | if (align_value == irb->codegen->invalid_instruction) |
| 5598 | 6063 | return align_value; |
| 5599 | 6064 | } |
| ... | ... | @@ -5606,20 +6071,39 @@ static IrInstruction *ir_gen_var_decl(IrBuilder *irb, Scope *scope, AstNode *nod |
| 5606 | 6071 | // Parser should ensure that this never happens |
| 5607 | 6072 | assert(variable_declaration->threadlocal_tok == nullptr); |
| 5608 | 6073 | |
| 6074 | IrInstruction *alloca = ir_build_alloca_src(irb, scope, node, align_value, |
| 6075 | buf_ptr(variable_declaration->symbol), is_comptime); |
| 6076 | |
| 6077 | // Create a result location for the initialization expression. |
| 6078 | ResultLocVar *result_loc_var = ir_build_var_result_loc(irb, alloca, var); |
| 6079 | ResultLoc *init_result_loc = (type_instruction == nullptr) ? &result_loc_var->base : nullptr; |
| 6080 | |
| 6081 | Scope *init_scope = is_comptime_scalar ? |
| 6082 | create_comptime_scope(irb->codegen, variable_declaration->expr, scope) : scope; |
| 6083 | |
| 5609 | 6084 | // Temporarily set the name of the IrExecutable to the VariableDeclaration |
| 5610 | 6085 | // so that the struct or enum from the init expression inherits the name. |
| 5611 | 6086 | Buf *old_exec_name = irb->exec->name; |
| 5612 | 6087 | irb->exec->name = variable_declaration->symbol; |
| 5613 | | IrInstruction *init_value = ir_gen_node(irb, variable_declaration->expr, scope); |
| 6088 | IrInstruction *init_value = ir_gen_node_extra(irb, variable_declaration->expr, init_scope, |
| 6089 | LValNone, init_result_loc); |
| 5614 | 6090 | irb->exec->name = old_exec_name; |
| 5615 | 6091 | |
| 5616 | 6092 | if (init_value == irb->codegen->invalid_instruction) |
| 5617 | | return init_value; |
| 6093 | return irb->codegen->invalid_instruction; |
| 6094 | |
| 6095 | if (type_instruction != nullptr) { |
| 6096 | IrInstruction *implicit_cast = ir_build_implicit_cast(irb, scope, node, type_instruction, init_value, |
| 6097 | &result_loc_var->base); |
| 6098 | ir_build_end_expr(irb, scope, node, implicit_cast, &result_loc_var->base); |
| 6099 | } |
| 5618 | 6100 | |
| 5619 | | return ir_build_var_decl_src(irb, scope, node, var, type_instruction, align_value, init_value); |
| 6101 | return ir_build_var_decl_src(irb, scope, node, var, align_value, alloca); |
| 5620 | 6102 | } |
| 5621 | 6103 | |
| 5622 | | static IrInstruction *ir_gen_while_expr(IrBuilder *irb, Scope *scope, AstNode *node) { |
| 6104 | static IrInstruction *ir_gen_while_expr(IrBuilder *irb, Scope *scope, AstNode *node, LVal lval, |
| 6105 | ResultLoc *result_loc) |
| 6106 | { |
| 5623 | 6107 | assert(node->type == NodeTypeWhileExpr); |
| 5624 | 6108 | |
| 5625 | 6109 | AstNode *continue_expr_node = node->data.while_expr.continue_expr; |
| ... | ... | @@ -5654,25 +6138,33 @@ static IrInstruction *ir_gen_while_expr(IrBuilder *irb, Scope *scope, AstNode *n |
| 5654 | 6138 | } else { |
| 5655 | 6139 | payload_scope = subexpr_scope; |
| 5656 | 6140 | } |
| 5657 | | IrInstruction *err_val_ptr = ir_gen_node_extra(irb, node->data.while_expr.condition, subexpr_scope, LValPtr); |
| 6141 | IrInstruction *err_val_ptr = ir_gen_node_extra(irb, node->data.while_expr.condition, subexpr_scope, |
| 6142 | LValPtr, nullptr); |
| 5658 | 6143 | if (err_val_ptr == irb->codegen->invalid_instruction) |
| 5659 | 6144 | return err_val_ptr; |
| 5660 | | IrInstruction *err_val = ir_build_load_ptr(irb, scope, node->data.while_expr.condition, err_val_ptr); |
| 5661 | | 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); |
| 5662 | 6146 | IrBasicBlock *after_cond_block = irb->current_basic_block; |
| 5663 | 6147 | IrInstruction *void_else_result = else_node ? nullptr : ir_mark_gen(ir_build_const_void(irb, scope, node)); |
| 6148 | IrInstruction *cond_br_inst; |
| 5664 | 6149 | if (!instr_is_unreachable(is_err)) { |
| 5665 | | ir_mark_gen(ir_build_cond_br(irb, scope, node->data.while_expr.condition, is_err, |
| 5666 | | 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(); |
| 5667 | 6156 | } |
| 5668 | 6157 | |
| 6158 | ResultLocPeerParent *peer_parent = ir_build_result_peers(irb, cond_br_inst, end_block, result_loc, |
| 6159 | is_comptime); |
| 6160 | |
| 5669 | 6161 | ir_set_cursor_at_end_and_append_block(irb, body_block); |
| 5670 | 6162 | if (var_symbol) { |
| 5671 | | IrInstruction *var_ptr_value = ir_build_unwrap_err_payload(irb, payload_scope, symbol_node, |
| 5672 | | err_val_ptr, false); |
| 5673 | | IrInstruction *var_value = node->data.while_expr.var_is_ptr ? |
| 5674 | | var_ptr_value : ir_build_load_ptr(irb, payload_scope, symbol_node, var_ptr_value); |
| 5675 | | 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); |
| 5676 | 6168 | } |
| 5677 | 6169 | |
| 5678 | 6170 | ZigList<IrInstruction *> incoming_values = {0}; |
| ... | ... | @@ -5684,7 +6176,12 @@ static IrInstruction *ir_gen_while_expr(IrBuilder *irb, Scope *scope, AstNode *n |
| 5684 | 6176 | loop_scope->is_comptime = is_comptime; |
| 5685 | 6177 | loop_scope->incoming_blocks = &incoming_blocks; |
| 5686 | 6178 | loop_scope->incoming_values = &incoming_values; |
| 6179 | loop_scope->lval = lval; |
| 6180 | loop_scope->peer_parent = peer_parent; |
| 5687 | 6181 | |
| 6182 | // Note the body block of the loop is not the place that lval and result_loc are used - |
| 6183 | // it's actually in break statements, handled similarly to return statements. |
| 6184 | // That is why we set those values in loop_scope above and not in this ir_gen_node call. |
| 5688 | 6185 | IrInstruction *body_result = ir_gen_node(irb, node->data.while_expr.body, &loop_scope->base); |
| 5689 | 6186 | if (body_result == irb->codegen->invalid_instruction) |
| 5690 | 6187 | return body_result; |
| ... | ... | @@ -5713,10 +6210,15 @@ static IrInstruction *ir_gen_while_expr(IrBuilder *irb, Scope *scope, AstNode *n |
| 5713 | 6210 | ZigVar *err_var = ir_create_var(irb, err_symbol_node, scope, err_symbol, |
| 5714 | 6211 | true, false, false, is_comptime); |
| 5715 | 6212 | Scope *err_scope = err_var->child_scope; |
| 5716 | | IrInstruction *err_var_value = ir_build_unwrap_err_code(irb, err_scope, err_symbol_node, err_val_ptr); |
| 5717 | | 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); |
| 5718 | 6215 | |
| 5719 | | IrInstruction *else_result = ir_gen_node(irb, else_node, err_scope); |
| 6216 | if (peer_parent->peers.length != 0) { |
| 6217 | peer_parent->peers.last()->next_bb = else_block; |
| 6218 | } |
| 6219 | ResultLocPeer *peer_result = create_peer_result(peer_parent); |
| 6220 | peer_parent->peers.append(peer_result); |
| 6221 | IrInstruction *else_result = ir_gen_node_extra(irb, else_node, err_scope, lval, &peer_result->base); |
| 5720 | 6222 | if (else_result == irb->codegen->invalid_instruction) |
| 5721 | 6223 | return else_result; |
| 5722 | 6224 | if (!instr_is_unreachable(else_result)) |
| ... | ... | @@ -5730,8 +6232,13 @@ static IrInstruction *ir_gen_while_expr(IrBuilder *irb, Scope *scope, AstNode *n |
| 5730 | 6232 | incoming_blocks.append(after_cond_block); |
| 5731 | 6233 | incoming_values.append(void_else_result); |
| 5732 | 6234 | } |
| 6235 | if (peer_parent->peers.length != 0) { |
| 6236 | peer_parent->peers.last()->next_bb = end_block; |
| 6237 | } |
| 5733 | 6238 | |
| 5734 | | return ir_build_phi(irb, scope, node, incoming_blocks.length, incoming_blocks.items, incoming_values.items); |
| 6239 | IrInstruction *phi = ir_build_phi(irb, scope, node, incoming_blocks.length, |
| 6240 | incoming_blocks.items, incoming_values.items, peer_parent); |
| 6241 | return ir_expr_wrap(irb, scope, phi, result_loc); |
| 5735 | 6242 | } else if (var_symbol != nullptr) { |
| 5736 | 6243 | ir_set_cursor_at_end_and_append_block(irb, cond_block); |
| 5737 | 6244 | Scope *subexpr_scope = create_runtime_scope(irb->codegen, node, scope, is_comptime); |
| ... | ... | @@ -5741,23 +6248,32 @@ static IrInstruction *ir_gen_while_expr(IrBuilder *irb, Scope *scope, AstNode *n |
| 5741 | 6248 | ZigVar *payload_var = ir_create_var(irb, symbol_node, subexpr_scope, var_symbol, |
| 5742 | 6249 | true, false, false, is_comptime); |
| 5743 | 6250 | Scope *child_scope = payload_var->child_scope; |
| 5744 | | IrInstruction *maybe_val_ptr = ir_gen_node_extra(irb, node->data.while_expr.condition, subexpr_scope, LValPtr); |
| 6251 | IrInstruction *maybe_val_ptr = ir_gen_node_extra(irb, node->data.while_expr.condition, subexpr_scope, |
| 6252 | LValPtr, nullptr); |
| 5745 | 6253 | if (maybe_val_ptr == irb->codegen->invalid_instruction) |
| 5746 | 6254 | return maybe_val_ptr; |
| 5747 | 6255 | IrInstruction *maybe_val = ir_build_load_ptr(irb, scope, node->data.while_expr.condition, maybe_val_ptr); |
| 5748 | 6256 | IrInstruction *is_non_null = ir_build_test_nonnull(irb, scope, node->data.while_expr.condition, maybe_val); |
| 5749 | 6257 | IrBasicBlock *after_cond_block = irb->current_basic_block; |
| 5750 | 6258 | IrInstruction *void_else_result = else_node ? nullptr : ir_mark_gen(ir_build_const_void(irb, scope, node)); |
| 6259 | IrInstruction *cond_br_inst; |
| 5751 | 6260 | if (!instr_is_unreachable(is_non_null)) { |
| 5752 | | ir_mark_gen(ir_build_cond_br(irb, scope, node->data.while_expr.condition, is_non_null, |
| 5753 | | 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(); |
| 5754 | 6267 | } |
| 5755 | 6268 | |
| 6269 | ResultLocPeerParent *peer_parent = ir_build_result_peers(irb, cond_br_inst, end_block, result_loc, |
| 6270 | is_comptime); |
| 6271 | |
| 5756 | 6272 | ir_set_cursor_at_end_and_append_block(irb, body_block); |
| 5757 | | IrInstruction *var_ptr_value = ir_build_optional_unwrap_ptr(irb, child_scope, symbol_node, maybe_val_ptr, false); |
| 5758 | | IrInstruction *var_value = node->data.while_expr.var_is_ptr ? |
| 5759 | | var_ptr_value : ir_build_load_ptr(irb, child_scope, symbol_node, var_ptr_value); |
| 5760 | | 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); |
| 5761 | 6277 | |
| 5762 | 6278 | ZigList<IrInstruction *> incoming_values = {0}; |
| 5763 | 6279 | ZigList<IrBasicBlock *> incoming_blocks = {0}; |
| ... | ... | @@ -5768,7 +6284,12 @@ static IrInstruction *ir_gen_while_expr(IrBuilder *irb, Scope *scope, AstNode *n |
| 5768 | 6284 | loop_scope->is_comptime = is_comptime; |
| 5769 | 6285 | loop_scope->incoming_blocks = &incoming_blocks; |
| 5770 | 6286 | loop_scope->incoming_values = &incoming_values; |
| 6287 | loop_scope->lval = lval; |
| 6288 | loop_scope->peer_parent = peer_parent; |
| 5771 | 6289 | |
| 6290 | // Note the body block of the loop is not the place that lval and result_loc are used - |
| 6291 | // it's actually in break statements, handled similarly to return statements. |
| 6292 | // That is why we set those values in loop_scope above and not in this ir_gen_node call. |
| 5772 | 6293 | IrInstruction *body_result = ir_gen_node(irb, node->data.while_expr.body, &loop_scope->base); |
| 5773 | 6294 | if (body_result == irb->codegen->invalid_instruction) |
| 5774 | 6295 | return body_result; |
| ... | ... | @@ -5793,7 +6314,12 @@ static IrInstruction *ir_gen_while_expr(IrBuilder *irb, Scope *scope, AstNode *n |
| 5793 | 6314 | if (else_node) { |
| 5794 | 6315 | ir_set_cursor_at_end_and_append_block(irb, else_block); |
| 5795 | 6316 | |
| 5796 | | else_result = ir_gen_node(irb, else_node, scope); |
| 6317 | if (peer_parent->peers.length != 0) { |
| 6318 | peer_parent->peers.last()->next_bb = else_block; |
| 6319 | } |
| 6320 | ResultLocPeer *peer_result = create_peer_result(peer_parent); |
| 6321 | peer_parent->peers.append(peer_result); |
| 6322 | else_result = ir_gen_node_extra(irb, else_node, scope, lval, &peer_result->base); |
| 5797 | 6323 | if (else_result == irb->codegen->invalid_instruction) |
| 5798 | 6324 | return else_result; |
| 5799 | 6325 | if (!instr_is_unreachable(else_result)) |
| ... | ... | @@ -5808,8 +6334,13 @@ static IrInstruction *ir_gen_while_expr(IrBuilder *irb, Scope *scope, AstNode *n |
| 5808 | 6334 | incoming_blocks.append(after_cond_block); |
| 5809 | 6335 | incoming_values.append(void_else_result); |
| 5810 | 6336 | } |
| 6337 | if (peer_parent->peers.length != 0) { |
| 6338 | peer_parent->peers.last()->next_bb = end_block; |
| 6339 | } |
| 5811 | 6340 | |
| 5812 | | return ir_build_phi(irb, scope, node, incoming_blocks.length, incoming_blocks.items, incoming_values.items); |
| 6341 | IrInstruction *phi = ir_build_phi(irb, scope, node, incoming_blocks.length, |
| 6342 | incoming_blocks.items, incoming_values.items, peer_parent); |
| 6343 | return ir_expr_wrap(irb, scope, phi, result_loc); |
| 5813 | 6344 | } else { |
| 5814 | 6345 | ir_set_cursor_at_end_and_append_block(irb, cond_block); |
| 5815 | 6346 | IrInstruction *cond_val = ir_gen_node(irb, node->data.while_expr.condition, scope); |
| ... | ... | @@ -5817,11 +6348,18 @@ static IrInstruction *ir_gen_while_expr(IrBuilder *irb, Scope *scope, AstNode *n |
| 5817 | 6348 | return cond_val; |
| 5818 | 6349 | IrBasicBlock *after_cond_block = irb->current_basic_block; |
| 5819 | 6350 | IrInstruction *void_else_result = else_node ? nullptr : ir_mark_gen(ir_build_const_void(irb, scope, node)); |
| 6351 | IrInstruction *cond_br_inst; |
| 5820 | 6352 | if (!instr_is_unreachable(cond_val)) { |
| 5821 | | ir_mark_gen(ir_build_cond_br(irb, scope, node->data.while_expr.condition, cond_val, |
| 5822 | | 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(); |
| 5823 | 6359 | } |
| 5824 | 6360 | |
| 6361 | ResultLocPeerParent *peer_parent = ir_build_result_peers(irb, cond_br_inst, end_block, result_loc, |
| 6362 | is_comptime); |
| 5825 | 6363 | ir_set_cursor_at_end_and_append_block(irb, body_block); |
| 5826 | 6364 | |
| 5827 | 6365 | ZigList<IrInstruction *> incoming_values = {0}; |
| ... | ... | @@ -5835,7 +6373,12 @@ static IrInstruction *ir_gen_while_expr(IrBuilder *irb, Scope *scope, AstNode *n |
| 5835 | 6373 | loop_scope->is_comptime = is_comptime; |
| 5836 | 6374 | loop_scope->incoming_blocks = &incoming_blocks; |
| 5837 | 6375 | loop_scope->incoming_values = &incoming_values; |
| 6376 | loop_scope->lval = lval; |
| 6377 | loop_scope->peer_parent = peer_parent; |
| 5838 | 6378 | |
| 6379 | // Note the body block of the loop is not the place that lval and result_loc are used - |
| 6380 | // it's actually in break statements, handled similarly to return statements. |
| 6381 | // That is why we set those values in loop_scope above and not in this ir_gen_node call. |
| 5839 | 6382 | IrInstruction *body_result = ir_gen_node(irb, node->data.while_expr.body, &loop_scope->base); |
| 5840 | 6383 | if (body_result == irb->codegen->invalid_instruction) |
| 5841 | 6384 | return body_result; |
| ... | ... | @@ -5860,7 +6403,13 @@ static IrInstruction *ir_gen_while_expr(IrBuilder *irb, Scope *scope, AstNode *n |
| 5860 | 6403 | if (else_node) { |
| 5861 | 6404 | ir_set_cursor_at_end_and_append_block(irb, else_block); |
| 5862 | 6405 | |
| 5863 | | else_result = ir_gen_node(irb, else_node, subexpr_scope); |
| 6406 | if (peer_parent->peers.length != 0) { |
| 6407 | peer_parent->peers.last()->next_bb = else_block; |
| 6408 | } |
| 6409 | ResultLocPeer *peer_result = create_peer_result(peer_parent); |
| 6410 | peer_parent->peers.append(peer_result); |
| 6411 | |
| 6412 | else_result = ir_gen_node_extra(irb, else_node, subexpr_scope, lval, &peer_result->base); |
| 5864 | 6413 | if (else_result == irb->codegen->invalid_instruction) |
| 5865 | 6414 | return else_result; |
| 5866 | 6415 | if (!instr_is_unreachable(else_result)) |
| ... | ... | @@ -5875,12 +6424,19 @@ static IrInstruction *ir_gen_while_expr(IrBuilder *irb, Scope *scope, AstNode *n |
| 5875 | 6424 | incoming_blocks.append(after_cond_block); |
| 5876 | 6425 | incoming_values.append(void_else_result); |
| 5877 | 6426 | } |
| 6427 | if (peer_parent->peers.length != 0) { |
| 6428 | peer_parent->peers.last()->next_bb = end_block; |
| 6429 | } |
| 5878 | 6430 | |
| 5879 | | return ir_build_phi(irb, scope, node, incoming_blocks.length, incoming_blocks.items, incoming_values.items); |
| 6431 | IrInstruction *phi = ir_build_phi(irb, scope, node, incoming_blocks.length, |
| 6432 | incoming_blocks.items, incoming_values.items, peer_parent); |
| 6433 | return ir_expr_wrap(irb, scope, phi, result_loc); |
| 5880 | 6434 | } |
| 5881 | 6435 | } |
| 5882 | 6436 | |
| 5883 | | static IrInstruction *ir_gen_for_expr(IrBuilder *irb, Scope *parent_scope, AstNode *node) { |
| 6437 | static IrInstruction *ir_gen_for_expr(IrBuilder *irb, Scope *parent_scope, AstNode *node, LVal lval, |
| 6438 | ResultLoc *result_loc) |
| 6439 | { |
| 5884 | 6440 | assert(node->type == NodeTypeForExpr); |
| 5885 | 6441 | |
| 5886 | 6442 | AstNode *array_node = node->data.for_expr.array_expr; |
| ... | ... | @@ -5895,76 +6451,67 @@ static IrInstruction *ir_gen_for_expr(IrBuilder *irb, Scope *parent_scope, AstNo |
| 5895 | 6451 | } |
| 5896 | 6452 | assert(elem_node->type == NodeTypeSymbol); |
| 5897 | 6453 | |
| 5898 | | IrInstruction *array_val_ptr = ir_gen_node_extra(irb, array_node, parent_scope, LValPtr); |
| 6454 | IrInstruction *array_val_ptr = ir_gen_node_extra(irb, array_node, parent_scope, LValPtr, nullptr); |
| 5899 | 6455 | if (array_val_ptr == irb->codegen->invalid_instruction) |
| 5900 | 6456 | return array_val_ptr; |
| 5901 | 6457 | |
| 5902 | | IrInstruction *pointer_type = ir_build_to_ptr_type(irb, parent_scope, array_node, array_val_ptr); |
| 5903 | | IrInstruction *elem_var_type; |
| 5904 | | if (node->data.for_expr.elem_is_ptr) { |
| 5905 | | elem_var_type = pointer_type; |
| 5906 | | } else { |
| 5907 | | elem_var_type = ir_build_ptr_type_child(irb, parent_scope, elem_node, pointer_type); |
| 5908 | | } |
| 5909 | | |
| 5910 | 6458 | IrInstruction *is_comptime = ir_build_const_bool(irb, parent_scope, node, |
| 5911 | 6459 | ir_should_inline(irb->exec, parent_scope) || node->data.for_expr.is_inline); |
| 5912 | 6460 | |
| 5913 | | // TODO make it an error to write to element variable or i variable. |
| 5914 | | Buf *elem_var_name = elem_node->data.symbol_expr.symbol; |
| 5915 | | ZigVar *elem_var = ir_create_var(irb, elem_node, parent_scope, elem_var_name, true, false, false, is_comptime); |
| 5916 | | Scope *child_scope = elem_var->child_scope; |
| 5917 | | |
| 5918 | | IrInstruction *undefined_value = ir_build_const_undefined(irb, child_scope, elem_node); |
| 5919 | | ir_build_var_decl_src(irb, child_scope, elem_node, elem_var, elem_var_type, nullptr, undefined_value); |
| 5920 | | IrInstruction *elem_var_ptr = ir_build_var_ptr(irb, child_scope, node, elem_var); |
| 5921 | | |
| 5922 | 6461 | AstNode *index_var_source_node; |
| 5923 | 6462 | ZigVar *index_var; |
| 6463 | const char *index_var_name; |
| 5924 | 6464 | if (index_node) { |
| 5925 | 6465 | index_var_source_node = index_node; |
| 5926 | | Buf *index_var_name = index_node->data.symbol_expr.symbol; |
| 5927 | | index_var = ir_create_var(irb, index_node, child_scope, index_var_name, true, false, false, is_comptime); |
| 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); |
| 5928 | 6469 | } else { |
| 5929 | 6470 | index_var_source_node = node; |
| 5930 | | index_var = ir_create_var(irb, node, child_scope, nullptr, true, false, true, is_comptime); |
| 6471 | index_var = ir_create_var(irb, node, parent_scope, nullptr, true, false, true, is_comptime); |
| 6472 | index_var_name = "i"; |
| 5931 | 6473 | } |
| 5932 | | child_scope = index_var->child_scope; |
| 5933 | 6474 | |
| 5934 | | IrInstruction *usize = ir_build_const_type(irb, child_scope, node, irb->codegen->builtin_types.entry_usize); |
| 5935 | | IrInstruction *zero = ir_build_const_usize(irb, child_scope, node, 0); |
| 5936 | | IrInstruction *one = ir_build_const_usize(irb, child_scope, node, 1); |
| 5937 | | ir_build_var_decl_src(irb, child_scope, index_var_source_node, index_var, usize, nullptr, zero); |
| 5938 | | 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); |
| 5939 | 6481 | |
| 5940 | 6482 | |
| 5941 | | IrBasicBlock *cond_block = ir_create_basic_block(irb, child_scope, "ForCond"); |
| 5942 | | IrBasicBlock *body_block = ir_create_basic_block(irb, child_scope, "ForBody"); |
| 5943 | | IrBasicBlock *end_block = ir_create_basic_block(irb, child_scope, "ForEnd"); |
| 5944 | | IrBasicBlock *else_block = else_node ? ir_create_basic_block(irb, child_scope, "ForElse") : end_block; |
| 5945 | | 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"); |
| 5946 | 6488 | |
| 5947 | 6489 | Buf *len_field_name = buf_create_from_str("len"); |
| 5948 | | IrInstruction *len_ref = ir_build_field_ptr(irb, child_scope, node, array_val_ptr, len_field_name); |
| 5949 | | IrInstruction *len_val = ir_build_load_ptr(irb, child_scope, node, len_ref); |
| 5950 | | 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); |
| 5951 | 6493 | |
| 5952 | 6494 | ir_set_cursor_at_end_and_append_block(irb, cond_block); |
| 5953 | | IrInstruction *index_val = ir_build_load_ptr(irb, child_scope, node, index_ptr); |
| 5954 | | 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); |
| 5955 | 6497 | IrBasicBlock *after_cond_block = irb->current_basic_block; |
| 5956 | 6498 | IrInstruction *void_else_value = else_node ? nullptr : ir_mark_gen(ir_build_const_void(irb, parent_scope, node)); |
| 5957 | | ir_mark_gen(ir_build_cond_br(irb, child_scope, node, cond, body_block, else_block, is_comptime)); |
| 6499 | IrInstruction *cond_br_inst = ir_mark_gen(ir_build_cond_br(irb, parent_scope, node, cond, |
| 6500 | body_block, else_block, is_comptime)); |
| 6501 | |
| 6502 | ResultLocPeerParent *peer_parent = ir_build_result_peers(irb, cond_br_inst, end_block, result_loc, is_comptime); |
| 5958 | 6503 | |
| 5959 | 6504 | ir_set_cursor_at_end_and_append_block(irb, body_block); |
| 5960 | | IrInstruction *elem_ptr = ir_build_elem_ptr(irb, child_scope, node, array_val_ptr, index_val, false, PtrLenSingle); |
| 5961 | | IrInstruction *elem_val; |
| 5962 | | if (node->data.for_expr.elem_is_ptr) { |
| 5963 | | elem_val = elem_ptr; |
| 5964 | | } else { |
| 5965 | | elem_val = ir_build_load_ptr(irb, child_scope, node, elem_ptr); |
| 5966 | | } |
| 5967 | | 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); |
| 5968 | 6515 | |
| 5969 | 6516 | ZigList<IrInstruction *> incoming_values = {0}; |
| 5970 | 6517 | ZigList<IrBasicBlock *> incoming_blocks = {0}; |
| ... | ... | @@ -5974,7 +6521,12 @@ static IrInstruction *ir_gen_for_expr(IrBuilder *irb, Scope *parent_scope, AstNo |
| 5974 | 6521 | loop_scope->is_comptime = is_comptime; |
| 5975 | 6522 | loop_scope->incoming_blocks = &incoming_blocks; |
| 5976 | 6523 | loop_scope->incoming_values = &incoming_values; |
| 6524 | loop_scope->lval = lval; |
| 6525 | loop_scope->peer_parent = peer_parent; |
| 5977 | 6526 | |
| 6527 | // Note the body block of the loop is not the place that lval and result_loc are used - |
| 6528 | // it's actually in break statements, handled similarly to return statements. |
| 6529 | // That is why we set those values in loop_scope above and not in this ir_gen_node call. |
| 5978 | 6530 | IrInstruction *body_result = ir_gen_node(irb, body_node, &loop_scope->base); |
| 5979 | 6531 | |
| 5980 | 6532 | if (!instr_is_unreachable(body_result)) { |
| ... | ... | @@ -5991,7 +6543,12 @@ static IrInstruction *ir_gen_for_expr(IrBuilder *irb, Scope *parent_scope, AstNo |
| 5991 | 6543 | if (else_node) { |
| 5992 | 6544 | ir_set_cursor_at_end_and_append_block(irb, else_block); |
| 5993 | 6545 | |
| 5994 | | else_result = ir_gen_node(irb, else_node, parent_scope); |
| 6546 | if (peer_parent->peers.length != 0) { |
| 6547 | peer_parent->peers.last()->next_bb = else_block; |
| 6548 | } |
| 6549 | ResultLocPeer *peer_result = create_peer_result(peer_parent); |
| 6550 | peer_parent->peers.append(peer_result); |
| 6551 | else_result = ir_gen_node_extra(irb, else_node, parent_scope, lval, &peer_result->base); |
| 5995 | 6552 | if (else_result == irb->codegen->invalid_instruction) |
| 5996 | 6553 | return else_result; |
| 5997 | 6554 | if (!instr_is_unreachable(else_result)) |
| ... | ... | @@ -6007,8 +6564,13 @@ static IrInstruction *ir_gen_for_expr(IrBuilder *irb, Scope *parent_scope, AstNo |
| 6007 | 6564 | incoming_blocks.append(after_cond_block); |
| 6008 | 6565 | incoming_values.append(void_else_value); |
| 6009 | 6566 | } |
| 6567 | if (peer_parent->peers.length != 0) { |
| 6568 | peer_parent->peers.last()->next_bb = end_block; |
| 6569 | } |
| 6010 | 6570 | |
| 6011 | | return ir_build_phi(irb, parent_scope, node, incoming_blocks.length, incoming_blocks.items, incoming_values.items); |
| 6571 | IrInstruction *phi = ir_build_phi(irb, parent_scope, node, incoming_blocks.length, |
| 6572 | incoming_blocks.items, incoming_values.items, peer_parent); |
| 6573 | return ir_expr_wrap(irb, parent_scope, phi, result_loc); |
| 6012 | 6574 | } |
| 6013 | 6575 | |
| 6014 | 6576 | static IrInstruction *ir_gen_bool_literal(IrBuilder *irb, Scope *scope, AstNode *node) { |
| ... | ... | @@ -6293,7 +6855,9 @@ static IrInstruction *ir_gen_asm_expr(IrBuilder *irb, Scope *scope, AstNode *nod |
| 6293 | 6855 | input_list, output_types, output_vars, return_count, is_volatile); |
| 6294 | 6856 | } |
| 6295 | 6857 | |
| 6296 | | static IrInstruction *ir_gen_if_optional_expr(IrBuilder *irb, Scope *scope, AstNode *node) { |
| 6858 | static IrInstruction *ir_gen_if_optional_expr(IrBuilder *irb, Scope *scope, AstNode *node, LVal lval, |
| 6859 | ResultLoc *result_loc) |
| 6860 | { |
| 6297 | 6861 | assert(node->type == NodeTypeIfOptional); |
| 6298 | 6862 | |
| 6299 | 6863 | Buf *var_symbol = node->data.test_expr.var_symbol; |
| ... | ... | @@ -6302,7 +6866,7 @@ static IrInstruction *ir_gen_if_optional_expr(IrBuilder *irb, Scope *scope, AstN |
| 6302 | 6866 | AstNode *else_node = node->data.test_expr.else_node; |
| 6303 | 6867 | bool var_is_ptr = node->data.test_expr.var_is_ptr; |
| 6304 | 6868 | |
| 6305 | | IrInstruction *maybe_val_ptr = ir_gen_node_extra(irb, expr_node, scope, LValPtr); |
| 6869 | IrInstruction *maybe_val_ptr = ir_gen_node_extra(irb, expr_node, scope, LValPtr, nullptr); |
| 6306 | 6870 | if (maybe_val_ptr == irb->codegen->invalid_instruction) |
| 6307 | 6871 | return maybe_val_ptr; |
| 6308 | 6872 | |
| ... | ... | @@ -6319,27 +6883,31 @@ static IrInstruction *ir_gen_if_optional_expr(IrBuilder *irb, Scope *scope, AstN |
| 6319 | 6883 | } else { |
| 6320 | 6884 | is_comptime = ir_build_test_comptime(irb, scope, node, is_non_null); |
| 6321 | 6885 | } |
| 6322 | | ir_build_cond_br(irb, scope, node, is_non_null, then_block, else_block, is_comptime); |
| 6886 | IrInstruction *cond_br_inst = ir_build_cond_br(irb, scope, node, is_non_null, |
| 6887 | then_block, else_block, is_comptime); |
| 6888 | |
| 6889 | ResultLocPeerParent *peer_parent = ir_build_binary_result_peers(irb, cond_br_inst, else_block, endif_block, |
| 6890 | result_loc, is_comptime); |
| 6323 | 6891 | |
| 6324 | 6892 | ir_set_cursor_at_end_and_append_block(irb, then_block); |
| 6325 | 6893 | |
| 6326 | 6894 | Scope *subexpr_scope = create_runtime_scope(irb->codegen, node, scope, is_comptime); |
| 6327 | 6895 | Scope *var_scope; |
| 6328 | 6896 | if (var_symbol) { |
| 6329 | | IrInstruction *var_type = nullptr; |
| 6330 | 6897 | bool is_shadowable = false; |
| 6331 | 6898 | bool is_const = true; |
| 6332 | 6899 | ZigVar *var = ir_create_var(irb, node, subexpr_scope, |
| 6333 | 6900 | var_symbol, is_const, is_const, is_shadowable, is_comptime); |
| 6334 | 6901 | |
| 6335 | | IrInstruction *var_ptr_value = ir_build_optional_unwrap_ptr(irb, subexpr_scope, node, maybe_val_ptr, false); |
| 6336 | | IrInstruction *var_value = var_is_ptr ? var_ptr_value : ir_build_load_ptr(irb, subexpr_scope, node, var_ptr_value); |
| 6337 | | 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); |
| 6338 | 6905 | var_scope = var->child_scope; |
| 6339 | 6906 | } else { |
| 6340 | 6907 | var_scope = subexpr_scope; |
| 6341 | 6908 | } |
| 6342 | | IrInstruction *then_expr_result = ir_gen_node(irb, then_node, var_scope); |
| 6909 | IrInstruction *then_expr_result = ir_gen_node_extra(irb, then_node, var_scope, lval, |
| 6910 | &peer_parent->peers.at(0)->base); |
| 6343 | 6911 | if (then_expr_result == irb->codegen->invalid_instruction) |
| 6344 | 6912 | return then_expr_result; |
| 6345 | 6913 | IrBasicBlock *after_then_block = irb->current_basic_block; |
| ... | ... | @@ -6349,11 +6917,12 @@ static IrInstruction *ir_gen_if_optional_expr(IrBuilder *irb, Scope *scope, AstN |
| 6349 | 6917 | ir_set_cursor_at_end_and_append_block(irb, else_block); |
| 6350 | 6918 | IrInstruction *else_expr_result; |
| 6351 | 6919 | if (else_node) { |
| 6352 | | else_expr_result = ir_gen_node(irb, else_node, subexpr_scope); |
| 6920 | else_expr_result = ir_gen_node_extra(irb, else_node, subexpr_scope, lval, &peer_parent->peers.at(1)->base); |
| 6353 | 6921 | if (else_expr_result == irb->codegen->invalid_instruction) |
| 6354 | 6922 | return else_expr_result; |
| 6355 | 6923 | } else { |
| 6356 | 6924 | else_expr_result = ir_build_const_void(irb, scope, node); |
| 6925 | ir_build_end_expr(irb, scope, node, else_expr_result, &peer_parent->peers.at(1)->base); |
| 6357 | 6926 | } |
| 6358 | 6927 | IrBasicBlock *after_else_block = irb->current_basic_block; |
| 6359 | 6928 | if (!instr_is_unreachable(else_expr_result)) |
| ... | ... | @@ -6367,10 +6936,13 @@ static IrInstruction *ir_gen_if_optional_expr(IrBuilder *irb, Scope *scope, AstN |
| 6367 | 6936 | incoming_blocks[0] = after_then_block; |
| 6368 | 6937 | incoming_blocks[1] = after_else_block; |
| 6369 | 6938 | |
| 6370 | | return ir_build_phi(irb, scope, node, 2, incoming_blocks, incoming_values); |
| 6939 | IrInstruction *phi = ir_build_phi(irb, scope, node, 2, incoming_blocks, incoming_values, peer_parent); |
| 6940 | return ir_expr_wrap(irb, scope, phi, result_loc); |
| 6371 | 6941 | } |
| 6372 | 6942 | |
| 6373 | | static IrInstruction *ir_gen_if_err_expr(IrBuilder *irb, Scope *scope, AstNode *node) { |
| 6943 | static IrInstruction *ir_gen_if_err_expr(IrBuilder *irb, Scope *scope, AstNode *node, LVal lval, |
| 6944 | ResultLoc *result_loc) |
| 6945 | { |
| 6374 | 6946 | assert(node->type == NodeTypeIfErrorExpr); |
| 6375 | 6947 | |
| 6376 | 6948 | AstNode *target_node = node->data.if_err_expr.target_node; |
| ... | ... | @@ -6381,12 +6953,12 @@ static IrInstruction *ir_gen_if_err_expr(IrBuilder *irb, Scope *scope, AstNode * |
| 6381 | 6953 | Buf *var_symbol = node->data.if_err_expr.var_symbol; |
| 6382 | 6954 | Buf *err_symbol = node->data.if_err_expr.err_symbol; |
| 6383 | 6955 | |
| 6384 | | IrInstruction *err_val_ptr = ir_gen_node_extra(irb, target_node, scope, LValPtr); |
| 6956 | IrInstruction *err_val_ptr = ir_gen_node_extra(irb, target_node, scope, LValPtr, nullptr); |
| 6385 | 6957 | if (err_val_ptr == irb->codegen->invalid_instruction) |
| 6386 | 6958 | return err_val_ptr; |
| 6387 | 6959 | |
| 6388 | 6960 | IrInstruction *err_val = ir_build_load_ptr(irb, scope, node, err_val_ptr); |
| 6389 | | IrInstruction *is_err = ir_build_test_err(irb, scope, node, err_val); |
| 6961 | IrInstruction *is_err = ir_build_test_err_src(irb, scope, node, err_val_ptr, true); |
| 6390 | 6962 | |
| 6391 | 6963 | IrBasicBlock *ok_block = ir_create_basic_block(irb, scope, "TryOk"); |
| 6392 | 6964 | IrBasicBlock *else_block = ir_create_basic_block(irb, scope, "TryElse"); |
| ... | ... | @@ -6394,27 +6966,31 @@ static IrInstruction *ir_gen_if_err_expr(IrBuilder *irb, Scope *scope, AstNode * |
| 6394 | 6966 | |
| 6395 | 6967 | bool force_comptime = ir_should_inline(irb->exec, scope); |
| 6396 | 6968 | IrInstruction *is_comptime = force_comptime ? ir_build_const_bool(irb, scope, node, true) : ir_build_test_comptime(irb, scope, node, is_err); |
| 6397 | | ir_build_cond_br(irb, scope, node, is_err, else_block, ok_block, is_comptime); |
| 6969 | IrInstruction *cond_br_inst = ir_build_cond_br(irb, scope, node, is_err, else_block, ok_block, is_comptime); |
| 6970 | |
| 6971 | ResultLocPeerParent *peer_parent = ir_build_binary_result_peers(irb, cond_br_inst, else_block, endif_block, |
| 6972 | result_loc, is_comptime); |
| 6398 | 6973 | |
| 6399 | 6974 | ir_set_cursor_at_end_and_append_block(irb, ok_block); |
| 6400 | 6975 | |
| 6401 | 6976 | Scope *subexpr_scope = create_runtime_scope(irb->codegen, node, scope, is_comptime); |
| 6402 | 6977 | Scope *var_scope; |
| 6403 | 6978 | if (var_symbol) { |
| 6404 | | IrInstruction *var_type = nullptr; |
| 6405 | 6979 | bool is_shadowable = false; |
| 6406 | 6980 | IrInstruction *var_is_comptime = force_comptime ? ir_build_const_bool(irb, subexpr_scope, node, true) : ir_build_test_comptime(irb, subexpr_scope, node, err_val); |
| 6407 | 6981 | ZigVar *var = ir_create_var(irb, node, subexpr_scope, |
| 6408 | 6982 | var_symbol, var_is_const, var_is_const, is_shadowable, var_is_comptime); |
| 6409 | 6983 | |
| 6410 | | IrInstruction *var_ptr_value = ir_build_unwrap_err_payload(irb, subexpr_scope, node, err_val_ptr, false); |
| 6411 | | IrInstruction *var_value = var_is_ptr ? var_ptr_value : ir_build_load_ptr(irb, subexpr_scope, node, var_ptr_value); |
| 6412 | | 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); |
| 6413 | 6988 | var_scope = var->child_scope; |
| 6414 | 6989 | } else { |
| 6415 | 6990 | var_scope = subexpr_scope; |
| 6416 | 6991 | } |
| 6417 | | IrInstruction *then_expr_result = ir_gen_node(irb, then_node, var_scope); |
| 6992 | IrInstruction *then_expr_result = ir_gen_node_extra(irb, then_node, var_scope, lval, |
| 6993 | &peer_parent->peers.at(0)->base); |
| 6418 | 6994 | if (then_expr_result == irb->codegen->invalid_instruction) |
| 6419 | 6995 | return then_expr_result; |
| 6420 | 6996 | IrBasicBlock *after_then_block = irb->current_basic_block; |
| ... | ... | @@ -6427,23 +7003,23 @@ static IrInstruction *ir_gen_if_err_expr(IrBuilder *irb, Scope *scope, AstNode * |
| 6427 | 7003 | if (else_node) { |
| 6428 | 7004 | Scope *err_var_scope; |
| 6429 | 7005 | if (err_symbol) { |
| 6430 | | IrInstruction *var_type = nullptr; |
| 6431 | 7006 | bool is_shadowable = false; |
| 6432 | 7007 | bool is_const = true; |
| 6433 | 7008 | ZigVar *var = ir_create_var(irb, node, subexpr_scope, |
| 6434 | 7009 | err_symbol, is_const, is_const, is_shadowable, is_comptime); |
| 6435 | 7010 | |
| 6436 | | IrInstruction *var_value = ir_build_unwrap_err_code(irb, subexpr_scope, node, err_val_ptr); |
| 6437 | | 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); |
| 6438 | 7013 | err_var_scope = var->child_scope; |
| 6439 | 7014 | } else { |
| 6440 | 7015 | err_var_scope = subexpr_scope; |
| 6441 | 7016 | } |
| 6442 | | else_expr_result = ir_gen_node(irb, else_node, err_var_scope); |
| 7017 | else_expr_result = ir_gen_node_extra(irb, else_node, err_var_scope, lval, &peer_parent->peers.at(1)->base); |
| 6443 | 7018 | if (else_expr_result == irb->codegen->invalid_instruction) |
| 6444 | 7019 | return else_expr_result; |
| 6445 | 7020 | } else { |
| 6446 | 7021 | else_expr_result = ir_build_const_void(irb, scope, node); |
| 7022 | ir_build_end_expr(irb, scope, node, else_expr_result, &peer_parent->peers.at(1)->base); |
| 6447 | 7023 | } |
| 6448 | 7024 | IrBasicBlock *after_else_block = irb->current_basic_block; |
| 6449 | 7025 | if (!instr_is_unreachable(else_expr_result)) |
| ... | ... | @@ -6457,14 +7033,15 @@ static IrInstruction *ir_gen_if_err_expr(IrBuilder *irb, Scope *scope, AstNode * |
| 6457 | 7033 | incoming_blocks[0] = after_then_block; |
| 6458 | 7034 | incoming_blocks[1] = after_else_block; |
| 6459 | 7035 | |
| 6460 | | return ir_build_phi(irb, scope, node, 2, incoming_blocks, incoming_values); |
| 7036 | IrInstruction *phi = ir_build_phi(irb, scope, node, 2, incoming_blocks, incoming_values, peer_parent); |
| 7037 | return ir_expr_wrap(irb, scope, phi, result_loc); |
| 6461 | 7038 | } |
| 6462 | 7039 | |
| 6463 | 7040 | static bool ir_gen_switch_prong_expr(IrBuilder *irb, Scope *scope, AstNode *switch_node, AstNode *prong_node, |
| 6464 | 7041 | IrBasicBlock *end_block, IrInstruction *is_comptime, IrInstruction *var_is_comptime, |
| 6465 | 7042 | IrInstruction *target_value_ptr, IrInstruction **prong_values, size_t prong_values_len, |
| 6466 | 7043 | ZigList<IrBasicBlock *> *incoming_blocks, ZigList<IrInstruction *> *incoming_values, |
| 6467 | | IrInstructionSwitchElseVar **out_switch_else_var) |
| 7044 | IrInstructionSwitchElseVar **out_switch_else_var, LVal lval, ResultLoc *result_loc) |
| 6468 | 7045 | { |
| 6469 | 7046 | assert(switch_node->type == NodeTypeSwitchExpr); |
| 6470 | 7047 | assert(prong_node->type == NodeTypeSwitchProng); |
| ... | ... | @@ -6482,28 +7059,27 @@ static bool ir_gen_switch_prong_expr(IrBuilder *irb, Scope *scope, AstNode *swit |
| 6482 | 7059 | ZigVar *var = ir_create_var(irb, var_symbol_node, scope, |
| 6483 | 7060 | var_name, is_const, is_const, is_shadowable, var_is_comptime); |
| 6484 | 7061 | child_scope = var->child_scope; |
| 6485 | | IrInstruction *var_value; |
| 7062 | IrInstruction *var_ptr; |
| 6486 | 7063 | if (out_switch_else_var != nullptr) { |
| 6487 | 7064 | IrInstructionSwitchElseVar *switch_else_var = ir_build_switch_else_var(irb, scope, var_symbol_node, |
| 6488 | 7065 | target_value_ptr); |
| 6489 | 7066 | *out_switch_else_var = switch_else_var; |
| 6490 | | IrInstruction *var_ptr_value = &switch_else_var->base; |
| 6491 | | var_value = var_is_ptr ? var_ptr_value : ir_build_load_ptr(irb, scope, var_symbol_node, var_ptr_value); |
| 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; |
| 6492 | 7069 | } else if (prong_values != nullptr) { |
| 6493 | | IrInstruction *var_ptr_value = ir_build_switch_var(irb, scope, var_symbol_node, target_value_ptr, |
| 7070 | IrInstruction *payload_ptr = ir_build_switch_var(irb, scope, var_symbol_node, target_value_ptr, |
| 6494 | 7071 | prong_values, prong_values_len); |
| 6495 | | var_value = var_is_ptr ? var_ptr_value : ir_build_load_ptr(irb, scope, var_symbol_node, var_ptr_value); |
| 7072 | var_ptr = var_is_ptr ? ir_build_ref(irb, scope, var_symbol_node, payload_ptr, true, false) : payload_ptr; |
| 6496 | 7073 | } else { |
| 6497 | | var_value = var_is_ptr ? target_value_ptr : ir_build_load_ptr(irb, scope, var_symbol_node, |
| 6498 | | 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; |
| 6499 | 7076 | } |
| 6500 | | IrInstruction *var_type = nullptr; // infer the type |
| 6501 | | 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); |
| 6502 | 7078 | } else { |
| 6503 | 7079 | child_scope = scope; |
| 6504 | 7080 | } |
| 6505 | 7081 | |
| 6506 | | IrInstruction *expr_result = ir_gen_node(irb, expr_node, child_scope); |
| 7082 | IrInstruction *expr_result = ir_gen_node_extra(irb, expr_node, child_scope, lval, result_loc); |
| 6507 | 7083 | if (expr_result == irb->codegen->invalid_instruction) |
| 6508 | 7084 | return false; |
| 6509 | 7085 | if (!instr_is_unreachable(expr_result)) |
| ... | ... | @@ -6513,11 +7089,13 @@ target_value_ptr); |
| 6513 | 7089 | return true; |
| 6514 | 7090 | } |
| 6515 | 7091 | |
| 6516 | | static IrInstruction *ir_gen_switch_expr(IrBuilder *irb, Scope *scope, AstNode *node) { |
| 7092 | static IrInstruction *ir_gen_switch_expr(IrBuilder *irb, Scope *scope, AstNode *node, LVal lval, |
| 7093 | ResultLoc *result_loc) |
| 7094 | { |
| 6517 | 7095 | assert(node->type == NodeTypeSwitchExpr); |
| 6518 | 7096 | |
| 6519 | 7097 | AstNode *target_node = node->data.switch_expr.expr; |
| 6520 | | IrInstruction *target_value_ptr = ir_gen_node_extra(irb, target_node, scope, LValPtr); |
| 7098 | IrInstruction *target_value_ptr = ir_gen_node_extra(irb, target_node, scope, LValPtr, nullptr); |
| 6521 | 7099 | if (target_value_ptr == irb->codegen->invalid_instruction) |
| 6522 | 7100 | return target_value_ptr; |
| 6523 | 7101 | IrInstruction *target_value = ir_build_switch_target(irb, scope, node, target_value_ptr); |
| ... | ... | @@ -6544,6 +7122,14 @@ static IrInstruction *ir_gen_switch_expr(IrBuilder *irb, Scope *scope, AstNode * |
| 6544 | 7122 | |
| 6545 | 7123 | IrInstructionSwitchElseVar *switch_else_var = nullptr; |
| 6546 | 7124 | |
| 7125 | ResultLocPeerParent *peer_parent = allocate<ResultLocPeerParent>(1); |
| 7126 | peer_parent->base.id = ResultLocIdPeerParent; |
| 7127 | peer_parent->end_bb = end_block; |
| 7128 | peer_parent->is_comptime = is_comptime; |
| 7129 | peer_parent->parent = result_loc; |
| 7130 | |
| 7131 | ir_build_reset_result(irb, scope, node, &peer_parent->base); |
| 7132 | |
| 6547 | 7133 | // First do the else and the ranges |
| 6548 | 7134 | Scope *subexpr_scope = create_runtime_scope(irb->codegen, node, scope, is_comptime); |
| 6549 | 7135 | Scope *comptime_scope = create_comptime_scope(irb->codegen, node, scope); |
| ... | ... | @@ -6552,6 +7138,7 @@ static IrInstruction *ir_gen_switch_expr(IrBuilder *irb, Scope *scope, AstNode * |
| 6552 | 7138 | AstNode *prong_node = node->data.switch_expr.prongs.at(prong_i); |
| 6553 | 7139 | size_t prong_item_count = prong_node->data.switch_prong.items.length; |
| 6554 | 7140 | if (prong_item_count == 0) { |
| 7141 | ResultLocPeer *this_peer_result_loc = create_peer_result(peer_parent); |
| 6555 | 7142 | if (else_prong) { |
| 6556 | 7143 | ErrorMsg *msg = add_node_error(irb->codegen, prong_node, |
| 6557 | 7144 | buf_sprintf("multiple else prongs in switch expression")); |
| ... | ... | @@ -6562,15 +7149,21 @@ static IrInstruction *ir_gen_switch_expr(IrBuilder *irb, Scope *scope, AstNode * |
| 6562 | 7149 | else_prong = prong_node; |
| 6563 | 7150 | |
| 6564 | 7151 | IrBasicBlock *prev_block = irb->current_basic_block; |
| 7152 | if (peer_parent->peers.length > 0) { |
| 7153 | peer_parent->peers.last()->next_bb = else_block; |
| 7154 | } |
| 7155 | peer_parent->peers.append(this_peer_result_loc); |
| 6565 | 7156 | ir_set_cursor_at_end_and_append_block(irb, else_block); |
| 6566 | 7157 | if (!ir_gen_switch_prong_expr(irb, subexpr_scope, node, prong_node, end_block, |
| 6567 | 7158 | is_comptime, var_is_comptime, target_value_ptr, nullptr, 0, &incoming_blocks, &incoming_values, |
| 6568 | | &switch_else_var)) |
| 7159 | &switch_else_var, lval, &this_peer_result_loc->base)) |
| 6569 | 7160 | { |
| 6570 | 7161 | return irb->codegen->invalid_instruction; |
| 6571 | 7162 | } |
| 6572 | 7163 | ir_set_cursor_at_end(irb, prev_block); |
| 6573 | 7164 | } else if (prong_node->data.switch_prong.any_items_are_range) { |
| 7165 | ResultLocPeer *this_peer_result_loc = create_peer_result(peer_parent); |
| 7166 | |
| 6574 | 7167 | IrInstruction *ok_bit = nullptr; |
| 6575 | 7168 | AstNode *last_item_node = nullptr; |
| 6576 | 7169 | for (size_t item_i = 0; item_i < prong_item_count; item_i += 1) { |
| ... | ... | @@ -6627,13 +7220,20 @@ static IrInstruction *ir_gen_switch_expr(IrBuilder *irb, Scope *scope, AstNode * |
| 6627 | 7220 | |
| 6628 | 7221 | assert(ok_bit); |
| 6629 | 7222 | assert(last_item_node); |
| 6630 | | ir_mark_gen(ir_build_cond_br(irb, scope, last_item_node, ok_bit, range_block_yes, |
| 6631 | | 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 | } |
| 6632 | 7228 | |
| 7229 | if (peer_parent->peers.length > 0) { |
| 7230 | peer_parent->peers.last()->next_bb = range_block_yes; |
| 7231 | } |
| 7232 | peer_parent->peers.append(this_peer_result_loc); |
| 6633 | 7233 | ir_set_cursor_at_end_and_append_block(irb, range_block_yes); |
| 6634 | 7234 | if (!ir_gen_switch_prong_expr(irb, subexpr_scope, node, prong_node, end_block, |
| 6635 | 7235 | is_comptime, var_is_comptime, target_value_ptr, nullptr, 0, |
| 6636 | | &incoming_blocks, &incoming_values, nullptr)) |
| 7236 | &incoming_blocks, &incoming_values, nullptr, lval, &this_peer_result_loc->base)) |
| 6637 | 7237 | { |
| 6638 | 7238 | return irb->codegen->invalid_instruction; |
| 6639 | 7239 | } |
| ... | ... | @@ -6651,6 +7251,8 @@ static IrInstruction *ir_gen_switch_expr(IrBuilder *irb, Scope *scope, AstNode * |
| 6651 | 7251 | if (prong_node->data.switch_prong.any_items_are_range) |
| 6652 | 7252 | continue; |
| 6653 | 7253 | |
| 7254 | ResultLocPeer *this_peer_result_loc = create_peer_result(peer_parent); |
| 7255 | |
| 6654 | 7256 | IrBasicBlock *prong_block = ir_create_basic_block(irb, scope, "SwitchProng"); |
| 6655 | 7257 | IrInstruction **items = allocate<IrInstruction *>(prong_item_count); |
| 6656 | 7258 | |
| ... | ... | @@ -6674,10 +7276,14 @@ static IrInstruction *ir_gen_switch_expr(IrBuilder *irb, Scope *scope, AstNode * |
| 6674 | 7276 | } |
| 6675 | 7277 | |
| 6676 | 7278 | IrBasicBlock *prev_block = irb->current_basic_block; |
| 7279 | if (peer_parent->peers.length > 0) { |
| 7280 | peer_parent->peers.last()->next_bb = prong_block; |
| 7281 | } |
| 7282 | peer_parent->peers.append(this_peer_result_loc); |
| 6677 | 7283 | ir_set_cursor_at_end_and_append_block(irb, prong_block); |
| 6678 | 7284 | if (!ir_gen_switch_prong_expr(irb, subexpr_scope, node, prong_node, end_block, |
| 6679 | 7285 | is_comptime, var_is_comptime, target_value_ptr, items, prong_item_count, |
| 6680 | | &incoming_blocks, &incoming_values, nullptr)) |
| 7286 | &incoming_blocks, &incoming_values, nullptr, lval, &this_peer_result_loc->base)) |
| 6681 | 7287 | { |
| 6682 | 7288 | return irb->codegen->invalid_instruction; |
| 6683 | 7289 | } |
| ... | ... | @@ -6686,38 +7292,57 @@ static IrInstruction *ir_gen_switch_expr(IrBuilder *irb, Scope *scope, AstNode * |
| 6686 | 7292 | |
| 6687 | 7293 | } |
| 6688 | 7294 | |
| 6689 | | IrInstruction *switch_prongs_void = ir_build_check_switch_prongs(irb, scope, node, target_value, check_ranges.items, check_ranges.length, |
| 6690 | | 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); |
| 6691 | 7297 | |
| 7298 | IrInstruction *br_instruction; |
| 6692 | 7299 | if (cases.length == 0) { |
| 6693 | | ir_build_br(irb, scope, node, else_block, is_comptime); |
| 7300 | br_instruction = ir_build_br(irb, scope, node, else_block, is_comptime); |
| 6694 | 7301 | } else { |
| 6695 | 7302 | IrInstructionSwitchBr *switch_br = ir_build_switch_br(irb, scope, node, target_value, else_block, |
| 6696 | 7303 | cases.length, cases.items, is_comptime, switch_prongs_void); |
| 6697 | 7304 | if (switch_else_var != nullptr) { |
| 6698 | 7305 | switch_else_var->switch_br = switch_br; |
| 6699 | 7306 | } |
| 7307 | br_instruction = &switch_br->base; |
| 7308 | } |
| 7309 | if (peer_parent->base.source_instruction == nullptr) { |
| 7310 | peer_parent->base.source_instruction = br_instruction; |
| 7311 | } |
| 7312 | for (size_t i = 0; i < peer_parent->peers.length; i += 1) { |
| 7313 | peer_parent->peers.at(i)->base.source_instruction = peer_parent->base.source_instruction; |
| 6700 | 7314 | } |
| 6701 | 7315 | |
| 6702 | 7316 | if (!else_prong) { |
| 7317 | if (peer_parent->peers.length != 0) { |
| 7318 | peer_parent->peers.last()->next_bb = else_block; |
| 7319 | } |
| 6703 | 7320 | ir_set_cursor_at_end_and_append_block(irb, else_block); |
| 6704 | 7321 | ir_build_unreachable(irb, scope, node); |
| 7322 | } else { |
| 7323 | if (peer_parent->peers.length != 0) { |
| 7324 | peer_parent->peers.last()->next_bb = end_block; |
| 7325 | } |
| 6705 | 7326 | } |
| 6706 | 7327 | |
| 6707 | 7328 | ir_set_cursor_at_end_and_append_block(irb, end_block); |
| 6708 | 7329 | assert(incoming_blocks.length == incoming_values.length); |
| 7330 | IrInstruction *result_instruction; |
| 6709 | 7331 | if (incoming_blocks.length == 0) { |
| 6710 | | return ir_build_const_void(irb, scope, node); |
| 7332 | result_instruction = ir_build_const_void(irb, scope, node); |
| 6711 | 7333 | } else { |
| 6712 | | return ir_build_phi(irb, scope, node, incoming_blocks.length, incoming_blocks.items, incoming_values.items); |
| 7334 | result_instruction = ir_build_phi(irb, scope, node, incoming_blocks.length, |
| 7335 | incoming_blocks.items, incoming_values.items, peer_parent); |
| 6713 | 7336 | } |
| 7337 | return ir_expr_wrap(irb, scope, result_instruction, result_loc); |
| 6714 | 7338 | } |
| 6715 | 7339 | |
| 6716 | 7340 | static IrInstruction *ir_gen_comptime(IrBuilder *irb, Scope *parent_scope, AstNode *node, LVal lval) { |
| 6717 | 7341 | assert(node->type == NodeTypeCompTime); |
| 6718 | 7342 | |
| 6719 | 7343 | Scope *child_scope = create_comptime_scope(irb->codegen, node, parent_scope); |
| 6720 | | return ir_gen_node_extra(irb, node->data.comptime_expr.expr, child_scope, lval); |
| 7344 | // purposefully pass null for result_loc and let EndExpr handle it |
| 7345 | return ir_gen_node_extra(irb, node->data.comptime_expr.expr, child_scope, lval, nullptr); |
| 6721 | 7346 | } |
| 6722 | 7347 | |
| 6723 | 7348 | static IrInstruction *ir_gen_return_from_block(IrBuilder *irb, Scope *break_scope, AstNode *node, ScopeBlock *block_scope) { |
| ... | ... | @@ -6730,7 +7355,11 @@ static IrInstruction *ir_gen_return_from_block(IrBuilder *irb, Scope *break_scop |
| 6730 | 7355 | |
| 6731 | 7356 | IrInstruction *result_value; |
| 6732 | 7357 | if (node->data.break_expr.expr) { |
| 6733 | | result_value = ir_gen_node(irb, node->data.break_expr.expr, break_scope); |
| 7358 | ResultLocPeer *peer_result = create_peer_result(block_scope->peer_parent); |
| 7359 | block_scope->peer_parent->peers.append(peer_result); |
| 7360 | |
| 7361 | result_value = ir_gen_node_extra(irb, node->data.break_expr.expr, break_scope, block_scope->lval, |
| 7362 | &peer_result->base); |
| 6734 | 7363 | if (result_value == irb->codegen->invalid_instruction) |
| 6735 | 7364 | return irb->codegen->invalid_instruction; |
| 6736 | 7365 | } else { |
| ... | ... | @@ -6800,7 +7429,11 @@ static IrInstruction *ir_gen_break(IrBuilder *irb, Scope *break_scope, AstNode * |
| 6800 | 7429 | |
| 6801 | 7430 | IrInstruction *result_value; |
| 6802 | 7431 | if (node->data.break_expr.expr) { |
| 6803 | | result_value = ir_gen_node(irb, node->data.break_expr.expr, break_scope); |
| 7432 | ResultLocPeer *peer_result = create_peer_result(loop_scope->peer_parent); |
| 7433 | loop_scope->peer_parent->peers.append(peer_result); |
| 7434 | |
| 7435 | result_value = ir_gen_node_extra(irb, node->data.break_expr.expr, break_scope, |
| 7436 | loop_scope->lval, &peer_result->base); |
| 6804 | 7437 | if (result_value == irb->codegen->invalid_instruction) |
| 6805 | 7438 | return irb->codegen->invalid_instruction; |
| 6806 | 7439 | } else { |
| ... | ... | @@ -6888,7 +7521,7 @@ static IrInstruction *ir_gen_defer(IrBuilder *irb, Scope *parent_scope, AstNode |
| 6888 | 7521 | return ir_build_const_void(irb, parent_scope, node); |
| 6889 | 7522 | } |
| 6890 | 7523 | |
| 6891 | | static IrInstruction *ir_gen_slice(IrBuilder *irb, Scope *scope, AstNode *node) { |
| 7524 | static IrInstruction *ir_gen_slice(IrBuilder *irb, Scope *scope, AstNode *node, LVal lval, ResultLoc *result_loc) { |
| 6892 | 7525 | assert(node->type == NodeTypeSliceExpr); |
| 6893 | 7526 | |
| 6894 | 7527 | AstNodeSliceExpr *slice_expr = &node->data.slice_expr; |
| ... | ... | @@ -6896,7 +7529,7 @@ static IrInstruction *ir_gen_slice(IrBuilder *irb, Scope *scope, AstNode *node) |
| 6896 | 7529 | AstNode *start_node = slice_expr->start; |
| 6897 | 7530 | AstNode *end_node = slice_expr->end; |
| 6898 | 7531 | |
| 6899 | | IrInstruction *ptr_value = ir_gen_node_extra(irb, array_node, scope, LValPtr); |
| 7532 | IrInstruction *ptr_value = ir_gen_node_extra(irb, array_node, scope, LValPtr, nullptr); |
| 6900 | 7533 | if (ptr_value == irb->codegen->invalid_instruction) |
| 6901 | 7534 | return irb->codegen->invalid_instruction; |
| 6902 | 7535 | |
| ... | ... | @@ -6913,11 +7546,14 @@ static IrInstruction *ir_gen_slice(IrBuilder *irb, Scope *scope, AstNode *node) |
| 6913 | 7546 | end_value = nullptr; |
| 6914 | 7547 | } |
| 6915 | 7548 | |
| 6916 | | return ir_build_slice(irb, scope, node, ptr_value, start_value, end_value, true); |
| 7549 | IrInstruction *slice = ir_build_slice_src(irb, scope, node, ptr_value, start_value, end_value, true, result_loc); |
| 7550 | return ir_lval_wrap(irb, scope, slice, lval, result_loc); |
| 6917 | 7551 | } |
| 6918 | 7552 | |
| 6919 | | static IrInstruction *ir_gen_catch(IrBuilder *irb, Scope *parent_scope, AstNode *node) { |
| 6920 | | 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); |
| 6921 | 7557 | |
| 6922 | 7558 | AstNode *op1_node = node->data.unwrap_err_expr.op1; |
| 6923 | 7559 | AstNode *op2_node = node->data.unwrap_err_expr.op2; |
| ... | ... | @@ -6930,16 +7566,15 @@ static IrInstruction *ir_gen_catch(IrBuilder *irb, Scope *parent_scope, AstNode |
| 6930 | 7566 | add_node_error(irb->codegen, var_node, buf_sprintf("unused variable: '%s'", buf_ptr(var_name))); |
| 6931 | 7567 | return irb->codegen->invalid_instruction; |
| 6932 | 7568 | } |
| 6933 | | return ir_gen_catch_unreachable(irb, parent_scope, node, op1_node, LValNone); |
| 7569 | return ir_gen_catch_unreachable(irb, parent_scope, node, op1_node, lval, result_loc); |
| 6934 | 7570 | } |
| 6935 | 7571 | |
| 6936 | 7572 | |
| 6937 | | IrInstruction *err_union_ptr = ir_gen_node_extra(irb, op1_node, parent_scope, LValPtr); |
| 7573 | IrInstruction *err_union_ptr = ir_gen_node_extra(irb, op1_node, parent_scope, LValPtr, nullptr); |
| 6938 | 7574 | if (err_union_ptr == irb->codegen->invalid_instruction) |
| 6939 | 7575 | return irb->codegen->invalid_instruction; |
| 6940 | 7576 | |
| 6941 | | IrInstruction *err_union_val = ir_build_load_ptr(irb, parent_scope, node, err_union_ptr); |
| 6942 | | 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); |
| 6943 | 7578 | |
| 6944 | 7579 | IrInstruction *is_comptime; |
| 6945 | 7580 | if (ir_should_inline(irb->exec, parent_scope)) { |
| ... | ... | @@ -6951,7 +7586,10 @@ static IrInstruction *ir_gen_catch(IrBuilder *irb, Scope *parent_scope, AstNode |
| 6951 | 7586 | IrBasicBlock *ok_block = ir_create_basic_block(irb, parent_scope, "UnwrapErrOk"); |
| 6952 | 7587 | IrBasicBlock *err_block = ir_create_basic_block(irb, parent_scope, "UnwrapErrError"); |
| 6953 | 7588 | IrBasicBlock *end_block = ir_create_basic_block(irb, parent_scope, "UnwrapErrEnd"); |
| 6954 | | ir_build_cond_br(irb, parent_scope, node, is_err, err_block, ok_block, is_comptime); |
| 7589 | IrInstruction *cond_br_inst = ir_build_cond_br(irb, parent_scope, node, is_err, err_block, ok_block, is_comptime); |
| 7590 | |
| 7591 | ResultLocPeerParent *peer_parent = ir_build_binary_result_peers(irb, cond_br_inst, ok_block, end_block, result_loc, |
| 7592 | is_comptime); |
| 6955 | 7593 | |
| 6956 | 7594 | ir_set_cursor_at_end_and_append_block(irb, err_block); |
| 6957 | 7595 | Scope *err_scope; |
| ... | ... | @@ -6963,12 +7601,12 @@ static IrInstruction *ir_gen_catch(IrBuilder *irb, Scope *parent_scope, AstNode |
| 6963 | 7601 | ZigVar *var = ir_create_var(irb, node, parent_scope, var_name, |
| 6964 | 7602 | is_const, is_const, is_shadowable, is_comptime); |
| 6965 | 7603 | err_scope = var->child_scope; |
| 6966 | | IrInstruction *err_val = ir_build_unwrap_err_code(irb, err_scope, node, err_union_ptr); |
| 6967 | | ir_build_var_decl_src(irb, err_scope, var_node, var, nullptr, nullptr, err_val); |
| 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); |
| 6968 | 7606 | } else { |
| 6969 | 7607 | err_scope = parent_scope; |
| 6970 | 7608 | } |
| 6971 | | IrInstruction *err_result = ir_gen_node(irb, op2_node, err_scope); |
| 7609 | IrInstruction *err_result = ir_gen_node_extra(irb, op2_node, err_scope, LValNone, &peer_parent->peers.at(0)->base); |
| 6972 | 7610 | if (err_result == irb->codegen->invalid_instruction) |
| 6973 | 7611 | return irb->codegen->invalid_instruction; |
| 6974 | 7612 | IrBasicBlock *after_err_block = irb->current_basic_block; |
| ... | ... | @@ -6976,8 +7614,9 @@ static IrInstruction *ir_gen_catch(IrBuilder *irb, Scope *parent_scope, AstNode |
| 6976 | 7614 | ir_mark_gen(ir_build_br(irb, err_scope, node, end_block, is_comptime)); |
| 6977 | 7615 | |
| 6978 | 7616 | ir_set_cursor_at_end_and_append_block(irb, ok_block); |
| 6979 | | IrInstruction *unwrapped_ptr = ir_build_unwrap_err_payload(irb, parent_scope, node, err_union_ptr, false); |
| 7617 | IrInstruction *unwrapped_ptr = ir_build_unwrap_err_payload(irb, parent_scope, node, err_union_ptr, false, false); |
| 6980 | 7618 | IrInstruction *unwrapped_payload = ir_build_load_ptr(irb, parent_scope, node, unwrapped_ptr); |
| 7619 | ir_build_end_expr(irb, parent_scope, node, unwrapped_payload, &peer_parent->peers.at(1)->base); |
| 6981 | 7620 | IrBasicBlock *after_ok_block = irb->current_basic_block; |
| 6982 | 7621 | ir_build_br(irb, parent_scope, node, end_block, is_comptime); |
| 6983 | 7622 | |
| ... | ... | @@ -6988,7 +7627,8 @@ static IrInstruction *ir_gen_catch(IrBuilder *irb, Scope *parent_scope, AstNode |
| 6988 | 7627 | IrBasicBlock **incoming_blocks = allocate<IrBasicBlock *>(2); |
| 6989 | 7628 | incoming_blocks[0] = after_err_block; |
| 6990 | 7629 | incoming_blocks[1] = after_ok_block; |
| 6991 | | return ir_build_phi(irb, parent_scope, node, 2, incoming_blocks, incoming_values); |
| 7630 | IrInstruction *phi = ir_build_phi(irb, parent_scope, node, 2, incoming_blocks, incoming_values, peer_parent); |
| 7631 | return ir_lval_wrap(irb, parent_scope, phi, lval, result_loc); |
| 6992 | 7632 | } |
| 6993 | 7633 | |
| 6994 | 7634 | static bool render_instance_name_recursive(CodeGen *codegen, Buf *name, Scope *outer_scope, Scope *inner_scope) { |
| ... | ... | @@ -7264,7 +7904,7 @@ static IrInstruction *ir_gen_cancel_target(IrBuilder *irb, Scope *scope, AstNode |
| 7264 | 7904 | IrInstruction *coro_promise_ptr = ir_build_coro_promise(irb, scope, node, casted_target_inst); |
| 7265 | 7905 | Buf *atomic_state_field_name = buf_create_from_str(ATOMIC_STATE_FIELD_NAME); |
| 7266 | 7906 | IrInstruction *atomic_state_ptr = ir_build_field_ptr(irb, scope, node, coro_promise_ptr, |
| 7267 | | atomic_state_field_name); |
| 7907 | atomic_state_field_name, false); |
| 7268 | 7908 | |
| 7269 | 7909 | // set the is_canceled bit |
| 7270 | 7910 | IrInstruction *prev_atomic_value = ir_build_atomic_rmw(irb, scope, node, |
| ... | ... | @@ -7343,7 +7983,7 @@ static IrInstruction *ir_gen_resume_target(IrBuilder *irb, Scope *scope, AstNode |
| 7343 | 7983 | IrInstruction *coro_promise_ptr = ir_build_coro_promise(irb, scope, node, casted_target_inst); |
| 7344 | 7984 | Buf *atomic_state_field_name = buf_create_from_str(ATOMIC_STATE_FIELD_NAME); |
| 7345 | 7985 | IrInstruction *atomic_state_ptr = ir_build_field_ptr(irb, scope, node, coro_promise_ptr, |
| 7346 | | atomic_state_field_name); |
| 7986 | atomic_state_field_name, false); |
| 7347 | 7987 | |
| 7348 | 7988 | // clear the is_suspended bit |
| 7349 | 7989 | IrInstruction *prev_atomic_value = ir_build_atomic_rmw(irb, scope, node, |
| ... | ... | @@ -7410,12 +8050,12 @@ static IrInstruction *ir_gen_await_expr(IrBuilder *irb, Scope *scope, AstNode *n |
| 7410 | 8050 | |
| 7411 | 8051 | IrInstruction *coro_promise_ptr = ir_build_coro_promise(irb, scope, node, target_inst); |
| 7412 | 8052 | Buf *result_ptr_field_name = buf_create_from_str(RESULT_PTR_FIELD_NAME); |
| 7413 | | IrInstruction *result_ptr_field_ptr = ir_build_field_ptr(irb, scope, node, coro_promise_ptr, result_ptr_field_name); |
| 8053 | IrInstruction *result_ptr_field_ptr = ir_build_field_ptr(irb, scope, node, coro_promise_ptr, result_ptr_field_name, false); |
| 7414 | 8054 | |
| 7415 | 8055 | if (irb->codegen->have_err_ret_tracing) { |
| 7416 | 8056 | IrInstruction *err_ret_trace_ptr = ir_build_error_return_trace(irb, scope, node, IrInstructionErrorReturnTrace::NonNull); |
| 7417 | 8057 | Buf *err_ret_trace_ptr_field_name = buf_create_from_str(ERR_RET_TRACE_PTR_FIELD_NAME); |
| 7418 | | IrInstruction *err_ret_trace_ptr_field_ptr = ir_build_field_ptr(irb, scope, node, coro_promise_ptr, err_ret_trace_ptr_field_name); |
| 8058 | IrInstruction *err_ret_trace_ptr_field_ptr = ir_build_field_ptr(irb, scope, node, coro_promise_ptr, err_ret_trace_ptr_field_name, false); |
| 7419 | 8059 | ir_build_store_ptr(irb, scope, node, err_ret_trace_ptr_field_ptr, err_ret_trace_ptr); |
| 7420 | 8060 | } |
| 7421 | 8061 | |
| ... | ... | @@ -7437,11 +8077,11 @@ static IrInstruction *ir_gen_await_expr(IrBuilder *irb, Scope *scope, AstNode *n |
| 7437 | 8077 | |
| 7438 | 8078 | Buf *atomic_state_field_name = buf_create_from_str(ATOMIC_STATE_FIELD_NAME); |
| 7439 | 8079 | IrInstruction *atomic_state_ptr = ir_build_field_ptr(irb, scope, node, coro_promise_ptr, |
| 7440 | | atomic_state_field_name); |
| 8080 | atomic_state_field_name, false); |
| 7441 | 8081 | |
| 7442 | 8082 | IrInstruction *promise_type_val = ir_build_const_type(irb, scope, node, irb->codegen->builtin_types.entry_promise); |
| 7443 | 8083 | IrInstruction *const_bool_false = ir_build_const_bool(irb, scope, node, false); |
| 7444 | | IrInstruction *undefined_value = ir_build_const_undefined(irb, scope, node); |
| 8084 | IrInstruction *undef = ir_build_const_undefined(irb, scope, node); |
| 7445 | 8085 | IrInstruction *usize_type_val = ir_build_const_type(irb, scope, node, irb->codegen->builtin_types.entry_usize); |
| 7446 | 8086 | IrInstruction *zero = ir_build_const_usize(irb, scope, node, 0); |
| 7447 | 8087 | IrInstruction *inverted_ptr_mask = ir_build_const_usize(irb, scope, node, 0x7); // 0b111 |
| ... | ... | @@ -7455,7 +8095,8 @@ static IrInstruction *ir_gen_await_expr(IrBuilder *irb, Scope *scope, AstNode *n |
| 7455 | 8095 | IrInstruction *target_promise_type = ir_build_typeof(irb, scope, node, target_inst); |
| 7456 | 8096 | IrInstruction *promise_result_type = ir_build_promise_result_type(irb, scope, node, target_promise_type); |
| 7457 | 8097 | ir_build_await_bookkeeping(irb, scope, node, promise_result_type); |
| 7458 | | ir_build_var_decl_src(irb, scope, node, result_var, promise_result_type, nullptr, undefined_value); |
| 8098 | IrInstruction *undef_promise_result = ir_build_implicit_cast(irb, scope, node, promise_result_type, undef, nullptr); |
| 8099 | build_decl_var_and_init(irb, scope, node, result_var, undef_promise_result, "result", const_bool_false); |
| 7459 | 8100 | IrInstruction *my_result_var_ptr = ir_build_var_ptr(irb, scope, node, result_var); |
| 7460 | 8101 | ir_build_store_ptr(irb, scope, node, result_ptr_field_ptr, my_result_var_ptr); |
| 7461 | 8102 | IrInstruction *save_token = ir_build_coro_save(irb, scope, node, irb->exec->coro_handle); |
| ... | ... | @@ -7490,12 +8131,12 @@ static IrInstruction *ir_gen_await_expr(IrBuilder *irb, Scope *scope, AstNode *n |
| 7490 | 8131 | ir_set_cursor_at_end_and_append_block(irb, no_suspend_block); |
| 7491 | 8132 | if (irb->codegen->have_err_ret_tracing) { |
| 7492 | 8133 | Buf *err_ret_trace_field_name = buf_create_from_str(ERR_RET_TRACE_FIELD_NAME); |
| 7493 | | IrInstruction *src_err_ret_trace_ptr = ir_build_field_ptr(irb, scope, node, coro_promise_ptr, err_ret_trace_field_name); |
| 8134 | IrInstruction *src_err_ret_trace_ptr = ir_build_field_ptr(irb, scope, node, coro_promise_ptr, err_ret_trace_field_name, false); |
| 7494 | 8135 | IrInstruction *dest_err_ret_trace_ptr = ir_build_error_return_trace(irb, scope, node, IrInstructionErrorReturnTrace::NonNull); |
| 7495 | 8136 | ir_build_merge_err_ret_traces(irb, scope, node, coro_promise_ptr, src_err_ret_trace_ptr, dest_err_ret_trace_ptr); |
| 7496 | 8137 | } |
| 7497 | 8138 | Buf *result_field_name = buf_create_from_str(RESULT_FIELD_NAME); |
| 7498 | | IrInstruction *promise_result_ptr = ir_build_field_ptr(irb, scope, node, coro_promise_ptr, result_field_name); |
| 8139 | IrInstruction *promise_result_ptr = ir_build_field_ptr(irb, scope, node, coro_promise_ptr, result_field_name, false); |
| 7499 | 8140 | // If the type of the result handle_is_ptr then this does not actually perform a load. But we need it to, |
| 7500 | 8141 | // because we're about to destroy the memory. So we store it into our result variable. |
| 7501 | 8142 | IrInstruction *no_suspend_result = ir_build_load_ptr(irb, scope, node, promise_result_ptr); |
| ... | ... | @@ -7671,7 +8312,8 @@ static IrInstruction *ir_gen_suspend(IrBuilder *irb, Scope *parent_scope, AstNod |
| 7671 | 8312 | incoming_values[0] = const_bool_true; |
| 7672 | 8313 | incoming_blocks[1] = post_cancel_awaiter_block; |
| 7673 | 8314 | incoming_values[1] = const_bool_false; |
| 7674 | | IrInstruction *destroy_ourselves = ir_build_phi(irb, parent_scope, node, 2, incoming_blocks, incoming_values); |
| 8315 | IrInstruction *destroy_ourselves = ir_build_phi(irb, parent_scope, node, 2, incoming_blocks, incoming_values, |
| 8316 | nullptr); |
| 7675 | 8317 | ir_gen_defers_for_block(irb, parent_scope, outer_scope, true); |
| 7676 | 8318 | ir_mark_gen(ir_build_cond_br(irb, parent_scope, node, destroy_ourselves, irb->exec->coro_final_cleanup_block, irb->exec->coro_early_final, const_bool_false)); |
| 7677 | 8319 | |
| ... | ... | @@ -7680,7 +8322,7 @@ static IrInstruction *ir_gen_suspend(IrBuilder *irb, Scope *parent_scope, AstNod |
| 7680 | 8322 | } |
| 7681 | 8323 | |
| 7682 | 8324 | static IrInstruction *ir_gen_node_raw(IrBuilder *irb, AstNode *node, Scope *scope, |
| 7683 | | LVal lval) |
| 8325 | LVal lval, ResultLoc *result_loc) |
| 7684 | 8326 | { |
| 7685 | 8327 | assert(scope); |
| 7686 | 8328 | switch (node->type) { |
| ... | ... | @@ -7694,37 +8336,37 @@ static IrInstruction *ir_gen_node_raw(IrBuilder *irb, AstNode *node, Scope *scop |
| 7694 | 8336 | case NodeTypeTestDecl: |
| 7695 | 8337 | zig_unreachable(); |
| 7696 | 8338 | case NodeTypeBlock: |
| 7697 | | return ir_lval_wrap(irb, scope, ir_gen_block(irb, scope, node), lval); |
| 8339 | return ir_gen_block(irb, scope, node, lval, result_loc); |
| 7698 | 8340 | case NodeTypeGroupedExpr: |
| 7699 | | return ir_gen_node_raw(irb, node->data.grouped_expr, scope, lval); |
| 8341 | return ir_gen_node_raw(irb, node->data.grouped_expr, scope, lval, result_loc); |
| 7700 | 8342 | case NodeTypeBinOpExpr: |
| 7701 | | return ir_lval_wrap(irb, scope, ir_gen_bin_op(irb, scope, node), lval); |
| 8343 | return ir_gen_bin_op(irb, scope, node, lval, result_loc); |
| 7702 | 8344 | case NodeTypeIntLiteral: |
| 7703 | | return ir_lval_wrap(irb, scope, ir_gen_int_lit(irb, scope, node), lval); |
| 8345 | return ir_lval_wrap(irb, scope, ir_gen_int_lit(irb, scope, node), lval, result_loc); |
| 7704 | 8346 | case NodeTypeFloatLiteral: |
| 7705 | | return ir_lval_wrap(irb, scope, ir_gen_float_lit(irb, scope, node), lval); |
| 8347 | return ir_lval_wrap(irb, scope, ir_gen_float_lit(irb, scope, node), lval, result_loc); |
| 7706 | 8348 | case NodeTypeCharLiteral: |
| 7707 | | return ir_lval_wrap(irb, scope, ir_gen_char_lit(irb, scope, node), lval); |
| 8349 | return ir_lval_wrap(irb, scope, ir_gen_char_lit(irb, scope, node), lval, result_loc); |
| 7708 | 8350 | case NodeTypeSymbol: |
| 7709 | | return ir_gen_symbol(irb, scope, node, lval); |
| 8351 | return ir_gen_symbol(irb, scope, node, lval, result_loc); |
| 7710 | 8352 | case NodeTypeFnCallExpr: |
| 7711 | | return ir_gen_fn_call(irb, scope, node, lval); |
| 8353 | return ir_gen_fn_call(irb, scope, node, lval, result_loc); |
| 7712 | 8354 | case NodeTypeIfBoolExpr: |
| 7713 | | return ir_lval_wrap(irb, scope, ir_gen_if_bool_expr(irb, scope, node), lval); |
| 8355 | return ir_gen_if_bool_expr(irb, scope, node, lval, result_loc); |
| 7714 | 8356 | case NodeTypePrefixOpExpr: |
| 7715 | | return ir_gen_prefix_op_expr(irb, scope, node, lval); |
| 8357 | return ir_gen_prefix_op_expr(irb, scope, node, lval, result_loc); |
| 7716 | 8358 | case NodeTypeContainerInitExpr: |
| 7717 | | return ir_lval_wrap(irb, scope, ir_gen_container_init_expr(irb, scope, node), lval); |
| 8359 | return ir_gen_container_init_expr(irb, scope, node, lval, result_loc); |
| 7718 | 8360 | case NodeTypeVariableDeclaration: |
| 7719 | | return ir_lval_wrap(irb, scope, ir_gen_var_decl(irb, scope, node), lval); |
| 8361 | return ir_gen_var_decl(irb, scope, node); |
| 7720 | 8362 | case NodeTypeWhileExpr: |
| 7721 | | return ir_lval_wrap(irb, scope, ir_gen_while_expr(irb, scope, node), lval); |
| 8363 | return ir_gen_while_expr(irb, scope, node, lval, result_loc); |
| 7722 | 8364 | case NodeTypeForExpr: |
| 7723 | | return ir_lval_wrap(irb, scope, ir_gen_for_expr(irb, scope, node), lval); |
| 8365 | return ir_gen_for_expr(irb, scope, node, lval, result_loc); |
| 7724 | 8366 | case NodeTypeArrayAccessExpr: |
| 7725 | | return ir_gen_array_access(irb, scope, node, lval); |
| 8367 | return ir_gen_array_access(irb, scope, node, lval, result_loc); |
| 7726 | 8368 | case NodeTypeReturnExpr: |
| 7727 | | return ir_gen_return(irb, scope, node, lval); |
| 8369 | return ir_gen_return(irb, scope, node, lval, result_loc); |
| 7728 | 8370 | case NodeTypeFieldAccessExpr: |
| 7729 | 8371 | { |
| 7730 | 8372 | IrInstruction *ptr_instruction = ir_gen_field_access(irb, scope, node); |
| ... | ... | @@ -7733,86 +8375,89 @@ static IrInstruction *ir_gen_node_raw(IrBuilder *irb, AstNode *node, Scope *scop |
| 7733 | 8375 | if (lval == LValPtr) |
| 7734 | 8376 | return ptr_instruction; |
| 7735 | 8377 | |
| 7736 | | return ir_build_load_ptr(irb, scope, node, ptr_instruction); |
| 8378 | IrInstruction *load_ptr = ir_build_load_ptr(irb, scope, node, ptr_instruction); |
| 8379 | return ir_expr_wrap(irb, scope, load_ptr, result_loc); |
| 7737 | 8380 | } |
| 7738 | 8381 | case NodeTypePtrDeref: { |
| 7739 | 8382 | AstNode *expr_node = node->data.ptr_deref_expr.target; |
| 7740 | | IrInstruction *value = ir_gen_node_extra(irb, expr_node, scope, lval); |
| 8383 | IrInstruction *value = ir_gen_node_extra(irb, expr_node, scope, lval, nullptr); |
| 7741 | 8384 | if (value == irb->codegen->invalid_instruction) |
| 7742 | 8385 | return value; |
| 7743 | 8386 | |
| 7744 | 8387 | // We essentially just converted any lvalue from &(x.*) to (&x).*; |
| 7745 | 8388 | // this inhibits checking that x is a pointer later, so we directly |
| 7746 | 8389 | // record whether the pointer check is needed |
| 7747 | | return ir_build_un_op_lval(irb, scope, node, IrUnOpDereference, value, lval); |
| 8390 | IrInstruction *un_op = ir_build_un_op_lval(irb, scope, node, IrUnOpDereference, value, lval, result_loc); |
| 8391 | return ir_expr_wrap(irb, scope, un_op, result_loc); |
| 7748 | 8392 | } |
| 7749 | 8393 | case NodeTypeUnwrapOptional: { |
| 7750 | 8394 | AstNode *expr_node = node->data.unwrap_optional.expr; |
| 7751 | 8395 | |
| 7752 | | IrInstruction *maybe_ptr = ir_gen_node_extra(irb, expr_node, scope, LValPtr); |
| 8396 | IrInstruction *maybe_ptr = ir_gen_node_extra(irb, expr_node, scope, LValPtr, nullptr); |
| 7753 | 8397 | if (maybe_ptr == irb->codegen->invalid_instruction) |
| 7754 | 8398 | return irb->codegen->invalid_instruction; |
| 7755 | 8399 | |
| 7756 | | IrInstruction *unwrapped_ptr = ir_build_optional_unwrap_ptr(irb, scope, node, maybe_ptr, true); |
| 8400 | IrInstruction *unwrapped_ptr = ir_build_optional_unwrap_ptr(irb, scope, node, maybe_ptr, true, false); |
| 7757 | 8401 | if (lval == LValPtr) |
| 7758 | 8402 | return unwrapped_ptr; |
| 7759 | 8403 | |
| 7760 | | return ir_build_load_ptr(irb, scope, node, unwrapped_ptr); |
| 8404 | IrInstruction *load_ptr = ir_build_load_ptr(irb, scope, node, unwrapped_ptr); |
| 8405 | return ir_expr_wrap(irb, scope, load_ptr, result_loc); |
| 7761 | 8406 | } |
| 7762 | 8407 | case NodeTypeBoolLiteral: |
| 7763 | | return ir_lval_wrap(irb, scope, ir_gen_bool_literal(irb, scope, node), lval); |
| 8408 | return ir_lval_wrap(irb, scope, ir_gen_bool_literal(irb, scope, node), lval, result_loc); |
| 7764 | 8409 | case NodeTypeArrayType: |
| 7765 | | return ir_lval_wrap(irb, scope, ir_gen_array_type(irb, scope, node), lval); |
| 8410 | return ir_lval_wrap(irb, scope, ir_gen_array_type(irb, scope, node), lval, result_loc); |
| 7766 | 8411 | case NodeTypePointerType: |
| 7767 | | return ir_lval_wrap(irb, scope, ir_gen_pointer_type(irb, scope, node), lval); |
| 8412 | return ir_lval_wrap(irb, scope, ir_gen_pointer_type(irb, scope, node), lval, result_loc); |
| 7768 | 8413 | case NodeTypePromiseType: |
| 7769 | | return ir_lval_wrap(irb, scope, ir_gen_promise_type(irb, scope, node), lval); |
| 8414 | return ir_lval_wrap(irb, scope, ir_gen_promise_type(irb, scope, node), lval, result_loc); |
| 7770 | 8415 | case NodeTypeStringLiteral: |
| 7771 | | return ir_lval_wrap(irb, scope, ir_gen_string_literal(irb, scope, node), lval); |
| 8416 | return ir_lval_wrap(irb, scope, ir_gen_string_literal(irb, scope, node), lval, result_loc); |
| 7772 | 8417 | case NodeTypeUndefinedLiteral: |
| 7773 | | return ir_lval_wrap(irb, scope, ir_gen_undefined_literal(irb, scope, node), lval); |
| 8418 | return ir_lval_wrap(irb, scope, ir_gen_undefined_literal(irb, scope, node), lval, result_loc); |
| 7774 | 8419 | case NodeTypeAsmExpr: |
| 7775 | | return ir_lval_wrap(irb, scope, ir_gen_asm_expr(irb, scope, node), lval); |
| 8420 | return ir_lval_wrap(irb, scope, ir_gen_asm_expr(irb, scope, node), lval, result_loc); |
| 7776 | 8421 | case NodeTypeNullLiteral: |
| 7777 | | return ir_lval_wrap(irb, scope, ir_gen_null_literal(irb, scope, node), lval); |
| 8422 | return ir_lval_wrap(irb, scope, ir_gen_null_literal(irb, scope, node), lval, result_loc); |
| 7778 | 8423 | case NodeTypeIfErrorExpr: |
| 7779 | | return ir_lval_wrap(irb, scope, ir_gen_if_err_expr(irb, scope, node), lval); |
| 8424 | return ir_gen_if_err_expr(irb, scope, node, lval, result_loc); |
| 7780 | 8425 | case NodeTypeIfOptional: |
| 7781 | | return ir_lval_wrap(irb, scope, ir_gen_if_optional_expr(irb, scope, node), lval); |
| 8426 | return ir_gen_if_optional_expr(irb, scope, node, lval, result_loc); |
| 7782 | 8427 | case NodeTypeSwitchExpr: |
| 7783 | | return ir_lval_wrap(irb, scope, ir_gen_switch_expr(irb, scope, node), lval); |
| 8428 | return ir_gen_switch_expr(irb, scope, node, lval, result_loc); |
| 7784 | 8429 | case NodeTypeCompTime: |
| 7785 | | return ir_gen_comptime(irb, scope, node, lval); |
| 8430 | return ir_expr_wrap(irb, scope, ir_gen_comptime(irb, scope, node, lval), result_loc); |
| 7786 | 8431 | case NodeTypeErrorType: |
| 7787 | | return ir_lval_wrap(irb, scope, ir_gen_error_type(irb, scope, node), lval); |
| 8432 | return ir_lval_wrap(irb, scope, ir_gen_error_type(irb, scope, node), lval, result_loc); |
| 7788 | 8433 | case NodeTypeBreak: |
| 7789 | | return ir_lval_wrap(irb, scope, ir_gen_break(irb, scope, node), lval); |
| 8434 | return ir_lval_wrap(irb, scope, ir_gen_break(irb, scope, node), lval, result_loc); |
| 7790 | 8435 | case NodeTypeContinue: |
| 7791 | | return ir_lval_wrap(irb, scope, ir_gen_continue(irb, scope, node), lval); |
| 8436 | return ir_lval_wrap(irb, scope, ir_gen_continue(irb, scope, node), lval, result_loc); |
| 7792 | 8437 | case NodeTypeUnreachable: |
| 7793 | | return ir_lval_wrap(irb, scope, ir_build_unreachable(irb, scope, node), lval); |
| 8438 | return ir_build_unreachable(irb, scope, node); |
| 7794 | 8439 | case NodeTypeDefer: |
| 7795 | | return ir_lval_wrap(irb, scope, ir_gen_defer(irb, scope, node), lval); |
| 8440 | return ir_lval_wrap(irb, scope, ir_gen_defer(irb, scope, node), lval, result_loc); |
| 7796 | 8441 | case NodeTypeSliceExpr: |
| 7797 | | return ir_lval_wrap(irb, scope, ir_gen_slice(irb, scope, node), lval); |
| 7798 | | case NodeTypeUnwrapErrorExpr: |
| 7799 | | 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); |
| 7800 | 8445 | case NodeTypeContainerDecl: |
| 7801 | | return ir_lval_wrap(irb, scope, ir_gen_container_decl(irb, scope, node), lval); |
| 8446 | return ir_lval_wrap(irb, scope, ir_gen_container_decl(irb, scope, node), lval, result_loc); |
| 7802 | 8447 | case NodeTypeFnProto: |
| 7803 | | return ir_lval_wrap(irb, scope, ir_gen_fn_proto(irb, scope, node), lval); |
| 8448 | return ir_lval_wrap(irb, scope, ir_gen_fn_proto(irb, scope, node), lval, result_loc); |
| 7804 | 8449 | case NodeTypeErrorSetDecl: |
| 7805 | | return ir_lval_wrap(irb, scope, ir_gen_err_set_decl(irb, scope, node), lval); |
| 8450 | return ir_lval_wrap(irb, scope, ir_gen_err_set_decl(irb, scope, node), lval, result_loc); |
| 7806 | 8451 | case NodeTypeCancel: |
| 7807 | | return ir_lval_wrap(irb, scope, ir_gen_cancel(irb, scope, node), lval); |
| 8452 | return ir_lval_wrap(irb, scope, ir_gen_cancel(irb, scope, node), lval, result_loc); |
| 7808 | 8453 | case NodeTypeResume: |
| 7809 | | return ir_lval_wrap(irb, scope, ir_gen_resume(irb, scope, node), lval); |
| 8454 | return ir_lval_wrap(irb, scope, ir_gen_resume(irb, scope, node), lval, result_loc); |
| 7810 | 8455 | case NodeTypeAwaitExpr: |
| 7811 | | return ir_lval_wrap(irb, scope, ir_gen_await_expr(irb, scope, node), lval); |
| 8456 | return ir_lval_wrap(irb, scope, ir_gen_await_expr(irb, scope, node), lval, result_loc); |
| 7812 | 8457 | case NodeTypeSuspend: |
| 7813 | | return ir_lval_wrap(irb, scope, ir_gen_suspend(irb, scope, node), lval); |
| 8458 | return ir_lval_wrap(irb, scope, ir_gen_suspend(irb, scope, node), lval, result_loc); |
| 7814 | 8459 | case NodeTypeEnumLiteral: |
| 7815 | | return ir_lval_wrap(irb, scope, ir_gen_enum_literal(irb, scope, node), lval); |
| 8460 | return ir_lval_wrap(irb, scope, ir_gen_enum_literal(irb, scope, node), lval, result_loc); |
| 7816 | 8461 | case NodeTypeInferredArrayType: |
| 7817 | 8462 | add_node_error(irb->codegen, node, |
| 7818 | 8463 | buf_sprintf("inferred array size invalid here")); |
| ... | ... | @@ -7821,14 +8466,28 @@ static IrInstruction *ir_gen_node_raw(IrBuilder *irb, AstNode *node, Scope *scop |
| 7821 | 8466 | zig_unreachable(); |
| 7822 | 8467 | } |
| 7823 | 8468 | |
| 7824 | | static IrInstruction *ir_gen_node_extra(IrBuilder *irb, AstNode *node, Scope *scope, LVal lval) { |
| 7825 | | 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); |
| 7826 | 8485 | irb->exec->invalid = irb->exec->invalid || (result == irb->codegen->invalid_instruction); |
| 7827 | 8486 | return result; |
| 7828 | 8487 | } |
| 7829 | 8488 | |
| 7830 | 8489 | static IrInstruction *ir_gen_node(IrBuilder *irb, AstNode *node, Scope *scope) { |
| 7831 | | return ir_gen_node_extra(irb, node, scope, LValNone); |
| 8490 | return ir_gen_node_extra(irb, node, scope, LValNone, nullptr); |
| 7832 | 8491 | } |
| 7833 | 8492 | |
| 7834 | 8493 | static void invalidate_exec(IrExecutable *exec) { |
| ... | ... | @@ -7879,17 +8538,19 @@ bool ir_gen(CodeGen *codegen, AstNode *node, Scope *scope, IrExecutable *ir_exec |
| 7879 | 8538 | |
| 7880 | 8539 | return_type = fn_entry->type_entry->data.fn.fn_type_id.return_type; |
| 7881 | 8540 | IrInstruction *undef = ir_build_const_undefined(irb, coro_scope, node); |
| 8541 | // TODO mark this var decl as "no safety" e.g. disable initializing the undef value to 0xaa |
| 7882 | 8542 | ZigType *coro_frame_type = get_promise_frame_type(irb->codegen, return_type); |
| 7883 | 8543 | IrInstruction *coro_frame_type_value = ir_build_const_type(irb, coro_scope, node, coro_frame_type); |
| 7884 | | // TODO mark this var decl as "no safety" e.g. disable initializing the undef value to 0xaa |
| 7885 | | 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); |
| 7886 | 8546 | coro_promise_ptr = ir_build_var_ptr(irb, coro_scope, node, promise_var); |
| 7887 | 8547 | |
| 7888 | 8548 | ZigVar *await_handle_var = ir_create_var(irb, node, coro_scope, nullptr, false, false, true, const_bool_false); |
| 7889 | 8549 | IrInstruction *null_value = ir_build_const_null(irb, coro_scope, node); |
| 7890 | 8550 | IrInstruction *await_handle_type_val = ir_build_const_type(irb, coro_scope, node, |
| 7891 | 8551 | get_optional_type(irb->codegen, irb->codegen->builtin_types.entry_promise)); |
| 7892 | | ir_build_var_decl_src(irb, coro_scope, node, await_handle_var, await_handle_type_val, nullptr, null_value); |
| 8552 | IrInstruction *null_await_handle = ir_build_implicit_cast(irb, coro_scope, node, await_handle_type_val, null_value, nullptr); |
| 8553 | build_decl_var_and_init(irb, coro_scope, node, await_handle_var, null_await_handle, "await_handle", const_bool_false); |
| 7893 | 8554 | irb->exec->await_handle_var_ptr = ir_build_var_ptr(irb, coro_scope, node, await_handle_var); |
| 7894 | 8555 | |
| 7895 | 8556 | u8_ptr_type = ir_build_const_type(irb, coro_scope, node, |
| ... | ... | @@ -7899,13 +8560,14 @@ bool ir_gen(CodeGen *codegen, AstNode *node, Scope *scope, IrExecutable *ir_exec |
| 7899 | 8560 | coro_id = ir_build_coro_id(irb, coro_scope, node, promise_as_u8_ptr); |
| 7900 | 8561 | coro_size_var = ir_create_var(irb, node, coro_scope, nullptr, false, false, true, const_bool_false); |
| 7901 | 8562 | IrInstruction *coro_size = ir_build_coro_size(irb, coro_scope, node); |
| 7902 | | ir_build_var_decl_src(irb, coro_scope, node, coro_size_var, nullptr, nullptr, coro_size); |
| 8563 | build_decl_var_and_init(irb, coro_scope, node, coro_size_var, coro_size, "coro_size", const_bool_false); |
| 7903 | 8564 | IrInstruction *implicit_allocator_ptr = ir_build_get_implicit_allocator(irb, coro_scope, node, |
| 7904 | 8565 | ImplicitAllocatorIdArg); |
| 7905 | 8566 | irb->exec->coro_allocator_var = ir_create_var(irb, node, coro_scope, nullptr, true, true, true, const_bool_false); |
| 7906 | | ir_build_var_decl_src(irb, coro_scope, node, irb->exec->coro_allocator_var, nullptr, nullptr, implicit_allocator_ptr); |
| 8567 | build_decl_var_and_init(irb, coro_scope, node, irb->exec->coro_allocator_var, implicit_allocator_ptr, |
| 8568 | "allocator", const_bool_false); |
| 7907 | 8569 | Buf *realloc_field_name = buf_create_from_str(ASYNC_REALLOC_FIELD_NAME); |
| 7908 | | IrInstruction *realloc_fn_ptr = ir_build_field_ptr(irb, coro_scope, node, implicit_allocator_ptr, realloc_field_name); |
| 8570 | IrInstruction *realloc_fn_ptr = ir_build_field_ptr(irb, coro_scope, node, implicit_allocator_ptr, realloc_field_name, false); |
| 7909 | 8571 | IrInstruction *realloc_fn = ir_build_load_ptr(irb, coro_scope, node, realloc_fn_ptr); |
| 7910 | 8572 | IrInstruction *maybe_coro_mem_ptr = ir_build_coro_alloc_helper(irb, coro_scope, node, realloc_fn, coro_size); |
| 7911 | 8573 | IrInstruction *alloc_result_is_ok = ir_build_test_nonnull(irb, coro_scope, node, maybe_coro_mem_ptr); |
| ... | ... | @@ -7925,32 +8587,32 @@ bool ir_gen(CodeGen *codegen, AstNode *node, Scope *scope, IrExecutable *ir_exec |
| 7925 | 8587 | |
| 7926 | 8588 | Buf *atomic_state_field_name = buf_create_from_str(ATOMIC_STATE_FIELD_NAME); |
| 7927 | 8589 | irb->exec->atomic_state_field_ptr = ir_build_field_ptr(irb, scope, node, coro_promise_ptr, |
| 7928 | | atomic_state_field_name); |
| 8590 | atomic_state_field_name, false); |
| 7929 | 8591 | IrInstruction *zero = ir_build_const_usize(irb, scope, node, 0); |
| 7930 | 8592 | ir_build_store_ptr(irb, scope, node, irb->exec->atomic_state_field_ptr, zero); |
| 7931 | 8593 | Buf *result_field_name = buf_create_from_str(RESULT_FIELD_NAME); |
| 7932 | | irb->exec->coro_result_field_ptr = ir_build_field_ptr(irb, scope, node, coro_promise_ptr, result_field_name); |
| 8594 | irb->exec->coro_result_field_ptr = ir_build_field_ptr(irb, scope, node, coro_promise_ptr, result_field_name, false); |
| 7933 | 8595 | result_ptr_field_name = buf_create_from_str(RESULT_PTR_FIELD_NAME); |
| 7934 | | irb->exec->coro_result_ptr_field_ptr = ir_build_field_ptr(irb, scope, node, coro_promise_ptr, result_ptr_field_name); |
| 8596 | irb->exec->coro_result_ptr_field_ptr = ir_build_field_ptr(irb, scope, node, coro_promise_ptr, result_ptr_field_name, false); |
| 7935 | 8597 | ir_build_store_ptr(irb, scope, node, irb->exec->coro_result_ptr_field_ptr, irb->exec->coro_result_field_ptr); |
| 7936 | 8598 | if (irb->codegen->have_err_ret_tracing) { |
| 7937 | 8599 | // initialize the error return trace |
| 7938 | 8600 | Buf *return_addresses_field_name = buf_create_from_str(RETURN_ADDRESSES_FIELD_NAME); |
| 7939 | | IrInstruction *return_addresses_ptr = ir_build_field_ptr(irb, scope, node, coro_promise_ptr, return_addresses_field_name); |
| 8601 | IrInstruction *return_addresses_ptr = ir_build_field_ptr(irb, scope, node, coro_promise_ptr, return_addresses_field_name, false); |
| 7940 | 8602 | |
| 7941 | 8603 | Buf *err_ret_trace_field_name = buf_create_from_str(ERR_RET_TRACE_FIELD_NAME); |
| 7942 | | err_ret_trace_ptr = ir_build_field_ptr(irb, scope, node, coro_promise_ptr, err_ret_trace_field_name); |
| 8604 | err_ret_trace_ptr = ir_build_field_ptr(irb, scope, node, coro_promise_ptr, err_ret_trace_field_name, false); |
| 7943 | 8605 | ir_build_mark_err_ret_trace_ptr(irb, scope, node, err_ret_trace_ptr); |
| 7944 | 8606 | |
| 7945 | 8607 | // coordinate with builtin.zig |
| 7946 | 8608 | Buf *index_name = buf_create_from_str("index"); |
| 7947 | | IrInstruction *index_ptr = ir_build_field_ptr(irb, scope, node, err_ret_trace_ptr, index_name); |
| 8609 | IrInstruction *index_ptr = ir_build_field_ptr(irb, scope, node, err_ret_trace_ptr, index_name, false); |
| 7948 | 8610 | ir_build_store_ptr(irb, scope, node, index_ptr, zero); |
| 7949 | 8611 | |
| 7950 | 8612 | Buf *instruction_addresses_name = buf_create_from_str("instruction_addresses"); |
| 7951 | | IrInstruction *addrs_slice_ptr = ir_build_field_ptr(irb, scope, node, err_ret_trace_ptr, instruction_addresses_name); |
| 8613 | IrInstruction *addrs_slice_ptr = ir_build_field_ptr(irb, scope, node, err_ret_trace_ptr, instruction_addresses_name, false); |
| 7952 | 8614 | |
| 7953 | | IrInstruction *slice_value = ir_build_slice(irb, scope, node, return_addresses_ptr, zero, nullptr, false); |
| 8615 | IrInstruction *slice_value = ir_build_slice_src(irb, scope, node, return_addresses_ptr, zero, nullptr, false, no_result_loc()); |
| 7954 | 8616 | ir_build_store_ptr(irb, scope, node, addrs_slice_ptr, slice_value); |
| 7955 | 8617 | } |
| 7956 | 8618 | |
| ... | ... | @@ -7961,7 +8623,7 @@ bool ir_gen(CodeGen *codegen, AstNode *node, Scope *scope, IrExecutable *ir_exec |
| 7961 | 8623 | irb->exec->coro_final_cleanup_block = ir_create_basic_block(irb, scope, "FinalCleanup"); |
| 7962 | 8624 | } |
| 7963 | 8625 | |
| 7964 | | IrInstruction *result = ir_gen_node_extra(irb, node, scope, LValNone); |
| 8626 | IrInstruction *result = ir_gen_node_extra(irb, node, scope, LValNone, nullptr); |
| 7965 | 8627 | assert(result); |
| 7966 | 8628 | if (irb->exec->invalid) |
| 7967 | 8629 | return false; |
| ... | ... | @@ -8009,7 +8671,7 @@ bool ir_gen(CodeGen *codegen, AstNode *node, Scope *scope, IrExecutable *ir_exec |
| 8009 | 8671 | } |
| 8010 | 8672 | if (irb->codegen->have_err_ret_tracing) { |
| 8011 | 8673 | Buf *err_ret_trace_ptr_field_name = buf_create_from_str(ERR_RET_TRACE_PTR_FIELD_NAME); |
| 8012 | | IrInstruction *err_ret_trace_ptr_field_ptr = ir_build_field_ptr(irb, scope, node, coro_promise_ptr, err_ret_trace_ptr_field_name); |
| 8674 | IrInstruction *err_ret_trace_ptr_field_ptr = ir_build_field_ptr(irb, scope, node, coro_promise_ptr, err_ret_trace_ptr_field_name, false); |
| 8013 | 8675 | IrInstruction *dest_err_ret_trace_ptr = ir_build_load_ptr(irb, scope, node, err_ret_trace_ptr_field_ptr); |
| 8014 | 8676 | ir_build_merge_err_ret_traces(irb, scope, node, coro_promise_ptr, err_ret_trace_ptr, dest_err_ret_trace_ptr); |
| 8015 | 8677 | } |
| ... | ... | @@ -8017,7 +8679,7 @@ bool ir_gen(CodeGen *codegen, AstNode *node, Scope *scope, IrExecutable *ir_exec |
| 8017 | 8679 | // a register or local variable which does not get spilled into the frame, |
| 8018 | 8680 | // otherwise llvm tries to access memory inside the destroyed frame. |
| 8019 | 8681 | IrInstruction *unwrapped_await_handle_ptr = ir_build_optional_unwrap_ptr(irb, scope, node, |
| 8020 | | irb->exec->await_handle_var_ptr, false); |
| 8682 | irb->exec->await_handle_var_ptr, false, false); |
| 8021 | 8683 | IrInstruction *await_handle_in_block = ir_build_load_ptr(irb, scope, node, unwrapped_await_handle_ptr); |
| 8022 | 8684 | ir_build_br(irb, scope, node, check_free_block, const_bool_false); |
| 8023 | 8685 | |
| ... | ... | @@ -8031,7 +8693,7 @@ bool ir_gen(CodeGen *codegen, AstNode *node, Scope *scope, IrExecutable *ir_exec |
| 8031 | 8693 | incoming_values[0] = const_bool_false; |
| 8032 | 8694 | incoming_blocks[1] = irb->exec->coro_normal_final; |
| 8033 | 8695 | incoming_values[1] = const_bool_true; |
| 8034 | | IrInstruction *resume_awaiter = ir_build_phi(irb, scope, node, 2, incoming_blocks, incoming_values); |
| 8696 | IrInstruction *resume_awaiter = ir_build_phi(irb, scope, node, 2, incoming_blocks, incoming_values, nullptr); |
| 8035 | 8697 | |
| 8036 | 8698 | IrBasicBlock **merge_incoming_blocks = allocate<IrBasicBlock *>(2); |
| 8037 | 8699 | IrInstruction **merge_incoming_values = allocate<IrInstruction *>(2); |
| ... | ... | @@ -8039,12 +8701,12 @@ bool ir_gen(CodeGen *codegen, AstNode *node, Scope *scope, IrExecutable *ir_exec |
| 8039 | 8701 | merge_incoming_values[0] = ir_build_const_undefined(irb, scope, node); |
| 8040 | 8702 | merge_incoming_blocks[1] = irb->exec->coro_normal_final; |
| 8041 | 8703 | merge_incoming_values[1] = await_handle_in_block; |
| 8042 | | IrInstruction *awaiter_handle = ir_build_phi(irb, scope, node, 2, merge_incoming_blocks, merge_incoming_values); |
| 8704 | IrInstruction *awaiter_handle = ir_build_phi(irb, scope, node, 2, merge_incoming_blocks, merge_incoming_values, nullptr); |
| 8043 | 8705 | |
| 8044 | 8706 | Buf *shrink_field_name = buf_create_from_str(ASYNC_SHRINK_FIELD_NAME); |
| 8045 | 8707 | IrInstruction *implicit_allocator_ptr = ir_build_get_implicit_allocator(irb, scope, node, |
| 8046 | 8708 | ImplicitAllocatorIdLocalVar); |
| 8047 | | IrInstruction *shrink_fn_ptr = ir_build_field_ptr(irb, scope, node, implicit_allocator_ptr, shrink_field_name); |
| 8709 | IrInstruction *shrink_fn_ptr = ir_build_field_ptr(irb, scope, node, implicit_allocator_ptr, shrink_field_name, false); |
| 8048 | 8710 | IrInstruction *shrink_fn = ir_build_load_ptr(irb, scope, node, shrink_fn_ptr); |
| 8049 | 8711 | IrInstruction *zero = ir_build_const_usize(irb, scope, node, 0); |
| 8050 | 8712 | IrInstruction *coro_mem_ptr_maybe = ir_build_coro_free(irb, scope, node, coro_id, irb->exec->coro_handle); |
| ... | ... | @@ -8056,7 +8718,8 @@ bool ir_gen(CodeGen *codegen, AstNode *node, Scope *scope, IrExecutable *ir_exec |
| 8056 | 8718 | IrInstruction *coro_mem_ptr_ref = ir_build_ref(irb, scope, node, coro_mem_ptr, true, false); |
| 8057 | 8719 | IrInstruction *coro_size_ptr = ir_build_var_ptr(irb, scope, node, coro_size_var); |
| 8058 | 8720 | IrInstruction *coro_size = ir_build_load_ptr(irb, scope, node, coro_size_ptr); |
| 8059 | | IrInstruction *mem_slice = ir_build_slice(irb, scope, node, coro_mem_ptr_ref, zero, coro_size, false); |
| 8721 | IrInstruction *mem_slice = ir_build_slice_src(irb, scope, node, coro_mem_ptr_ref, zero, coro_size, false, |
| 8722 | no_result_loc()); |
| 8060 | 8723 | size_t arg_count = 5; |
| 8061 | 8724 | IrInstruction **args = allocate<IrInstruction *>(arg_count); |
| 8062 | 8725 | args[0] = implicit_allocator_ptr; // self |
| ... | ... | @@ -8070,7 +8733,8 @@ bool ir_gen(CodeGen *codegen, AstNode *node, Scope *scope, IrExecutable *ir_exec |
| 8070 | 8733 | // non-allocating. Basically coroutines are not supported right now until they are reworked. |
| 8071 | 8734 | args[3] = ir_build_const_usize(irb, scope, node, 1); // new_size |
| 8072 | 8735 | args[4] = ir_build_const_usize(irb, scope, node, 1); // new_align |
| 8073 | | ir_build_call(irb, scope, node, nullptr, shrink_fn, arg_count, args, false, FnInlineAuto, false, nullptr, nullptr); |
| 8736 | ir_build_call_src(irb, scope, node, nullptr, shrink_fn, arg_count, args, false, FnInlineAuto, false, nullptr, |
| 8737 | nullptr, no_result_loc()); |
| 8074 | 8738 | |
| 8075 | 8739 | IrBasicBlock *resume_block = ir_create_basic_block(irb, scope, "Resume"); |
| 8076 | 8740 | ir_build_cond_br(irb, scope, node, resume_awaiter, resume_block, irb->exec->coro_suspend_block, const_bool_false); |
| ... | ... | @@ -8177,6 +8841,15 @@ static ConstExprValue *ir_exec_const_result(CodeGen *codegen, IrExecutable *exec |
| 8177 | 8841 | } |
| 8178 | 8842 | return &value->value; |
| 8179 | 8843 | } else if (ir_has_side_effects(instruction)) { |
| 8844 | if (instr_is_comptime(instruction)) { |
| 8845 | switch (instruction->id) { |
| 8846 | case IrInstructionIdUnwrapErrPayload: |
| 8847 | case IrInstructionIdUnionFieldPtr: |
| 8848 | continue; |
| 8849 | default: |
| 8850 | break; |
| 8851 | } |
| 8852 | } |
| 8180 | 8853 | exec_add_error_node(codegen, exec, instruction->source_node, |
| 8181 | 8854 | buf_sprintf("unable to evaluate constant expression")); |
| 8182 | 8855 | return &codegen->invalid_instruction->value; |
| ... | ... | @@ -9154,15 +9827,6 @@ static bool ir_num_lit_fits_in_other_type(IrAnalyze *ira, IrInstruction *instruc |
| 9154 | 9827 | return false; |
| 9155 | 9828 | } |
| 9156 | 9829 | |
| 9157 | | static bool is_slice(ZigType *type) { |
| 9158 | | return type->id == ZigTypeIdStruct && type->data.structure.is_slice; |
| 9159 | | } |
| 9160 | | |
| 9161 | | static bool slice_is_const(ZigType *type) { |
| 9162 | | assert(is_slice(type)); |
| 9163 | | return type->data.structure.fields[slice_ptr_index].type_entry->data.pointer.is_const; |
| 9164 | | } |
| 9165 | | |
| 9166 | 9830 | static bool is_tagged_union(ZigType *type) { |
| 9167 | 9831 | if (type->id != ZigTypeIdUnion) |
| 9168 | 9832 | return false; |
| ... | ... | @@ -9533,9 +10197,21 @@ static ZigType *ir_resolve_peer_types(IrAnalyze *ira, AstNode *source_node, ZigT |
| 9533 | 10197 | { |
| 9534 | 10198 | Error err; |
| 9535 | 10199 | assert(instruction_count >= 1); |
| 9536 | | IrInstruction *prev_inst = instructions[0]; |
| 9537 | | if (type_is_invalid(prev_inst->value.type)) { |
| 9538 | | 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; |
| 9539 | 10215 | } |
| 9540 | 10216 | ErrorTableEntry **errors = nullptr; |
| 9541 | 10217 | size_t errors_count = 0; |
| ... | ... | @@ -9560,7 +10236,7 @@ static ZigType *ir_resolve_peer_types(IrAnalyze *ira, AstNode *source_node, ZigT |
| 9560 | 10236 | |
| 9561 | 10237 | bool any_are_null = (prev_inst->value.type->id == ZigTypeIdNull); |
| 9562 | 10238 | bool convert_to_const_slice = false; |
| 9563 | | for (size_t i = 1; i < instruction_count; i += 1) { |
| 10239 | for (; i < instruction_count; i += 1) { |
| 9564 | 10240 | IrInstruction *cur_inst = instructions[i]; |
| 9565 | 10241 | ZigType *cur_type = cur_inst->value.type; |
| 9566 | 10242 | ZigType *prev_type = prev_inst->value.type; |
| ... | ... | @@ -9579,7 +10255,7 @@ static ZigType *ir_resolve_peer_types(IrAnalyze *ira, AstNode *source_node, ZigT |
| 9579 | 10255 | } |
| 9580 | 10256 | |
| 9581 | 10257 | if (prev_type->id == ZigTypeIdErrorSet) { |
| 9582 | | assert(err_set_type != nullptr); |
| 10258 | ir_assert(err_set_type != nullptr, prev_inst); |
| 9583 | 10259 | if (cur_type->id == ZigTypeIdErrorSet) { |
| 9584 | 10260 | if (type_is_global_error_set(err_set_type)) { |
| 9585 | 10261 | continue; |
| ... | ... | @@ -9839,6 +10515,7 @@ static ZigType *ir_resolve_peer_types(IrAnalyze *ira, AstNode *source_node, ZigT |
| 9839 | 10515 | |
| 9840 | 10516 | if (prev_type->id == ZigTypeIdNull) { |
| 9841 | 10517 | prev_inst = cur_inst; |
| 10518 | any_are_null = true; |
| 9842 | 10519 | continue; |
| 9843 | 10520 | } |
| 9844 | 10521 | |
| ... | ... | @@ -10153,6 +10830,8 @@ static ZigType *ir_resolve_peer_types(IrAnalyze *ira, AstNode *source_node, ZigT |
| 10153 | 10830 | } else if (prev_inst->value.type->id == ZigTypeIdOptional) { |
| 10154 | 10831 | return prev_inst->value.type; |
| 10155 | 10832 | } else { |
| 10833 | if ((err = type_resolve(ira->codegen, prev_inst->value.type, ResolveStatusSizeKnown))) |
| 10834 | return ira->codegen->builtin_types.entry_invalid; |
| 10156 | 10835 | return get_optional_type(ira->codegen, prev_inst->value.type); |
| 10157 | 10836 | } |
| 10158 | 10837 | } else { |
| ... | ... | @@ -10160,24 +10839,18 @@ static ZigType *ir_resolve_peer_types(IrAnalyze *ira, AstNode *source_node, ZigT |
| 10160 | 10839 | } |
| 10161 | 10840 | } |
| 10162 | 10841 | |
| 10163 | | static void ir_add_alloca(IrAnalyze *ira, IrInstruction *instruction, ZigType *type_entry) { |
| 10164 | | if (type_has_bits(type_entry) && handle_is_ptr(type_entry)) { |
| 10165 | | ZigFn *fn_entry = exec_fn_entry(ira->new_irb.exec); |
| 10166 | | if (fn_entry != nullptr) { |
| 10167 | | fn_entry->alloca_list.append(instruction); |
| 10168 | | } |
| 10169 | | } |
| 10170 | | } |
| 10171 | | |
| 10172 | 10842 | static void copy_const_val(ConstExprValue *dest, ConstExprValue *src, bool same_global_refs) { |
| 10173 | 10843 | ConstGlobalRefs *global_refs = dest->global_refs; |
| 10174 | | assert(!same_global_refs || src->global_refs != nullptr); |
| 10175 | | *dest = *src; |
| 10844 | memcpy(dest, src, sizeof(ConstExprValue)); |
| 10176 | 10845 | if (!same_global_refs) { |
| 10177 | 10846 | dest->global_refs = global_refs; |
| 10847 | if (src->special == ConstValSpecialUndef) |
| 10848 | return; |
| 10178 | 10849 | if (dest->type->id == ZigTypeIdStruct) { |
| 10179 | | dest->data.x_struct.fields = allocate_nonzero<ConstExprValue>(dest->type->data.structure.src_field_count); |
| 10180 | | memcpy(dest->data.x_struct.fields, src->data.x_struct.fields, sizeof(ConstExprValue) * dest->type->data.structure.src_field_count); |
| 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 | } |
| 10181 | 10854 | } |
| 10182 | 10855 | } |
| 10183 | 10856 | } |
| ... | ... | @@ -10195,7 +10868,6 @@ static bool eval_const_expr_implicit_cast(IrAnalyze *ira, IrInstruction *source_ |
| 10195 | 10868 | zig_unreachable(); |
| 10196 | 10869 | case CastOpErrSet: |
| 10197 | 10870 | case CastOpBitCast: |
| 10198 | | case CastOpPtrOfArrayToSlice: |
| 10199 | 10871 | zig_panic("TODO"); |
| 10200 | 10872 | case CastOpNoop: |
| 10201 | 10873 | { |
| ... | ... | @@ -10295,7 +10967,7 @@ static IrInstruction *ir_const(IrAnalyze *ira, IrInstruction *old_instruction, Z |
| 10295 | 10967 | } |
| 10296 | 10968 | |
| 10297 | 10969 | static IrInstruction *ir_resolve_cast(IrAnalyze *ira, IrInstruction *source_instr, IrInstruction *value, |
| 10298 | | ZigType *wanted_type, CastOp cast_op, bool need_alloca) |
| 10970 | ZigType *wanted_type, CastOp cast_op) |
| 10299 | 10971 | { |
| 10300 | 10972 | if (instr_is_comptime(value) || !type_has_bits(wanted_type)) { |
| 10301 | 10973 | IrInstruction *result = ir_const(ira, source_instr, wanted_type); |
| ... | ... | @@ -10308,9 +10980,6 @@ static IrInstruction *ir_resolve_cast(IrAnalyze *ira, IrInstruction *source_inst |
| 10308 | 10980 | } else { |
| 10309 | 10981 | IrInstruction *result = ir_build_cast(&ira->new_irb, source_instr->scope, source_instr->source_node, wanted_type, value, cast_op); |
| 10310 | 10982 | result->value.type = wanted_type; |
| 10311 | | if (need_alloca) { |
| 10312 | | ir_add_alloca(ira, result, wanted_type); |
| 10313 | | } |
| 10314 | 10983 | return result; |
| 10315 | 10984 | } |
| 10316 | 10985 | } |
| ... | ... | @@ -10352,7 +11021,7 @@ static IrInstruction *ir_resolve_ptr_of_array_to_unknown_len_ptr(IrAnalyze *ira, |
| 10352 | 11021 | } |
| 10353 | 11022 | |
| 10354 | 11023 | static IrInstruction *ir_resolve_ptr_of_array_to_slice(IrAnalyze *ira, IrInstruction *source_instr, |
| 10355 | | IrInstruction *value, ZigType *wanted_type) |
| 11024 | IrInstruction *value, ZigType *wanted_type, ResultLoc *result_loc) |
| 10356 | 11025 | { |
| 10357 | 11026 | Error err; |
| 10358 | 11027 | |
| ... | ... | @@ -10383,11 +11052,12 @@ static IrInstruction *ir_resolve_ptr_of_array_to_slice(IrAnalyze *ira, IrInstruc |
| 10383 | 11052 | } |
| 10384 | 11053 | } |
| 10385 | 11054 | |
| 10386 | | IrInstruction *result = ir_build_cast(&ira->new_irb, source_instr->scope, source_instr->source_node, |
| 10387 | | wanted_type, value, CastOpPtrOfArrayToSlice); |
| 10388 | | result->value.type = wanted_type; |
| 10389 | | ir_add_alloca(ira, result, wanted_type); |
| 10390 | | 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); |
| 10391 | 11061 | } |
| 10392 | 11062 | |
| 10393 | 11063 | static IrBasicBlock *ir_get_new_bb(IrAnalyze *ira, IrBasicBlock *old_bb, IrInstruction *ref_old_instruction) { |
| ... | ... | @@ -10419,51 +11089,136 @@ static IrBasicBlock *ir_get_new_bb_runtime(IrAnalyze *ira, IrBasicBlock *old_bb, |
| 10419 | 11089 | } |
| 10420 | 11090 | |
| 10421 | 11091 | static void ir_start_bb(IrAnalyze *ira, IrBasicBlock *old_bb, IrBasicBlock *const_predecessor_bb) { |
| 11092 | assert(!old_bb->suspended); |
| 10422 | 11093 | ira->instruction_index = 0; |
| 10423 | 11094 | ira->old_irb.current_basic_block = old_bb; |
| 10424 | 11095 | ira->const_predecessor_bb = const_predecessor_bb; |
| 11096 | ira->old_bb_index = old_bb->index; |
| 10425 | 11097 | } |
| 10426 | 11098 | |
| 10427 | | static void ir_finish_bb(IrAnalyze *ira) { |
| 10428 | | ira->new_irb.exec->basic_block_list.append(ira->new_irb.current_basic_block); |
| 10429 | | ira->instruction_index += 1; |
| 10430 | | while (ira->instruction_index < ira->old_irb.current_basic_block->instruction_list.length) { |
| 10431 | | IrInstruction *next_instruction = ira->old_irb.current_basic_block->instruction_list.at(ira->instruction_index); |
| 10432 | | if (!next_instruction->is_gen) { |
| 10433 | | ir_add_error(ira, next_instruction, buf_sprintf("unreachable code")); |
| 10434 | | break; |
| 10435 | | } |
| 10436 | | 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; |
| 10437 | 11124 | } |
| 11125 | return ira->codegen->unreach_instruction; |
| 11126 | } |
| 11127 | |
| 11128 | static IrInstruction *ira_resume(IrAnalyze *ira) { |
| 11129 | IrSuspendPosition pos = ira->resume_stack.pop(); |
| 11130 | if (ira->codegen->verbose_ir) { |
| 11131 | fprintf(stderr, "resume (%zu,%zu) ", pos.basic_block_index, pos.instruction_index); |
| 11132 | } |
| 11133 | ira->old_bb_index = pos.basic_block_index; |
| 11134 | ira->old_irb.current_basic_block = ira->old_irb.exec->basic_block_list.at(ira->old_bb_index); |
| 11135 | assert(ira->old_irb.current_basic_block->in_resume_stack); |
| 11136 | ira->old_irb.current_basic_block->in_resume_stack = false; |
| 11137 | ira->old_irb.current_basic_block->suspended = false; |
| 11138 | ira->instruction_index = pos.instruction_index; |
| 11139 | assert(pos.instruction_index < ira->old_irb.current_basic_block->instruction_list.length); |
| 11140 | if (ira->codegen->verbose_ir) { |
| 11141 | fprintf(stderr, "%s_%zu #%zu\n", ira->old_irb.current_basic_block->name_hint, |
| 11142 | ira->old_irb.current_basic_block->debug_id, |
| 11143 | ira->old_irb.current_basic_block->instruction_list.at(pos.instruction_index)->debug_id); |
| 11144 | } |
| 11145 | ira->const_predecessor_bb = nullptr; |
| 11146 | ira->new_irb.current_basic_block = ira->old_irb.current_basic_block->other; |
| 11147 | assert(ira->new_irb.current_basic_block != nullptr); |
| 11148 | return ira->codegen->unreach_instruction; |
| 11149 | } |
| 10438 | 11150 | |
| 10439 | | size_t my_old_bb_index = ira->old_bb_index; |
| 11151 | static void ir_start_next_bb(IrAnalyze *ira) { |
| 10440 | 11152 | ira->old_bb_index += 1; |
| 10441 | 11153 | |
| 10442 | 11154 | bool need_repeat = true; |
| 10443 | 11155 | for (;;) { |
| 10444 | 11156 | while (ira->old_bb_index < ira->old_irb.exec->basic_block_list.length) { |
| 10445 | 11157 | IrBasicBlock *old_bb = ira->old_irb.exec->basic_block_list.at(ira->old_bb_index); |
| 10446 | | if (old_bb->other == nullptr) { |
| 11158 | if (old_bb->other == nullptr && old_bb->suspend_instruction_ref == nullptr) { |
| 10447 | 11159 | ira->old_bb_index += 1; |
| 10448 | 11160 | continue; |
| 10449 | 11161 | } |
| 10450 | | if (old_bb->other->instruction_list.length != 0 || ira->old_bb_index == my_old_bb_index) { |
| 11162 | // if it's already started, or |
| 11163 | // if it's a suspended block, |
| 11164 | // then skip it |
| 11165 | if (old_bb->suspended || |
| 11166 | (old_bb->other != nullptr && old_bb->other->instruction_list.length != 0) || |
| 11167 | (old_bb->other != nullptr && old_bb->other->already_appended)) |
| 11168 | { |
| 10451 | 11169 | ira->old_bb_index += 1; |
| 10452 | 11170 | continue; |
| 10453 | 11171 | } |
| 10454 | | ira->new_irb.current_basic_block = old_bb->other; |
| 10455 | 11172 | |
| 11173 | // if there is a resume_stack, pop one from there rather than moving on. |
| 11174 | // the last item of the resume stack will be a basic block that will |
| 11175 | // move on to the next one below |
| 11176 | if (ira->resume_stack.length != 0) { |
| 11177 | ira_resume(ira); |
| 11178 | return; |
| 11179 | } |
| 11180 | |
| 11181 | if (old_bb->other == nullptr) { |
| 11182 | old_bb->other = ir_get_new_bb_runtime(ira, old_bb, old_bb->suspend_instruction_ref); |
| 11183 | } |
| 11184 | ira->new_irb.current_basic_block = old_bb->other; |
| 10456 | 11185 | ir_start_bb(ira, old_bb, nullptr); |
| 10457 | 11186 | return; |
| 10458 | 11187 | } |
| 10459 | | if (!need_repeat) |
| 11188 | if (!need_repeat) { |
| 11189 | if (ira->resume_stack.length != 0) { |
| 11190 | ira_resume(ira); |
| 11191 | } |
| 10460 | 11192 | return; |
| 11193 | } |
| 10461 | 11194 | need_repeat = false; |
| 10462 | 11195 | ira->old_bb_index = 0; |
| 10463 | 11196 | continue; |
| 10464 | 11197 | } |
| 10465 | 11198 | } |
| 10466 | 11199 | |
| 11200 | static void ir_finish_bb(IrAnalyze *ira) { |
| 11201 | if (!ira->new_irb.current_basic_block->already_appended) { |
| 11202 | ira->new_irb.current_basic_block->already_appended = true; |
| 11203 | if (ira->codegen->verbose_ir) { |
| 11204 | fprintf(stderr, "append new bb %s_%zu\n", ira->new_irb.current_basic_block->name_hint, |
| 11205 | ira->new_irb.current_basic_block->debug_id); |
| 11206 | } |
| 11207 | ira->new_irb.exec->basic_block_list.append(ira->new_irb.current_basic_block); |
| 11208 | } |
| 11209 | ira->instruction_index += 1; |
| 11210 | while (ira->instruction_index < ira->old_irb.current_basic_block->instruction_list.length) { |
| 11211 | IrInstruction *next_instruction = ira->old_irb.current_basic_block->instruction_list.at(ira->instruction_index); |
| 11212 | if (!next_instruction->is_gen) { |
| 11213 | ir_add_error(ira, next_instruction, buf_sprintf("unreachable code")); |
| 11214 | break; |
| 11215 | } |
| 11216 | ira->instruction_index += 1; |
| 11217 | } |
| 11218 | |
| 11219 | ir_start_next_bb(ira); |
| 11220 | } |
| 11221 | |
| 10467 | 11222 | static IrInstruction *ir_unreach_error(IrAnalyze *ira) { |
| 10468 | 11223 | ira->old_bb_index = SIZE_MAX; |
| 10469 | 11224 | ira->new_irb.exec->invalid = true; |
| ... | ... | @@ -10524,6 +11279,12 @@ static IrInstruction *ir_const_undef(IrAnalyze *ira, IrInstruction *source_instr |
| 10524 | 11279 | return result; |
| 10525 | 11280 | } |
| 10526 | 11281 | |
| 11282 | static IrInstruction *ir_const_unreachable(IrAnalyze *ira, IrInstruction *source_instruction) { |
| 11283 | IrInstruction *result = ir_const(ira, source_instruction, ira->codegen->builtin_types.entry_unreachable); |
| 11284 | result->value.special = ConstValSpecialStatic; |
| 11285 | return result; |
| 11286 | } |
| 11287 | |
| 10527 | 11288 | static IrInstruction *ir_const_void(IrAnalyze *ira, IrInstruction *source_instruction) { |
| 10528 | 11289 | return ir_const(ira, source_instruction, ira->codegen->builtin_types.entry_void); |
| 10529 | 11290 | } |
| ... | ... | @@ -10721,7 +11482,7 @@ static ZigFn *ir_resolve_fn(IrAnalyze *ira, IrInstruction *fn_value) { |
| 10721 | 11482 | } |
| 10722 | 11483 | |
| 10723 | 11484 | static IrInstruction *ir_analyze_optional_wrap(IrAnalyze *ira, IrInstruction *source_instr, IrInstruction *value, |
| 10724 | | ZigType *wanted_type) |
| 11485 | ZigType *wanted_type, ResultLoc *result_loc) |
| 10725 | 11486 | { |
| 10726 | 11487 | assert(wanted_type->id == ZigTypeIdOptional); |
| 10727 | 11488 | |
| ... | ... | @@ -10747,20 +11508,29 @@ static IrInstruction *ir_analyze_optional_wrap(IrAnalyze *ira, IrInstruction *so |
| 10747 | 11508 | return &const_instruction->base; |
| 10748 | 11509 | } |
| 10749 | 11510 | |
| 10750 | | IrInstruction *result = ir_build_maybe_wrap(&ira->new_irb, source_instr->scope, source_instr->source_node, value); |
| 10751 | | 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); |
| 10752 | 11522 | result->value.data.rh_maybe = RuntimeHintOptionalNonNull; |
| 10753 | | ir_add_alloca(ira, result, wanted_type); |
| 10754 | 11523 | return result; |
| 10755 | 11524 | } |
| 10756 | 11525 | |
| 10757 | 11526 | static IrInstruction *ir_analyze_err_wrap_payload(IrAnalyze *ira, IrInstruction *source_instr, |
| 10758 | | IrInstruction *value, ZigType *wanted_type) |
| 11527 | IrInstruction *value, ZigType *wanted_type, ResultLoc *result_loc) |
| 10759 | 11528 | { |
| 10760 | 11529 | assert(wanted_type->id == ZigTypeIdErrorUnion); |
| 10761 | 11530 | |
| 11531 | ZigType *payload_type = wanted_type->data.error_union.payload_type; |
| 11532 | ZigType *err_set_type = wanted_type->data.error_union.err_set_type; |
| 10762 | 11533 | if (instr_is_comptime(value)) { |
| 10763 | | ZigType *payload_type = wanted_type->data.error_union.payload_type; |
| 10764 | 11534 | IrInstruction *casted_payload = ir_implicit_cast(ira, value, payload_type); |
| 10765 | 11535 | if (type_is_invalid(casted_payload->value.type)) |
| 10766 | 11536 | return ira->codegen->invalid_instruction; |
| ... | ... | @@ -10770,7 +11540,7 @@ static IrInstruction *ir_analyze_err_wrap_payload(IrAnalyze *ira, IrInstruction |
| 10770 | 11540 | return ira->codegen->invalid_instruction; |
| 10771 | 11541 | |
| 10772 | 11542 | ConstExprValue *err_set_val = create_const_vals(1); |
| 10773 | | err_set_val->type = wanted_type->data.error_union.err_set_type; |
| 11543 | err_set_val->type = err_set_type; |
| 10774 | 11544 | err_set_val->special = ConstValSpecialStatic; |
| 10775 | 11545 | err_set_val->data.x_err_set = nullptr; |
| 10776 | 11546 | |
| ... | ... | @@ -10783,10 +11553,19 @@ static IrInstruction *ir_analyze_err_wrap_payload(IrAnalyze *ira, IrInstruction |
| 10783 | 11553 | return &const_instruction->base; |
| 10784 | 11554 | } |
| 10785 | 11555 | |
| 10786 | | IrInstruction *result = ir_build_err_wrap_payload(&ira->new_irb, source_instr->scope, source_instr->source_node, value); |
| 10787 | | 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); |
| 10788 | 11568 | result->value.data.rh_error_union = RuntimeHintErrorUnionNonError; |
| 10789 | | ir_add_alloca(ira, result, wanted_type); |
| 10790 | 11569 | return result; |
| 10791 | 11570 | } |
| 10792 | 11571 | |
| ... | ... | @@ -10833,7 +11612,9 @@ static IrInstruction *ir_analyze_err_set_cast(IrAnalyze *ira, IrInstruction *sou |
| 10833 | 11612 | return result; |
| 10834 | 11613 | } |
| 10835 | 11614 | |
| 10836 | | static IrInstruction *ir_analyze_err_wrap_code(IrAnalyze *ira, IrInstruction *source_instr, IrInstruction *value, ZigType *wanted_type) { |
| 11615 | static IrInstruction *ir_analyze_err_wrap_code(IrAnalyze *ira, IrInstruction *source_instr, IrInstruction *value, |
| 11616 | ZigType *wanted_type, ResultLoc *result_loc) |
| 11617 | { |
| 10837 | 11618 | assert(wanted_type->id == ZigTypeIdErrorUnion); |
| 10838 | 11619 | |
| 10839 | 11620 | IrInstruction *casted_value = ir_implicit_cast(ira, value, wanted_type->data.error_union.err_set_type); |
| ... | ... | @@ -10857,10 +11638,20 @@ static IrInstruction *ir_analyze_err_wrap_code(IrAnalyze *ira, IrInstruction *so |
| 10857 | 11638 | return &const_instruction->base; |
| 10858 | 11639 | } |
| 10859 | 11640 | |
| 10860 | | IrInstruction *result = ir_build_err_wrap_code(&ira->new_irb, source_instr->scope, source_instr->source_node, value); |
| 10861 | | 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); |
| 10862 | 11654 | result->value.data.rh_error_union = RuntimeHintErrorUnionError; |
| 10863 | | ir_add_alloca(ira, result, wanted_type); |
| 10864 | 11655 | return result; |
| 10865 | 11656 | } |
| 10866 | 11657 | |
| ... | ... | @@ -10920,20 +11711,21 @@ static IrInstruction *ir_get_ref(IrAnalyze *ira, IrInstruction *source_instructi |
| 10920 | 11711 | |
| 10921 | 11712 | ZigType *ptr_type = get_pointer_to_type_extra(ira->codegen, value->value.type, |
| 10922 | 11713 | is_const, is_volatile, PtrLenSingle, 0, 0, 0, false); |
| 10923 | | IrInstruction *new_instruction = ir_build_ref(&ira->new_irb, source_instruction->scope, |
| 10924 | | source_instruction->source_node, value, is_const, is_volatile); |
| 10925 | | new_instruction->value.type = ptr_type; |
| 10926 | | new_instruction->value.data.rh_ptr = RuntimeHintPtrStack; |
| 11714 | |
| 11715 | IrInstruction *result_loc; |
| 10927 | 11716 | if (type_has_bits(ptr_type) && !handle_is_ptr(value->value.type)) { |
| 10928 | | ZigFn *fn_entry = exec_fn_entry(ira->new_irb.exec); |
| 10929 | | assert(fn_entry); |
| 10930 | | 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; |
| 10931 | 11720 | } |
| 11721 | |
| 11722 | IrInstruction *new_instruction = ir_build_ref_gen(ira, source_instruction, ptr_type, value, result_loc); |
| 11723 | new_instruction->value.data.rh_ptr = RuntimeHintPtrStack; |
| 10932 | 11724 | return new_instruction; |
| 10933 | 11725 | } |
| 10934 | 11726 | |
| 10935 | 11727 | static IrInstruction *ir_analyze_array_to_slice(IrAnalyze *ira, IrInstruction *source_instr, |
| 10936 | | IrInstruction *array_arg, ZigType *wanted_type) |
| 11728 | IrInstruction *array_arg, ZigType *wanted_type, ResultLoc *result_loc) |
| 10937 | 11729 | { |
| 10938 | 11730 | assert(is_slice(wanted_type)); |
| 10939 | 11731 | // In this function we honor the const-ness of wanted_type, because |
| ... | ... | @@ -10942,7 +11734,7 @@ static IrInstruction *ir_analyze_array_to_slice(IrAnalyze *ira, IrInstruction *s |
| 10942 | 11734 | IrInstruction *array_ptr = nullptr; |
| 10943 | 11735 | IrInstruction *array; |
| 10944 | 11736 | if (array_arg->value.type->id == ZigTypeIdPointer) { |
| 10945 | | array = ir_get_deref(ira, source_instr, array_arg); |
| 11737 | array = ir_get_deref(ira, source_instr, array_arg, nullptr); |
| 10946 | 11738 | array_ptr = array_arg; |
| 10947 | 11739 | } else { |
| 10948 | 11740 | array = array_arg; |
| ... | ... | @@ -10965,12 +11757,14 @@ static IrInstruction *ir_analyze_array_to_slice(IrAnalyze *ira, IrInstruction *s |
| 10965 | 11757 | |
| 10966 | 11758 | if (!array_ptr) array_ptr = ir_get_ref(ira, source_instr, array, true, false); |
| 10967 | 11759 | |
| 10968 | | IrInstruction *result = ir_build_slice(&ira->new_irb, source_instr->scope, |
| 10969 | | source_instr->source_node, array_ptr, start, end, false); |
| 10970 | | 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); |
| 10971 | 11766 | result->value.data.rh_slice.id = RuntimeHintSliceIdLen; |
| 10972 | 11767 | result->value.data.rh_slice.len = array_type->data.array.len; |
| 10973 | | ir_add_alloca(ira, result, result->value.type); |
| 10974 | 11768 | |
| 10975 | 11769 | return result; |
| 10976 | 11770 | } |
| ... | ... | @@ -11608,7 +12402,7 @@ static IrInstruction *ir_analyze_array_to_vector(IrAnalyze *ira, IrInstruction * |
| 11608 | 12402 | } |
| 11609 | 12403 | |
| 11610 | 12404 | static IrInstruction *ir_analyze_vector_to_array(IrAnalyze *ira, IrInstruction *source_instr, |
| 11611 | | IrInstruction *vector, ZigType *array_type) |
| 12405 | IrInstruction *vector, ZigType *array_type, ResultLoc *result_loc) |
| 11612 | 12406 | { |
| 11613 | 12407 | if (instr_is_comptime(vector)) { |
| 11614 | 12408 | // arrays and vectors have the same ConstExprValue representation |
| ... | ... | @@ -11617,7 +12411,14 @@ static IrInstruction *ir_analyze_vector_to_array(IrAnalyze *ira, IrInstruction * |
| 11617 | 12411 | result->value.type = array_type; |
| 11618 | 12412 | return result; |
| 11619 | 12413 | } |
| 11620 | | return ir_build_vector_to_array(ira, source_instr, vector, array_type); |
| 12414 | if (result_loc == nullptr) { |
| 12415 | result_loc = no_result_loc(); |
| 12416 | } |
| 12417 | IrInstruction *result_loc_inst = ir_resolve_result(ira, source_instr, result_loc, array_type, nullptr, true, false); |
| 12418 | if (type_is_invalid(result_loc_inst->value.type) || instr_is_unreachable(result_loc_inst)) { |
| 12419 | return result_loc_inst; |
| 12420 | } |
| 12421 | return ir_build_vector_to_array(ira, source_instr, array_type, vector, result_loc_inst); |
| 11621 | 12422 | } |
| 11622 | 12423 | |
| 11623 | 12424 | static IrInstruction *ir_analyze_int_to_c_ptr(IrAnalyze *ira, IrInstruction *source_instr, |
| ... | ... | @@ -11667,7 +12468,7 @@ static bool is_pointery_and_elem_is_not_pointery(ZigType *ty) { |
| 11667 | 12468 | } |
| 11668 | 12469 | |
| 11669 | 12470 | static IrInstruction *ir_analyze_cast(IrAnalyze *ira, IrInstruction *source_instr, |
| 11670 | | ZigType *wanted_type, IrInstruction *value) |
| 12471 | ZigType *wanted_type, IrInstruction *value, ResultLoc *result_loc) |
| 11671 | 12472 | { |
| 11672 | 12473 | Error err; |
| 11673 | 12474 | ZigType *actual_type = value->value.type; |
| ... | ... | @@ -11683,7 +12484,7 @@ static IrInstruction *ir_analyze_cast(IrAnalyze *ira, IrInstruction *source_inst |
| 11683 | 12484 | if (const_cast_result.id == ConstCastResultIdInvalid) |
| 11684 | 12485 | return ira->codegen->invalid_instruction; |
| 11685 | 12486 | if (const_cast_result.id == ConstCastResultIdOk) { |
| 11686 | | return ir_resolve_cast(ira, source_instr, value, wanted_type, CastOpNoop, false); |
| 12487 | return ir_resolve_cast(ira, source_instr, value, wanted_type, CastOpNoop); |
| 11687 | 12488 | } |
| 11688 | 12489 | |
| 11689 | 12490 | // cast from T to ?T |
| ... | ... | @@ -11693,12 +12494,12 @@ static IrInstruction *ir_analyze_cast(IrAnalyze *ira, IrInstruction *source_inst |
| 11693 | 12494 | if (types_match_const_cast_only(ira, wanted_child_type, actual_type, source_node, |
| 11694 | 12495 | false).id == ConstCastResultIdOk) |
| 11695 | 12496 | { |
| 11696 | | return ir_analyze_optional_wrap(ira, source_instr, value, wanted_type); |
| 12497 | return ir_analyze_optional_wrap(ira, source_instr, value, wanted_type, result_loc); |
| 11697 | 12498 | } else if (actual_type->id == ZigTypeIdComptimeInt || |
| 11698 | 12499 | actual_type->id == ZigTypeIdComptimeFloat) |
| 11699 | 12500 | { |
| 11700 | 12501 | if (ir_num_lit_fits_in_other_type(ira, value, wanted_child_type, true)) { |
| 11701 | | return ir_analyze_optional_wrap(ira, source_instr, value, wanted_type); |
| 12502 | return ir_analyze_optional_wrap(ira, source_instr, value, wanted_type, result_loc); |
| 11702 | 12503 | } else { |
| 11703 | 12504 | return ira->codegen->invalid_instruction; |
| 11704 | 12505 | } |
| ... | ... | @@ -11722,7 +12523,7 @@ static IrInstruction *ir_analyze_cast(IrAnalyze *ira, IrInstruction *source_inst |
| 11722 | 12523 | wanted_child_type); |
| 11723 | 12524 | if (type_is_invalid(cast1->value.type)) |
| 11724 | 12525 | return ira->codegen->invalid_instruction; |
| 11725 | | return ir_analyze_optional_wrap(ira, source_instr, cast1, wanted_type); |
| 12526 | return ir_analyze_optional_wrap(ira, source_instr, cast1, wanted_type, result_loc); |
| 11726 | 12527 | } |
| 11727 | 12528 | } |
| 11728 | 12529 | } |
| ... | ... | @@ -11732,12 +12533,12 @@ static IrInstruction *ir_analyze_cast(IrAnalyze *ira, IrInstruction *source_inst |
| 11732 | 12533 | if (types_match_const_cast_only(ira, wanted_type->data.error_union.payload_type, actual_type, |
| 11733 | 12534 | source_node, false).id == ConstCastResultIdOk) |
| 11734 | 12535 | { |
| 11735 | | return ir_analyze_err_wrap_payload(ira, source_instr, value, wanted_type); |
| 12536 | return ir_analyze_err_wrap_payload(ira, source_instr, value, wanted_type, result_loc); |
| 11736 | 12537 | } else if (actual_type->id == ZigTypeIdComptimeInt || |
| 11737 | 12538 | actual_type->id == ZigTypeIdComptimeFloat) |
| 11738 | 12539 | { |
| 11739 | 12540 | if (ir_num_lit_fits_in_other_type(ira, value, wanted_type->data.error_union.payload_type, true)) { |
| 11740 | | return ir_analyze_err_wrap_payload(ira, source_instr, value, wanted_type); |
| 12541 | return ir_analyze_err_wrap_payload(ira, source_instr, value, wanted_type, result_loc); |
| 11741 | 12542 | } else { |
| 11742 | 12543 | return ira->codegen->invalid_instruction; |
| 11743 | 12544 | } |
| ... | ... | @@ -11755,11 +12556,11 @@ static IrInstruction *ir_analyze_cast(IrAnalyze *ira, IrInstruction *source_inst |
| 11755 | 12556 | actual_type->id == ZigTypeIdComptimeInt || |
| 11756 | 12557 | actual_type->id == ZigTypeIdComptimeFloat) |
| 11757 | 12558 | { |
| 11758 | | IrInstruction *cast1 = ir_analyze_cast(ira, source_instr, wanted_type->data.error_union.payload_type, value); |
| 12559 | IrInstruction *cast1 = ir_analyze_cast(ira, source_instr, wanted_type->data.error_union.payload_type, value, nullptr); |
| 11759 | 12560 | if (type_is_invalid(cast1->value.type)) |
| 11760 | 12561 | return ira->codegen->invalid_instruction; |
| 11761 | 12562 | |
| 11762 | | IrInstruction *cast2 = ir_analyze_cast(ira, source_instr, wanted_type, cast1); |
| 12563 | IrInstruction *cast2 = ir_analyze_cast(ira, source_instr, wanted_type, cast1, result_loc); |
| 11763 | 12564 | if (type_is_invalid(cast2->value.type)) |
| 11764 | 12565 | return ira->codegen->invalid_instruction; |
| 11765 | 12566 | |
| ... | ... | @@ -11841,7 +12642,7 @@ static IrInstruction *ir_analyze_cast(IrAnalyze *ira, IrInstruction *source_inst |
| 11841 | 12642 | types_match_const_cast_only(ira, ptr_type->data.pointer.child_type, actual_type->data.array.child_type, |
| 11842 | 12643 | source_node, false).id == ConstCastResultIdOk) |
| 11843 | 12644 | { |
| 11844 | | return ir_analyze_array_to_slice(ira, source_instr, value, wanted_type); |
| 12645 | return ir_analyze_array_to_slice(ira, source_instr, value, wanted_type, result_loc); |
| 11845 | 12646 | } |
| 11846 | 12647 | } |
| 11847 | 12648 | |
| ... | ... | @@ -11858,11 +12659,11 @@ static IrInstruction *ir_analyze_cast(IrAnalyze *ira, IrInstruction *source_inst |
| 11858 | 12659 | types_match_const_cast_only(ira, ptr_type->data.pointer.child_type, actual_type->data.array.child_type, |
| 11859 | 12660 | source_node, false).id == ConstCastResultIdOk) |
| 11860 | 12661 | { |
| 11861 | | IrInstruction *cast1 = ir_analyze_cast(ira, source_instr, wanted_type->data.maybe.child_type, value); |
| 12662 | IrInstruction *cast1 = ir_analyze_cast(ira, source_instr, wanted_type->data.maybe.child_type, value, nullptr); |
| 11862 | 12663 | if (type_is_invalid(cast1->value.type)) |
| 11863 | 12664 | return ira->codegen->invalid_instruction; |
| 11864 | 12665 | |
| 11865 | | IrInstruction *cast2 = ir_analyze_cast(ira, source_instr, wanted_type, cast1); |
| 12666 | IrInstruction *cast2 = ir_analyze_cast(ira, source_instr, wanted_type, cast1, result_loc); |
| 11866 | 12667 | if (type_is_invalid(cast2->value.type)) |
| 11867 | 12668 | return ira->codegen->invalid_instruction; |
| 11868 | 12669 | |
| ... | ... | @@ -11905,7 +12706,7 @@ static IrInstruction *ir_analyze_cast(IrAnalyze *ira, IrInstruction *source_inst |
| 11905 | 12706 | array_type->data.array.child_type, source_node, |
| 11906 | 12707 | !slice_ptr_type->data.pointer.is_const).id == ConstCastResultIdOk) |
| 11907 | 12708 | { |
| 11908 | | return ir_resolve_ptr_of_array_to_slice(ira, source_instr, value, wanted_type); |
| 12709 | return ir_resolve_ptr_of_array_to_slice(ira, source_instr, value, wanted_type, result_loc); |
| 11909 | 12710 | } |
| 11910 | 12711 | } |
| 11911 | 12712 | |
| ... | ... | @@ -11936,11 +12737,11 @@ static IrInstruction *ir_analyze_cast(IrAnalyze *ira, IrInstruction *source_inst |
| 11936 | 12737 | types_match_const_cast_only(ira, ptr_type->data.pointer.child_type, actual_type->data.array.child_type, |
| 11937 | 12738 | source_node, false).id == ConstCastResultIdOk) |
| 11938 | 12739 | { |
| 11939 | | IrInstruction *cast1 = ir_analyze_cast(ira, source_instr, wanted_type->data.error_union.payload_type, value); |
| 12740 | IrInstruction *cast1 = ir_analyze_cast(ira, source_instr, wanted_type->data.error_union.payload_type, value, nullptr); |
| 11940 | 12741 | if (type_is_invalid(cast1->value.type)) |
| 11941 | 12742 | return ira->codegen->invalid_instruction; |
| 11942 | 12743 | |
| 11943 | | IrInstruction *cast2 = ir_analyze_cast(ira, source_instr, wanted_type, cast1); |
| 12744 | IrInstruction *cast2 = ir_analyze_cast(ira, source_instr, wanted_type, cast1, result_loc); |
| 11944 | 12745 | if (type_is_invalid(cast2->value.type)) |
| 11945 | 12746 | return ira->codegen->invalid_instruction; |
| 11946 | 12747 | |
| ... | ... | @@ -11952,7 +12753,7 @@ static IrInstruction *ir_analyze_cast(IrAnalyze *ira, IrInstruction *source_inst |
| 11952 | 12753 | if (wanted_type->id == ZigTypeIdErrorUnion && |
| 11953 | 12754 | actual_type->id == ZigTypeIdErrorSet) |
| 11954 | 12755 | { |
| 11955 | | return ir_analyze_err_wrap_code(ira, source_instr, value, wanted_type); |
| 12756 | return ir_analyze_err_wrap_code(ira, source_instr, value, wanted_type, result_loc); |
| 11956 | 12757 | } |
| 11957 | 12758 | |
| 11958 | 12759 | // cast from typed number to integer or float literal. |
| ... | ... | @@ -12076,7 +12877,7 @@ static IrInstruction *ir_analyze_cast(IrAnalyze *ira, IrInstruction *source_inst |
| 12076 | 12877 | types_match_const_cast_only(ira, wanted_type->data.array.child_type, |
| 12077 | 12878 | actual_type->data.vector.elem_type, source_node, false).id == ConstCastResultIdOk) |
| 12078 | 12879 | { |
| 12079 | | return ir_analyze_vector_to_array(ira, source_instr, value, wanted_type); |
| 12880 | return ir_analyze_vector_to_array(ira, source_instr, value, wanted_type, result_loc); |
| 12080 | 12881 | } |
| 12081 | 12882 | |
| 12082 | 12883 | // cast from [N]T to @Vector(N, T) |
| ... | ... | @@ -12118,7 +12919,9 @@ static IrInstruction *ir_analyze_cast(IrAnalyze *ira, IrInstruction *source_inst |
| 12118 | 12919 | return ira->codegen->invalid_instruction; |
| 12119 | 12920 | } |
| 12120 | 12921 | |
| 12121 | | static IrInstruction *ir_implicit_cast(IrAnalyze *ira, IrInstruction *value, ZigType *expected_type) { |
| 12922 | static IrInstruction *ir_implicit_cast_with_result(IrAnalyze *ira, IrInstruction *value, ZigType *expected_type, |
| 12923 | ResultLoc *result_loc) |
| 12924 | { |
| 12122 | 12925 | assert(value); |
| 12123 | 12926 | assert(value != ira->codegen->invalid_instruction); |
| 12124 | 12927 | assert(!expected_type || !type_is_invalid(expected_type)); |
| ... | ... | @@ -12131,63 +12934,76 @@ static IrInstruction *ir_implicit_cast(IrAnalyze *ira, IrInstruction *value, Zig |
| 12131 | 12934 | if (value->value.type->id == ZigTypeIdUnreachable) |
| 12132 | 12935 | return value; |
| 12133 | 12936 | |
| 12134 | | return ir_analyze_cast(ira, value, expected_type, value); |
| 12937 | return ir_analyze_cast(ira, value, expected_type, value, result_loc); |
| 12938 | } |
| 12939 | |
| 12940 | static IrInstruction *ir_implicit_cast(IrAnalyze *ira, IrInstruction *value, ZigType *expected_type) { |
| 12941 | return ir_implicit_cast_with_result(ira, value, expected_type, nullptr); |
| 12135 | 12942 | } |
| 12136 | 12943 | |
| 12137 | | static IrInstruction *ir_get_deref(IrAnalyze *ira, IrInstruction *source_instruction, IrInstruction *ptr) { |
| 12944 | static IrInstruction *ir_get_deref(IrAnalyze *ira, IrInstruction *source_instruction, IrInstruction *ptr, |
| 12945 | ResultLoc *result_loc) |
| 12946 | { |
| 12138 | 12947 | Error err; |
| 12139 | 12948 | ZigType *type_entry = ptr->value.type; |
| 12140 | | if (type_is_invalid(type_entry)) { |
| 12949 | if (type_is_invalid(type_entry)) |
| 12141 | 12950 | return ira->codegen->invalid_instruction; |
| 12142 | | } else if (type_entry->id == ZigTypeIdPointer) { |
| 12143 | | ZigType *child_type = type_entry->data.pointer.child_type; |
| 12144 | | // if the child type has one possible value, the deref is comptime |
| 12145 | | switch (type_has_one_possible_value(ira->codegen, child_type)) { |
| 12146 | | case OnePossibleValueInvalid: |
| 12147 | | return ira->codegen->invalid_instruction; |
| 12148 | | case OnePossibleValueYes: |
| 12149 | | return ir_const(ira, source_instruction, child_type); |
| 12150 | | case OnePossibleValueNo: |
| 12151 | | break; |
| 12152 | | } |
| 12153 | | if (instr_is_comptime(ptr)) { |
| 12154 | | if (ptr->value.special == ConstValSpecialUndef) { |
| 12155 | | ir_add_error(ira, ptr, buf_sprintf("attempt to dereference undefined value")); |
| 12156 | | return ira->codegen->invalid_instruction; |
| 12157 | | } |
| 12158 | | if (ptr->value.data.x_ptr.mut == ConstPtrMutComptimeConst || |
| 12159 | | ptr->value.data.x_ptr.mut == ConstPtrMutComptimeVar) |
| 12160 | | { |
| 12161 | | ConstExprValue *pointee = const_ptr_pointee_unchecked(ira->codegen, &ptr->value); |
| 12162 | | if (pointee->special != ConstValSpecialRuntime) { |
| 12163 | | IrInstruction *result = ir_const(ira, source_instruction, child_type); |
| 12164 | 12951 | |
| 12165 | | if ((err = ir_read_const_ptr(ira, ira->codegen, source_instruction->source_node, &result->value, |
| 12166 | | &ptr->value))) |
| 12167 | | { |
| 12168 | | return ira->codegen->invalid_instruction; |
| 12169 | | } |
| 12170 | | result->value.type = child_type; |
| 12171 | | return result; |
| 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; |
| 12973 | } |
| 12974 | if (ptr->value.data.x_ptr.mut != ConstPtrMutRuntimeVar) { |
| 12975 | ConstExprValue *pointee = const_ptr_pointee_unchecked(ira->codegen, &ptr->value); |
| 12976 | if (pointee->special != ConstValSpecialRuntime) { |
| 12977 | IrInstruction *result = ir_const(ira, source_instruction, child_type); |
| 12978 | |
| 12979 | if ((err = ir_read_const_ptr(ira, ira->codegen, source_instruction->source_node, &result->value, |
| 12980 | &ptr->value))) |
| 12981 | { |
| 12982 | return ira->codegen->invalid_instruction; |
| 12172 | 12983 | } |
| 12984 | result->value.type = child_type; |
| 12985 | return result; |
| 12173 | 12986 | } |
| 12174 | 12987 | } |
| 12175 | | // if the instruction is a const ref instruction we can skip it |
| 12176 | | if (ptr->id == IrInstructionIdRef) { |
| 12177 | | IrInstructionRef *ref_inst = reinterpret_cast<IrInstructionRef *>(ptr); |
| 12178 | | return ref_inst->value; |
| 12179 | | } |
| 12180 | | IrInstruction *result = ir_build_load_ptr_gen(ira, source_instruction, ptr, child_type); |
| 12181 | | if (type_entry->data.pointer.host_int_bytes != 0 && handle_is_ptr(child_type)) { |
| 12182 | | 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; |
| 12183 | 13001 | } |
| 12184 | | return result; |
| 12185 | 13002 | } else { |
| 12186 | | ir_add_error_node(ira, source_instruction->source_node, |
| 12187 | | buf_sprintf("attempt to dereference non-pointer type '%s'", |
| 12188 | | buf_ptr(&type_entry->name))); |
| 12189 | | return ira->codegen->invalid_instruction; |
| 13003 | result_loc_inst = nullptr; |
| 12190 | 13004 | } |
| 13005 | |
| 13006 | return ir_build_load_ptr_gen(ira, source_instruction, ptr, child_type, result_loc_inst); |
| 12191 | 13007 | } |
| 12192 | 13008 | |
| 12193 | 13009 | static bool ir_resolve_align(IrAnalyze *ira, IrInstruction *value, uint32_t *out) { |
| ... | ... | @@ -12401,6 +13217,14 @@ static IrInstruction *ir_analyze_instruction_return(IrAnalyze *ira, IrInstructio |
| 12401 | 13217 | if (type_is_invalid(value->value.type)) |
| 12402 | 13218 | return ir_unreach_error(ira); |
| 12403 | 13219 | |
| 13220 | if (!instr_is_comptime(value) && handle_is_ptr(ira->explicit_return_type)) { |
| 13221 | // result location mechanism took care of it. |
| 13222 | IrInstruction *result = ir_build_return(&ira->new_irb, instruction->base.scope, |
| 13223 | instruction->base.source_node, nullptr); |
| 13224 | result->value.type = ira->codegen->builtin_types.entry_unreachable; |
| 13225 | return ir_finish_anal(ira, result); |
| 13226 | } |
| 13227 | |
| 12404 | 13228 | IrInstruction *casted_value = ir_implicit_cast(ira, value, ira->explicit_return_type); |
| 12405 | 13229 | if (type_is_invalid(casted_value->value.type)) { |
| 12406 | 13230 | AstNode *source_node = ira->explicit_return_type_source_node; |
| ... | ... | @@ -12563,7 +13387,7 @@ static IrInstruction *ir_analyze_bin_op_cmp(IrAnalyze *ira, IrInstructionBinOp * |
| 12563 | 13387 | } else { |
| 12564 | 13388 | return is_non_null; |
| 12565 | 13389 | } |
| 12566 | | } else if (is_equality_cmp && |
| 13390 | } else if (is_equality_cmp && |
| 12567 | 13391 | ((op1->value.type->id == ZigTypeIdNull && op2->value.type->id == ZigTypeIdPointer && |
| 12568 | 13392 | op2->value.type->data.pointer.ptr_len == PtrLenC) || |
| 12569 | 13393 | (op2->value.type->id == ZigTypeIdNull && op1->value.type->id == ZigTypeIdPointer && |
| ... | ... | @@ -13005,7 +13829,7 @@ static ErrorMsg *ir_eval_math_op_scalar(IrAnalyze *ira, IrInstruction *source_in |
| 13005 | 13829 | } |
| 13006 | 13830 | } else { |
| 13007 | 13831 | float_div_trunc(out_val, op1_val, op2_val); |
| 13008 | | ConstExprValue remainder; |
| 13832 | ConstExprValue remainder = {}; |
| 13009 | 13833 | float_rem(&remainder, op1_val, op2_val); |
| 13010 | 13834 | if (float_cmp_zero(&remainder) != CmpEQ) { |
| 13011 | 13835 | return ir_add_error(ira, source_instr, buf_sprintf("exact division had a remainder")); |
| ... | ... | @@ -13380,8 +14204,8 @@ static IrInstruction *ir_analyze_bin_op_math(IrAnalyze *ira, IrInstructionBinOp |
| 13380 | 14204 | // have a remainder function ambiguity problem |
| 13381 | 14205 | ok = true; |
| 13382 | 14206 | } else { |
| 13383 | | ConstExprValue rem_result; |
| 13384 | | ConstExprValue mod_result; |
| 14207 | ConstExprValue rem_result = {}; |
| 14208 | ConstExprValue mod_result = {}; |
| 13385 | 14209 | float_rem(&rem_result, op1_val, op2_val); |
| 13386 | 14210 | float_mod(&mod_result, op1_val, op2_val); |
| 13387 | 14211 | ok = float_cmp(&rem_result, &mod_result) == CmpEQ; |
| ... | ... | @@ -13604,10 +14428,12 @@ static IrInstruction *ir_analyze_array_cat(IrAnalyze *ira, IrInstructionBinOp *i |
| 13604 | 14428 | |
| 13605 | 14429 | size_t next_index = 0; |
| 13606 | 14430 | for (size_t i = op1_array_index; i < op1_array_end; i += 1, next_index += 1) { |
| 13607 | | out_array_val->data.x_array.data.s_none.elements[next_index] = op1_array_val->data.x_array.data.s_none.elements[i]; |
| 14431 | copy_const_val(&out_array_val->data.x_array.data.s_none.elements[next_index], |
| 14432 | &op1_array_val->data.x_array.data.s_none.elements[i], true); |
| 13608 | 14433 | } |
| 13609 | 14434 | for (size_t i = op2_array_index; i < op2_array_end; i += 1, next_index += 1) { |
| 13610 | | out_array_val->data.x_array.data.s_none.elements[next_index] = op2_array_val->data.x_array.data.s_none.elements[i]; |
| 14435 | copy_const_val(&out_array_val->data.x_array.data.s_none.elements[next_index], |
| 14436 | &op2_array_val->data.x_array.data.s_none.elements[i], true); |
| 13611 | 14437 | } |
| 13612 | 14438 | if (next_index < new_len) { |
| 13613 | 14439 | ConstExprValue *null_byte = &out_array_val->data.x_array.data.s_none.elements[next_index]; |
| ... | ... | @@ -13668,7 +14494,8 @@ static IrInstruction *ir_analyze_array_mult(IrAnalyze *ira, IrInstructionBinOp * |
| 13668 | 14494 | uint64_t i = 0; |
| 13669 | 14495 | for (uint64_t x = 0; x < mult_amt; x += 1) { |
| 13670 | 14496 | for (uint64_t y = 0; y < old_array_len; y += 1) { |
| 13671 | | out_val->data.x_array.data.s_none.elements[i] = array_val->data.x_array.data.s_none.elements[y]; |
| 14497 | copy_const_val(&out_val->data.x_array.data.s_none.elements[i], |
| 14498 | &array_val->data.x_array.data.s_none.elements[y], true); |
| 13672 | 14499 | i += 1; |
| 13673 | 14500 | } |
| 13674 | 14501 | } |
| ... | ... | @@ -13765,12 +14592,6 @@ static IrInstruction *ir_analyze_instruction_decl_var(IrAnalyze *ira, |
| 13765 | 14592 | Error err; |
| 13766 | 14593 | ZigVar *var = decl_var_instruction->var; |
| 13767 | 14594 | |
| 13768 | | IrInstruction *init_value = decl_var_instruction->init_value->child; |
| 13769 | | if (type_is_invalid(init_value->value.type)) { |
| 13770 | | var->var_type = ira->codegen->builtin_types.entry_invalid; |
| 13771 | | return ira->codegen->invalid_instruction; |
| 13772 | | } |
| 13773 | | |
| 13774 | 14595 | ZigType *explicit_type = nullptr; |
| 13775 | 14596 | IrInstruction *var_type = nullptr; |
| 13776 | 14597 | if (decl_var_instruction->var_type != nullptr) { |
| ... | ... | @@ -13785,18 +14606,40 @@ static IrInstruction *ir_analyze_instruction_decl_var(IrAnalyze *ira, |
| 13785 | 14606 | |
| 13786 | 14607 | AstNode *source_node = decl_var_instruction->base.source_node; |
| 13787 | 14608 | |
| 13788 | | IrInstruction *casted_init_value = ir_implicit_cast(ira, init_value, explicit_type); |
| 13789 | 14609 | bool is_comptime_var = ir_get_var_is_comptime(var); |
| 13790 | 14610 | |
| 13791 | 14611 | bool var_class_requires_const = false; |
| 13792 | 14612 | |
| 13793 | | ZigType *result_type = casted_init_value->value.type; |
| 14613 | IrInstruction *var_ptr = decl_var_instruction->ptr->child; |
| 14614 | // if this is null, a compiler error happened and did not initialize the variable. |
| 14615 | // if there are no compile errors there may be a missing ir_expr_wrap in pass1 IR generation. |
| 14616 | if (var_ptr == nullptr || type_is_invalid(var_ptr->value.type)) { |
| 14617 | ir_assert(var_ptr != nullptr || ira->codegen->errors.length != 0, &decl_var_instruction->base); |
| 14618 | var->var_type = ira->codegen->builtin_types.entry_invalid; |
| 14619 | return ira->codegen->invalid_instruction; |
| 14620 | } |
| 14621 | |
| 14622 | // The ir_build_var_decl_src call is supposed to pass a pointer to the allocation, not an initialization value. |
| 14623 | ir_assert(var_ptr->value.type->id == ZigTypeIdPointer, &decl_var_instruction->base); |
| 14624 | |
| 14625 | ZigType *result_type = var_ptr->value.type->data.pointer.child_type; |
| 13794 | 14626 | if (type_is_invalid(result_type)) { |
| 13795 | 14627 | result_type = ira->codegen->builtin_types.entry_invalid; |
| 13796 | 14628 | } else if (result_type->id == ZigTypeIdUnreachable || result_type->id == ZigTypeIdOpaque) { |
| 13797 | | ir_add_error_node(ira, source_node, |
| 13798 | | buf_sprintf("variable of type '%s' not allowed", buf_ptr(&result_type->name))); |
| 13799 | | 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 | } |
| 13800 | 14643 | } |
| 13801 | 14644 | |
| 13802 | 14645 | switch (type_requires_comptime(ira->codegen, result_type)) { |
| ... | ... | @@ -13813,18 +14656,20 @@ static IrInstruction *ir_analyze_instruction_decl_var(IrAnalyze *ira, |
| 13813 | 14656 | } |
| 13814 | 14657 | break; |
| 13815 | 14658 | case ReqCompTimeNo: |
| 13816 | | if (casted_init_value->value.special == ConstValSpecialStatic && |
| 13817 | | casted_init_value->value.type->id == ZigTypeIdFn && |
| 13818 | | casted_init_value->value.data.x_ptr.special != ConstPtrSpecialHardCodedAddr && |
| 13819 | | casted_init_value->value.data.x_ptr.data.fn.fn_entry->fn_inline == FnInlineAlways) |
| 13820 | | { |
| 13821 | | var_class_requires_const = true; |
| 13822 | | if (!var->src_is_const && !is_comptime_var) { |
| 13823 | | ErrorMsg *msg = ir_add_error_node(ira, source_node, |
| 13824 | | buf_sprintf("functions marked inline must be stored in const or comptime var")); |
| 13825 | | AstNode *proto_node = casted_init_value->value.data.x_ptr.data.fn.fn_entry->proto_node; |
| 13826 | | add_error_note(ira->codegen, msg, proto_node, buf_sprintf("declared here")); |
| 13827 | | 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 | } |
| 13828 | 14673 | } |
| 13829 | 14674 | } |
| 13830 | 14675 | break; |
| ... | ... | @@ -13871,11 +14716,29 @@ static IrInstruction *ir_analyze_instruction_decl_var(IrAnalyze *ira, |
| 13871 | 14716 | } |
| 13872 | 14717 | } |
| 13873 | 14718 | |
| 13874 | | if (casted_init_value->value.special != ConstValSpecialRuntime) { |
| 13875 | | 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) { |
| 13876 | 14739 | assert(var->mem_slot_index < ira->exec_context.mem_slot_list.length); |
| 13877 | 14740 | ConstExprValue *mem_slot = ira->exec_context.mem_slot_list.at(var->mem_slot_index); |
| 13878 | | copy_const_val(mem_slot, &casted_init_value->value, !is_comptime_var || var->gen_is_const); |
| 14741 | copy_const_val(mem_slot, init_val, !is_comptime_var || var->gen_is_const); |
| 13879 | 14742 | |
| 13880 | 14743 | if (is_comptime_var || (var_class_requires_const && var->gen_is_const)) { |
| 13881 | 14744 | return ir_const_void(ira, &decl_var_instruction->base); |
| ... | ... | @@ -13892,7 +14755,7 @@ static IrInstruction *ir_analyze_instruction_decl_var(IrAnalyze *ira, |
| 13892 | 14755 | if (fn_entry) |
| 13893 | 14756 | fn_entry->variable_list.append(var); |
| 13894 | 14757 | |
| 13895 | | return ir_build_var_decl_gen(ira, &decl_var_instruction->base, var, casted_init_value); |
| 14758 | return ir_build_var_decl_gen(ira, &decl_var_instruction->base, var, var_ptr); |
| 13896 | 14759 | } |
| 13897 | 14760 | |
| 13898 | 14761 | static IrInstruction *ir_analyze_instruction_export(IrAnalyze *ira, IrInstructionExport *instruction) { |
| ... | ... | @@ -14186,7 +15049,7 @@ IrInstruction *ir_get_implicit_allocator(IrAnalyze *ira, IrInstruction *source_i |
| 14186 | 15049 | ZigVar *coro_allocator_var = ira->old_irb.exec->coro_allocator_var; |
| 14187 | 15050 | assert(coro_allocator_var != nullptr); |
| 14188 | 15051 | IrInstruction *var_ptr_inst = ir_get_var_ptr(ira, source_instr, coro_allocator_var); |
| 14189 | | IrInstruction *result = ir_get_deref(ira, source_instr, var_ptr_inst); |
| 15052 | IrInstruction *result = ir_get_deref(ira, source_instr, var_ptr_inst, nullptr); |
| 14190 | 15053 | assert(result->value.type != nullptr); |
| 14191 | 15054 | return result; |
| 14192 | 15055 | } |
| ... | ... | @@ -14194,7 +15057,436 @@ IrInstruction *ir_get_implicit_allocator(IrAnalyze *ira, IrInstruction *source_i |
| 14194 | 15057 | zig_unreachable(); |
| 14195 | 15058 | } |
| 14196 | 15059 | |
| 14197 | | static IrInstruction *ir_analyze_async_call(IrAnalyze *ira, IrInstructionCall *call_instruction, ZigFn *fn_entry, |
| 15060 | static IrInstruction *ir_analyze_alloca(IrAnalyze *ira, IrInstruction *source_inst, ZigType *var_type, |
| 15061 | uint32_t align, const char *name_hint, bool force_comptime) |
| 15062 | { |
| 15063 | Error err; |
| 15064 | |
| 15065 | ConstExprValue *pointee = create_const_vals(1); |
| 15066 | pointee->special = ConstValSpecialUndef; |
| 15067 | |
| 15068 | IrInstructionAllocaGen *result = ir_create_alloca_gen(ira, source_inst, align, name_hint); |
| 15069 | result->base.value.special = ConstValSpecialStatic; |
| 15070 | result->base.value.data.x_ptr.special = ConstPtrSpecialRef; |
| 15071 | result->base.value.data.x_ptr.mut = force_comptime ? ConstPtrMutComptimeVar : ConstPtrMutInfer; |
| 15072 | result->base.value.data.x_ptr.data.ref.pointee = pointee; |
| 15073 | |
| 15074 | if ((err = type_resolve(ira->codegen, var_type, ResolveStatusZeroBitsKnown))) |
| 15075 | return ira->codegen->invalid_instruction; |
| 15076 | assert(result->base.value.data.x_ptr.special != ConstPtrSpecialInvalid); |
| 15077 | |
| 15078 | pointee->type = var_type; |
| 15079 | result->base.value.type = get_pointer_to_type_extra(ira->codegen, var_type, false, false, |
| 15080 | PtrLenSingle, align, 0, 0, false); |
| 15081 | |
| 15082 | ZigFn *fn_entry = exec_fn_entry(ira->new_irb.exec); |
| 15083 | if (fn_entry != nullptr) { |
| 15084 | fn_entry->alloca_gen_list.append(result); |
| 15085 | } |
| 15086 | result->base.is_gen = true; |
| 15087 | return &result->base; |
| 15088 | } |
| 15089 | |
| 15090 | static ZigType *ir_result_loc_expected_type(IrAnalyze *ira, IrInstruction *suspend_source_instr, |
| 15091 | ResultLoc *result_loc) |
| 15092 | { |
| 15093 | switch (result_loc->id) { |
| 15094 | case ResultLocIdInvalid: |
| 15095 | case ResultLocIdPeerParent: |
| 15096 | zig_unreachable(); |
| 15097 | case ResultLocIdNone: |
| 15098 | case ResultLocIdVar: |
| 15099 | case ResultLocIdBitCast: |
| 15100 | return nullptr; |
| 15101 | case ResultLocIdInstruction: |
| 15102 | return result_loc->source_instruction->child->value.type; |
| 15103 | case ResultLocIdReturn: |
| 15104 | return ira->explicit_return_type; |
| 15105 | case ResultLocIdPeer: |
| 15106 | return reinterpret_cast<ResultLocPeer*>(result_loc)->parent->resolved_type; |
| 15107 | } |
| 15108 | zig_unreachable(); |
| 15109 | } |
| 15110 | |
| 15111 | static bool type_can_bit_cast(ZigType *t) { |
| 15112 | switch (t->id) { |
| 15113 | case ZigTypeIdInvalid: |
| 15114 | zig_unreachable(); |
| 15115 | case ZigTypeIdMetaType: |
| 15116 | case ZigTypeIdOpaque: |
| 15117 | case ZigTypeIdBoundFn: |
| 15118 | case ZigTypeIdArgTuple: |
| 15119 | case ZigTypeIdUnreachable: |
| 15120 | case ZigTypeIdComptimeFloat: |
| 15121 | case ZigTypeIdComptimeInt: |
| 15122 | case ZigTypeIdEnumLiteral: |
| 15123 | case ZigTypeIdUndefined: |
| 15124 | case ZigTypeIdNull: |
| 15125 | case ZigTypeIdPointer: |
| 15126 | return false; |
| 15127 | default: |
| 15128 | // TODO list these types out explicitly, there are probably some other invalid ones here |
| 15129 | return true; |
| 15130 | } |
| 15131 | } |
| 15132 | |
| 15133 | static void set_up_result_loc_for_inferred_comptime(IrInstruction *ptr) { |
| 15134 | ConstExprValue *undef_child = create_const_vals(1); |
| 15135 | undef_child->type = ptr->value.type->data.pointer.child_type; |
| 15136 | undef_child->special = ConstValSpecialUndef; |
| 15137 | ptr->value.special = ConstValSpecialStatic; |
| 15138 | ptr->value.data.x_ptr.mut = ConstPtrMutInfer; |
| 15139 | ptr->value.data.x_ptr.special = ConstPtrSpecialRef; |
| 15140 | ptr->value.data.x_ptr.data.ref.pointee = undef_child; |
| 15141 | } |
| 15142 | |
| 15143 | // when calling this function, at the callsite must check for result type noreturn and propagate it up |
| 15144 | static IrInstruction *ir_resolve_result_raw(IrAnalyze *ira, IrInstruction *suspend_source_instr, |
| 15145 | ResultLoc *result_loc, ZigType *value_type, IrInstruction *value, bool force_runtime, bool non_null_comptime) |
| 15146 | { |
| 15147 | Error err; |
| 15148 | if (result_loc->resolved_loc != nullptr) { |
| 15149 | // allow to redo the result location if the value is known and comptime and the previous one isn't |
| 15150 | if (value == nullptr || !instr_is_comptime(value) || instr_is_comptime(result_loc->resolved_loc)) { |
| 15151 | return result_loc->resolved_loc; |
| 15152 | } |
| 15153 | } |
| 15154 | result_loc->gen_instruction = value; |
| 15155 | result_loc->implicit_elem_type = value_type; |
| 15156 | switch (result_loc->id) { |
| 15157 | case ResultLocIdInvalid: |
| 15158 | case ResultLocIdPeerParent: |
| 15159 | zig_unreachable(); |
| 15160 | case ResultLocIdNone: { |
| 15161 | if (value != nullptr) { |
| 15162 | return nullptr; |
| 15163 | } |
| 15164 | // need to return a result location and don't have one. use a stack allocation |
| 15165 | IrInstructionAllocaGen *alloca_gen = ir_create_alloca_gen(ira, suspend_source_instr, 0, ""); |
| 15166 | if ((err = type_resolve(ira->codegen, value_type, ResolveStatusZeroBitsKnown))) |
| 15167 | return ira->codegen->invalid_instruction; |
| 15168 | alloca_gen->base.value.type = get_pointer_to_type_extra(ira->codegen, value_type, false, false, |
| 15169 | PtrLenSingle, 0, 0, 0, false); |
| 15170 | set_up_result_loc_for_inferred_comptime(&alloca_gen->base); |
| 15171 | ZigFn *fn_entry = exec_fn_entry(ira->new_irb.exec); |
| 15172 | if (fn_entry != nullptr) { |
| 15173 | fn_entry->alloca_gen_list.append(alloca_gen); |
| 15174 | } |
| 15175 | result_loc->written = true; |
| 15176 | result_loc->resolved_loc = &alloca_gen->base; |
| 15177 | return result_loc->resolved_loc; |
| 15178 | } |
| 15179 | case ResultLocIdVar: { |
| 15180 | ResultLocVar *result_loc_var = reinterpret_cast<ResultLocVar *>(result_loc); |
| 15181 | assert(result_loc->source_instruction->id == IrInstructionIdAllocaSrc); |
| 15182 | |
| 15183 | if (value_type->id == ZigTypeIdUnreachable || value_type->id == ZigTypeIdOpaque) { |
| 15184 | ir_add_error(ira, result_loc->source_instruction, |
| 15185 | buf_sprintf("variable of type '%s' not allowed", buf_ptr(&value_type->name))); |
| 15186 | return ira->codegen->invalid_instruction; |
| 15187 | } |
| 15188 | |
| 15189 | IrInstructionAllocaSrc *alloca_src = |
| 15190 | reinterpret_cast<IrInstructionAllocaSrc *>(result_loc->source_instruction); |
| 15191 | bool force_comptime; |
| 15192 | if (!ir_resolve_comptime(ira, alloca_src->is_comptime->child, &force_comptime)) |
| 15193 | return ira->codegen->invalid_instruction; |
| 15194 | bool is_comptime = force_comptime || (value != nullptr && |
| 15195 | value->value.special != ConstValSpecialRuntime && result_loc_var->var->gen_is_const); |
| 15196 | |
| 15197 | if (alloca_src->base.child == nullptr || is_comptime) { |
| 15198 | uint32_t align = 0; |
| 15199 | if (alloca_src->align != nullptr && !ir_resolve_align(ira, alloca_src->align->child, &align)) { |
| 15200 | return ira->codegen->invalid_instruction; |
| 15201 | } |
| 15202 | IrInstruction *alloca_gen; |
| 15203 | if (is_comptime && value != nullptr) { |
| 15204 | if (align > value->value.global_refs->align) { |
| 15205 | value->value.global_refs->align = align; |
| 15206 | } |
| 15207 | alloca_gen = ir_get_ref(ira, result_loc->source_instruction, value, true, false); |
| 15208 | } else { |
| 15209 | alloca_gen = ir_analyze_alloca(ira, result_loc->source_instruction, value_type, align, |
| 15210 | alloca_src->name_hint, force_comptime); |
| 15211 | } |
| 15212 | if (alloca_src->base.child != nullptr) { |
| 15213 | alloca_src->base.child->ref_count = 0; |
| 15214 | } |
| 15215 | alloca_src->base.child = alloca_gen; |
| 15216 | } |
| 15217 | result_loc->written = true; |
| 15218 | result_loc->resolved_loc = is_comptime ? nullptr : alloca_src->base.child; |
| 15219 | return result_loc->resolved_loc; |
| 15220 | } |
| 15221 | case ResultLocIdInstruction: { |
| 15222 | result_loc->written = true; |
| 15223 | result_loc->resolved_loc = result_loc->source_instruction->child; |
| 15224 | return result_loc->resolved_loc; |
| 15225 | } |
| 15226 | case ResultLocIdReturn: { |
| 15227 | if (!non_null_comptime) { |
| 15228 | bool is_comptime = value != nullptr && value->value.special != ConstValSpecialRuntime; |
| 15229 | if (is_comptime) |
| 15230 | return nullptr; |
| 15231 | } |
| 15232 | if ((err = type_resolve(ira->codegen, ira->explicit_return_type, ResolveStatusZeroBitsKnown))) { |
| 15233 | return ira->codegen->invalid_instruction; |
| 15234 | } |
| 15235 | if (!type_has_bits(ira->explicit_return_type) || !handle_is_ptr(ira->explicit_return_type)) |
| 15236 | return nullptr; |
| 15237 | |
| 15238 | ZigType *ptr_return_type = get_pointer_to_type(ira->codegen, ira->explicit_return_type, false); |
| 15239 | result_loc->written = true; |
| 15240 | result_loc->resolved_loc = ir_build_return_ptr(ira, result_loc->source_instruction, ptr_return_type); |
| 15241 | if (ir_should_inline(ira->old_irb.exec, result_loc->source_instruction->scope)) { |
| 15242 | set_up_result_loc_for_inferred_comptime(result_loc->resolved_loc); |
| 15243 | } |
| 15244 | return result_loc->resolved_loc; |
| 15245 | } |
| 15246 | case ResultLocIdPeer: { |
| 15247 | ResultLocPeer *result_peer = reinterpret_cast<ResultLocPeer *>(result_loc); |
| 15248 | ResultLocPeerParent *peer_parent = result_peer->parent; |
| 15249 | |
| 15250 | if (peer_parent->peers.length == 1) { |
| 15251 | IrInstruction *parent_result_loc = ir_resolve_result(ira, suspend_source_instr, peer_parent->parent, |
| 15252 | value_type, value, force_runtime, non_null_comptime); |
| 15253 | result_peer->suspend_pos.basic_block_index = SIZE_MAX; |
| 15254 | result_peer->suspend_pos.instruction_index = SIZE_MAX; |
| 15255 | if (parent_result_loc == nullptr || type_is_invalid(parent_result_loc->value.type) || |
| 15256 | parent_result_loc->value.type->id == ZigTypeIdUnreachable) |
| 15257 | { |
| 15258 | return parent_result_loc; |
| 15259 | } |
| 15260 | result_loc->written = true; |
| 15261 | result_loc->resolved_loc = parent_result_loc; |
| 15262 | return result_loc->resolved_loc; |
| 15263 | } |
| 15264 | |
| 15265 | bool is_comptime; |
| 15266 | if (!ir_resolve_comptime(ira, peer_parent->is_comptime->child, &is_comptime)) |
| 15267 | return ira->codegen->invalid_instruction; |
| 15268 | peer_parent->skipped = is_comptime; |
| 15269 | if (peer_parent->skipped) { |
| 15270 | if (non_null_comptime) { |
| 15271 | return ir_resolve_result(ira, suspend_source_instr, peer_parent->parent, |
| 15272 | value_type, value, force_runtime, non_null_comptime); |
| 15273 | } |
| 15274 | return nullptr; |
| 15275 | } |
| 15276 | |
| 15277 | if (peer_parent->resolved_type == nullptr) { |
| 15278 | if (peer_parent->end_bb->suspend_instruction_ref == nullptr) { |
| 15279 | peer_parent->end_bb->suspend_instruction_ref = suspend_source_instr; |
| 15280 | } |
| 15281 | IrInstruction *unreach_inst = ira_suspend(ira, suspend_source_instr, result_peer->next_bb, |
| 15282 | &result_peer->suspend_pos); |
| 15283 | if (result_peer->next_bb == nullptr) { |
| 15284 | ir_start_next_bb(ira); |
| 15285 | } |
| 15286 | return unreach_inst; |
| 15287 | } |
| 15288 | |
| 15289 | IrInstruction *parent_result_loc = ir_resolve_result(ira, suspend_source_instr, peer_parent->parent, |
| 15290 | peer_parent->resolved_type, nullptr, force_runtime, non_null_comptime); |
| 15291 | if (parent_result_loc == nullptr || type_is_invalid(parent_result_loc->value.type) || |
| 15292 | parent_result_loc->value.type->id == ZigTypeIdUnreachable) |
| 15293 | { |
| 15294 | return parent_result_loc; |
| 15295 | } |
| 15296 | // because is_comptime is false, we mark this a runtime pointer |
| 15297 | parent_result_loc->value.special = ConstValSpecialRuntime; |
| 15298 | result_loc->written = true; |
| 15299 | result_loc->resolved_loc = parent_result_loc; |
| 15300 | return result_loc->resolved_loc; |
| 15301 | } |
| 15302 | case ResultLocIdBitCast: { |
| 15303 | ResultLocBitCast *result_bit_cast = reinterpret_cast<ResultLocBitCast *>(result_loc); |
| 15304 | ZigType *dest_type = ir_resolve_type(ira, result_bit_cast->base.source_instruction->child); |
| 15305 | if (type_is_invalid(dest_type)) |
| 15306 | return ira->codegen->invalid_instruction; |
| 15307 | |
| 15308 | if (get_codegen_ptr_type(dest_type) != nullptr) { |
| 15309 | ir_add_error(ira, result_loc->source_instruction, |
| 15310 | buf_sprintf("unable to @bitCast to pointer type '%s'", buf_ptr(&dest_type->name))); |
| 15311 | return ira->codegen->invalid_instruction; |
| 15312 | } |
| 15313 | |
| 15314 | if (!type_can_bit_cast(dest_type)) { |
| 15315 | ir_add_error(ira, result_loc->source_instruction, |
| 15316 | buf_sprintf("unable to @bitCast to type '%s'", buf_ptr(&dest_type->name))); |
| 15317 | return ira->codegen->invalid_instruction; |
| 15318 | } |
| 15319 | |
| 15320 | if (get_codegen_ptr_type(value_type) != nullptr) { |
| 15321 | ir_add_error(ira, suspend_source_instr, |
| 15322 | buf_sprintf("unable to @bitCast from pointer type '%s'", buf_ptr(&value_type->name))); |
| 15323 | return ira->codegen->invalid_instruction; |
| 15324 | } |
| 15325 | |
| 15326 | if (!type_can_bit_cast(value_type)) { |
| 15327 | ir_add_error(ira, suspend_source_instr, |
| 15328 | buf_sprintf("unable to @bitCast from type '%s'", buf_ptr(&value_type->name))); |
| 15329 | return ira->codegen->invalid_instruction; |
| 15330 | } |
| 15331 | |
| 15332 | IrInstruction *bitcasted_value; |
| 15333 | if (value != nullptr) { |
| 15334 | bitcasted_value = ir_analyze_bit_cast(ira, result_loc->source_instruction, value, dest_type); |
| 15335 | } else { |
| 15336 | bitcasted_value = nullptr; |
| 15337 | } |
| 15338 | |
| 15339 | IrInstruction *parent_result_loc = ir_resolve_result(ira, suspend_source_instr, result_bit_cast->parent, |
| 15340 | dest_type, bitcasted_value, force_runtime, non_null_comptime); |
| 15341 | if (parent_result_loc == nullptr || type_is_invalid(parent_result_loc->value.type) || |
| 15342 | parent_result_loc->value.type->id == ZigTypeIdUnreachable) |
| 15343 | { |
| 15344 | return parent_result_loc; |
| 15345 | } |
| 15346 | ZigType *parent_ptr_type = parent_result_loc->value.type; |
| 15347 | assert(parent_ptr_type->id == ZigTypeIdPointer); |
| 15348 | if ((err = type_resolve(ira->codegen, parent_ptr_type->data.pointer.child_type, |
| 15349 | ResolveStatusAlignmentKnown))) |
| 15350 | { |
| 15351 | return ira->codegen->invalid_instruction; |
| 15352 | } |
| 15353 | uint64_t parent_ptr_align = get_ptr_align(ira->codegen, parent_ptr_type); |
| 15354 | ZigType *ptr_type = get_pointer_to_type_extra(ira->codegen, value_type, |
| 15355 | parent_ptr_type->data.pointer.is_const, parent_ptr_type->data.pointer.is_volatile, PtrLenSingle, |
| 15356 | parent_ptr_align, 0, 0, parent_ptr_type->data.pointer.allow_zero); |
| 15357 | |
| 15358 | result_loc->written = true; |
| 15359 | result_loc->resolved_loc = ir_analyze_ptr_cast(ira, suspend_source_instr, parent_result_loc, |
| 15360 | ptr_type, result_bit_cast->base.source_instruction, false); |
| 15361 | return result_loc->resolved_loc; |
| 15362 | } |
| 15363 | } |
| 15364 | zig_unreachable(); |
| 15365 | } |
| 15366 | |
| 15367 | static IrInstruction *ir_resolve_result(IrAnalyze *ira, IrInstruction *suspend_source_instr, |
| 15368 | ResultLoc *result_loc_pass1, ZigType *value_type, IrInstruction *value, bool force_runtime, |
| 15369 | bool non_null_comptime) |
| 15370 | { |
| 15371 | IrInstruction *result_loc = ir_resolve_result_raw(ira, suspend_source_instr, result_loc_pass1, value_type, |
| 15372 | value, force_runtime, non_null_comptime); |
| 15373 | if (result_loc == nullptr || (instr_is_unreachable(result_loc) || type_is_invalid(result_loc->value.type))) |
| 15374 | return result_loc; |
| 15375 | |
| 15376 | if ((force_runtime || (value != nullptr && !instr_is_comptime(value))) && |
| 15377 | result_loc_pass1->written && result_loc->value.data.x_ptr.mut == ConstPtrMutInfer) |
| 15378 | { |
| 15379 | result_loc->value.special = ConstValSpecialRuntime; |
| 15380 | } |
| 15381 | |
| 15382 | ir_assert(result_loc->value.type->id == ZigTypeIdPointer, suspend_source_instr); |
| 15383 | ZigType *actual_elem_type = result_loc->value.type->data.pointer.child_type; |
| 15384 | if (actual_elem_type->id == ZigTypeIdOptional && value_type->id != ZigTypeIdOptional && |
| 15385 | value_type->id != ZigTypeIdNull) |
| 15386 | { |
| 15387 | return ir_analyze_unwrap_optional_payload(ira, suspend_source_instr, result_loc, false, true); |
| 15388 | } else if (actual_elem_type->id == ZigTypeIdErrorUnion && value_type->id != ZigTypeIdErrorUnion) { |
| 15389 | if (value_type->id == ZigTypeIdErrorSet) { |
| 15390 | return ir_analyze_unwrap_err_code(ira, suspend_source_instr, result_loc, true); |
| 15391 | } else { |
| 15392 | IrInstruction *unwrapped_err_ptr = ir_analyze_unwrap_error_payload(ira, suspend_source_instr, |
| 15393 | result_loc, false, true); |
| 15394 | ZigType *actual_payload_type = actual_elem_type->data.error_union.payload_type; |
| 15395 | if (actual_payload_type->id == ZigTypeIdOptional && value_type->id != ZigTypeIdOptional) { |
| 15396 | return ir_analyze_unwrap_optional_payload(ira, suspend_source_instr, unwrapped_err_ptr, false, true); |
| 15397 | } else { |
| 15398 | return unwrapped_err_ptr; |
| 15399 | } |
| 15400 | } |
| 15401 | } else if (is_slice(actual_elem_type) && value_type->id == ZigTypeIdArray) { |
| 15402 | // need to allow EndExpr to do the implicit cast from array to slice |
| 15403 | result_loc_pass1->written = false; |
| 15404 | } |
| 15405 | return result_loc; |
| 15406 | } |
| 15407 | |
| 15408 | static IrInstruction *ir_analyze_instruction_implicit_cast(IrAnalyze *ira, IrInstructionImplicitCast *instruction) { |
| 15409 | ZigType *dest_type = ir_resolve_type(ira, instruction->dest_type->child); |
| 15410 | if (type_is_invalid(dest_type)) |
| 15411 | return ira->codegen->invalid_instruction; |
| 15412 | |
| 15413 | IrInstruction *target = instruction->target->child; |
| 15414 | if (type_is_invalid(target->value.type)) |
| 15415 | return ira->codegen->invalid_instruction; |
| 15416 | |
| 15417 | return ir_implicit_cast_with_result(ira, target, dest_type, instruction->result_loc); |
| 15418 | } |
| 15419 | |
| 15420 | static IrInstruction *ir_analyze_instruction_resolve_result(IrAnalyze *ira, IrInstructionResolveResult *instruction) { |
| 15421 | ZigType *implicit_elem_type = ir_resolve_type(ira, instruction->ty->child); |
| 15422 | if (type_is_invalid(implicit_elem_type)) |
| 15423 | return ira->codegen->invalid_instruction; |
| 15424 | IrInstruction *result_loc = ir_resolve_result(ira, &instruction->base, instruction->result_loc, |
| 15425 | implicit_elem_type, nullptr, false, true); |
| 15426 | if (result_loc != nullptr) |
| 15427 | return result_loc; |
| 15428 | |
| 15429 | ZigFn *fn = exec_fn_entry(ira->new_irb.exec); |
| 15430 | if (fn != nullptr && fn->type_entry->data.fn.fn_type_id.cc == CallingConventionAsync && |
| 15431 | instruction->result_loc->id == ResultLocIdReturn) |
| 15432 | { |
| 15433 | result_loc = ir_resolve_result(ira, &instruction->base, no_result_loc(), |
| 15434 | implicit_elem_type, nullptr, false, true); |
| 15435 | if (result_loc != nullptr && |
| 15436 | (type_is_invalid(result_loc->value.type) || instr_is_unreachable(result_loc))) |
| 15437 | { |
| 15438 | return result_loc; |
| 15439 | } |
| 15440 | result_loc->value.special = ConstValSpecialRuntime; |
| 15441 | return result_loc; |
| 15442 | } |
| 15443 | |
| 15444 | IrInstruction *result = ir_const(ira, &instruction->base, implicit_elem_type); |
| 15445 | result->value.special = ConstValSpecialUndef; |
| 15446 | IrInstruction *ptr = ir_get_ref(ira, &instruction->base, result, false, false); |
| 15447 | ptr->value.data.x_ptr.mut = ConstPtrMutComptimeVar; |
| 15448 | return ptr; |
| 15449 | } |
| 15450 | |
| 15451 | static void ir_reset_result(ResultLoc *result_loc) { |
| 15452 | result_loc->written = false; |
| 15453 | result_loc->resolved_loc = nullptr; |
| 15454 | result_loc->gen_instruction = nullptr; |
| 15455 | result_loc->implicit_elem_type = nullptr; |
| 15456 | switch (result_loc->id) { |
| 15457 | case ResultLocIdInvalid: |
| 15458 | zig_unreachable(); |
| 15459 | case ResultLocIdPeerParent: { |
| 15460 | ResultLocPeerParent *peer_parent = reinterpret_cast<ResultLocPeerParent *>(result_loc); |
| 15461 | peer_parent->skipped = false; |
| 15462 | peer_parent->done_resuming = false; |
| 15463 | peer_parent->resolved_type = nullptr; |
| 15464 | for (size_t i = 0; i < peer_parent->peers.length; i += 1) { |
| 15465 | ir_reset_result(&peer_parent->peers.at(i)->base); |
| 15466 | } |
| 15467 | break; |
| 15468 | } |
| 15469 | case ResultLocIdVar: { |
| 15470 | IrInstructionAllocaSrc *alloca_src = |
| 15471 | reinterpret_cast<IrInstructionAllocaSrc *>(result_loc->source_instruction); |
| 15472 | alloca_src->base.child = nullptr; |
| 15473 | break; |
| 15474 | } |
| 15475 | case ResultLocIdPeer: |
| 15476 | case ResultLocIdNone: |
| 15477 | case ResultLocIdReturn: |
| 15478 | case ResultLocIdInstruction: |
| 15479 | case ResultLocIdBitCast: |
| 15480 | break; |
| 15481 | } |
| 15482 | } |
| 15483 | |
| 15484 | static IrInstruction *ir_analyze_instruction_reset_result(IrAnalyze *ira, IrInstructionResetResult *instruction) { |
| 15485 | ir_reset_result(instruction->result_loc); |
| 15486 | return ir_const_void(ira, &instruction->base); |
| 15487 | } |
| 15488 | |
| 15489 | static IrInstruction *ir_analyze_async_call(IrAnalyze *ira, IrInstructionCallSrc *call_instruction, ZigFn *fn_entry, |
| 14198 | 15490 | ZigType *fn_type, IrInstruction *fn_ref, IrInstruction **casted_args, size_t arg_count, |
| 14199 | 15491 | IrInstruction *async_allocator_inst) |
| 14200 | 15492 | { |
| ... | ... | @@ -14202,7 +15494,7 @@ static IrInstruction *ir_analyze_async_call(IrAnalyze *ira, IrInstructionCall *c |
| 14202 | 15494 | ir_assert(async_allocator_inst->value.type->id == ZigTypeIdPointer, &call_instruction->base); |
| 14203 | 15495 | ZigType *container_type = async_allocator_inst->value.type->data.pointer.child_type; |
| 14204 | 15496 | IrInstruction *field_ptr_inst = ir_analyze_container_field_ptr(ira, realloc_field_name, &call_instruction->base, |
| 14205 | | async_allocator_inst, container_type); |
| 15497 | async_allocator_inst, container_type, false); |
| 14206 | 15498 | if (type_is_invalid(field_ptr_inst->value.type)) { |
| 14207 | 15499 | return ira->codegen->invalid_instruction; |
| 14208 | 15500 | } |
| ... | ... | @@ -14227,10 +15519,15 @@ static IrInstruction *ir_analyze_async_call(IrAnalyze *ira, IrInstructionCall *c |
| 14227 | 15519 | ZigType *promise_type = get_promise_type(ira->codegen, return_type); |
| 14228 | 15520 | ZigType *async_return_type = get_error_union_type(ira->codegen, alloc_fn_error_set_type, promise_type); |
| 14229 | 15521 | |
| 14230 | | IrInstruction *result = ir_build_call(&ira->new_irb, call_instruction->base.scope, call_instruction->base.source_node, |
| 14231 | | fn_entry, fn_ref, arg_count, casted_args, false, FnInlineAuto, true, async_allocator_inst, nullptr); |
| 14232 | | result->value.type = async_return_type; |
| 14233 | | return result; |
| 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); |
| 14234 | 15531 | } |
| 14235 | 15532 | |
| 14236 | 15533 | static bool ir_analyze_fn_call_inline_arg(IrAnalyze *ira, AstNode *fn_proto_node, |
| ... | ... | @@ -14253,7 +15550,7 @@ static bool ir_analyze_fn_call_inline_arg(IrAnalyze *ira, AstNode *fn_proto_node |
| 14253 | 15550 | casted_arg = arg; |
| 14254 | 15551 | } |
| 14255 | 15552 | |
| 14256 | | ConstExprValue *arg_val = ir_resolve_const(ira, casted_arg, UndefBad); |
| 15553 | ConstExprValue *arg_val = ir_resolve_const(ira, casted_arg, UndefOk); |
| 14257 | 15554 | if (!arg_val) |
| 14258 | 15555 | return false; |
| 14259 | 15556 | |
| ... | ... | @@ -14309,7 +15606,7 @@ static bool ir_analyze_fn_call_generic_arg(IrAnalyze *ira, AstNode *fn_proto_nod |
| 14309 | 15606 | arg_val = create_const_runtime(casted_arg->value.type); |
| 14310 | 15607 | } |
| 14311 | 15608 | if (arg_part_of_generic_id) { |
| 14312 | | generic_id->params[generic_id->param_count] = *arg_val; |
| 15609 | copy_const_val(&generic_id->params[generic_id->param_count], arg_val, true); |
| 14313 | 15610 | generic_id->param_count += 1; |
| 14314 | 15611 | } |
| 14315 | 15612 | |
| ... | ... | @@ -14480,7 +15777,9 @@ static IrInstruction *ir_analyze_store_ptr(IrAnalyze *ira, IrInstruction *source |
| 14480 | 15777 | ir_add_error(ira, source_instr, buf_sprintf("cannot assign to constant")); |
| 14481 | 15778 | return ira->codegen->invalid_instruction; |
| 14482 | 15779 | } |
| 14483 | | if (ptr->value.data.x_ptr.mut == ConstPtrMutComptimeVar) { |
| 15780 | if (ptr->value.data.x_ptr.mut == ConstPtrMutComptimeVar || |
| 15781 | ptr->value.data.x_ptr.mut == ConstPtrMutInfer) |
| 15782 | { |
| 14484 | 15783 | if (instr_is_comptime(value)) { |
| 14485 | 15784 | ConstExprValue *dest_val = const_ptr_pointee(ira, ira->codegen, &ptr->value, source_instr->source_node); |
| 14486 | 15785 | if (dest_val == nullptr) |
| ... | ... | @@ -14494,18 +15793,24 @@ static IrInstruction *ir_analyze_store_ptr(IrAnalyze *ira, IrInstruction *source |
| 14494 | 15793 | // ConstPtrMutComptimeVar, thus defeating the logic below. |
| 14495 | 15794 | bool same_global_refs = ptr->value.data.x_ptr.mut != ConstPtrMutComptimeVar; |
| 14496 | 15795 | copy_const_val(dest_val, &value->value, same_global_refs); |
| 14497 | | if (!ira->new_irb.current_basic_block->must_be_comptime_source_instr) { |
| 15796 | if (ptr->value.data.x_ptr.mut == ConstPtrMutComptimeVar && |
| 15797 | !ira->new_irb.current_basic_block->must_be_comptime_source_instr) |
| 15798 | { |
| 14498 | 15799 | ira->new_irb.current_basic_block->must_be_comptime_source_instr = source_instr; |
| 14499 | 15800 | } |
| 14500 | 15801 | return ir_const_void(ira, source_instr); |
| 14501 | 15802 | } |
| 14502 | 15803 | } |
| 14503 | | ir_add_error(ira, source_instr, |
| 14504 | | buf_sprintf("cannot store runtime value in compile time variable")); |
| 14505 | | ConstExprValue *dest_val = const_ptr_pointee_unchecked(ira->codegen, &ptr->value); |
| 14506 | | 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; |
| 14507 | 15811 | |
| 14508 | | return ira->codegen->invalid_instruction; |
| 15812 | return ira->codegen->invalid_instruction; |
| 15813 | } |
| 14509 | 15814 | } |
| 14510 | 15815 | } |
| 14511 | 15816 | |
| ... | ... | @@ -14534,7 +15839,7 @@ static IrInstruction *ir_analyze_store_ptr(IrAnalyze *ira, IrInstruction *source |
| 14534 | 15839 | return result; |
| 14535 | 15840 | } |
| 14536 | 15841 | |
| 14537 | | static IrInstruction *ir_analyze_fn_call(IrAnalyze *ira, IrInstructionCall *call_instruction, |
| 15842 | static IrInstruction *ir_analyze_fn_call(IrAnalyze *ira, IrInstructionCallSrc *call_instruction, |
| 14538 | 15843 | ZigFn *fn_entry, ZigType *fn_type, IrInstruction *fn_ref, |
| 14539 | 15844 | IrInstruction *first_arg_ptr, bool comptime_fn_call, FnInline fn_inline) |
| 14540 | 15845 | { |
| ... | ... | @@ -14637,7 +15942,7 @@ static IrInstruction *ir_analyze_fn_call(IrAnalyze *ira, IrInstructionCall *call |
| 14637 | 15942 | if (!first_arg_known_bare && handle_is_ptr(first_arg_ptr->value.type->data.pointer.child_type)) { |
| 14638 | 15943 | first_arg = first_arg_ptr; |
| 14639 | 15944 | } else { |
| 14640 | | first_arg = ir_get_deref(ira, first_arg_ptr, first_arg_ptr); |
| 15945 | first_arg = ir_get_deref(ira, first_arg_ptr, first_arg_ptr, nullptr); |
| 14641 | 15946 | if (type_is_invalid(first_arg->value.type)) |
| 14642 | 15947 | return ira->codegen->invalid_instruction; |
| 14643 | 15948 | } |
| ... | ... | @@ -14796,7 +16101,7 @@ static IrInstruction *ir_analyze_fn_call(IrAnalyze *ira, IrInstructionCall *call |
| 14796 | 16101 | if (!first_arg_known_bare && handle_is_ptr(first_arg_ptr->value.type->data.pointer.child_type)) { |
| 14797 | 16102 | first_arg = first_arg_ptr; |
| 14798 | 16103 | } else { |
| 14799 | | first_arg = ir_get_deref(ira, first_arg_ptr, first_arg_ptr); |
| 16104 | first_arg = ir_get_deref(ira, first_arg_ptr, first_arg_ptr, nullptr); |
| 14800 | 16105 | if (type_is_invalid(first_arg->value.type)) |
| 14801 | 16106 | return ira->codegen->invalid_instruction; |
| 14802 | 16107 | } |
| ... | ... | @@ -14840,7 +16145,7 @@ static IrInstruction *ir_analyze_fn_call(IrAnalyze *ira, IrInstructionCall *call |
| 14840 | 16145 | if (type_is_invalid(arg_var_ptr_inst->value.type)) |
| 14841 | 16146 | return ira->codegen->invalid_instruction; |
| 14842 | 16147 | |
| 14843 | | IrInstruction *arg_tuple_arg = ir_get_deref(ira, arg, arg_var_ptr_inst); |
| 16148 | IrInstruction *arg_tuple_arg = ir_get_deref(ira, arg, arg_var_ptr_inst, nullptr); |
| 14844 | 16149 | if (type_is_invalid(arg_tuple_arg->value.type)) |
| 14845 | 16150 | return ira->codegen->invalid_instruction; |
| 14846 | 16151 | |
| ... | ... | @@ -14889,7 +16194,7 @@ static IrInstruction *ir_analyze_fn_call(IrAnalyze *ira, IrInstructionCall *call |
| 14889 | 16194 | nullptr, nullptr, fn_proto_node->data.fn_proto.align_expr, nullptr, ira->new_irb.exec, nullptr); |
| 14890 | 16195 | IrInstructionConst *const_instruction = ir_create_instruction<IrInstructionConst>(&ira->new_irb, |
| 14891 | 16196 | impl_fn->child_scope, fn_proto_node->data.fn_proto.align_expr); |
| 14892 | | const_instruction->base.value = *align_result; |
| 16197 | copy_const_val(&const_instruction->base.value, align_result, true); |
| 14893 | 16198 | |
| 14894 | 16199 | uint32_t align_bytes = 0; |
| 14895 | 16200 | ir_resolve_align(ira, &const_instruction->base, &align_bytes); |
| ... | ... | @@ -14971,6 +16276,19 @@ static IrInstruction *ir_analyze_fn_call(IrAnalyze *ira, IrInstructionCall *call |
| 14971 | 16276 | } |
| 14972 | 16277 | |
| 14973 | 16278 | FnTypeId *impl_fn_type_id = &impl_fn->type_entry->data.fn.fn_type_id; |
| 16279 | IrInstruction *result_loc; |
| 16280 | if (handle_is_ptr(impl_fn_type_id->return_type)) { |
| 16281 | result_loc = ir_resolve_result(ira, &call_instruction->base, call_instruction->result_loc, |
| 16282 | impl_fn_type_id->return_type, nullptr, true, true); |
| 16283 | if (result_loc != nullptr && (type_is_invalid(result_loc->value.type) || |
| 16284 | instr_is_unreachable(result_loc))) |
| 16285 | { |
| 16286 | return result_loc; |
| 16287 | } |
| 16288 | } else { |
| 16289 | result_loc = nullptr; |
| 16290 | } |
| 16291 | |
| 14974 | 16292 | if (fn_type_can_fail(impl_fn_type_id)) { |
| 14975 | 16293 | parent_fn_entry->calls_or_awaits_errorable_fn = true; |
| 14976 | 16294 | } |
| ... | ... | @@ -14979,18 +16297,14 @@ static IrInstruction *ir_analyze_fn_call(IrAnalyze *ira, IrInstructionCall *call |
| 14979 | 16297 | if (call_instruction->is_async) { |
| 14980 | 16298 | IrInstruction *result = ir_analyze_async_call(ira, call_instruction, impl_fn, impl_fn->type_entry, |
| 14981 | 16299 | fn_ref, casted_args, impl_param_count, async_allocator_inst); |
| 14982 | | ir_add_alloca(ira, result, result->value.type); |
| 14983 | 16300 | return ir_finish_anal(ira, result); |
| 14984 | 16301 | } |
| 14985 | 16302 | |
| 14986 | 16303 | assert(async_allocator_inst == nullptr); |
| 14987 | | IrInstruction *new_call_instruction = ir_build_call(&ira->new_irb, |
| 14988 | | call_instruction->base.scope, call_instruction->base.source_node, |
| 14989 | | impl_fn, nullptr, impl_param_count, casted_args, false, fn_inline, |
| 14990 | | call_instruction->is_async, nullptr, casted_new_stack); |
| 14991 | | new_call_instruction->value.type = impl_fn_type_id->return_type; |
| 14992 | | |
| 14993 | | ir_add_alloca(ira, new_call_instruction, impl_fn_type_id->return_type); |
| 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); |
| 14994 | 16308 | |
| 14995 | 16309 | return ir_finish_anal(ira, new_call_instruction); |
| 14996 | 16310 | } |
| ... | ... | @@ -15018,7 +16332,7 @@ static IrInstruction *ir_analyze_fn_call(IrAnalyze *ira, IrInstructionCall *call |
| 15018 | 16332 | { |
| 15019 | 16333 | first_arg = first_arg_ptr; |
| 15020 | 16334 | } else { |
| 15021 | | first_arg = ir_get_deref(ira, first_arg_ptr, first_arg_ptr); |
| 16335 | first_arg = ir_get_deref(ira, first_arg_ptr, first_arg_ptr, nullptr); |
| 15022 | 16336 | if (type_is_invalid(first_arg->value.type)) |
| 15023 | 16337 | return ira->codegen->invalid_instruction; |
| 15024 | 16338 | } |
| ... | ... | @@ -15075,7 +16389,6 @@ static IrInstruction *ir_analyze_fn_call(IrAnalyze *ira, IrInstructionCall *call |
| 15075 | 16389 | |
| 15076 | 16390 | IrInstruction *result = ir_analyze_async_call(ira, call_instruction, fn_entry, fn_type, fn_ref, |
| 15077 | 16391 | casted_args, call_param_count, async_allocator_inst); |
| 15078 | | ir_add_alloca(ira, result, result->value.type); |
| 15079 | 16392 | return ir_finish_anal(ira, result); |
| 15080 | 16393 | } |
| 15081 | 16394 | |
| ... | ... | @@ -15085,15 +16398,24 @@ static IrInstruction *ir_analyze_fn_call(IrAnalyze *ira, IrInstructionCall *call |
| 15085 | 16398 | return ira->codegen->invalid_instruction; |
| 15086 | 16399 | } |
| 15087 | 16400 | |
| 15088 | | IrInstruction *new_call_instruction = ir_build_call(&ira->new_irb, |
| 15089 | | call_instruction->base.scope, call_instruction->base.source_node, |
| 15090 | | fn_entry, fn_ref, call_param_count, casted_args, false, fn_inline, false, nullptr, casted_new_stack); |
| 15091 | | new_call_instruction->value.type = return_type; |
| 15092 | | 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); |
| 15093 | 16415 | return ir_finish_anal(ira, new_call_instruction); |
| 15094 | 16416 | } |
| 15095 | 16417 | |
| 15096 | | static IrInstruction *ir_analyze_instruction_call(IrAnalyze *ira, IrInstructionCall *call_instruction) { |
| 16418 | static IrInstruction *ir_analyze_instruction_call(IrAnalyze *ira, IrInstructionCallSrc *call_instruction) { |
| 15097 | 16419 | IrInstruction *fn_ref = call_instruction->fn_ref->child; |
| 15098 | 16420 | if (type_is_invalid(fn_ref->value.type)) |
| 15099 | 16421 | return ira->codegen->invalid_instruction; |
| ... | ... | @@ -15117,7 +16439,8 @@ static IrInstruction *ir_analyze_instruction_call(IrAnalyze *ira, IrInstructionC |
| 15117 | 16439 | |
| 15118 | 16440 | IrInstruction *arg = call_instruction->args[0]->child; |
| 15119 | 16441 | |
| 15120 | | IrInstruction *cast_instruction = ir_analyze_cast(ira, &call_instruction->base, dest_type, arg); |
| 16442 | IrInstruction *cast_instruction = ir_analyze_cast(ira, &call_instruction->base, dest_type, arg, |
| 16443 | call_instruction->result_loc); |
| 15121 | 16444 | if (type_is_invalid(cast_instruction->value.type)) |
| 15122 | 16445 | return ira->codegen->invalid_instruction; |
| 15123 | 16446 | return ir_finish_anal(ira, cast_instruction); |
| ... | ... | @@ -15170,7 +16493,7 @@ static Error ir_read_const_ptr(IrAnalyze *ira, CodeGen *codegen, AstNode *source |
| 15170 | 16493 | |
| 15171 | 16494 | if (dst_size <= src_size) { |
| 15172 | 16495 | if (src_size == dst_size && types_have_same_zig_comptime_repr(pointee->type, out_val->type)) { |
| 15173 | | copy_const_val(out_val, pointee, ptr_val->data.x_ptr.mut == ConstPtrMutComptimeConst); |
| 16496 | copy_const_val(out_val, pointee, ptr_val->data.x_ptr.mut != ConstPtrMutComptimeVar); |
| 15174 | 16497 | return ErrorNone; |
| 15175 | 16498 | } |
| 15176 | 16499 | Buf buf = BUF_INIT; |
| ... | ... | @@ -15419,7 +16742,7 @@ static IrInstruction *ir_analyze_instruction_un_op(IrAnalyze *ira, IrInstruction |
| 15419 | 16742 | return ira->codegen->invalid_instruction; |
| 15420 | 16743 | } |
| 15421 | 16744 | |
| 15422 | | IrInstruction *result = ir_get_deref(ira, &instruction->base, ptr); |
| 16745 | IrInstruction *result = ir_get_deref(ira, &instruction->base, ptr, instruction->result_loc); |
| 15423 | 16746 | if (result == ira->codegen->invalid_instruction) |
| 15424 | 16747 | return ira->codegen->invalid_instruction; |
| 15425 | 16748 | |
| ... | ... | @@ -15438,6 +16761,19 @@ static IrInstruction *ir_analyze_instruction_un_op(IrAnalyze *ira, IrInstruction |
| 15438 | 16761 | zig_unreachable(); |
| 15439 | 16762 | } |
| 15440 | 16763 | |
| 16764 | static void ir_push_resume(IrAnalyze *ira, IrSuspendPosition pos) { |
| 16765 | IrBasicBlock *old_bb = ira->old_irb.exec->basic_block_list.at(pos.basic_block_index); |
| 16766 | if (old_bb->in_resume_stack) return; |
| 16767 | ira->resume_stack.append(pos); |
| 16768 | old_bb->in_resume_stack = true; |
| 16769 | } |
| 16770 | |
| 16771 | static void ir_push_resume_block(IrAnalyze *ira, IrBasicBlock *old_bb) { |
| 16772 | if (ira->resume_stack.length != 0) { |
| 16773 | ir_push_resume(ira, {old_bb->index, 0}); |
| 16774 | } |
| 16775 | } |
| 16776 | |
| 15441 | 16777 | static IrInstruction *ir_analyze_instruction_br(IrAnalyze *ira, IrInstructionBr *br_instruction) { |
| 15442 | 16778 | IrBasicBlock *old_dest_block = br_instruction->dest_block; |
| 15443 | 16779 | |
| ... | ... | @@ -15445,13 +16781,15 @@ static IrInstruction *ir_analyze_instruction_br(IrAnalyze *ira, IrInstructionBr |
| 15445 | 16781 | if (!ir_resolve_comptime(ira, br_instruction->is_comptime->child, &is_comptime)) |
| 15446 | 16782 | return ir_unreach_error(ira); |
| 15447 | 16783 | |
| 15448 | | if (is_comptime || old_dest_block->ref_count == 1) |
| 16784 | if (is_comptime || (old_dest_block->ref_count == 1 && old_dest_block->suspend_instruction_ref == nullptr)) |
| 15449 | 16785 | return ir_inline_bb(ira, &br_instruction->base, old_dest_block); |
| 15450 | 16786 | |
| 15451 | 16787 | IrBasicBlock *new_bb = ir_get_new_bb_runtime(ira, old_dest_block, &br_instruction->base); |
| 15452 | 16788 | if (new_bb == nullptr) |
| 15453 | 16789 | return ir_unreach_error(ira); |
| 15454 | 16790 | |
| 16791 | ir_push_resume_block(ira, old_dest_block); |
| 16792 | |
| 15455 | 16793 | IrInstruction *result = ir_build_br(&ira->new_irb, |
| 15456 | 16794 | br_instruction->base.scope, br_instruction->base.source_node, new_bb, nullptr); |
| 15457 | 16795 | result->value.type = ira->codegen->builtin_types.entry_unreachable; |
| ... | ... | @@ -15480,13 +16818,15 @@ static IrInstruction *ir_analyze_instruction_cond_br(IrAnalyze *ira, IrInstructi |
| 15480 | 16818 | IrBasicBlock *old_dest_block = cond_is_true ? |
| 15481 | 16819 | cond_br_instruction->then_block : cond_br_instruction->else_block; |
| 15482 | 16820 | |
| 15483 | | if (is_comptime || old_dest_block->ref_count == 1) |
| 16821 | if (is_comptime || (old_dest_block->ref_count == 1 && old_dest_block->suspend_instruction_ref == nullptr)) |
| 15484 | 16822 | return ir_inline_bb(ira, &cond_br_instruction->base, old_dest_block); |
| 15485 | 16823 | |
| 15486 | 16824 | IrBasicBlock *new_dest_block = ir_get_new_bb_runtime(ira, old_dest_block, &cond_br_instruction->base); |
| 15487 | 16825 | if (new_dest_block == nullptr) |
| 15488 | 16826 | return ir_unreach_error(ira); |
| 15489 | 16827 | |
| 16828 | ir_push_resume_block(ira, old_dest_block); |
| 16829 | |
| 15490 | 16830 | IrInstruction *result = ir_build_br(&ira->new_irb, |
| 15491 | 16831 | cond_br_instruction->base.scope, cond_br_instruction->base.source_node, new_dest_block, nullptr); |
| 15492 | 16832 | result->value.type = ira->codegen->builtin_types.entry_unreachable; |
| ... | ... | @@ -15502,6 +16842,9 @@ static IrInstruction *ir_analyze_instruction_cond_br(IrAnalyze *ira, IrInstructi |
| 15502 | 16842 | if (new_else_block == nullptr) |
| 15503 | 16843 | return ir_unreach_error(ira); |
| 15504 | 16844 | |
| 16845 | ir_push_resume_block(ira, cond_br_instruction->else_block); |
| 16846 | ir_push_resume_block(ira, cond_br_instruction->then_block); |
| 16847 | |
| 15505 | 16848 | IrInstruction *result = ir_build_cond_br(&ira->new_irb, |
| 15506 | 16849 | cond_br_instruction->base.scope, cond_br_instruction->base.source_node, |
| 15507 | 16850 | casted_condition, new_then_block, new_else_block, nullptr); |
| ... | ... | @@ -15540,11 +16883,85 @@ static IrInstruction *ir_analyze_instruction_phi(IrAnalyze *ira, IrInstructionPh |
| 15540 | 16883 | zig_unreachable(); |
| 15541 | 16884 | } |
| 15542 | 16885 | |
| 15543 | | ZigList<IrBasicBlock*> new_incoming_blocks = {0}; |
| 15544 | | ZigList<IrInstruction*> new_incoming_values = {0}; |
| 15545 | | |
| 15546 | | for (size_t i = 0; i < phi_instruction->incoming_count; i += 1) { |
| 15547 | | IrBasicBlock *predecessor = phi_instruction->incoming_blocks[i]; |
| 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 | |
| 16960 | ZigList<IrBasicBlock*> new_incoming_blocks = {0}; |
| 16961 | ZigList<IrInstruction*> new_incoming_values = {0}; |
| 16962 | |
| 16963 | for (size_t i = 0; i < phi_instruction->incoming_count; i += 1) { |
| 16964 | IrBasicBlock *predecessor = phi_instruction->incoming_blocks[i]; |
| 15548 | 16965 | if (predecessor->ref_count == 0) |
| 15549 | 16966 | continue; |
| 15550 | 16967 | |
| ... | ... | @@ -15612,7 +17029,7 @@ static IrInstruction *ir_analyze_instruction_phi(IrAnalyze *ira, IrInstructionPh |
| 15612 | 17029 | IrInstruction *branch_instruction = predecessor->instruction_list.pop(); |
| 15613 | 17030 | ir_set_cursor_at_end(&ira->new_irb, predecessor); |
| 15614 | 17031 | IrInstruction *casted_value = ir_implicit_cast(ira, new_value, resolved_type); |
| 15615 | | if (casted_value == ira->codegen->invalid_instruction) { |
| 17032 | if (type_is_invalid(casted_value->value.type)) { |
| 15616 | 17033 | return ira->codegen->invalid_instruction; |
| 15617 | 17034 | } |
| 15618 | 17035 | new_incoming_values.items[i] = casted_value; |
| ... | ... | @@ -15628,7 +17045,7 @@ static IrInstruction *ir_analyze_instruction_phi(IrAnalyze *ira, IrInstructionPh |
| 15628 | 17045 | |
| 15629 | 17046 | IrInstruction *result = ir_build_phi(&ira->new_irb, |
| 15630 | 17047 | phi_instruction->base.scope, phi_instruction->base.source_node, |
| 15631 | | new_incoming_blocks.length, new_incoming_blocks.items, new_incoming_values.items); |
| 17048 | new_incoming_blocks.length, new_incoming_blocks.items, new_incoming_values.items, nullptr); |
| 15632 | 17049 | result->value.type = resolved_type; |
| 15633 | 17050 | |
| 15634 | 17051 | if (all_stack_ptrs) { |
| ... | ... | @@ -15846,6 +17263,48 @@ static IrInstruction *ir_analyze_instruction_elem_ptr(IrAnalyze *ira, IrInstruct |
| 15846 | 17263 | if (array_ptr_val == nullptr) |
| 15847 | 17264 | return ira->codegen->invalid_instruction; |
| 15848 | 17265 | |
| 17266 | if (array_ptr_val->special == ConstValSpecialUndef && elem_ptr_instruction->init_array_type != nullptr) { |
| 17267 | if (array_type->id == ZigTypeIdArray) { |
| 17268 | array_ptr_val->data.x_array.special = ConstArraySpecialNone; |
| 17269 | array_ptr_val->data.x_array.data.s_none.elements = create_const_vals(array_type->data.array.len); |
| 17270 | array_ptr_val->special = ConstValSpecialStatic; |
| 17271 | for (size_t i = 0; i < array_type->data.array.len; i += 1) { |
| 17272 | ConstExprValue *elem_val = &array_ptr_val->data.x_array.data.s_none.elements[i]; |
| 17273 | elem_val->special = ConstValSpecialUndef; |
| 17274 | elem_val->type = array_type->data.array.child_type; |
| 17275 | elem_val->parent.id = ConstParentIdArray; |
| 17276 | elem_val->parent.data.p_array.array_val = array_ptr_val; |
| 17277 | elem_val->parent.data.p_array.elem_index = i; |
| 17278 | } |
| 17279 | } else if (is_slice(array_type)) { |
| 17280 | ZigType *actual_array_type = ir_resolve_type(ira, elem_ptr_instruction->init_array_type->child); |
| 17281 | if (type_is_invalid(actual_array_type)) |
| 17282 | return ira->codegen->invalid_instruction; |
| 17283 | assert(actual_array_type->id == ZigTypeIdArray); |
| 17284 | |
| 17285 | ConstExprValue *array_init_val = create_const_vals(1); |
| 17286 | array_init_val->special = ConstValSpecialStatic; |
| 17287 | array_init_val->type = actual_array_type; |
| 17288 | array_init_val->data.x_array.special = ConstArraySpecialNone; |
| 17289 | array_init_val->data.x_array.data.s_none.elements = create_const_vals(actual_array_type->data.array.len); |
| 17290 | array_init_val->special = ConstValSpecialStatic; |
| 17291 | for (size_t i = 0; i < actual_array_type->data.array.len; i += 1) { |
| 17292 | ConstExprValue *elem_val = &array_init_val->data.x_array.data.s_none.elements[i]; |
| 17293 | elem_val->special = ConstValSpecialUndef; |
| 17294 | elem_val->type = actual_array_type->data.array.child_type; |
| 17295 | elem_val->parent.id = ConstParentIdArray; |
| 17296 | elem_val->parent.data.p_array.array_val = array_init_val; |
| 17297 | elem_val->parent.data.p_array.elem_index = i; |
| 17298 | } |
| 17299 | |
| 17300 | init_const_slice(ira->codegen, array_ptr_val, array_init_val, 0, actual_array_type->data.array.len, |
| 17301 | false); |
| 17302 | array_ptr_val->data.x_struct.fields[slice_ptr_index].data.x_ptr.mut = ConstPtrMutInfer; |
| 17303 | } else { |
| 17304 | zig_unreachable(); |
| 17305 | } |
| 17306 | } |
| 17307 | |
| 15849 | 17308 | if (array_ptr_val->special != ConstValSpecialRuntime && |
| 15850 | 17309 | (array_type->id != ZigTypeIdPointer || |
| 15851 | 17310 | array_ptr_val->data.x_ptr.special != ConstPtrSpecialHardCodedAddr)) |
| ... | ... | @@ -15911,8 +17370,9 @@ static IrInstruction *ir_analyze_instruction_elem_ptr(IrAnalyze *ira, IrInstruct |
| 15911 | 17370 | } else if (is_slice(array_type)) { |
| 15912 | 17371 | ConstExprValue *ptr_field = &array_ptr_val->data.x_struct.fields[slice_ptr_index]; |
| 15913 | 17372 | if (ptr_field->data.x_ptr.special == ConstPtrSpecialHardCodedAddr) { |
| 15914 | | IrInstruction *result = ir_build_elem_ptr(&ira->new_irb, elem_ptr_instruction->base.scope, elem_ptr_instruction->base.source_node, |
| 15915 | | array_ptr, casted_elem_index, false, elem_ptr_instruction->ptr_len); |
| 17373 | IrInstruction *result = ir_build_elem_ptr(&ira->new_irb, elem_ptr_instruction->base.scope, |
| 17374 | elem_ptr_instruction->base.source_node, array_ptr, casted_elem_index, false, |
| 17375 | elem_ptr_instruction->ptr_len, nullptr); |
| 15916 | 17376 | result->value.type = return_type; |
| 15917 | 17377 | return result; |
| 15918 | 17378 | } |
| ... | ... | @@ -15965,7 +17425,16 @@ static IrInstruction *ir_analyze_instruction_elem_ptr(IrAnalyze *ira, IrInstruct |
| 15965 | 17425 | } |
| 15966 | 17426 | return result; |
| 15967 | 17427 | } else if (array_type->id == ZigTypeIdArray) { |
| 15968 | | IrInstruction *result = ir_const(ira, &elem_ptr_instruction->base, return_type); |
| 17428 | IrInstruction *result; |
| 17429 | if (orig_array_ptr_val->data.x_ptr.mut == ConstPtrMutInfer) { |
| 17430 | result = ir_build_elem_ptr(&ira->new_irb, elem_ptr_instruction->base.scope, |
| 17431 | elem_ptr_instruction->base.source_node, array_ptr, casted_elem_index, |
| 17432 | false, elem_ptr_instruction->ptr_len, elem_ptr_instruction->init_array_type); |
| 17433 | result->value.type = return_type; |
| 17434 | result->value.special = ConstValSpecialStatic; |
| 17435 | } else { |
| 17436 | result = ir_const(ira, &elem_ptr_instruction->base, return_type); |
| 17437 | } |
| 15969 | 17438 | ConstExprValue *out_val = &result->value; |
| 15970 | 17439 | out_val->data.x_ptr.special = ConstPtrSpecialBaseArray; |
| 15971 | 17440 | out_val->data.x_ptr.mut = orig_array_ptr_val->data.x_ptr.mut; |
| ... | ... | @@ -15977,7 +17446,6 @@ static IrInstruction *ir_analyze_instruction_elem_ptr(IrAnalyze *ira, IrInstruct |
| 15977 | 17446 | } |
| 15978 | 17447 | } |
| 15979 | 17448 | } |
| 15980 | | |
| 15981 | 17449 | } else { |
| 15982 | 17450 | // runtime known element index |
| 15983 | 17451 | switch (type_requires_comptime(ira->codegen, return_type)) { |
| ... | ... | @@ -16003,8 +17471,9 @@ static IrInstruction *ir_analyze_instruction_elem_ptr(IrAnalyze *ira, IrInstruct |
| 16003 | 17471 | } |
| 16004 | 17472 | } |
| 16005 | 17473 | |
| 16006 | | IrInstruction *result = ir_build_elem_ptr(&ira->new_irb, elem_ptr_instruction->base.scope, elem_ptr_instruction->base.source_node, |
| 16007 | | array_ptr, casted_elem_index, safety_check_on, elem_ptr_instruction->ptr_len); |
| 17474 | IrInstruction *result = ir_build_elem_ptr(&ira->new_irb, elem_ptr_instruction->base.scope, |
| 17475 | elem_ptr_instruction->base.source_node, array_ptr, casted_elem_index, safety_check_on, |
| 17476 | elem_ptr_instruction->ptr_len, elem_ptr_instruction->init_array_type); |
| 16008 | 17477 | result->value.type = return_type; |
| 16009 | 17478 | return result; |
| 16010 | 17479 | } |
| ... | ... | @@ -16049,8 +17518,80 @@ static IrInstruction *ir_analyze_container_member_access_inner(IrAnalyze *ira, |
| 16049 | 17518 | return ira->codegen->invalid_instruction; |
| 16050 | 17519 | } |
| 16051 | 17520 | |
| 17521 | static IrInstruction *ir_analyze_struct_field_ptr(IrAnalyze *ira, IrInstruction *source_instr, |
| 17522 | TypeStructField *field, IrInstruction *struct_ptr, ZigType *struct_type, bool initializing) |
| 17523 | { |
| 17524 | switch (type_has_one_possible_value(ira->codegen, field->type_entry)) { |
| 17525 | case OnePossibleValueInvalid: |
| 17526 | return ira->codegen->invalid_instruction; |
| 17527 | case OnePossibleValueYes: { |
| 17528 | IrInstruction *elem = ir_const(ira, source_instr, field->type_entry); |
| 17529 | return ir_get_ref(ira, source_instr, elem, false, false); |
| 17530 | } |
| 17531 | case OnePossibleValueNo: |
| 17532 | break; |
| 17533 | } |
| 17534 | assert(struct_ptr->value.type->id == ZigTypeIdPointer); |
| 17535 | bool is_packed = (struct_type->data.structure.layout == ContainerLayoutPacked); |
| 17536 | uint32_t align_bytes = is_packed ? 1 : get_abi_alignment(ira->codegen, field->type_entry); |
| 17537 | uint32_t ptr_bit_offset = struct_ptr->value.type->data.pointer.bit_offset_in_host; |
| 17538 | uint32_t ptr_host_int_bytes = struct_ptr->value.type->data.pointer.host_int_bytes; |
| 17539 | uint32_t host_int_bytes_for_result_type = (ptr_host_int_bytes == 0) ? |
| 17540 | get_host_int_bytes(ira->codegen, struct_type, field) : ptr_host_int_bytes; |
| 17541 | bool is_const = struct_ptr->value.type->data.pointer.is_const; |
| 17542 | bool is_volatile = struct_ptr->value.type->data.pointer.is_volatile; |
| 17543 | ZigType *ptr_type = get_pointer_to_type_extra(ira->codegen, field->type_entry, |
| 17544 | is_const, is_volatile, PtrLenSingle, align_bytes, |
| 17545 | (uint32_t)(ptr_bit_offset + field->bit_offset_in_host), |
| 17546 | (uint32_t)host_int_bytes_for_result_type, false); |
| 17547 | if (instr_is_comptime(struct_ptr)) { |
| 17548 | ConstExprValue *ptr_val = ir_resolve_const(ira, struct_ptr, UndefBad); |
| 17549 | if (!ptr_val) |
| 17550 | return ira->codegen->invalid_instruction; |
| 17551 | |
| 17552 | if (ptr_val->data.x_ptr.special != ConstPtrSpecialHardCodedAddr) { |
| 17553 | ConstExprValue *struct_val = const_ptr_pointee(ira, ira->codegen, ptr_val, source_instr->source_node); |
| 17554 | if (struct_val == nullptr) |
| 17555 | return ira->codegen->invalid_instruction; |
| 17556 | if (type_is_invalid(struct_val->type)) |
| 17557 | return ira->codegen->invalid_instruction; |
| 17558 | if (struct_val->special == ConstValSpecialUndef && initializing) { |
| 17559 | struct_val->data.x_struct.fields = create_const_vals(struct_type->data.structure.src_field_count); |
| 17560 | struct_val->special = ConstValSpecialStatic; |
| 17561 | for (size_t i = 0; i < struct_type->data.structure.src_field_count; i += 1) { |
| 17562 | ConstExprValue *field_val = &struct_val->data.x_struct.fields[i]; |
| 17563 | field_val->special = ConstValSpecialUndef; |
| 17564 | field_val->type = struct_type->data.structure.fields[i].type_entry; |
| 17565 | field_val->parent.id = ConstParentIdStruct; |
| 17566 | field_val->parent.data.p_struct.struct_val = struct_val; |
| 17567 | field_val->parent.data.p_struct.field_index = i; |
| 17568 | } |
| 17569 | } |
| 17570 | IrInstruction *result; |
| 17571 | if (ptr_val->data.x_ptr.mut == ConstPtrMutInfer) { |
| 17572 | result = ir_build_struct_field_ptr(&ira->new_irb, source_instr->scope, |
| 17573 | source_instr->source_node, struct_ptr, field); |
| 17574 | result->value.type = ptr_type; |
| 17575 | result->value.special = ConstValSpecialStatic; |
| 17576 | } else { |
| 17577 | result = ir_const(ira, source_instr, ptr_type); |
| 17578 | } |
| 17579 | ConstExprValue *const_val = &result->value; |
| 17580 | const_val->data.x_ptr.special = ConstPtrSpecialBaseStruct; |
| 17581 | const_val->data.x_ptr.mut = ptr_val->data.x_ptr.mut; |
| 17582 | const_val->data.x_ptr.data.base_struct.struct_val = struct_val; |
| 17583 | const_val->data.x_ptr.data.base_struct.field_index = field->src_index; |
| 17584 | return result; |
| 17585 | } |
| 17586 | } |
| 17587 | IrInstruction *result = ir_build_struct_field_ptr(&ira->new_irb, source_instr->scope, source_instr->source_node, |
| 17588 | struct_ptr, field); |
| 17589 | result->value.type = ptr_type; |
| 17590 | return result; |
| 17591 | } |
| 17592 | |
| 16052 | 17593 | static IrInstruction *ir_analyze_container_field_ptr(IrAnalyze *ira, Buf *field_name, |
| 16053 | | IrInstruction *source_instr, IrInstruction *container_ptr, ZigType *container_type) |
| 17594 | IrInstruction *source_instr, IrInstruction *container_ptr, ZigType *container_type, bool initializing) |
| 16054 | 17595 | { |
| 16055 | 17596 | Error err; |
| 16056 | 17597 | |
| ... | ... | @@ -16059,81 +17600,55 @@ static IrInstruction *ir_analyze_container_field_ptr(IrAnalyze *ira, Buf *field_ |
| 16059 | 17600 | return ira->codegen->invalid_instruction; |
| 16060 | 17601 | |
| 16061 | 17602 | assert(container_ptr->value.type->id == ZigTypeIdPointer); |
| 16062 | | bool is_const = container_ptr->value.type->data.pointer.is_const; |
| 16063 | | bool is_volatile = container_ptr->value.type->data.pointer.is_volatile; |
| 16064 | 17603 | if (bare_type->id == ZigTypeIdStruct) { |
| 16065 | 17604 | TypeStructField *field = find_struct_type_field(bare_type, field_name); |
| 16066 | | if (field) { |
| 16067 | | switch (type_has_one_possible_value(ira->codegen, field->type_entry)) { |
| 16068 | | case OnePossibleValueInvalid: |
| 16069 | | return ira->codegen->invalid_instruction; |
| 16070 | | case OnePossibleValueYes: { |
| 16071 | | IrInstruction *elem = ir_const(ira, source_instr, field->type_entry); |
| 16072 | | return ir_get_ref(ira, source_instr, elem, false, false); |
| 16073 | | } |
| 16074 | | case OnePossibleValueNo: |
| 16075 | | break; |
| 16076 | | } |
| 16077 | | bool is_packed = (bare_type->data.structure.layout == ContainerLayoutPacked); |
| 16078 | | uint32_t align_bytes = is_packed ? 1 : get_abi_alignment(ira->codegen, field->type_entry); |
| 16079 | | uint32_t ptr_bit_offset = container_ptr->value.type->data.pointer.bit_offset_in_host; |
| 16080 | | uint32_t ptr_host_int_bytes = container_ptr->value.type->data.pointer.host_int_bytes; |
| 16081 | | uint32_t host_int_bytes_for_result_type = (ptr_host_int_bytes == 0) ? |
| 16082 | | get_host_int_bytes(ira->codegen, bare_type, field) : ptr_host_int_bytes; |
| 16083 | | if (instr_is_comptime(container_ptr)) { |
| 16084 | | ConstExprValue *ptr_val = ir_resolve_const(ira, container_ptr, UndefBad); |
| 16085 | | if (!ptr_val) |
| 16086 | | return ira->codegen->invalid_instruction; |
| 16087 | | |
| 16088 | | if (ptr_val->data.x_ptr.special != ConstPtrSpecialHardCodedAddr) { |
| 16089 | | ConstExprValue *struct_val = const_ptr_pointee(ira, ira->codegen, ptr_val, source_instr->source_node); |
| 16090 | | if (struct_val == nullptr) |
| 16091 | | return ira->codegen->invalid_instruction; |
| 16092 | | if (type_is_invalid(struct_val->type)) |
| 16093 | | return ira->codegen->invalid_instruction; |
| 16094 | | ZigType *ptr_type = get_pointer_to_type_extra(ira->codegen, field->type_entry, |
| 16095 | | is_const, is_volatile, PtrLenSingle, align_bytes, |
| 16096 | | (uint32_t)(ptr_bit_offset + field->bit_offset_in_host), |
| 16097 | | (uint32_t)host_int_bytes_for_result_type, false); |
| 16098 | | IrInstruction *result = ir_const(ira, source_instr, ptr_type); |
| 16099 | | ConstExprValue *const_val = &result->value; |
| 16100 | | const_val->data.x_ptr.special = ConstPtrSpecialBaseStruct; |
| 16101 | | const_val->data.x_ptr.mut = container_ptr->value.data.x_ptr.mut; |
| 16102 | | const_val->data.x_ptr.data.base_struct.struct_val = struct_val; |
| 16103 | | const_val->data.x_ptr.data.base_struct.field_index = field->src_index; |
| 16104 | | return result; |
| 16105 | | } |
| 16106 | | } |
| 16107 | | IrInstruction *result = ir_build_struct_field_ptr(&ira->new_irb, source_instr->scope, source_instr->source_node, |
| 16108 | | container_ptr, field); |
| 16109 | | result->value.type = get_pointer_to_type_extra(ira->codegen, field->type_entry, is_const, is_volatile, |
| 16110 | | PtrLenSingle, |
| 16111 | | align_bytes, |
| 16112 | | (uint32_t)(ptr_bit_offset + field->bit_offset_in_host), |
| 16113 | | host_int_bytes_for_result_type, false); |
| 16114 | | return result; |
| 17605 | if (field != nullptr) { |
| 17606 | return ir_analyze_struct_field_ptr(ira, source_instr, field, container_ptr, bare_type, initializing); |
| 16115 | 17607 | } else { |
| 16116 | 17608 | return ir_analyze_container_member_access_inner(ira, bare_type, field_name, |
| 16117 | 17609 | source_instr, container_ptr, container_type); |
| 16118 | 17610 | } |
| 16119 | | } else if (bare_type->id == ZigTypeIdEnum) { |
| 17611 | } |
| 17612 | |
| 17613 | if (bare_type->id == ZigTypeIdEnum) { |
| 16120 | 17614 | return ir_analyze_container_member_access_inner(ira, bare_type, field_name, |
| 16121 | 17615 | source_instr, container_ptr, container_type); |
| 16122 | | } else if (bare_type->id == ZigTypeIdUnion) { |
| 17616 | } |
| 17617 | |
| 17618 | if (bare_type->id == ZigTypeIdUnion) { |
| 17619 | bool is_const = container_ptr->value.type->data.pointer.is_const; |
| 17620 | bool is_volatile = container_ptr->value.type->data.pointer.is_volatile; |
| 17621 | |
| 16123 | 17622 | TypeUnionField *field = find_union_type_field(bare_type, field_name); |
| 16124 | | if (field) { |
| 16125 | | if (instr_is_comptime(container_ptr)) { |
| 16126 | | ConstExprValue *ptr_val = ir_resolve_const(ira, container_ptr, UndefBad); |
| 16127 | | if (!ptr_val) |
| 17623 | if (field == nullptr) { |
| 17624 | return ir_analyze_container_member_access_inner(ira, bare_type, field_name, |
| 17625 | source_instr, container_ptr, container_type); |
| 17626 | } |
| 17627 | ZigType *ptr_type = get_pointer_to_type_extra(ira->codegen, field->type_entry, |
| 17628 | is_const, is_volatile, PtrLenSingle, 0, 0, 0, false); |
| 17629 | if (instr_is_comptime(container_ptr)) { |
| 17630 | ConstExprValue *ptr_val = ir_resolve_const(ira, container_ptr, UndefBad); |
| 17631 | if (!ptr_val) |
| 17632 | return ira->codegen->invalid_instruction; |
| 17633 | |
| 17634 | if (ptr_val->data.x_ptr.special != ConstPtrSpecialHardCodedAddr) { |
| 17635 | ConstExprValue *union_val = const_ptr_pointee(ira, ira->codegen, ptr_val, source_instr->source_node); |
| 17636 | if (union_val == nullptr) |
| 17637 | return ira->codegen->invalid_instruction; |
| 17638 | if (type_is_invalid(union_val->type)) |
| 16128 | 17639 | return ira->codegen->invalid_instruction; |
| 16129 | 17640 | |
| 16130 | | if (ptr_val->data.x_ptr.special != ConstPtrSpecialHardCodedAddr) { |
| 16131 | | ConstExprValue *union_val = const_ptr_pointee(ira, ira->codegen, ptr_val, source_instr->source_node); |
| 16132 | | if (union_val == nullptr) |
| 16133 | | return ira->codegen->invalid_instruction; |
| 16134 | | if (type_is_invalid(union_val->type)) |
| 16135 | | return ira->codegen->invalid_instruction; |
| 17641 | if (initializing) { |
| 17642 | ConstExprValue *payload_val = create_const_vals(1); |
| 17643 | payload_val->special = ConstValSpecialUndef; |
| 17644 | payload_val->type = field->type_entry; |
| 17645 | payload_val->parent.id = ConstParentIdUnion; |
| 17646 | payload_val->parent.data.p_union.union_val = union_val; |
| 16136 | 17647 | |
| 17648 | union_val->special = ConstValSpecialStatic; |
| 17649 | bigint_init_bigint(&union_val->data.x_union.tag, &field->enum_field->value); |
| 17650 | union_val->data.x_union.payload = payload_val; |
| 17651 | } else { |
| 16137 | 17652 | TypeUnionField *actual_field = find_union_field_by_tag(bare_type, &union_val->data.x_union.tag); |
| 16138 | 17653 | if (actual_field == nullptr) |
| 16139 | 17654 | zig_unreachable(); |
| ... | ... | @@ -16144,33 +17659,35 @@ static IrInstruction *ir_analyze_container_field_ptr(IrAnalyze *ira, Buf *field_ |
| 16144 | 17659 | buf_ptr(actual_field->name))); |
| 16145 | 17660 | return ira->codegen->invalid_instruction; |
| 16146 | 17661 | } |
| 17662 | } |
| 16147 | 17663 | |
| 16148 | | ConstExprValue *payload_val = union_val->data.x_union.payload; |
| 17664 | ConstExprValue *payload_val = union_val->data.x_union.payload; |
| 16149 | 17665 | |
| 16150 | | ZigType *field_type = field->type_entry; |
| 16151 | | ZigType *ptr_type = get_pointer_to_type_extra(ira->codegen, field_type, |
| 16152 | | is_const, is_volatile, PtrLenSingle, 0, 0, 0, false); |
| 16153 | 17666 | |
| 16154 | | IrInstruction *result = ir_const(ira, source_instr, ptr_type); |
| 16155 | | ConstExprValue *const_val = &result->value; |
| 16156 | | const_val->data.x_ptr.special = ConstPtrSpecialRef; |
| 16157 | | const_val->data.x_ptr.mut = container_ptr->value.data.x_ptr.mut; |
| 16158 | | const_val->data.x_ptr.data.ref.pointee = payload_val; |
| 16159 | | return result; |
| 17667 | IrInstruction *result; |
| 17668 | if (ptr_val->data.x_ptr.mut == ConstPtrMutInfer) { |
| 17669 | result = ir_build_union_field_ptr(&ira->new_irb, source_instr->scope, |
| 17670 | source_instr->source_node, container_ptr, field, true, initializing); |
| 17671 | result->value.type = ptr_type; |
| 17672 | result->value.special = ConstValSpecialStatic; |
| 17673 | } else { |
| 17674 | result = ir_const(ira, source_instr, ptr_type); |
| 16160 | 17675 | } |
| 17676 | ConstExprValue *const_val = &result->value; |
| 17677 | const_val->data.x_ptr.special = ConstPtrSpecialRef; |
| 17678 | const_val->data.x_ptr.mut = container_ptr->value.data.x_ptr.mut; |
| 17679 | const_val->data.x_ptr.data.ref.pointee = payload_val; |
| 17680 | return result; |
| 16161 | 17681 | } |
| 16162 | | |
| 16163 | | IrInstruction *result = ir_build_union_field_ptr(&ira->new_irb, source_instr->scope, source_instr->source_node, container_ptr, field); |
| 16164 | | result->value.type = get_pointer_to_type_extra(ira->codegen, field->type_entry, is_const, is_volatile, |
| 16165 | | PtrLenSingle, 0, 0, 0, false); |
| 16166 | | return result; |
| 16167 | | } else { |
| 16168 | | return ir_analyze_container_member_access_inner(ira, bare_type, field_name, |
| 16169 | | source_instr, container_ptr, container_type); |
| 16170 | 17682 | } |
| 16171 | | } else { |
| 16172 | | zig_unreachable(); |
| 17683 | |
| 17684 | IrInstruction *result = ir_build_union_field_ptr(&ira->new_irb, source_instr->scope, |
| 17685 | source_instr->source_node, container_ptr, field, true, initializing); |
| 17686 | result->value.type = ptr_type; |
| 17687 | return result; |
| 16173 | 17688 | } |
| 17689 | |
| 17690 | zig_unreachable(); |
| 16174 | 17691 | } |
| 16175 | 17692 | |
| 16176 | 17693 | static void add_link_lib_symbol(IrAnalyze *ira, Buf *lib_name, Buf *symbol_name, AstNode *source_node) { |
| ... | ... | @@ -16208,6 +17725,11 @@ static void add_link_lib_symbol(IrAnalyze *ira, Buf *lib_name, Buf *symbol_name, |
| 16208 | 17725 | link_lib->symbols.append(symbol_name); |
| 16209 | 17726 | } |
| 16210 | 17727 | |
| 17728 | static IrInstruction *ir_error_dependency_loop(IrAnalyze *ira, IrInstruction *source_instr) { |
| 17729 | ErrorMsg *msg = ir_add_error(ira, source_instr, buf_sprintf("dependency loop detected")); |
| 17730 | emit_error_notes_for_ref_stack(ira->codegen, msg); |
| 17731 | return ira->codegen->invalid_instruction; |
| 17732 | } |
| 16211 | 17733 | |
| 16212 | 17734 | static IrInstruction *ir_analyze_decl_ref(IrAnalyze *ira, IrInstruction *source_instruction, Tld *tld) { |
| 16213 | 17735 | resolve_top_level_decl(ira->codegen, tld, source_instruction->source_node); |
| ... | ... | @@ -16222,6 +17744,9 @@ static IrInstruction *ir_analyze_decl_ref(IrAnalyze *ira, IrInstruction *source_ |
| 16222 | 17744 | { |
| 16223 | 17745 | TldVar *tld_var = (TldVar *)tld; |
| 16224 | 17746 | ZigVar *var = tld_var->var; |
| 17747 | if (var == nullptr) { |
| 17748 | return ir_error_dependency_loop(ira, source_instruction); |
| 17749 | } |
| 16225 | 17750 | if (tld_var->extern_lib_name != nullptr) { |
| 16226 | 17751 | add_link_lib_symbol(ira, tld_var->extern_lib_name, &var->name, source_instruction->source_node); |
| 16227 | 17752 | } |
| ... | ... | @@ -16237,23 +17762,13 @@ static IrInstruction *ir_analyze_decl_ref(IrAnalyze *ira, IrInstruction *source_ |
| 16237 | 17762 | if (type_is_invalid(fn_entry->type_entry)) |
| 16238 | 17763 | return ira->codegen->invalid_instruction; |
| 16239 | 17764 | |
| 16240 | | // TODO instead of allocating this every time, put it in the tld value and we can reference |
| 16241 | | // the same one every time |
| 16242 | | ConstExprValue *const_val = create_const_vals(1); |
| 16243 | | const_val->special = ConstValSpecialStatic; |
| 16244 | | const_val->type = fn_entry->type_entry; |
| 16245 | | const_val->data.x_ptr.data.fn.fn_entry = fn_entry; |
| 16246 | | const_val->data.x_ptr.special = ConstPtrSpecialFunction; |
| 16247 | | const_val->data.x_ptr.mut = ConstPtrMutComptimeConst; |
| 16248 | | |
| 16249 | 17765 | if (tld_fn->extern_lib_name != nullptr) { |
| 16250 | 17766 | add_link_lib_symbol(ira, tld_fn->extern_lib_name, &fn_entry->symbol_name, source_instruction->source_node); |
| 16251 | 17767 | } |
| 16252 | 17768 | |
| 16253 | | bool ptr_is_const = true; |
| 16254 | | bool ptr_is_volatile = false; |
| 16255 | | return ir_get_const_ptr(ira, source_instruction, const_val, fn_entry->type_entry, |
| 16256 | | ConstPtrMutComptimeConst, ptr_is_const, ptr_is_volatile, 0); |
| 17769 | IrInstruction *fn_inst = ir_create_const_fn(&ira->new_irb, source_instruction->scope, |
| 17770 | source_instruction->source_node, fn_entry); |
| 17771 | return ir_get_ref(ira, source_instruction, fn_inst, true, false); |
| 16257 | 17772 | } |
| 16258 | 17773 | } |
| 16259 | 17774 | zig_unreachable(); |
| ... | ... | @@ -16295,14 +17810,14 @@ static IrInstruction *ir_analyze_instruction_field_ptr(IrAnalyze *ira, IrInstruc |
| 16295 | 17810 | assert(container_ptr->value.type->id == ZigTypeIdPointer); |
| 16296 | 17811 | if (container_type->id == ZigTypeIdPointer) { |
| 16297 | 17812 | ZigType *bare_type = container_ref_type(container_type); |
| 16298 | | IrInstruction *container_child = ir_get_deref(ira, &field_ptr_instruction->base, container_ptr); |
| 16299 | | IrInstruction *result = ir_analyze_container_field_ptr(ira, field_name, &field_ptr_instruction->base, container_child, bare_type); |
| 17813 | IrInstruction *container_child = ir_get_deref(ira, &field_ptr_instruction->base, container_ptr, nullptr); |
| 17814 | IrInstruction *result = ir_analyze_container_field_ptr(ira, field_name, &field_ptr_instruction->base, container_child, bare_type, field_ptr_instruction->initializing); |
| 16300 | 17815 | return result; |
| 16301 | 17816 | } else { |
| 16302 | | IrInstruction *result = ir_analyze_container_field_ptr(ira, field_name, &field_ptr_instruction->base, container_ptr, container_type); |
| 17817 | IrInstruction *result = ir_analyze_container_field_ptr(ira, field_name, &field_ptr_instruction->base, container_ptr, container_type, field_ptr_instruction->initializing); |
| 16303 | 17818 | return result; |
| 16304 | 17819 | } |
| 16305 | | } else if (is_array_ref(container_type)) { |
| 17820 | } else if (is_array_ref(container_type) && !field_ptr_instruction->initializing) { |
| 16306 | 17821 | if (buf_eql_str(field_name, "len")) { |
| 16307 | 17822 | ConstExprValue *len_val = create_const_vals(1); |
| 16308 | 17823 | if (container_type->id == ZigTypeIdPointer) { |
| ... | ... | @@ -16617,6 +18132,10 @@ static IrInstruction *ir_analyze_instruction_field_ptr(IrAnalyze *ira, IrInstruc |
| 16617 | 18132 | buf_sprintf("type '%s' does not support field access", buf_ptr(&child_type->name))); |
| 16618 | 18133 | return ira->codegen->invalid_instruction; |
| 16619 | 18134 | } |
| 18135 | } else if (field_ptr_instruction->initializing) { |
| 18136 | ir_add_error(ira, &field_ptr_instruction->base, |
| 18137 | buf_sprintf("type '%s' does not support struct initialization syntax", buf_ptr(&container_type->name))); |
| 18138 | return ira->codegen->invalid_instruction; |
| 16620 | 18139 | } else { |
| 16621 | 18140 | ir_add_error_node(ira, field_ptr_instruction->base.source_node, |
| 16622 | 18141 | buf_sprintf("type '%s' does not support field access", buf_ptr(&container_type->name))); |
| ... | ... | @@ -16640,7 +18159,7 @@ static IrInstruction *ir_analyze_instruction_load_ptr(IrAnalyze *ira, IrInstruct |
| 16640 | 18159 | IrInstruction *ptr = instruction->ptr->child; |
| 16641 | 18160 | if (type_is_invalid(ptr->value.type)) |
| 16642 | 18161 | return ira->codegen->invalid_instruction; |
| 16643 | | return ir_get_deref(ira, &instruction->base, ptr); |
| 18162 | return ir_get_deref(ira, &instruction->base, ptr, nullptr); |
| 16644 | 18163 | } |
| 16645 | 18164 | |
| 16646 | 18165 | static IrInstruction *ir_analyze_instruction_typeof(IrAnalyze *ira, IrInstructionTypeOf *typeof_instruction) { |
| ... | ... | @@ -16651,64 +18170,6 @@ static IrInstruction *ir_analyze_instruction_typeof(IrAnalyze *ira, IrInstructio |
| 16651 | 18170 | return ir_const_type(ira, &typeof_instruction->base, type_entry); |
| 16652 | 18171 | } |
| 16653 | 18172 | |
| 16654 | | static IrInstruction *ir_analyze_instruction_to_ptr_type(IrAnalyze *ira, |
| 16655 | | IrInstructionToPtrType *to_ptr_type_instruction) |
| 16656 | | { |
| 16657 | | Error err; |
| 16658 | | IrInstruction *ptr_ptr = to_ptr_type_instruction->ptr->child; |
| 16659 | | if (type_is_invalid(ptr_ptr->value.type)) |
| 16660 | | return ira->codegen->invalid_instruction; |
| 16661 | | |
| 16662 | | ZigType *ptr_ptr_type = ptr_ptr->value.type; |
| 16663 | | assert(ptr_ptr_type->id == ZigTypeIdPointer); |
| 16664 | | ZigType *type_entry = ptr_ptr_type->data.pointer.child_type; |
| 16665 | | |
| 16666 | | ZigType *ptr_type; |
| 16667 | | if (type_entry->id == ZigTypeIdArray) { |
| 16668 | | ptr_type = get_pointer_to_type(ira->codegen, type_entry->data.array.child_type, ptr_ptr_type->data.pointer.is_const); |
| 16669 | | } else if (is_array_ref(type_entry)) { |
| 16670 | | ptr_type = get_pointer_to_type(ira->codegen, |
| 16671 | | type_entry->data.pointer.child_type->data.array.child_type, type_entry->data.pointer.is_const); |
| 16672 | | } else if (is_slice(type_entry)) { |
| 16673 | | ZigType *slice_ptr_type = type_entry->data.structure.fields[0].type_entry; |
| 16674 | | ptr_type = adjust_ptr_len(ira->codegen, slice_ptr_type, PtrLenSingle); |
| 16675 | | // If the pointer is over-aligned, we may have to reduce it based on the alignment of the element type. |
| 16676 | | if (slice_ptr_type->data.pointer.explicit_alignment != 0) { |
| 16677 | | ZigType *elem_type = slice_ptr_type->data.pointer.child_type; |
| 16678 | | if ((err = type_resolve(ira->codegen, elem_type, ResolveStatusAlignmentKnown))) |
| 16679 | | return ira->codegen->invalid_instruction; |
| 16680 | | uint32_t elem_align = get_abi_alignment(ira->codegen, elem_type); |
| 16681 | | uint32_t reduced_align = min(elem_align, slice_ptr_type->data.pointer.explicit_alignment); |
| 16682 | | ptr_type = adjust_ptr_align(ira->codegen, ptr_type, reduced_align); |
| 16683 | | } |
| 16684 | | } else if (type_entry->id == ZigTypeIdArgTuple) { |
| 16685 | | zig_panic("TODO for loop on var args"); |
| 16686 | | } else { |
| 16687 | | ir_add_error_node(ira, to_ptr_type_instruction->base.source_node, |
| 16688 | | buf_sprintf("expected array type, found '%s'", buf_ptr(&type_entry->name))); |
| 16689 | | return ira->codegen->invalid_instruction; |
| 16690 | | } |
| 16691 | | |
| 16692 | | return ir_const_type(ira, &to_ptr_type_instruction->base, ptr_type); |
| 16693 | | } |
| 16694 | | |
| 16695 | | static IrInstruction *ir_analyze_instruction_ptr_type_child(IrAnalyze *ira, |
| 16696 | | IrInstructionPtrTypeChild *ptr_type_child_instruction) |
| 16697 | | { |
| 16698 | | IrInstruction *type_value = ptr_type_child_instruction->value->child; |
| 16699 | | ZigType *type_entry = ir_resolve_type(ira, type_value); |
| 16700 | | if (type_is_invalid(type_entry)) |
| 16701 | | return ira->codegen->invalid_instruction; |
| 16702 | | |
| 16703 | | if (type_entry->id != ZigTypeIdPointer) { |
| 16704 | | ir_add_error_node(ira, ptr_type_child_instruction->base.source_node, |
| 16705 | | buf_sprintf("expected pointer type, found '%s'", buf_ptr(&type_entry->name))); |
| 16706 | | return ira->codegen->invalid_instruction; |
| 16707 | | } |
| 16708 | | |
| 16709 | | return ir_const_type(ira, &ptr_type_child_instruction->base, type_entry->data.pointer.child_type); |
| 16710 | | } |
| 16711 | | |
| 16712 | 18173 | static IrInstruction *ir_analyze_instruction_set_cold(IrAnalyze *ira, IrInstructionSetCold *instruction) { |
| 16713 | 18174 | if (ira->new_irb.exec->is_inline) { |
| 16714 | 18175 | // ignore setCold when running functions at compile time |
| ... | ... | @@ -17138,7 +18599,7 @@ static IrInstruction *ir_analyze_instruction_test_non_null(IrAnalyze *ira, IrIns |
| 17138 | 18599 | } |
| 17139 | 18600 | |
| 17140 | 18601 | static IrInstruction *ir_analyze_unwrap_optional_payload(IrAnalyze *ira, IrInstruction *source_instr, |
| 17141 | | IrInstruction *base_ptr, bool safety_check_on) |
| 18602 | IrInstruction *base_ptr, bool safety_check_on, bool initializing) |
| 17142 | 18603 | { |
| 17143 | 18604 | ZigType *ptr_type = base_ptr->value.type; |
| 17144 | 18605 | assert(ptr_type->id == ZigTypeIdPointer); |
| ... | ... | @@ -17168,7 +18629,7 @@ static IrInstruction *ir_analyze_unwrap_optional_payload(IrAnalyze *ira, IrInstr |
| 17168 | 18629 | } |
| 17169 | 18630 | if (!safety_check_on) |
| 17170 | 18631 | return base_ptr; |
| 17171 | | IrInstruction *c_ptr_val = ir_get_deref(ira, source_instr, base_ptr); |
| 18632 | IrInstruction *c_ptr_val = ir_get_deref(ira, source_instr, base_ptr, nullptr); |
| 17172 | 18633 | ir_build_assert_non_null(ira, source_instr, c_ptr_val); |
| 17173 | 18634 | return base_ptr; |
| 17174 | 18635 | } |
| ... | ... | @@ -17183,34 +18644,84 @@ static IrInstruction *ir_analyze_unwrap_optional_payload(IrAnalyze *ira, IrInstr |
| 17183 | 18644 | ZigType *result_type = get_pointer_to_type_extra(ira->codegen, child_type, |
| 17184 | 18645 | ptr_type->data.pointer.is_const, ptr_type->data.pointer.is_volatile, PtrLenSingle, 0, 0, 0, false); |
| 17185 | 18646 | |
| 18647 | bool same_comptime_repr = types_have_same_zig_comptime_repr(type_entry, child_type); |
| 18648 | |
| 17186 | 18649 | if (instr_is_comptime(base_ptr)) { |
| 17187 | | ConstExprValue *val = ir_resolve_const(ira, base_ptr, UndefBad); |
| 17188 | | if (!val) |
| 18650 | ConstExprValue *ptr_val = ir_resolve_const(ira, base_ptr, UndefBad); |
| 18651 | if (!ptr_val) |
| 17189 | 18652 | return ira->codegen->invalid_instruction; |
| 17190 | | if (val->data.x_ptr.mut != ConstPtrMutRuntimeVar) { |
| 17191 | | ConstExprValue *maybe_val = const_ptr_pointee(ira, ira->codegen, val, source_instr->source_node); |
| 17192 | | if (maybe_val == nullptr) |
| 18653 | if (ptr_val->data.x_ptr.mut != ConstPtrMutRuntimeVar) { |
| 18654 | ConstExprValue *optional_val = const_ptr_pointee(ira, ira->codegen, ptr_val, source_instr->source_node); |
| 18655 | if (optional_val == nullptr) |
| 17193 | 18656 | return ira->codegen->invalid_instruction; |
| 17194 | 18657 | |
| 17195 | | if (optional_value_is_null(maybe_val)) { |
| 18658 | if (initializing && optional_val->special == ConstValSpecialUndef) { |
| 18659 | switch (type_has_one_possible_value(ira->codegen, child_type)) { |
| 18660 | case OnePossibleValueInvalid: |
| 18661 | return ira->codegen->invalid_instruction; |
| 18662 | case OnePossibleValueNo: |
| 18663 | if (!same_comptime_repr) { |
| 18664 | ConstExprValue *payload_val = create_const_vals(1); |
| 18665 | payload_val->type = child_type; |
| 18666 | payload_val->special = ConstValSpecialUndef; |
| 18667 | payload_val->parent.id = ConstParentIdOptionalPayload; |
| 18668 | payload_val->parent.data.p_optional_payload.optional_val = optional_val; |
| 18669 | |
| 18670 | optional_val->data.x_optional = payload_val; |
| 18671 | optional_val->special = ConstValSpecialStatic; |
| 18672 | } |
| 18673 | break; |
| 18674 | case OnePossibleValueYes: { |
| 18675 | ConstExprValue *pointee = create_const_vals(1); |
| 18676 | pointee->special = ConstValSpecialStatic; |
| 18677 | pointee->type = child_type; |
| 18678 | pointee->parent.id = ConstParentIdOptionalPayload; |
| 18679 | pointee->parent.data.p_optional_payload.optional_val = optional_val; |
| 18680 | |
| 18681 | optional_val->special = ConstValSpecialStatic; |
| 18682 | optional_val->data.x_optional = pointee; |
| 18683 | break; |
| 18684 | } |
| 18685 | } |
| 18686 | } else if (optional_value_is_null(optional_val)) { |
| 17196 | 18687 | ir_add_error(ira, source_instr, buf_sprintf("unable to unwrap null")); |
| 17197 | 18688 | return ira->codegen->invalid_instruction; |
| 17198 | 18689 | } |
| 17199 | | IrInstruction *result = ir_const(ira, source_instr, result_type); |
| 17200 | | ConstExprValue *out_val = &result->value; |
| 17201 | | out_val->data.x_ptr.special = ConstPtrSpecialRef; |
| 17202 | | out_val->data.x_ptr.mut = val->data.x_ptr.mut; |
| 17203 | | if (types_have_same_zig_comptime_repr(type_entry, child_type)) { |
| 17204 | | out_val->data.x_ptr.data.ref.pointee = maybe_val; |
| 18690 | |
| 18691 | IrInstruction *result; |
| 18692 | if (ptr_val->data.x_ptr.mut == ConstPtrMutInfer) { |
| 18693 | result = ir_build_optional_unwrap_ptr(&ira->new_irb, source_instr->scope, |
| 18694 | source_instr->source_node, base_ptr, false, initializing); |
| 18695 | result->value.type = result_type; |
| 18696 | result->value.special = ConstValSpecialStatic; |
| 17205 | 18697 | } else { |
| 17206 | | out_val->data.x_ptr.data.ref.pointee = maybe_val->data.x_optional; |
| 18698 | result = ir_const(ira, source_instr, result_type); |
| 18699 | } |
| 18700 | ConstExprValue *result_val = &result->value; |
| 18701 | result_val->data.x_ptr.special = ConstPtrSpecialRef; |
| 18702 | result_val->data.x_ptr.mut = ptr_val->data.x_ptr.mut; |
| 18703 | switch (type_has_one_possible_value(ira->codegen, child_type)) { |
| 18704 | case OnePossibleValueInvalid: |
| 18705 | return ira->codegen->invalid_instruction; |
| 18706 | case OnePossibleValueNo: |
| 18707 | if (same_comptime_repr) { |
| 18708 | result_val->data.x_ptr.data.ref.pointee = optional_val; |
| 18709 | } else { |
| 18710 | assert(optional_val->data.x_optional != nullptr); |
| 18711 | result_val->data.x_ptr.data.ref.pointee = optional_val->data.x_optional; |
| 18712 | } |
| 18713 | break; |
| 18714 | case OnePossibleValueYes: |
| 18715 | assert(optional_val->data.x_optional != nullptr); |
| 18716 | result_val->data.x_ptr.data.ref.pointee = optional_val->data.x_optional; |
| 18717 | break; |
| 17207 | 18718 | } |
| 17208 | 18719 | return result; |
| 17209 | 18720 | } |
| 17210 | 18721 | } |
| 17211 | 18722 | |
| 17212 | 18723 | IrInstruction *result = ir_build_optional_unwrap_ptr(&ira->new_irb, source_instr->scope, |
| 17213 | | source_instr->source_node, base_ptr, safety_check_on); |
| 18724 | source_instr->source_node, base_ptr, safety_check_on, initializing); |
| 17214 | 18725 | result->value.type = result_type; |
| 17215 | 18726 | return result; |
| 17216 | 18727 | } |
| ... | ... | @@ -17222,7 +18733,8 @@ static IrInstruction *ir_analyze_instruction_optional_unwrap_ptr(IrAnalyze *ira, |
| 17222 | 18733 | if (type_is_invalid(base_ptr->value.type)) |
| 17223 | 18734 | return ira->codegen->invalid_instruction; |
| 17224 | 18735 | |
| 17225 | | return ir_analyze_unwrap_optional_payload(ira, &instruction->base, base_ptr, instruction->safety_check_on); |
| 18736 | return ir_analyze_unwrap_optional_payload(ira, &instruction->base, base_ptr, |
| 18737 | instruction->safety_check_on, false); |
| 17226 | 18738 | } |
| 17227 | 18739 | |
| 17228 | 18740 | static IrInstruction *ir_analyze_instruction_ctz(IrAnalyze *ira, IrInstructionCtz *instruction) { |
| ... | ... | @@ -17523,7 +19035,7 @@ static IrInstruction *ir_analyze_instruction_switch_target(IrAnalyze *ira, |
| 17523 | 19035 | return result; |
| 17524 | 19036 | } |
| 17525 | 19037 | |
| 17526 | | IrInstruction *result = ir_get_deref(ira, &switch_target_instruction->base, target_value_ptr); |
| 19038 | IrInstruction *result = ir_get_deref(ira, &switch_target_instruction->base, target_value_ptr, nullptr); |
| 17527 | 19039 | result->value.type = target_type; |
| 17528 | 19040 | return result; |
| 17529 | 19041 | } |
| ... | ... | @@ -17553,7 +19065,7 @@ static IrInstruction *ir_analyze_instruction_switch_target(IrAnalyze *ira, |
| 17553 | 19065 | return result; |
| 17554 | 19066 | } |
| 17555 | 19067 | |
| 17556 | | IrInstruction *union_value = ir_get_deref(ira, &switch_target_instruction->base, target_value_ptr); |
| 19068 | IrInstruction *union_value = ir_get_deref(ira, &switch_target_instruction->base, target_value_ptr, nullptr); |
| 17557 | 19069 | union_value->value.type = target_type; |
| 17558 | 19070 | |
| 17559 | 19071 | IrInstruction *union_tag_inst = ir_build_union_tag(&ira->new_irb, switch_target_instruction->base.scope, |
| ... | ... | @@ -17577,7 +19089,7 @@ static IrInstruction *ir_analyze_instruction_switch_target(IrAnalyze *ira, |
| 17577 | 19089 | return result; |
| 17578 | 19090 | } |
| 17579 | 19091 | |
| 17580 | | IrInstruction *enum_value = ir_get_deref(ira, &switch_target_instruction->base, target_value_ptr); |
| 19092 | IrInstruction *enum_value = ir_get_deref(ira, &switch_target_instruction->base, target_value_ptr, nullptr); |
| 17581 | 19093 | enum_value->value.type = target_type; |
| 17582 | 19094 | return enum_value; |
| 17583 | 19095 | } |
| ... | ... | @@ -17650,7 +19162,7 @@ static IrInstruction *ir_analyze_instruction_switch_var(IrAnalyze *ira, IrInstru |
| 17650 | 19162 | } |
| 17651 | 19163 | |
| 17652 | 19164 | IrInstruction *result = ir_build_union_field_ptr(&ira->new_irb, |
| 17653 | | instruction->base.scope, instruction->base.source_node, target_value_ptr, field); |
| 19165 | instruction->base.scope, instruction->base.source_node, target_value_ptr, field, false, false); |
| 17654 | 19166 | result->value.type = get_pointer_to_type(ira->codegen, field->type_entry, |
| 17655 | 19167 | target_value_ptr->value.type->data.pointer.is_const); |
| 17656 | 19168 | return result; |
| ... | ... | @@ -17860,7 +19372,8 @@ static IrInstruction *ir_analyze_instruction_ref(IrAnalyze *ira, IrInstructionRe |
| 17860 | 19372 | } |
| 17861 | 19373 | |
| 17862 | 19374 | static IrInstruction *ir_analyze_container_init_fields_union(IrAnalyze *ira, IrInstruction *instruction, |
| 17863 | | ZigType *container_type, size_t instr_field_count, IrInstructionContainerInitFieldsField *fields) |
| 19375 | ZigType *container_type, size_t instr_field_count, IrInstructionContainerInitFieldsField *fields, |
| 19376 | IrInstruction *result_loc) |
| 17864 | 19377 | { |
| 17865 | 19378 | Error err; |
| 17866 | 19379 | assert(container_type->id == ZigTypeIdUnion); |
| ... | ... | @@ -17875,12 +19388,12 @@ static IrInstruction *ir_analyze_container_init_fields_union(IrAnalyze *ira, IrI |
| 17875 | 19388 | } |
| 17876 | 19389 | |
| 17877 | 19390 | IrInstructionContainerInitFieldsField *field = &fields[0]; |
| 17878 | | IrInstruction *field_value = field->value->child; |
| 17879 | | if (type_is_invalid(field_value->value.type)) |
| 19391 | IrInstruction *field_result_loc = field->result_loc->child; |
| 19392 | if (type_is_invalid(field_result_loc->value.type)) |
| 17880 | 19393 | return ira->codegen->invalid_instruction; |
| 17881 | 19394 | |
| 17882 | 19395 | TypeUnionField *type_field = find_union_type_field(container_type, field->name); |
| 17883 | | if (!type_field) { |
| 19396 | if (type_field == nullptr) { |
| 17884 | 19397 | ir_add_error_node(ira, field->source_node, |
| 17885 | 19398 | buf_sprintf("no member named '%s' in union '%s'", |
| 17886 | 19399 | buf_ptr(field->name), buf_ptr(&container_type->name))); |
| ... | ... | @@ -17890,46 +19403,36 @@ static IrInstruction *ir_analyze_container_init_fields_union(IrAnalyze *ira, IrI |
| 17890 | 19403 | if (type_is_invalid(type_field->type_entry)) |
| 17891 | 19404 | return ira->codegen->invalid_instruction; |
| 17892 | 19405 | |
| 17893 | | IrInstruction *casted_field_value = ir_implicit_cast(ira, field_value, type_field->type_entry); |
| 17894 | | if (casted_field_value == ira->codegen->invalid_instruction) |
| 17895 | | return ira->codegen->invalid_instruction; |
| 17896 | | |
| 17897 | | if ((err = type_resolve(ira->codegen, casted_field_value->value.type, ResolveStatusZeroBitsKnown))) |
| 17898 | | return ira->codegen->invalid_instruction; |
| 19406 | if (result_loc->value.data.x_ptr.mut == ConstPtrMutInfer) { |
| 19407 | if (instr_is_comptime(field_result_loc) && |
| 19408 | field_result_loc->value.data.x_ptr.mut != ConstPtrMutRuntimeVar) |
| 19409 | { |
| 19410 | // nothing |
| 19411 | } else { |
| 19412 | result_loc->value.special = ConstValSpecialRuntime; |
| 19413 | } |
| 19414 | } |
| 17899 | 19415 | |
| 17900 | 19416 | bool is_comptime = ir_should_inline(ira->new_irb.exec, instruction->scope) |
| 17901 | 19417 | || type_requires_comptime(ira->codegen, container_type) == ReqCompTimeYes; |
| 17902 | | if (is_comptime || casted_field_value->value.special != ConstValSpecialRuntime || |
| 17903 | | !type_has_bits(casted_field_value->value.type)) |
| 17904 | | { |
| 17905 | | ConstExprValue *field_val = ir_resolve_const(ira, casted_field_value, UndefOk); |
| 17906 | | if (!field_val) |
| 17907 | | return ira->codegen->invalid_instruction; |
| 17908 | | |
| 17909 | | IrInstruction *result = ir_const(ira, instruction, container_type); |
| 17910 | | ConstExprValue *out_val = &result->value; |
| 17911 | | out_val->data.x_union.payload = field_val; |
| 17912 | | out_val->data.x_union.tag = type_field->enum_field->value; |
| 17913 | | out_val->parent.id = ConstParentIdUnion; |
| 17914 | | out_val->parent.data.p_union.union_val = out_val; |
| 17915 | 19418 | |
| 17916 | | return result; |
| 19419 | IrInstruction *result = ir_get_deref(ira, instruction, result_loc, nullptr); |
| 19420 | if (is_comptime && !instr_is_comptime(result)) { |
| 19421 | ir_add_error(ira, field->result_loc, |
| 19422 | buf_sprintf("unable to evaluate constant expression")); |
| 19423 | return ira->codegen->invalid_instruction; |
| 17917 | 19424 | } |
| 17918 | | |
| 17919 | | IrInstruction *new_instruction = ir_build_union_init(&ira->new_irb, |
| 17920 | | instruction->scope, instruction->source_node, |
| 17921 | | container_type, type_field, casted_field_value); |
| 17922 | | new_instruction->value.type = container_type; |
| 17923 | | ir_add_alloca(ira, new_instruction, container_type); |
| 17924 | | return new_instruction; |
| 19425 | return result; |
| 17925 | 19426 | } |
| 17926 | 19427 | |
| 17927 | 19428 | static IrInstruction *ir_analyze_container_init_fields(IrAnalyze *ira, IrInstruction *instruction, |
| 17928 | | ZigType *container_type, size_t instr_field_count, IrInstructionContainerInitFieldsField *fields) |
| 19429 | ZigType *container_type, size_t instr_field_count, IrInstructionContainerInitFieldsField *fields, |
| 19430 | IrInstruction *result_loc) |
| 17929 | 19431 | { |
| 17930 | 19432 | Error err; |
| 17931 | 19433 | if (container_type->id == ZigTypeIdUnion) { |
| 17932 | | return ir_analyze_container_init_fields_union(ira, instruction, container_type, instr_field_count, fields); |
| 19434 | return ir_analyze_container_init_fields_union(ira, instruction, container_type, instr_field_count, |
| 19435 | fields, result_loc); |
| 17933 | 19436 | } |
| 17934 | 19437 | if (container_type->id != ZigTypeIdStruct || is_slice(container_type)) { |
| 17935 | 19438 | ir_add_error(ira, instruction, |
| ... | ... | @@ -17946,22 +19449,28 @@ static IrInstruction *ir_analyze_container_init_fields(IrAnalyze *ira, IrInstruc |
| 17946 | 19449 | IrInstruction *first_non_const_instruction = nullptr; |
| 17947 | 19450 | |
| 17948 | 19451 | AstNode **field_assign_nodes = allocate<AstNode *>(actual_field_count); |
| 17949 | | |
| 17950 | | IrInstructionStructInitField *new_fields = allocate<IrInstructionStructInitField>(actual_field_count); |
| 19452 | ZigList<IrInstruction *> const_ptrs = {}; |
| 17951 | 19453 | |
| 17952 | 19454 | bool is_comptime = ir_should_inline(ira->new_irb.exec, instruction->scope) |
| 17953 | 19455 | || type_requires_comptime(ira->codegen, container_type) == ReqCompTimeYes; |
| 17954 | 19456 | |
| 17955 | | ConstExprValue const_val = {}; |
| 17956 | | const_val.special = ConstValSpecialStatic; |
| 17957 | | const_val.type = container_type; |
| 17958 | | // const_val.global_refs = allocate<ConstGlobalRefs>(1); |
| 17959 | | const_val.data.x_struct.fields = create_const_vals(actual_field_count); |
| 19457 | |
| 19458 | // Here we iterate over the fields that have been initialized, and emit |
| 19459 | // compile errors for missing fields and duplicate fields. |
| 19460 | // It is only now that we find out whether the struct initialization can be a comptime |
| 19461 | // value, but we have already emitted runtime instructions for the fields that |
| 19462 | // were initialized with runtime values, and have omitted instructions that would have |
| 19463 | // initialized fields with comptime values. |
| 19464 | // So now we must clean up this situation. If it turns out the struct initialization can |
| 19465 | // be a comptime value, overwrite ConstPtrMutInfer with ConstPtrMutComptimeConst. |
| 19466 | // Otherwise, we must emit instructions to runtime-initialize the fields that have |
| 19467 | // comptime-known values. |
| 19468 | |
| 17960 | 19469 | for (size_t i = 0; i < instr_field_count; i += 1) { |
| 17961 | 19470 | IrInstructionContainerInitFieldsField *field = &fields[i]; |
| 17962 | 19471 | |
| 17963 | | IrInstruction *field_value = field->value->child; |
| 17964 | | if (type_is_invalid(field_value->value.type)) |
| 19472 | IrInstruction *field_result_loc = field->result_loc->child; |
| 19473 | if (type_is_invalid(field_result_loc->value.type)) |
| 17965 | 19474 | return ira->codegen->invalid_instruction; |
| 17966 | 19475 | |
| 17967 | 19476 | TypeStructField *type_field = find_struct_type_field(container_type, field->name); |
| ... | ... | @@ -17975,10 +19484,6 @@ static IrInstruction *ir_analyze_container_init_fields(IrAnalyze *ira, IrInstruc |
| 17975 | 19484 | if (type_is_invalid(type_field->type_entry)) |
| 17976 | 19485 | return ira->codegen->invalid_instruction; |
| 17977 | 19486 | |
| 17978 | | IrInstruction *casted_field_value = ir_implicit_cast(ira, field_value, type_field->type_entry); |
| 17979 | | if (casted_field_value == ira->codegen->invalid_instruction) |
| 17980 | | return ira->codegen->invalid_instruction; |
| 17981 | | |
| 17982 | 19487 | size_t field_index = type_field->src_index; |
| 17983 | 19488 | AstNode *existing_assign_node = field_assign_nodes[field_index]; |
| 17984 | 19489 | if (existing_assign_node) { |
| ... | ... | @@ -17988,26 +19493,18 @@ static IrInstruction *ir_analyze_container_init_fields(IrAnalyze *ira, IrInstruc |
| 17988 | 19493 | } |
| 17989 | 19494 | field_assign_nodes[field_index] = field->source_node; |
| 17990 | 19495 | |
| 17991 | | new_fields[field_index].value = casted_field_value; |
| 17992 | | new_fields[field_index].type_struct_field = type_field; |
| 17993 | | |
| 17994 | | if (const_val.special == ConstValSpecialStatic) { |
| 17995 | | if (is_comptime || casted_field_value->value.special != ConstValSpecialRuntime) { |
| 17996 | | ConstExprValue *field_val = ir_resolve_const(ira, casted_field_value, UndefOk); |
| 17997 | | if (!field_val) |
| 17998 | | return ira->codegen->invalid_instruction; |
| 17999 | | |
| 18000 | | copy_const_val(&const_val.data.x_struct.fields[field_index], field_val, true); |
| 18001 | | } else { |
| 18002 | | first_non_const_instruction = casted_field_value; |
| 18003 | | const_val.special = ConstValSpecialRuntime; |
| 18004 | | } |
| 19496 | if (instr_is_comptime(field_result_loc) && |
| 19497 | field_result_loc->value.data.x_ptr.mut != ConstPtrMutRuntimeVar) |
| 19498 | { |
| 19499 | const_ptrs.append(field_result_loc); |
| 19500 | } else { |
| 19501 | first_non_const_instruction = field_result_loc; |
| 18005 | 19502 | } |
| 18006 | 19503 | } |
| 18007 | 19504 | |
| 18008 | 19505 | bool any_missing = false; |
| 18009 | 19506 | for (size_t i = 0; i < actual_field_count; i += 1) { |
| 18010 | | if (field_assign_nodes[i]) continue; |
| 19507 | if (field_assign_nodes[i] != nullptr) continue; |
| 18011 | 19508 | |
| 18012 | 19509 | // look for a default field value |
| 18013 | 19510 | TypeStructField *field = &container_type->data.structure.fields[i]; |
| ... | ... | @@ -18033,182 +19530,177 @@ static IrInstruction *ir_analyze_container_init_fields(IrAnalyze *ira, IrInstruc |
| 18033 | 19530 | IrInstruction *runtime_inst = ir_const(ira, instruction, field->init_val->type); |
| 18034 | 19531 | copy_const_val(&runtime_inst->value, field->init_val, true); |
| 18035 | 19532 | |
| 18036 | | new_fields[i].value = runtime_inst; |
| 18037 | | new_fields[i].type_struct_field = field; |
| 18038 | | |
| 18039 | | if (const_val.special == ConstValSpecialStatic) { |
| 18040 | | copy_const_val(&const_val.data.x_struct.fields[i], field->init_val, true); |
| 19533 | IrInstruction *field_ptr = ir_analyze_struct_field_ptr(ira, instruction, field, result_loc, |
| 19534 | container_type, true); |
| 19535 | ir_analyze_store_ptr(ira, instruction, field_ptr, runtime_inst); |
| 19536 | if (instr_is_comptime(field_ptr) && field_ptr->value.data.x_ptr.mut != ConstPtrMutRuntimeVar) { |
| 19537 | const_ptrs.append(field_ptr); |
| 19538 | } else { |
| 19539 | first_non_const_instruction = result_loc; |
| 18041 | 19540 | } |
| 18042 | 19541 | } |
| 18043 | 19542 | if (any_missing) |
| 18044 | 19543 | return ira->codegen->invalid_instruction; |
| 18045 | 19544 | |
| 18046 | | if (const_val.special == ConstValSpecialStatic) { |
| 18047 | | IrInstruction *result = ir_const(ira, instruction, nullptr); |
| 18048 | | ConstExprValue *out_val = &result->value; |
| 18049 | | copy_const_val(out_val, &const_val, false); |
| 18050 | | out_val->type = container_type; |
| 18051 | | |
| 18052 | | for (size_t i = 0; i < instr_field_count; i += 1) { |
| 18053 | | ConstExprValue *field_val = &out_val->data.x_struct.fields[i]; |
| 18054 | | ConstParent *parent = get_const_val_parent(ira->codegen, field_val); |
| 18055 | | if (parent != nullptr) { |
| 18056 | | parent->id = ConstParentIdStruct; |
| 18057 | | parent->data.p_struct.field_index = i; |
| 18058 | | parent->data.p_struct.struct_val = out_val; |
| 19545 | if (result_loc->value.data.x_ptr.mut == ConstPtrMutInfer) { |
| 19546 | if (const_ptrs.length != actual_field_count) { |
| 19547 | result_loc->value.special = ConstValSpecialRuntime; |
| 19548 | for (size_t i = 0; i < const_ptrs.length; i += 1) { |
| 19549 | IrInstruction *field_result_loc = const_ptrs.at(i); |
| 19550 | IrInstruction *deref = ir_get_deref(ira, field_result_loc, field_result_loc, nullptr); |
| 19551 | field_result_loc->value.special = ConstValSpecialRuntime; |
| 19552 | ir_analyze_store_ptr(ira, field_result_loc, field_result_loc, deref); |
| 18059 | 19553 | } |
| 18060 | 19554 | } |
| 18061 | | |
| 18062 | | return result; |
| 18063 | 19555 | } |
| 18064 | 19556 | |
| 18065 | | if (is_comptime) { |
| 19557 | IrInstruction *result = ir_get_deref(ira, instruction, result_loc, nullptr); |
| 19558 | |
| 19559 | if (is_comptime && !instr_is_comptime(result)) { |
| 18066 | 19560 | ir_add_error_node(ira, first_non_const_instruction->source_node, |
| 18067 | 19561 | buf_sprintf("unable to evaluate constant expression")); |
| 18068 | 19562 | return ira->codegen->invalid_instruction; |
| 18069 | 19563 | } |
| 18070 | 19564 | |
| 18071 | | IrInstruction *new_instruction = ir_build_struct_init(&ira->new_irb, |
| 18072 | | instruction->scope, instruction->source_node, |
| 18073 | | container_type, actual_field_count, new_fields); |
| 18074 | | new_instruction->value.type = container_type; |
| 18075 | | ir_add_alloca(ira, new_instruction, container_type); |
| 18076 | | return new_instruction; |
| 19565 | return result; |
| 18077 | 19566 | } |
| 18078 | 19567 | |
| 18079 | 19568 | static IrInstruction *ir_analyze_instruction_container_init_list(IrAnalyze *ira, |
| 18080 | 19569 | IrInstructionContainerInitList *instruction) |
| 18081 | 19570 | { |
| 18082 | | Error err; |
| 19571 | ZigType *container_type = ir_resolve_type(ira, instruction->container_type->child); |
| 19572 | if (type_is_invalid(container_type)) |
| 19573 | return ira->codegen->invalid_instruction; |
| 18083 | 19574 | |
| 18084 | 19575 | size_t elem_count = instruction->item_count; |
| 18085 | 19576 | |
| 18086 | | ZigType *container_type; |
| 18087 | | if (instruction->container_type != nullptr) { |
| 18088 | | container_type = ir_resolve_type(ira, instruction->container_type->child); |
| 18089 | | if (type_is_invalid(container_type)) |
| 18090 | | return ira->codegen->invalid_instruction; |
| 18091 | | } else { |
| 18092 | | ZigType *elem_type = ir_resolve_type(ira, instruction->elem_type->child); |
| 18093 | | if (type_is_invalid(elem_type)) |
| 18094 | | return ira->codegen->invalid_instruction; |
| 18095 | | if ((err = type_resolve(ira->codegen, elem_type, ResolveStatusSizeKnown))) { |
| 18096 | | return ira->codegen->invalid_instruction; |
| 18097 | | } |
| 18098 | | container_type = get_array_type(ira->codegen, elem_type, elem_count); |
| 18099 | | } |
| 18100 | | |
| 18101 | 19577 | if (is_slice(container_type)) { |
| 18102 | 19578 | ir_add_error(ira, &instruction->base, |
| 18103 | 19579 | buf_sprintf("expected array type or [_], found slice")); |
| 18104 | 19580 | return ira->codegen->invalid_instruction; |
| 18105 | | } else if (container_type->id == ZigTypeIdStruct && !is_slice(container_type) && elem_count == 0) { |
| 18106 | | return ir_analyze_container_init_fields(ira, &instruction->base, container_type, |
| 18107 | | 0, nullptr); |
| 18108 | | } else if (container_type->id == ZigTypeIdArray) { |
| 18109 | | // array is same as slice init but we make a compile error if the length is wrong |
| 18110 | | ZigType *child_type; |
| 18111 | | if (container_type->id == ZigTypeIdArray) { |
| 18112 | | child_type = container_type->data.array.child_type; |
| 18113 | | if (container_type->data.array.len != elem_count) { |
| 18114 | | ZigType *literal_type = get_array_type(ira->codegen, child_type, elem_count); |
| 18115 | | |
| 18116 | | ir_add_error(ira, &instruction->base, |
| 18117 | | buf_sprintf("expected %s literal, found %s literal", |
| 18118 | | buf_ptr(&container_type->name), buf_ptr(&literal_type->name))); |
| 18119 | | return ira->codegen->invalid_instruction; |
| 18120 | | } |
| 18121 | | } else { |
| 18122 | | ZigType *pointer_type = container_type->data.structure.fields[slice_ptr_index].type_entry; |
| 18123 | | assert(pointer_type->id == ZigTypeIdPointer); |
| 18124 | | child_type = pointer_type->data.pointer.child_type; |
| 18125 | | } |
| 19581 | } |
| 18126 | 19582 | |
| 18127 | | if ((err = type_resolve(ira->codegen, child_type, ResolveStatusSizeKnown))) { |
| 19583 | if (container_type->id == ZigTypeIdVoid) { |
| 19584 | if (elem_count != 0) { |
| 19585 | ir_add_error_node(ira, instruction->base.source_node, |
| 19586 | buf_sprintf("void expression expects no arguments")); |
| 18128 | 19587 | return ira->codegen->invalid_instruction; |
| 18129 | 19588 | } |
| 19589 | return ir_const_void(ira, &instruction->base); |
| 19590 | } |
| 18130 | 19591 | |
| 18131 | | ZigType *fixed_size_array_type = get_array_type(ira->codegen, child_type, elem_count); |
| 19592 | if (container_type->id == ZigTypeIdStruct && elem_count == 0) { |
| 19593 | ir_assert(instruction->result_loc != nullptr, &instruction->base); |
| 19594 | IrInstruction *result_loc = instruction->result_loc->child; |
| 19595 | if (type_is_invalid(result_loc->value.type)) |
| 19596 | return result_loc; |
| 19597 | return ir_analyze_container_init_fields(ira, &instruction->base, container_type, 0, nullptr, result_loc); |
| 19598 | } |
| 19599 | |
| 19600 | if (container_type->id != ZigTypeIdArray) { |
| 19601 | ir_add_error_node(ira, instruction->base.source_node, |
| 19602 | buf_sprintf("type '%s' does not support array initialization", |
| 19603 | buf_ptr(&container_type->name))); |
| 19604 | return ira->codegen->invalid_instruction; |
| 19605 | } |
| 18132 | 19606 | |
| 18133 | | ConstExprValue const_val = {}; |
| 18134 | | const_val.special = ConstValSpecialStatic; |
| 18135 | | const_val.type = fixed_size_array_type; |
| 18136 | | // const_val.global_refs = allocate<ConstGlobalRefs>(1); |
| 18137 | | const_val.data.x_array.data.s_none.elements = create_const_vals(elem_count); |
| 19607 | ir_assert(instruction->result_loc != nullptr, &instruction->base); |
| 19608 | IrInstruction *result_loc = instruction->result_loc->child; |
| 19609 | if (type_is_invalid(result_loc->value.type)) |
| 19610 | return result_loc; |
| 19611 | ir_assert(result_loc->value.type->id == ZigTypeIdPointer, &instruction->base); |
| 18138 | 19612 | |
| 18139 | | bool is_comptime = ir_should_inline(ira->new_irb.exec, instruction->base.scope); |
| 19613 | ZigType *child_type = container_type->data.array.child_type; |
| 19614 | if (container_type->data.array.len != elem_count) { |
| 19615 | ZigType *literal_type = get_array_type(ira->codegen, child_type, elem_count); |
| 18140 | 19616 | |
| 18141 | | IrInstruction **new_items = allocate<IrInstruction *>(elem_count); |
| 19617 | ir_add_error(ira, &instruction->base, |
| 19618 | buf_sprintf("expected %s literal, found %s literal", |
| 19619 | buf_ptr(&container_type->name), buf_ptr(&literal_type->name))); |
| 19620 | return ira->codegen->invalid_instruction; |
| 19621 | } |
| 18142 | 19622 | |
| 18143 | | IrInstruction *first_non_const_instruction = nullptr; |
| 19623 | switch (type_has_one_possible_value(ira->codegen, container_type)) { |
| 19624 | case OnePossibleValueInvalid: |
| 19625 | return ira->codegen->invalid_instruction; |
| 19626 | case OnePossibleValueYes: |
| 19627 | return ir_const(ira, &instruction->base, container_type); |
| 19628 | case OnePossibleValueNo: |
| 19629 | break; |
| 19630 | } |
| 18144 | 19631 | |
| 18145 | | for (size_t i = 0; i < elem_count; i += 1) { |
| 18146 | | IrInstruction *arg_value = instruction->items[i]->child; |
| 18147 | | if (type_is_invalid(arg_value->value.type)) |
| 18148 | | return ira->codegen->invalid_instruction; |
| 19632 | bool is_comptime; |
| 19633 | switch (type_requires_comptime(ira->codegen, container_type)) { |
| 19634 | case ReqCompTimeInvalid: |
| 19635 | return ira->codegen->invalid_instruction; |
| 19636 | case ReqCompTimeNo: |
| 19637 | is_comptime = ir_should_inline(ira->new_irb.exec, instruction->base.scope); |
| 19638 | break; |
| 19639 | case ReqCompTimeYes: |
| 19640 | is_comptime = true; |
| 19641 | break; |
| 19642 | } |
| 18149 | 19643 | |
| 18150 | | IrInstruction *casted_arg = ir_implicit_cast(ira, arg_value, child_type); |
| 18151 | | if (casted_arg == ira->codegen->invalid_instruction) |
| 18152 | | return ira->codegen->invalid_instruction; |
| 19644 | IrInstruction *first_non_const_instruction = nullptr; |
| 18153 | 19645 | |
| 18154 | | new_items[i] = casted_arg; |
| 19646 | // The Result Location Mechanism has already emitted runtime instructions to |
| 19647 | // initialize runtime elements and has omitted instructions for the comptime |
| 19648 | // elements. However it is only now that we find out whether the array initialization |
| 19649 | // can be a comptime value. So we must clean up the situation. If it turns out |
| 19650 | // array initialization can be a comptime value, overwrite ConstPtrMutInfer with |
| 19651 | // ConstPtrMutComptimeConst. Otherwise, emit instructions to runtime-initialize the |
| 19652 | // elements that have comptime-known values. |
| 19653 | ZigList<IrInstruction *> const_ptrs = {}; |
| 19654 | |
| 19655 | for (size_t i = 0; i < elem_count; i += 1) { |
| 19656 | IrInstruction *elem_result_loc = instruction->elem_result_loc_list[i]->child; |
| 19657 | if (type_is_invalid(elem_result_loc->value.type)) |
| 19658 | return ira->codegen->invalid_instruction; |
| 18155 | 19659 | |
| 18156 | | if (const_val.special == ConstValSpecialStatic) { |
| 18157 | | if (is_comptime || casted_arg->value.special != ConstValSpecialRuntime) { |
| 18158 | | ConstExprValue *elem_val = ir_resolve_const(ira, casted_arg, UndefBad); |
| 18159 | | if (!elem_val) |
| 18160 | | return ira->codegen->invalid_instruction; |
| 19660 | assert(elem_result_loc->value.type->id == ZigTypeIdPointer); |
| 18161 | 19661 | |
| 18162 | | copy_const_val(&const_val.data.x_array.data.s_none.elements[i], elem_val, true); |
| 18163 | | } else { |
| 18164 | | first_non_const_instruction = casted_arg; |
| 18165 | | const_val.special = ConstValSpecialRuntime; |
| 18166 | | } |
| 18167 | | } |
| 19662 | if (instr_is_comptime(elem_result_loc) && |
| 19663 | elem_result_loc->value.data.x_ptr.mut != ConstPtrMutRuntimeVar) |
| 19664 | { |
| 19665 | const_ptrs.append(elem_result_loc); |
| 19666 | } else { |
| 19667 | first_non_const_instruction = elem_result_loc; |
| 18168 | 19668 | } |
| 19669 | } |
| 18169 | 19670 | |
| 18170 | | if (const_val.special == ConstValSpecialStatic) { |
| 18171 | | IrInstruction *result = ir_const(ira, &instruction->base, nullptr); |
| 18172 | | ConstExprValue *out_val = &result->value; |
| 18173 | | copy_const_val(out_val, &const_val, false); |
| 18174 | | result->value.type = fixed_size_array_type; |
| 18175 | | for (size_t i = 0; i < elem_count; i += 1) { |
| 18176 | | ConstExprValue *elem_val = &out_val->data.x_array.data.s_none.elements[i]; |
| 18177 | | ConstParent *parent = get_const_val_parent(ira->codegen, elem_val); |
| 18178 | | if (parent != nullptr) { |
| 18179 | | parent->id = ConstParentIdArray; |
| 18180 | | parent->data.p_array.array_val = out_val; |
| 18181 | | parent->data.p_array.elem_index = i; |
| 18182 | | } |
| 19671 | if (result_loc->value.data.x_ptr.mut == ConstPtrMutInfer) { |
| 19672 | if (const_ptrs.length != elem_count) { |
| 19673 | result_loc->value.special = ConstValSpecialRuntime; |
| 19674 | for (size_t i = 0; i < const_ptrs.length; i += 1) { |
| 19675 | IrInstruction *elem_result_loc = const_ptrs.at(i); |
| 19676 | assert(elem_result_loc->value.special == ConstValSpecialStatic); |
| 19677 | IrInstruction *deref = ir_get_deref(ira, elem_result_loc, elem_result_loc, nullptr); |
| 19678 | elem_result_loc->value.special = ConstValSpecialRuntime; |
| 19679 | ir_analyze_store_ptr(ira, elem_result_loc, elem_result_loc, deref); |
| 18183 | 19680 | } |
| 18184 | | return result; |
| 18185 | 19681 | } |
| 19682 | } |
| 18186 | 19683 | |
| 18187 | | if (is_comptime) { |
| 18188 | | ir_add_error_node(ira, first_non_const_instruction->source_node, |
| 18189 | | buf_sprintf("unable to evaluate constant expression")); |
| 18190 | | return ira->codegen->invalid_instruction; |
| 18191 | | } |
| 19684 | IrInstruction *result = ir_get_deref(ira, &instruction->base, result_loc, nullptr); |
| 19685 | if (instr_is_comptime(result)) |
| 19686 | return result; |
| 18192 | 19687 | |
| 18193 | | IrInstruction *new_instruction = ir_build_container_init_list(&ira->new_irb, |
| 18194 | | instruction->base.scope, instruction->base.source_node, |
| 18195 | | nullptr, nullptr, elem_count, new_items); |
| 18196 | | new_instruction->value.type = fixed_size_array_type; |
| 18197 | | ir_add_alloca(ira, new_instruction, fixed_size_array_type); |
| 18198 | | return new_instruction; |
| 18199 | | } else if (container_type->id == ZigTypeIdVoid) { |
| 18200 | | if (elem_count != 0) { |
| 18201 | | ir_add_error_node(ira, instruction->base.source_node, |
| 18202 | | buf_sprintf("void expression expects no arguments")); |
| 18203 | | return ira->codegen->invalid_instruction; |
| 18204 | | } |
| 18205 | | return ir_const_void(ira, &instruction->base); |
| 18206 | | } else { |
| 18207 | | ir_add_error_node(ira, instruction->base.source_node, |
| 18208 | | buf_sprintf("type '%s' does not support array initialization", |
| 18209 | | buf_ptr(&container_type->name))); |
| 19688 | if (is_comptime) { |
| 19689 | ir_add_error_node(ira, first_non_const_instruction->source_node, |
| 19690 | buf_sprintf("unable to evaluate constant expression")); |
| 19691 | return ira->codegen->invalid_instruction; |
| 19692 | } |
| 19693 | |
| 19694 | ZigType *result_elem_type = result_loc->value.type->data.pointer.child_type; |
| 19695 | if (is_slice(result_elem_type)) { |
| 19696 | ErrorMsg *msg = ir_add_error(ira, &instruction->base, |
| 19697 | buf_sprintf("runtime-initialized array cannot be casted to slice type '%s'", |
| 19698 | buf_ptr(&result_elem_type->name))); |
| 19699 | add_error_note(ira->codegen, msg, first_non_const_instruction->source_node, |
| 19700 | buf_sprintf("this value is not comptime-known")); |
| 18210 | 19701 | return ira->codegen->invalid_instruction; |
| 18211 | 19702 | } |
| 19703 | return result; |
| 18212 | 19704 | } |
| 18213 | 19705 | |
| 18214 | 19706 | static IrInstruction *ir_analyze_instruction_container_init_fields(IrAnalyze *ira, |
| ... | ... | @@ -18219,8 +19711,13 @@ static IrInstruction *ir_analyze_instruction_container_init_fields(IrAnalyze *ir |
| 18219 | 19711 | if (type_is_invalid(container_type)) |
| 18220 | 19712 | return ira->codegen->invalid_instruction; |
| 18221 | 19713 | |
| 19714 | ir_assert(instruction->result_loc != nullptr, &instruction->base); |
| 19715 | IrInstruction *result_loc = instruction->result_loc->child; |
| 19716 | if (type_is_invalid(result_loc->value.type)) |
| 19717 | return result_loc; |
| 19718 | |
| 18222 | 19719 | return ir_analyze_container_init_fields(ira, &instruction->base, container_type, |
| 18223 | | instruction->field_count, instruction->fields); |
| 19720 | instruction->field_count, instruction->fields, result_loc); |
| 18224 | 19721 | } |
| 18225 | 19722 | |
| 18226 | 19723 | static IrInstruction *ir_analyze_instruction_compile_err(IrAnalyze *ira, |
| ... | ... | @@ -18489,12 +19986,6 @@ static IrInstruction *ir_analyze_instruction_bit_offset_of(IrAnalyze *ira, |
| 18489 | 19986 | return ir_const_unsigned(ira, &instruction->base, bit_offset); |
| 18490 | 19987 | } |
| 18491 | 19988 | |
| 18492 | | static IrInstruction *ir_error_dependency_loop(IrAnalyze *ira, IrInstruction *source_instr) { |
| 18493 | | ErrorMsg *msg = ir_add_error(ira, source_instr, buf_sprintf("dependency loop detected")); |
| 18494 | | emit_error_notes_for_ref_stack(ira->codegen, msg); |
| 18495 | | return ira->codegen->invalid_instruction; |
| 18496 | | } |
| 18497 | | |
| 18498 | 19989 | static void ensure_field_index(ZigType *type, const char *field_name, size_t index) { |
| 18499 | 19990 | Buf *field_name_buf; |
| 18500 | 19991 | |
| ... | ... | @@ -19613,7 +21104,7 @@ static IrInstruction *ir_analyze_instruction_c_import(IrAnalyze *ira, IrInstruct |
| 19613 | 21104 | ir_add_error_node(ira, node, buf_sprintf("C import failed: unable to make dir: %s", err_str(err))); |
| 19614 | 21105 | return ira->codegen->invalid_instruction; |
| 19615 | 21106 | } |
| 19616 | | |
| 21107 | |
| 19617 | 21108 | if ((err = os_write_file(&tmp_c_file_path, &cimport_scope->buf))) { |
| 19618 | 21109 | ir_add_error_node(ira, node, buf_sprintf("C import failed: unable to write .h file: %s", err_str(err))); |
| 19619 | 21110 | return ira->codegen->invalid_instruction; |
| ... | ... | @@ -19900,12 +21391,21 @@ static IrInstruction *ir_analyze_instruction_cmpxchg(IrAnalyze *ira, IrInstructi |
| 19900 | 21391 | zig_panic("TODO compile-time execution of cmpxchg"); |
| 19901 | 21392 | } |
| 19902 | 21393 | |
| 19903 | | IrInstruction *result = ir_build_cmpxchg_gen(ira, &instruction->base, |
| 21394 | ZigType *result_type = get_optional_type(ira->codegen, operand_type); |
| 21395 | IrInstruction *result_loc; |
| 21396 | if (handle_is_ptr(result_type)) { |
| 21397 | result_loc = ir_resolve_result(ira, &instruction->base, instruction->result_loc, |
| 21398 | result_type, nullptr, true, false); |
| 21399 | if (type_is_invalid(result_loc->value.type) || instr_is_unreachable(result_loc)) { |
| 21400 | return result_loc; |
| 21401 | } |
| 21402 | } else { |
| 21403 | result_loc = nullptr; |
| 21404 | } |
| 21405 | |
| 21406 | return ir_build_cmpxchg_gen(ira, &instruction->base, result_type, |
| 19904 | 21407 | casted_ptr, casted_cmp_value, casted_new_value, |
| 19905 | | success_order, failure_order, instruction->is_weak); |
| 19906 | | result->value.type = get_optional_type(ira->codegen, operand_type); |
| 19907 | | ir_add_alloca(ira, result, result->value.type); |
| 19908 | | return result; |
| 21408 | success_order, failure_order, instruction->is_weak, result_loc); |
| 19909 | 21409 | } |
| 19910 | 21410 | |
| 19911 | 21411 | static IrInstruction *ir_analyze_instruction_fence(IrAnalyze *ira, IrInstructionFence *instruction) { |
| ... | ... | @@ -20043,7 +21543,7 @@ static IrInstruction *ir_analyze_instruction_float_cast(IrAnalyze *ira, IrInstru |
| 20043 | 21543 | } else { |
| 20044 | 21544 | op = CastOpNumLitToConcrete; |
| 20045 | 21545 | } |
| 20046 | | return ir_resolve_cast(ira, &instruction->base, target, dest_type, op, false); |
| 21546 | return ir_resolve_cast(ira, &instruction->base, target, dest_type, op); |
| 20047 | 21547 | } else { |
| 20048 | 21548 | return ira->codegen->invalid_instruction; |
| 20049 | 21549 | } |
| ... | ... | @@ -20151,6 +21651,12 @@ static IrInstruction *ir_analyze_instruction_from_bytes(IrAnalyze *ira, IrInstru |
| 20151 | 21651 | } |
| 20152 | 21652 | } |
| 20153 | 21653 | |
| 21654 | IrInstruction *result_loc = ir_resolve_result(ira, &instruction->base, instruction->result_loc, |
| 21655 | dest_slice_type, nullptr, true, false); |
| 21656 | if (result_loc != nullptr && (type_is_invalid(result_loc->value.type) || instr_is_unreachable(result_loc))) { |
| 21657 | return result_loc; |
| 21658 | } |
| 21659 | |
| 20154 | 21660 | if (casted_value->value.data.rh_slice.id == RuntimeHintSliceIdLen) { |
| 20155 | 21661 | known_len = casted_value->value.data.rh_slice.len; |
| 20156 | 21662 | have_known_len = true; |
| ... | ... | @@ -20170,9 +21676,7 @@ static IrInstruction *ir_analyze_instruction_from_bytes(IrAnalyze *ira, IrInstru |
| 20170 | 21676 | } |
| 20171 | 21677 | } |
| 20172 | 21678 | |
| 20173 | | IrInstruction *result = ir_build_resize_slice(ira, &instruction->base, casted_value, dest_slice_type); |
| 20174 | | ir_add_alloca(ira, result, dest_slice_type); |
| 20175 | | return result; |
| 21679 | return ir_build_resize_slice(ira, &instruction->base, casted_value, dest_slice_type, result_loc); |
| 20176 | 21680 | } |
| 20177 | 21681 | |
| 20178 | 21682 | static IrInstruction *ir_analyze_instruction_to_bytes(IrAnalyze *ira, IrInstructionToBytes *instruction) { |
| ... | ... | @@ -20224,9 +21728,13 @@ static IrInstruction *ir_analyze_instruction_to_bytes(IrAnalyze *ira, IrInstruct |
| 20224 | 21728 | return result; |
| 20225 | 21729 | } |
| 20226 | 21730 | |
| 20227 | | IrInstruction *result = ir_build_resize_slice(ira, &instruction->base, target, dest_slice_type); |
| 20228 | | ir_add_alloca(ira, result, dest_slice_type); |
| 20229 | | return result; |
| 21731 | IrInstruction *result_loc = ir_resolve_result(ira, &instruction->base, instruction->result_loc, |
| 21732 | dest_slice_type, nullptr, true, false); |
| 21733 | if (type_is_invalid(result_loc->value.type) || instr_is_unreachable(result_loc)) { |
| 21734 | return result_loc; |
| 21735 | } |
| 21736 | |
| 21737 | return ir_build_resize_slice(ira, &instruction->base, target, dest_slice_type, result_loc); |
| 20230 | 21738 | } |
| 20231 | 21739 | |
| 20232 | 21740 | static Error resolve_ptr_align(IrAnalyze *ira, ZigType *ty, uint32_t *result_align) { |
| ... | ... | @@ -20258,7 +21766,7 @@ static IrInstruction *ir_analyze_instruction_int_to_float(IrAnalyze *ira, IrInst |
| 20258 | 21766 | return ira->codegen->invalid_instruction; |
| 20259 | 21767 | } |
| 20260 | 21768 | |
| 20261 | | return ir_resolve_cast(ira, &instruction->base, target, dest_type, CastOpIntToFloat, false); |
| 21769 | return ir_resolve_cast(ira, &instruction->base, target, dest_type, CastOpIntToFloat); |
| 20262 | 21770 | } |
| 20263 | 21771 | |
| 20264 | 21772 | static IrInstruction *ir_analyze_instruction_float_to_int(IrAnalyze *ira, IrInstructionFloatToInt *instruction) { |
| ... | ... | @@ -20280,7 +21788,7 @@ static IrInstruction *ir_analyze_instruction_float_to_int(IrAnalyze *ira, IrInst |
| 20280 | 21788 | return ira->codegen->invalid_instruction; |
| 20281 | 21789 | } |
| 20282 | 21790 | |
| 20283 | | return ir_resolve_cast(ira, &instruction->base, target, dest_type, CastOpFloatToInt, false); |
| 21791 | return ir_resolve_cast(ira, &instruction->base, target, dest_type, CastOpFloatToInt); |
| 20284 | 21792 | } |
| 20285 | 21793 | |
| 20286 | 21794 | static IrInstruction *ir_analyze_instruction_err_to_int(IrAnalyze *ira, IrInstructionErrToInt *instruction) { |
| ... | ... | @@ -20332,7 +21840,7 @@ static IrInstruction *ir_analyze_instruction_bool_to_int(IrAnalyze *ira, IrInstr |
| 20332 | 21840 | } |
| 20333 | 21841 | |
| 20334 | 21842 | ZigType *u1_type = get_int_type(ira->codegen, false, 1); |
| 20335 | | return ir_resolve_cast(ira, &instruction->base, target, u1_type, CastOpBoolToInt, false); |
| 21843 | return ir_resolve_cast(ira, &instruction->base, target, u1_type, CastOpBoolToInt); |
| 20336 | 21844 | } |
| 20337 | 21845 | |
| 20338 | 21846 | static IrInstruction *ir_analyze_instruction_int_type(IrAnalyze *ira, IrInstructionIntType *instruction) { |
| ... | ... | @@ -20493,7 +22001,7 @@ static IrInstruction *ir_analyze_instruction_memset(IrAnalyze *ira, IrInstructio |
| 20493 | 22001 | |
| 20494 | 22002 | ConstExprValue *byte_val = &casted_byte->value; |
| 20495 | 22003 | for (size_t i = start; i < end; i += 1) { |
| 20496 | | dest_elements[i] = *byte_val; |
| 22004 | copy_const_val(&dest_elements[i], byte_val, true); |
| 20497 | 22005 | } |
| 20498 | 22006 | |
| 20499 | 22007 | return ir_const_void(ira, &instruction->base); |
| ... | ... | @@ -20563,7 +22071,7 @@ static IrInstruction *ir_analyze_instruction_memcpy(IrAnalyze *ira, IrInstructio |
| 20563 | 22071 | return ira->codegen->invalid_instruction; |
| 20564 | 22072 | |
| 20565 | 22073 | // TODO test this at comptime with u8 and non-u8 types |
| 20566 | | // TODO test with dest ptr being a global runtime variable |
| 22074 | // TODO test with dest ptr being a global runtime variable |
| 20567 | 22075 | if (casted_dest_ptr->value.special == ConstValSpecialStatic && |
| 20568 | 22076 | casted_src_ptr->value.special == ConstValSpecialStatic && |
| 20569 | 22077 | casted_count->value.special == ConstValSpecialStatic && |
| ... | ... | @@ -20661,7 +22169,7 @@ static IrInstruction *ir_analyze_instruction_memcpy(IrAnalyze *ira, IrInstructio |
| 20661 | 22169 | // TODO check for noalias violations - this should be generalized to work for any function |
| 20662 | 22170 | |
| 20663 | 22171 | for (size_t i = 0; i < count; i += 1) { |
| 20664 | | dest_elements[dest_start + i] = src_elements[src_start + i]; |
| 22172 | copy_const_val(&dest_elements[dest_start + i], &src_elements[src_start + i], true); |
| 20665 | 22173 | } |
| 20666 | 22174 | |
| 20667 | 22175 | return ir_const_void(ira, &instruction->base); |
| ... | ... | @@ -20673,7 +22181,7 @@ static IrInstruction *ir_analyze_instruction_memcpy(IrAnalyze *ira, IrInstructio |
| 20673 | 22181 | return result; |
| 20674 | 22182 | } |
| 20675 | 22183 | |
| 20676 | | static IrInstruction *ir_analyze_instruction_slice(IrAnalyze *ira, IrInstructionSlice *instruction) { |
| 22184 | static IrInstruction *ir_analyze_instruction_slice(IrAnalyze *ira, IrInstructionSliceSrc *instruction) { |
| 20677 | 22185 | IrInstruction *ptr_ptr = instruction->ptr->child; |
| 20678 | 22186 | if (type_is_invalid(ptr_ptr->value.type)) |
| 20679 | 22187 | return ira->codegen->invalid_instruction; |
| ... | ... | @@ -20962,12 +22470,13 @@ static IrInstruction *ir_analyze_instruction_slice(IrAnalyze *ira, IrInstruction |
| 20962 | 22470 | return result; |
| 20963 | 22471 | } |
| 20964 | 22472 | |
| 20965 | | IrInstruction *new_instruction = ir_build_slice(&ira->new_irb, |
| 20966 | | instruction->base.scope, instruction->base.source_node, |
| 20967 | | ptr_ptr, casted_start, end, instruction->safety_check_on); |
| 20968 | | new_instruction->value.type = return_type; |
| 20969 | | ir_add_alloca(ira, new_instruction, return_type); |
| 20970 | | return new_instruction; |
| 22473 | IrInstruction *result_loc = ir_resolve_result(ira, &instruction->base, instruction->result_loc, |
| 22474 | return_type, nullptr, true, false); |
| 22475 | if (type_is_invalid(result_loc->value.type) || instr_is_unreachable(result_loc)) { |
| 22476 | return result_loc; |
| 22477 | } |
| 22478 | return ir_build_slice_gen(ira, &instruction->base, return_type, |
| 22479 | ptr_ptr, casted_start, end, instruction->safety_check_on, result_loc); |
| 20971 | 22480 | } |
| 20972 | 22481 | |
| 20973 | 22482 | static IrInstruction *ir_analyze_instruction_member_count(IrAnalyze *ira, IrInstructionMemberCount *instruction) { |
| ... | ... | @@ -21291,6 +22800,19 @@ static IrInstruction *ir_analyze_instruction_overflow_op(IrAnalyze *ira, IrInstr |
| 21291 | 22800 | return result; |
| 21292 | 22801 | } |
| 21293 | 22802 | |
| 22803 | static IrInstruction *ir_analyze_instruction_result_ptr(IrAnalyze *ira, IrInstructionResultPtr *instruction) { |
| 22804 | IrInstruction *result = instruction->result->child; |
| 22805 | if (type_is_invalid(result->value.type)) |
| 22806 | return result; |
| 22807 | |
| 22808 | if (instruction->result_loc->written && instruction->result_loc->resolved_loc != nullptr && |
| 22809 | !instr_is_comptime(result)) |
| 22810 | { |
| 22811 | return instruction->result_loc->resolved_loc; |
| 22812 | } |
| 22813 | return ir_get_ref(ira, &instruction->base, result, true, false); |
| 22814 | } |
| 22815 | |
| 21294 | 22816 | static void ir_eval_mul_add(IrAnalyze *ira, IrInstructionMulAdd *source_instr, ZigType *float_type, |
| 21295 | 22817 | ConstExprValue *op1, ConstExprValue *op2, ConstExprValue *op3, ConstExprValue *out_val) { |
| 21296 | 22818 | if (float_type->id == ZigTypeIdComptimeFloat) { |
| ... | ... | @@ -21410,15 +22932,17 @@ static IrInstruction *ir_analyze_instruction_mul_add(IrAnalyze *ira, IrInstructi |
| 21410 | 22932 | return result; |
| 21411 | 22933 | } |
| 21412 | 22934 | |
| 21413 | | static IrInstruction *ir_analyze_instruction_test_err(IrAnalyze *ira, IrInstructionTestErr *instruction) { |
| 21414 | | IrInstruction *value = instruction->value->child; |
| 21415 | | if (type_is_invalid(value->value.type)) |
| 22935 | static IrInstruction *ir_analyze_instruction_test_err(IrAnalyze *ira, IrInstructionTestErrSrc *instruction) { |
| 22936 | IrInstruction *base_ptr = instruction->base_ptr->child; |
| 22937 | if (type_is_invalid(base_ptr->value.type)) |
| 21416 | 22938 | return ira->codegen->invalid_instruction; |
| 21417 | 22939 | |
| 22940 | IrInstruction *value = ir_get_deref(ira, &instruction->base, base_ptr, nullptr); |
| 21418 | 22941 | ZigType *type_entry = value->value.type; |
| 21419 | | if (type_is_invalid(type_entry)) { |
| 22942 | if (type_is_invalid(type_entry)) |
| 21420 | 22943 | return ira->codegen->invalid_instruction; |
| 21421 | | } else if (type_entry->id == ZigTypeIdErrorUnion) { |
| 22944 | |
| 22945 | if (type_entry->id == ZigTypeIdErrorUnion) { |
| 21422 | 22946 | if (instr_is_comptime(value)) { |
| 21423 | 22947 | ConstExprValue *err_union_val = ir_resolve_const(ira, value, UndefBad); |
| 21424 | 22948 | if (!err_union_val) |
| ... | ... | @@ -21430,21 +22954,20 @@ static IrInstruction *ir_analyze_instruction_test_err(IrAnalyze *ira, IrInstruct |
| 21430 | 22954 | } |
| 21431 | 22955 | } |
| 21432 | 22956 | |
| 21433 | | ZigType *err_set_type = type_entry->data.error_union.err_set_type; |
| 21434 | | if (!resolve_inferred_error_set(ira->codegen, err_set_type, instruction->base.source_node)) { |
| 21435 | | return ira->codegen->invalid_instruction; |
| 21436 | | } |
| 21437 | | if (!type_is_global_error_set(err_set_type) && |
| 21438 | | err_set_type->data.error_set.err_count == 0) |
| 21439 | | { |
| 21440 | | assert(err_set_type->data.error_set.infer_fn == nullptr); |
| 21441 | | return ir_const_bool(ira, &instruction->base, false); |
| 22957 | if (instruction->resolve_err_set) { |
| 22958 | ZigType *err_set_type = type_entry->data.error_union.err_set_type; |
| 22959 | if (!resolve_inferred_error_set(ira->codegen, err_set_type, instruction->base.source_node)) { |
| 22960 | return ira->codegen->invalid_instruction; |
| 22961 | } |
| 22962 | if (!type_is_global_error_set(err_set_type) && |
| 22963 | err_set_type->data.error_set.err_count == 0) |
| 22964 | { |
| 22965 | assert(err_set_type->data.error_set.infer_fn == nullptr); |
| 22966 | return ir_const_bool(ira, &instruction->base, false); |
| 22967 | } |
| 21442 | 22968 | } |
| 21443 | 22969 | |
| 21444 | | IrInstruction *result = ir_build_test_err(&ira->new_irb, |
| 21445 | | instruction->base.scope, instruction->base.source_node, value); |
| 21446 | | result->value.type = ira->codegen->builtin_types.entry_bool; |
| 21447 | | return result; |
| 22970 | return ir_build_test_err_gen(ira, &instruction->base, value); |
| 21448 | 22971 | } else if (type_entry->id == ZigTypeIdErrorSet) { |
| 21449 | 22972 | return ir_const_bool(ira, &instruction->base, true); |
| 21450 | 22973 | } else { |
| ... | ... | @@ -21452,10 +22975,9 @@ static IrInstruction *ir_analyze_instruction_test_err(IrAnalyze *ira, IrInstruct |
| 21452 | 22975 | } |
| 21453 | 22976 | } |
| 21454 | 22977 | |
| 21455 | | static IrInstruction *ir_analyze_instruction_unwrap_err_code(IrAnalyze *ira, IrInstructionUnwrapErrCode *instruction) { |
| 21456 | | IrInstruction *base_ptr = instruction->err_union->child; |
| 21457 | | if (type_is_invalid(base_ptr->value.type)) |
| 21458 | | return ira->codegen->invalid_instruction; |
| 22978 | static IrInstruction *ir_analyze_unwrap_err_code(IrAnalyze *ira, IrInstruction *source_instr, |
| 22979 | IrInstruction *base_ptr, bool initializing) |
| 22980 | { |
| 21459 | 22981 | ZigType *ptr_type = base_ptr->value.type; |
| 21460 | 22982 | |
| 21461 | 22983 | // This will be a pointer type because unwrap err payload IR instruction operates on a pointer to a thing. |
| ... | ... | @@ -21471,40 +22993,79 @@ static IrInstruction *ir_analyze_instruction_unwrap_err_code(IrAnalyze *ira, IrI |
| 21471 | 22993 | return ira->codegen->invalid_instruction; |
| 21472 | 22994 | } |
| 21473 | 22995 | |
| 22996 | ZigType *err_set_type = type_entry->data.error_union.err_set_type; |
| 22997 | ZigType *result_type = get_pointer_to_type_extra(ira->codegen, err_set_type, |
| 22998 | ptr_type->data.pointer.is_const, ptr_type->data.pointer.is_volatile, PtrLenSingle, |
| 22999 | ptr_type->data.pointer.explicit_alignment, 0, 0, false); |
| 23000 | |
| 21474 | 23001 | if (instr_is_comptime(base_ptr)) { |
| 21475 | 23002 | ConstExprValue *ptr_val = ir_resolve_const(ira, base_ptr, UndefBad); |
| 21476 | 23003 | if (!ptr_val) |
| 21477 | 23004 | return ira->codegen->invalid_instruction; |
| 21478 | | if (ptr_val->data.x_ptr.mut != ConstPtrMutRuntimeVar) { |
| 21479 | | ConstExprValue *err_union_val = const_ptr_pointee(ira, ira->codegen, ptr_val, instruction->base.source_node); |
| 23005 | if (ptr_val->data.x_ptr.mut != ConstPtrMutRuntimeVar && |
| 23006 | ptr_val->data.x_ptr.special != ConstPtrSpecialHardCodedAddr) |
| 23007 | { |
| 23008 | ConstExprValue *err_union_val = const_ptr_pointee(ira, ira->codegen, ptr_val, source_instr->source_node); |
| 21480 | 23009 | if (err_union_val == nullptr) |
| 21481 | 23010 | return ira->codegen->invalid_instruction; |
| 21482 | | if (err_union_val->special != ConstValSpecialRuntime) { |
| 21483 | | ErrorTableEntry *err = err_union_val->data.x_err_union.error_set->data.x_err_set; |
| 21484 | | assert(err); |
| 21485 | 23011 | |
| 21486 | | IrInstruction *result = ir_const(ira, &instruction->base, |
| 21487 | | type_entry->data.error_union.err_set_type); |
| 21488 | | result->value.data.x_err_set = err; |
| 21489 | | return result; |
| 23012 | if (initializing && err_union_val->special == ConstValSpecialUndef) { |
| 23013 | ConstExprValue *vals = create_const_vals(2); |
| 23014 | ConstExprValue *err_set_val = &vals[0]; |
| 23015 | ConstExprValue *payload_val = &vals[1]; |
| 23016 | |
| 23017 | err_set_val->special = ConstValSpecialUndef; |
| 23018 | err_set_val->type = err_set_type; |
| 23019 | err_set_val->parent.id = ConstParentIdErrUnionCode; |
| 23020 | err_set_val->parent.data.p_err_union_code.err_union_val = err_union_val; |
| 23021 | |
| 23022 | payload_val->special = ConstValSpecialUndef; |
| 23023 | payload_val->type = type_entry->data.error_union.payload_type; |
| 23024 | payload_val->parent.id = ConstParentIdErrUnionPayload; |
| 23025 | payload_val->parent.data.p_err_union_payload.err_union_val = err_union_val; |
| 23026 | |
| 23027 | err_union_val->special = ConstValSpecialStatic; |
| 23028 | err_union_val->data.x_err_union.error_set = err_set_val; |
| 23029 | err_union_val->data.x_err_union.payload = payload_val; |
| 23030 | } |
| 23031 | ir_assert(err_union_val->special != ConstValSpecialRuntime, source_instr); |
| 23032 | |
| 23033 | IrInstruction *result; |
| 23034 | if (ptr_val->data.x_ptr.mut == ConstPtrMutInfer) { |
| 23035 | result = ir_build_unwrap_err_code(&ira->new_irb, source_instr->scope, |
| 23036 | source_instr->source_node, base_ptr); |
| 23037 | result->value.type = result_type; |
| 23038 | result->value.special = ConstValSpecialStatic; |
| 23039 | } else { |
| 23040 | result = ir_const(ira, source_instr, result_type); |
| 21490 | 23041 | } |
| 23042 | ConstExprValue *const_val = &result->value; |
| 23043 | const_val->data.x_ptr.special = ConstPtrSpecialBaseErrorUnionCode; |
| 23044 | const_val->data.x_ptr.data.base_err_union_code.err_union_val = err_union_val; |
| 23045 | const_val->data.x_ptr.mut = ptr_val->data.x_ptr.mut; |
| 23046 | return result; |
| 21491 | 23047 | } |
| 21492 | 23048 | } |
| 21493 | 23049 | |
| 21494 | 23050 | IrInstruction *result = ir_build_unwrap_err_code(&ira->new_irb, |
| 21495 | | instruction->base.scope, instruction->base.source_node, base_ptr); |
| 21496 | | result->value.type = type_entry->data.error_union.err_set_type; |
| 23051 | source_instr->scope, source_instr->source_node, base_ptr); |
| 23052 | result->value.type = result_type; |
| 21497 | 23053 | return result; |
| 21498 | 23054 | } |
| 21499 | 23055 | |
| 21500 | | static IrInstruction *ir_analyze_instruction_unwrap_err_payload(IrAnalyze *ira, |
| 21501 | | IrInstructionUnwrapErrPayload *instruction) |
| 23056 | static IrInstruction *ir_analyze_instruction_unwrap_err_code(IrAnalyze *ira, |
| 23057 | IrInstructionUnwrapErrCode *instruction) |
| 21502 | 23058 | { |
| 21503 | | assert(instruction->value->child); |
| 21504 | | IrInstruction *value = instruction->value->child; |
| 21505 | | if (type_is_invalid(value->value.type)) |
| 23059 | IrInstruction *base_ptr = instruction->err_union_ptr->child; |
| 23060 | if (type_is_invalid(base_ptr->value.type)) |
| 21506 | 23061 | return ira->codegen->invalid_instruction; |
| 21507 | | ZigType *ptr_type = value->value.type; |
| 23062 | return ir_analyze_unwrap_err_code(ira, &instruction->base, base_ptr, false); |
| 23063 | } |
| 23064 | |
| 23065 | static IrInstruction *ir_analyze_unwrap_error_payload(IrAnalyze *ira, IrInstruction *source_instr, |
| 23066 | IrInstruction *base_ptr, bool safety_check_on, bool initializing) |
| 23067 | { |
| 23068 | ZigType *ptr_type = base_ptr->value.type; |
| 21508 | 23069 | |
| 21509 | 23070 | // This will be a pointer type because unwrap err payload IR instruction operates on a pointer to a thing. |
| 21510 | 23071 | assert(ptr_type->id == ZigTypeIdPointer); |
| ... | ... | @@ -21514,7 +23075,7 @@ static IrInstruction *ir_analyze_instruction_unwrap_err_payload(IrAnalyze *ira, |
| 21514 | 23075 | return ira->codegen->invalid_instruction; |
| 21515 | 23076 | |
| 21516 | 23077 | if (type_entry->id != ZigTypeIdErrorUnion) { |
| 21517 | | ir_add_error(ira, value, |
| 23078 | ir_add_error(ira, base_ptr, |
| 21518 | 23079 | buf_sprintf("expected error union type, found '%s'", buf_ptr(&type_entry->name))); |
| 21519 | 23080 | return ira->codegen->invalid_instruction; |
| 21520 | 23081 | } |
| ... | ... | @@ -21526,36 +23087,73 @@ static IrInstruction *ir_analyze_instruction_unwrap_err_payload(IrAnalyze *ira, |
| 21526 | 23087 | ZigType *result_type = get_pointer_to_type_extra(ira->codegen, payload_type, |
| 21527 | 23088 | ptr_type->data.pointer.is_const, ptr_type->data.pointer.is_volatile, |
| 21528 | 23089 | PtrLenSingle, 0, 0, 0, false); |
| 21529 | | if (instr_is_comptime(value)) { |
| 21530 | | ConstExprValue *ptr_val = ir_resolve_const(ira, value, UndefBad); |
| 23090 | if (instr_is_comptime(base_ptr)) { |
| 23091 | ConstExprValue *ptr_val = ir_resolve_const(ira, base_ptr, UndefBad); |
| 21531 | 23092 | if (!ptr_val) |
| 21532 | 23093 | return ira->codegen->invalid_instruction; |
| 21533 | 23094 | if (ptr_val->data.x_ptr.mut != ConstPtrMutRuntimeVar) { |
| 21534 | | ConstExprValue *err_union_val = const_ptr_pointee(ira, ira->codegen, ptr_val, instruction->base.source_node); |
| 23095 | ConstExprValue *err_union_val = const_ptr_pointee(ira, ira->codegen, ptr_val, source_instr->source_node); |
| 21535 | 23096 | if (err_union_val == nullptr) |
| 21536 | 23097 | return ira->codegen->invalid_instruction; |
| 23098 | if (err_union_val->special == ConstValSpecialUndef && initializing) { |
| 23099 | ConstExprValue *vals = create_const_vals(2); |
| 23100 | ConstExprValue *err_set_val = &vals[0]; |
| 23101 | ConstExprValue *payload_val = &vals[1]; |
| 23102 | |
| 23103 | err_set_val->special = ConstValSpecialStatic; |
| 23104 | err_set_val->type = type_entry->data.error_union.err_set_type; |
| 23105 | err_set_val->data.x_err_set = nullptr; |
| 23106 | |
| 23107 | payload_val->special = ConstValSpecialUndef; |
| 23108 | payload_val->type = payload_type; |
| 23109 | |
| 23110 | err_union_val->special = ConstValSpecialStatic; |
| 23111 | err_union_val->data.x_err_union.error_set = err_set_val; |
| 23112 | err_union_val->data.x_err_union.payload = payload_val; |
| 23113 | } |
| 23114 | |
| 21537 | 23115 | if (err_union_val->special != ConstValSpecialRuntime) { |
| 21538 | 23116 | ErrorTableEntry *err = err_union_val->data.x_err_union.error_set->data.x_err_set; |
| 21539 | 23117 | if (err != nullptr) { |
| 21540 | | ir_add_error(ira, &instruction->base, |
| 23118 | ir_add_error(ira, source_instr, |
| 21541 | 23119 | buf_sprintf("caught unexpected error '%s'", buf_ptr(&err->name))); |
| 21542 | 23120 | return ira->codegen->invalid_instruction; |
| 21543 | 23121 | } |
| 21544 | 23122 | |
| 21545 | | IrInstruction *result = ir_const(ira, &instruction->base, result_type); |
| 23123 | IrInstruction *result; |
| 23124 | if (ptr_val->data.x_ptr.mut == ConstPtrMutInfer) { |
| 23125 | result = ir_build_unwrap_err_payload(&ira->new_irb, source_instr->scope, |
| 23126 | source_instr->source_node, base_ptr, safety_check_on, initializing); |
| 23127 | result->value.type = result_type; |
| 23128 | result->value.special = ConstValSpecialStatic; |
| 23129 | } else { |
| 23130 | result = ir_const(ira, source_instr, result_type); |
| 23131 | } |
| 21546 | 23132 | result->value.data.x_ptr.special = ConstPtrSpecialRef; |
| 21547 | 23133 | result->value.data.x_ptr.data.ref.pointee = err_union_val->data.x_err_union.payload; |
| 23134 | result->value.data.x_ptr.mut = ptr_val->data.x_ptr.mut; |
| 21548 | 23135 | return result; |
| 21549 | 23136 | } |
| 21550 | 23137 | } |
| 21551 | 23138 | } |
| 21552 | 23139 | |
| 21553 | | IrInstruction *result = ir_build_unwrap_err_payload(&ira->new_irb, |
| 21554 | | instruction->base.scope, instruction->base.source_node, value, instruction->safety_check_on); |
| 23140 | IrInstruction *result = ir_build_unwrap_err_payload(&ira->new_irb, source_instr->scope, |
| 23141 | source_instr->source_node, base_ptr, safety_check_on, initializing); |
| 21555 | 23142 | result->value.type = result_type; |
| 21556 | 23143 | return result; |
| 21557 | 23144 | } |
| 21558 | 23145 | |
| 23146 | static IrInstruction *ir_analyze_instruction_unwrap_err_payload(IrAnalyze *ira, |
| 23147 | IrInstructionUnwrapErrPayload *instruction) |
| 23148 | { |
| 23149 | assert(instruction->value->child); |
| 23150 | IrInstruction *value = instruction->value->child; |
| 23151 | if (type_is_invalid(value->value.type)) |
| 23152 | return ira->codegen->invalid_instruction; |
| 23153 | |
| 23154 | return ir_analyze_unwrap_error_payload(ira, &instruction->base, value, instruction->safety_check_on, false); |
| 23155 | } |
| 23156 | |
| 21559 | 23157 | static IrInstruction *ir_analyze_instruction_fn_proto(IrAnalyze *ira, IrInstructionFnProto *instruction) { |
| 21560 | 23158 | AstNode *proto_node = instruction->base.source_node; |
| 21561 | 23159 | assert(proto_node->type == NodeTypeFnProto); |
| ... | ... | @@ -22047,14 +23645,19 @@ static IrInstruction *ir_analyze_ptr_cast(IrAnalyze *ira, IrInstruction *source_ |
| 22047 | 23645 | } |
| 22048 | 23646 | } |
| 22049 | 23647 | |
| 22050 | | IrInstruction *result = ir_const(ira, source_instr, dest_type); |
| 23648 | IrInstruction *result; |
| 23649 | if (ptr->value.data.x_ptr.mut == ConstPtrMutInfer) { |
| 23650 | result = ir_build_ptr_cast_gen(ira, source_instr, dest_type, ptr, safety_check_on); |
| 23651 | } else { |
| 23652 | result = ir_const(ira, source_instr, dest_type); |
| 23653 | } |
| 22051 | 23654 | copy_const_val(&result->value, val, true); |
| 22052 | 23655 | result->value.type = dest_type; |
| 22053 | 23656 | |
| 22054 | 23657 | // Keep the bigger alignment, it can only help- |
| 22055 | 23658 | // unless the target is zero bits. |
| 22056 | 23659 | if (src_align_bytes > dest_align_bytes && type_has_bits(dest_type)) { |
| 22057 | | result = ir_align_cast(ira, result, src_align_bytes, false); |
| 23660 | result = ir_align_cast(ira, result, src_align_bytes, false); |
| 22058 | 23661 | } |
| 22059 | 23662 | |
| 22060 | 23663 | return result; |
| ... | ... | @@ -22138,6 +23741,8 @@ static void buf_write_value_bytes(CodeGen *codegen, uint8_t *buf, ConstExprValue |
| 22138 | 23741 | case ZigTypeIdUndefined: |
| 22139 | 23742 | case ZigTypeIdNull: |
| 22140 | 23743 | case ZigTypeIdPromise: |
| 23744 | case ZigTypeIdErrorUnion: |
| 23745 | case ZigTypeIdErrorSet: |
| 22141 | 23746 | zig_unreachable(); |
| 22142 | 23747 | case ZigTypeIdVoid: |
| 22143 | 23748 | return; |
| ... | ... | @@ -22241,10 +23846,6 @@ static void buf_write_value_bytes(CodeGen *codegen, uint8_t *buf, ConstExprValue |
| 22241 | 23846 | } |
| 22242 | 23847 | case ZigTypeIdOptional: |
| 22243 | 23848 | zig_panic("TODO buf_write_value_bytes maybe type"); |
| 22244 | | case ZigTypeIdErrorUnion: |
| 22245 | | zig_panic("TODO buf_write_value_bytes error union"); |
| 22246 | | case ZigTypeIdErrorSet: |
| 22247 | | zig_panic("TODO buf_write_value_bytes pure error type"); |
| 22248 | 23849 | case ZigTypeIdFn: |
| 22249 | 23850 | zig_panic("TODO buf_write_value_bytes fn type"); |
| 22250 | 23851 | case ZigTypeIdUnion: |
| ... | ... | @@ -22433,28 +24034,6 @@ static Error buf_read_value_bytes(IrAnalyze *ira, CodeGen *codegen, AstNode *sou |
| 22433 | 24034 | zig_unreachable(); |
| 22434 | 24035 | } |
| 22435 | 24036 | |
| 22436 | | static bool type_can_bit_cast(ZigType *t) { |
| 22437 | | switch (t->id) { |
| 22438 | | case ZigTypeIdInvalid: |
| 22439 | | zig_unreachable(); |
| 22440 | | case ZigTypeIdMetaType: |
| 22441 | | case ZigTypeIdOpaque: |
| 22442 | | case ZigTypeIdBoundFn: |
| 22443 | | case ZigTypeIdArgTuple: |
| 22444 | | case ZigTypeIdUnreachable: |
| 22445 | | case ZigTypeIdComptimeFloat: |
| 22446 | | case ZigTypeIdComptimeInt: |
| 22447 | | case ZigTypeIdEnumLiteral: |
| 22448 | | case ZigTypeIdUndefined: |
| 22449 | | case ZigTypeIdNull: |
| 22450 | | case ZigTypeIdPointer: |
| 22451 | | return false; |
| 22452 | | default: |
| 22453 | | // TODO list these types out explicitly, there are probably some other invalid ones here |
| 22454 | | return true; |
| 22455 | | } |
| 22456 | | } |
| 22457 | | |
| 22458 | 24037 | static IrInstruction *ir_analyze_bit_cast(IrAnalyze *ira, IrInstruction *source_instr, IrInstruction *value, |
| 22459 | 24038 | ZigType *dest_type) |
| 22460 | 24039 | { |
| ... | ... | @@ -22506,49 +24085,7 @@ static IrInstruction *ir_analyze_bit_cast(IrAnalyze *ira, IrInstruction *source_ |
| 22506 | 24085 | return result; |
| 22507 | 24086 | } |
| 22508 | 24087 | |
| 22509 | | IrInstruction *result = ir_build_bit_cast_gen(ira, source_instr, value, dest_type); |
| 22510 | | if (handle_is_ptr(dest_type) && !handle_is_ptr(src_type)) { |
| 22511 | | ir_add_alloca(ira, result, dest_type); |
| 22512 | | } |
| 22513 | | return result; |
| 22514 | | } |
| 22515 | | |
| 22516 | | static IrInstruction *ir_analyze_instruction_bit_cast(IrAnalyze *ira, IrInstructionBitCast *instruction) { |
| 22517 | | IrInstruction *dest_type_value = instruction->dest_type->child; |
| 22518 | | ZigType *dest_type = ir_resolve_type(ira, dest_type_value); |
| 22519 | | if (type_is_invalid(dest_type)) |
| 22520 | | return ira->codegen->invalid_instruction; |
| 22521 | | |
| 22522 | | IrInstruction *value = instruction->value->child; |
| 22523 | | ZigType *src_type = value->value.type; |
| 22524 | | if (type_is_invalid(src_type)) |
| 22525 | | return ira->codegen->invalid_instruction; |
| 22526 | | |
| 22527 | | if (get_codegen_ptr_type(src_type) != nullptr) { |
| 22528 | | ir_add_error(ira, value, |
| 22529 | | buf_sprintf("unable to @bitCast from pointer type '%s'", buf_ptr(&src_type->name))); |
| 22530 | | return ira->codegen->invalid_instruction; |
| 22531 | | } |
| 22532 | | |
| 22533 | | if (!type_can_bit_cast(src_type)) { |
| 22534 | | ir_add_error(ira, dest_type_value, |
| 22535 | | buf_sprintf("unable to @bitCast from type '%s'", buf_ptr(&src_type->name))); |
| 22536 | | return ira->codegen->invalid_instruction; |
| 22537 | | } |
| 22538 | | |
| 22539 | | if (get_codegen_ptr_type(dest_type) != nullptr) { |
| 22540 | | ir_add_error(ira, dest_type_value, |
| 22541 | | buf_sprintf("unable to @bitCast to pointer type '%s'", buf_ptr(&dest_type->name))); |
| 22542 | | return ira->codegen->invalid_instruction; |
| 22543 | | } |
| 22544 | | |
| 22545 | | if (!type_can_bit_cast(dest_type)) { |
| 22546 | | ir_add_error(ira, dest_type_value, |
| 22547 | | buf_sprintf("unable to @bitCast to type '%s'", buf_ptr(&dest_type->name))); |
| 22548 | | return ira->codegen->invalid_instruction; |
| 22549 | | } |
| 22550 | | |
| 22551 | | return ir_analyze_bit_cast(ira, &instruction->base, value, dest_type); |
| 24088 | return ir_build_bit_cast_gen(ira, source_instr, value, dest_type); |
| 22552 | 24089 | } |
| 22553 | 24090 | |
| 22554 | 24091 | static IrInstruction *ir_analyze_int_to_ptr(IrAnalyze *ira, IrInstruction *source_instr, IrInstruction *target, |
| ... | ... | @@ -22618,58 +24155,15 @@ static IrInstruction *ir_analyze_instruction_int_to_ptr(IrAnalyze *ira, IrInstru |
| 22618 | 24155 | static IrInstruction *ir_analyze_instruction_decl_ref(IrAnalyze *ira, |
| 22619 | 24156 | IrInstructionDeclRef *instruction) |
| 22620 | 24157 | { |
| 22621 | | Tld *tld = instruction->tld; |
| 22622 | | LVal lval = instruction->lval; |
| 22623 | | |
| 22624 | | resolve_top_level_decl(ira->codegen, tld, instruction->base.source_node); |
| 22625 | | if (tld->resolution == TldResolutionInvalid) |
| 24158 | IrInstruction *ref_instruction = ir_analyze_decl_ref(ira, &instruction->base, instruction->tld); |
| 24159 | if (type_is_invalid(ref_instruction->value.type)) |
| 22626 | 24160 | return ira->codegen->invalid_instruction; |
| 22627 | 24161 | |
| 22628 | | switch (tld->id) { |
| 22629 | | case TldIdContainer: |
| 22630 | | case TldIdCompTime: |
| 22631 | | zig_unreachable(); |
| 22632 | | case TldIdVar: { |
| 22633 | | TldVar *tld_var = (TldVar *)tld; |
| 22634 | | ZigVar *var = tld_var->var; |
| 22635 | | |
| 22636 | | if (var == nullptr) { |
| 22637 | | return ir_error_dependency_loop(ira, &instruction->base); |
| 22638 | | } |
| 22639 | | |
| 22640 | | IrInstruction *var_ptr = ir_get_var_ptr(ira, &instruction->base, var); |
| 22641 | | if (type_is_invalid(var_ptr->value.type)) |
| 22642 | | return ira->codegen->invalid_instruction; |
| 22643 | | |
| 22644 | | if (tld_var->extern_lib_name != nullptr) { |
| 22645 | | add_link_lib_symbol(ira, tld_var->extern_lib_name, &var->name, instruction->base.source_node); |
| 22646 | | } |
| 22647 | | |
| 22648 | | if (lval == LValPtr) { |
| 22649 | | return var_ptr; |
| 22650 | | } else { |
| 22651 | | return ir_get_deref(ira, &instruction->base, var_ptr); |
| 22652 | | } |
| 22653 | | } |
| 22654 | | case TldIdFn: { |
| 22655 | | TldFn *tld_fn = (TldFn *)tld; |
| 22656 | | ZigFn *fn_entry = tld_fn->fn_entry; |
| 22657 | | ir_assert(fn_entry->type_entry, &instruction->base); |
| 22658 | | |
| 22659 | | if (tld_fn->extern_lib_name != nullptr) { |
| 22660 | | add_link_lib_symbol(ira, tld_fn->extern_lib_name, &fn_entry->symbol_name, instruction->base.source_node); |
| 22661 | | } |
| 22662 | | |
| 22663 | | IrInstruction *ref_instruction = ir_create_const_fn(&ira->new_irb, instruction->base.scope, |
| 22664 | | instruction->base.source_node, fn_entry); |
| 22665 | | if (lval == LValPtr) { |
| 22666 | | return ir_get_ref(ira, &instruction->base, ref_instruction, true, false); |
| 22667 | | } else { |
| 22668 | | return ref_instruction; |
| 22669 | | } |
| 22670 | | } |
| 24162 | if (instruction->lval == LValPtr) { |
| 24163 | return ref_instruction; |
| 24164 | } else { |
| 24165 | return ir_get_deref(ira, &instruction->base, ref_instruction, nullptr); |
| 22671 | 24166 | } |
| 22672 | | zig_unreachable(); |
| 22673 | 24167 | } |
| 22674 | 24168 | |
| 22675 | 24169 | static IrInstruction *ir_analyze_instruction_ptr_to_int(IrAnalyze *ira, IrInstructionPtrToInt *instruction) { |
| ... | ... | @@ -23183,7 +24677,7 @@ static IrInstruction *ir_analyze_instruction_atomic_load(IrAnalyze *ira, IrInstr |
| 23183 | 24677 | } |
| 23184 | 24678 | |
| 23185 | 24679 | if (instr_is_comptime(casted_ptr)) { |
| 23186 | | IrInstruction *result = ir_get_deref(ira, &instruction->base, casted_ptr); |
| 24680 | IrInstruction *result = ir_get_deref(ira, &instruction->base, casted_ptr, nullptr); |
| 23187 | 24681 | ir_assert(result->value.type != nullptr, &instruction->base); |
| 23188 | 24682 | return result; |
| 23189 | 24683 | } |
| ... | ... | @@ -23721,12 +25215,56 @@ static IrInstruction *ir_analyze_instruction_undeclared_ident(IrAnalyze *ira, Ir |
| 23721 | 25215 | return ira->codegen->invalid_instruction; |
| 23722 | 25216 | } |
| 23723 | 25217 | |
| 23724 | | static IrInstruction *ir_analyze_instruction_nocast(IrAnalyze *ira, IrInstruction *instruction) { |
| 25218 | static IrInstruction *ir_analyze_instruction_end_expr(IrAnalyze *ira, IrInstructionEndExpr *instruction) { |
| 25219 | IrInstruction *value = instruction->value->child; |
| 25220 | if (type_is_invalid(value->value.type)) |
| 25221 | return ira->codegen->invalid_instruction; |
| 25222 | |
| 25223 | bool was_written = instruction->result_loc->written; |
| 25224 | IrInstruction *result_loc = ir_resolve_result(ira, &instruction->base, instruction->result_loc, |
| 25225 | value->value.type, value, false, false); |
| 25226 | if (result_loc != nullptr) { |
| 25227 | if (type_is_invalid(result_loc->value.type)) |
| 25228 | return ira->codegen->invalid_instruction; |
| 25229 | if (result_loc->value.type->id == ZigTypeIdUnreachable) |
| 25230 | return result_loc; |
| 25231 | |
| 25232 | if (!was_written) { |
| 25233 | IrInstruction *store_ptr = ir_analyze_store_ptr(ira, &instruction->base, result_loc, value); |
| 25234 | if (type_is_invalid(store_ptr->value.type)) { |
| 25235 | return ira->codegen->invalid_instruction; |
| 25236 | } |
| 25237 | } |
| 25238 | |
| 25239 | if (result_loc->value.data.x_ptr.mut == ConstPtrMutInfer) { |
| 25240 | if (instr_is_comptime(value)) { |
| 25241 | result_loc->value.data.x_ptr.mut = ConstPtrMutComptimeConst; |
| 25242 | } else { |
| 25243 | result_loc->value.special = ConstValSpecialRuntime; |
| 25244 | } |
| 25245 | } |
| 25246 | } |
| 25247 | |
| 25248 | return ir_const_void(ira, &instruction->base); |
| 25249 | } |
| 25250 | |
| 25251 | static IrInstruction *ir_analyze_instruction_bit_cast_src(IrAnalyze *ira, IrInstructionBitCastSrc *instruction) { |
| 25252 | IrInstruction *operand = instruction->operand->child; |
| 25253 | if (type_is_invalid(operand->value.type)) |
| 25254 | return operand; |
| 25255 | |
| 25256 | IrInstruction *result_loc = ir_resolve_result(ira, &instruction->base, |
| 25257 | &instruction->result_loc_bit_cast->base, operand->value.type, operand, false, false); |
| 25258 | if (result_loc != nullptr && (type_is_invalid(result_loc->value.type) || instr_is_unreachable(result_loc))) |
| 25259 | return result_loc; |
| 25260 | |
| 25261 | return instruction->result_loc_bit_cast->parent->gen_instruction; |
| 25262 | } |
| 25263 | |
| 25264 | static IrInstruction *ir_analyze_instruction_base(IrAnalyze *ira, IrInstruction *instruction) { |
| 23725 | 25265 | switch (instruction->id) { |
| 23726 | 25266 | case IrInstructionIdInvalid: |
| 23727 | 25267 | case IrInstructionIdWidenOrShorten: |
| 23728 | | case IrInstructionIdStructInit: |
| 23729 | | case IrInstructionIdUnionInit: |
| 23730 | 25268 | case IrInstructionIdStructFieldPtr: |
| 23731 | 25269 | case IrInstructionIdUnionFieldPtr: |
| 23732 | 25270 | case IrInstructionIdOptionalWrap: |
| ... | ... | @@ -23738,11 +25276,18 @@ static IrInstruction *ir_analyze_instruction_nocast(IrAnalyze *ira, IrInstructio |
| 23738 | 25276 | case IrInstructionIdCmpxchgGen: |
| 23739 | 25277 | case IrInstructionIdArrayToVector: |
| 23740 | 25278 | case IrInstructionIdVectorToArray: |
| 25279 | case IrInstructionIdPtrOfArrayToSlice: |
| 23741 | 25280 | case IrInstructionIdAssertZero: |
| 23742 | 25281 | case IrInstructionIdAssertNonNull: |
| 23743 | 25282 | case IrInstructionIdResizeSlice: |
| 23744 | 25283 | case IrInstructionIdLoadPtrGen: |
| 23745 | 25284 | case IrInstructionIdBitCastGen: |
| 25285 | case IrInstructionIdCallGen: |
| 25286 | case IrInstructionIdReturnPtr: |
| 25287 | case IrInstructionIdAllocaGen: |
| 25288 | case IrInstructionIdSliceGen: |
| 25289 | case IrInstructionIdRefGen: |
| 25290 | case IrInstructionIdTestErrGen: |
| 23746 | 25291 | zig_unreachable(); |
| 23747 | 25292 | |
| 23748 | 25293 | case IrInstructionIdReturn: |
| ... | ... | @@ -23765,8 +25310,8 @@ static IrInstruction *ir_analyze_instruction_nocast(IrAnalyze *ira, IrInstructio |
| 23765 | 25310 | return ir_analyze_instruction_var_ptr(ira, (IrInstructionVarPtr *)instruction); |
| 23766 | 25311 | case IrInstructionIdFieldPtr: |
| 23767 | 25312 | return ir_analyze_instruction_field_ptr(ira, (IrInstructionFieldPtr *)instruction); |
| 23768 | | case IrInstructionIdCall: |
| 23769 | | return ir_analyze_instruction_call(ira, (IrInstructionCall *)instruction); |
| 25313 | case IrInstructionIdCallSrc: |
| 25314 | return ir_analyze_instruction_call(ira, (IrInstructionCallSrc *)instruction); |
| 23770 | 25315 | case IrInstructionIdBr: |
| 23771 | 25316 | return ir_analyze_instruction_br(ira, (IrInstructionBr *)instruction); |
| 23772 | 25317 | case IrInstructionIdCondBr: |
| ... | ... | @@ -23777,10 +25322,6 @@ static IrInstruction *ir_analyze_instruction_nocast(IrAnalyze *ira, IrInstructio |
| 23777 | 25322 | return ir_analyze_instruction_phi(ira, (IrInstructionPhi *)instruction); |
| 23778 | 25323 | case IrInstructionIdTypeOf: |
| 23779 | 25324 | return ir_analyze_instruction_typeof(ira, (IrInstructionTypeOf *)instruction); |
| 23780 | | case IrInstructionIdToPtrType: |
| 23781 | | return ir_analyze_instruction_to_ptr_type(ira, (IrInstructionToPtrType *)instruction); |
| 23782 | | case IrInstructionIdPtrTypeChild: |
| 23783 | | return ir_analyze_instruction_ptr_type_child(ira, (IrInstructionPtrTypeChild *)instruction); |
| 23784 | 25325 | case IrInstructionIdSetCold: |
| 23785 | 25326 | return ir_analyze_instruction_set_cold(ira, (IrInstructionSetCold *)instruction); |
| 23786 | 25327 | case IrInstructionIdSetRuntimeSafety: |
| ... | ... | @@ -23881,8 +25422,8 @@ static IrInstruction *ir_analyze_instruction_nocast(IrAnalyze *ira, IrInstructio |
| 23881 | 25422 | return ir_analyze_instruction_memset(ira, (IrInstructionMemset *)instruction); |
| 23882 | 25423 | case IrInstructionIdMemcpy: |
| 23883 | 25424 | return ir_analyze_instruction_memcpy(ira, (IrInstructionMemcpy *)instruction); |
| 23884 | | case IrInstructionIdSlice: |
| 23885 | | return ir_analyze_instruction_slice(ira, (IrInstructionSlice *)instruction); |
| 25425 | case IrInstructionIdSliceSrc: |
| 25426 | return ir_analyze_instruction_slice(ira, (IrInstructionSliceSrc *)instruction); |
| 23886 | 25427 | case IrInstructionIdMemberCount: |
| 23887 | 25428 | return ir_analyze_instruction_member_count(ira, (IrInstructionMemberCount *)instruction); |
| 23888 | 25429 | case IrInstructionIdMemberType: |
| ... | ... | @@ -23901,8 +25442,8 @@ static IrInstruction *ir_analyze_instruction_nocast(IrAnalyze *ira, IrInstructio |
| 23901 | 25442 | return ir_analyze_instruction_align_of(ira, (IrInstructionAlignOf *)instruction); |
| 23902 | 25443 | case IrInstructionIdOverflowOp: |
| 23903 | 25444 | return ir_analyze_instruction_overflow_op(ira, (IrInstructionOverflowOp *)instruction); |
| 23904 | | case IrInstructionIdTestErr: |
| 23905 | | return ir_analyze_instruction_test_err(ira, (IrInstructionTestErr *)instruction); |
| 25445 | case IrInstructionIdTestErrSrc: |
| 25446 | return ir_analyze_instruction_test_err(ira, (IrInstructionTestErrSrc *)instruction); |
| 23906 | 25447 | case IrInstructionIdUnwrapErrCode: |
| 23907 | 25448 | return ir_analyze_instruction_unwrap_err_code(ira, (IrInstructionUnwrapErrCode *)instruction); |
| 23908 | 25449 | case IrInstructionIdUnwrapErrPayload: |
| ... | ... | @@ -23921,8 +25462,6 @@ static IrInstruction *ir_analyze_instruction_nocast(IrAnalyze *ira, IrInstructio |
| 23921 | 25462 | return ir_analyze_instruction_panic(ira, (IrInstructionPanic *)instruction); |
| 23922 | 25463 | case IrInstructionIdPtrCastSrc: |
| 23923 | 25464 | return ir_analyze_instruction_ptr_cast(ira, (IrInstructionPtrCastSrc *)instruction); |
| 23924 | | case IrInstructionIdBitCast: |
| 23925 | | return ir_analyze_instruction_bit_cast(ira, (IrInstructionBitCast *)instruction); |
| 23926 | 25465 | case IrInstructionIdIntToPtr: |
| 23927 | 25466 | return ir_analyze_instruction_int_to_ptr(ira, (IrInstructionIntToPtr *)instruction); |
| 23928 | 25467 | case IrInstructionIdPtrToInt: |
| ... | ... | @@ -23945,6 +25484,14 @@ static IrInstruction *ir_analyze_instruction_nocast(IrAnalyze *ira, IrInstructio |
| 23945 | 25484 | return ir_analyze_instruction_ptr_type(ira, (IrInstructionPtrType *)instruction); |
| 23946 | 25485 | case IrInstructionIdAlignCast: |
| 23947 | 25486 | return ir_analyze_instruction_align_cast(ira, (IrInstructionAlignCast *)instruction); |
| 25487 | case IrInstructionIdImplicitCast: |
| 25488 | return ir_analyze_instruction_implicit_cast(ira, (IrInstructionImplicitCast *)instruction); |
| 25489 | case IrInstructionIdResolveResult: |
| 25490 | return ir_analyze_instruction_resolve_result(ira, (IrInstructionResolveResult *)instruction); |
| 25491 | case IrInstructionIdResetResult: |
| 25492 | return ir_analyze_instruction_reset_result(ira, (IrInstructionResetResult *)instruction); |
| 25493 | case IrInstructionIdResultPtr: |
| 25494 | return ir_analyze_instruction_result_ptr(ira, (IrInstructionResultPtr *)instruction); |
| 23948 | 25495 | case IrInstructionIdOpaqueType: |
| 23949 | 25496 | return ir_analyze_instruction_opaque_type(ira, (IrInstructionOpaqueType *)instruction); |
| 23950 | 25497 | case IrInstructionIdSetAlignStack: |
| ... | ... | @@ -24021,17 +25568,16 @@ static IrInstruction *ir_analyze_instruction_nocast(IrAnalyze *ira, IrInstructio |
| 24021 | 25568 | return ir_analyze_instruction_has_decl(ira, (IrInstructionHasDecl *)instruction); |
| 24022 | 25569 | case IrInstructionIdUndeclaredIdent: |
| 24023 | 25570 | return ir_analyze_instruction_undeclared_ident(ira, (IrInstructionUndeclaredIdent *)instruction); |
| 25571 | case IrInstructionIdAllocaSrc: |
| 25572 | return nullptr; |
| 25573 | case IrInstructionIdEndExpr: |
| 25574 | return ir_analyze_instruction_end_expr(ira, (IrInstructionEndExpr *)instruction); |
| 25575 | case IrInstructionIdBitCastSrc: |
| 25576 | return ir_analyze_instruction_bit_cast_src(ira, (IrInstructionBitCastSrc *)instruction); |
| 24024 | 25577 | } |
| 24025 | 25578 | zig_unreachable(); |
| 24026 | 25579 | } |
| 24027 | 25580 | |
| 24028 | | static IrInstruction *ir_analyze_instruction(IrAnalyze *ira, IrInstruction *old_instruction) { |
| 24029 | | IrInstruction *new_instruction = ir_analyze_instruction_nocast(ira, old_instruction); |
| 24030 | | ir_assert(new_instruction->value.type != nullptr, old_instruction); |
| 24031 | | old_instruction->child = new_instruction; |
| 24032 | | return new_instruction; |
| 24033 | | } |
| 24034 | | |
| 24035 | 25581 | // This function attempts to evaluate IR code while doing type checking and other analysis. |
| 24036 | 25582 | // It emits a new IrExecutable which is partially evaluated IR code. |
| 24037 | 25583 | ZigType *ir_analyze(CodeGen *codegen, IrExecutable *old_exec, IrExecutable *new_exec, |
| ... | ... | @@ -24077,14 +25623,22 @@ ZigType *ir_analyze(CodeGen *codegen, IrExecutable *old_exec, IrExecutable *new_ |
| 24077 | 25623 | continue; |
| 24078 | 25624 | } |
| 24079 | 25625 | |
| 24080 | | IrInstruction *new_instruction = ir_analyze_instruction(ira, old_instruction); |
| 24081 | | if (type_is_invalid(new_instruction->value.type) && ir_should_inline(new_exec, old_instruction->scope)) { |
| 24082 | | return ira->codegen->builtin_types.entry_invalid; |
| 25626 | if (ira->codegen->verbose_ir) { |
| 25627 | fprintf(stderr, "analyze #%zu\n", old_instruction->debug_id); |
| 24083 | 25628 | } |
| 25629 | IrInstruction *new_instruction = ir_analyze_instruction_base(ira, old_instruction); |
| 25630 | if (new_instruction != nullptr) { |
| 25631 | ir_assert(new_instruction->value.type != nullptr || new_instruction->value.type != nullptr, old_instruction); |
| 25632 | old_instruction->child = new_instruction; |
| 24084 | 25633 | |
| 24085 | | // unreachable instructions do their own control flow. |
| 24086 | | if (new_instruction->value.type->id == ZigTypeIdUnreachable) |
| 24087 | | continue; |
| 25634 | if (type_is_invalid(new_instruction->value.type)) { |
| 25635 | return ira->codegen->builtin_types.entry_invalid; |
| 25636 | } |
| 25637 | |
| 25638 | // unreachable instructions do their own control flow. |
| 25639 | if (new_instruction->value.type->id == ZigTypeIdUnreachable) |
| 25640 | continue; |
| 25641 | } |
| 24088 | 25642 | |
| 24089 | 25643 | ira->instruction_index += 1; |
| 24090 | 25644 | } |
| ... | ... | @@ -24109,7 +25663,8 @@ bool ir_has_side_effects(IrInstruction *instruction) { |
| 24109 | 25663 | case IrInstructionIdDeclVarSrc: |
| 24110 | 25664 | case IrInstructionIdDeclVarGen: |
| 24111 | 25665 | case IrInstructionIdStorePtr: |
| 24112 | | case IrInstructionIdCall: |
| 25666 | case IrInstructionIdCallSrc: |
| 25667 | case IrInstructionIdCallGen: |
| 24113 | 25668 | case IrInstructionIdReturn: |
| 24114 | 25669 | case IrInstructionIdUnreachable: |
| 24115 | 25670 | case IrInstructionIdSetCold: |
| ... | ... | @@ -24156,27 +25711,28 @@ bool ir_has_side_effects(IrInstruction *instruction) { |
| 24156 | 25711 | case IrInstructionIdResizeSlice: |
| 24157 | 25712 | case IrInstructionIdGlobalAsm: |
| 24158 | 25713 | case IrInstructionIdUndeclaredIdent: |
| 25714 | case IrInstructionIdEndExpr: |
| 25715 | case IrInstructionIdPtrOfArrayToSlice: |
| 25716 | case IrInstructionIdSliceGen: |
| 25717 | case IrInstructionIdOptionalWrap: |
| 25718 | case IrInstructionIdVectorToArray: |
| 25719 | case IrInstructionIdResetResult: |
| 24159 | 25720 | return true; |
| 24160 | 25721 | |
| 24161 | 25722 | case IrInstructionIdPhi: |
| 24162 | 25723 | case IrInstructionIdUnOp: |
| 24163 | 25724 | case IrInstructionIdBinOp: |
| 24164 | 25725 | case IrInstructionIdLoadPtr: |
| 24165 | | case IrInstructionIdLoadPtrGen: |
| 24166 | 25726 | case IrInstructionIdConst: |
| 24167 | 25727 | case IrInstructionIdCast: |
| 24168 | 25728 | case IrInstructionIdContainerInitList: |
| 24169 | 25729 | case IrInstructionIdContainerInitFields: |
| 24170 | | case IrInstructionIdStructInit: |
| 24171 | | case IrInstructionIdUnionInit: |
| 24172 | 25730 | case IrInstructionIdFieldPtr: |
| 24173 | 25731 | case IrInstructionIdElemPtr: |
| 24174 | 25732 | case IrInstructionIdVarPtr: |
| 25733 | case IrInstructionIdReturnPtr: |
| 24175 | 25734 | case IrInstructionIdTypeOf: |
| 24176 | | case IrInstructionIdToPtrType: |
| 24177 | | case IrInstructionIdPtrTypeChild: |
| 24178 | 25735 | case IrInstructionIdStructFieldPtr: |
| 24179 | | case IrInstructionIdUnionFieldPtr: |
| 24180 | 25736 | case IrInstructionIdArrayType: |
| 24181 | 25737 | case IrInstructionIdPromiseType: |
| 24182 | 25738 | case IrInstructionIdSliceType: |
| ... | ... | @@ -24198,7 +25754,7 @@ bool ir_has_side_effects(IrInstruction *instruction) { |
| 24198 | 25754 | case IrInstructionIdIntType: |
| 24199 | 25755 | case IrInstructionIdVectorType: |
| 24200 | 25756 | case IrInstructionIdBoolNot: |
| 24201 | | case IrInstructionIdSlice: |
| 25757 | case IrInstructionIdSliceSrc: |
| 24202 | 25758 | case IrInstructionIdMemberCount: |
| 24203 | 25759 | case IrInstructionIdMemberType: |
| 24204 | 25760 | case IrInstructionIdMemberName: |
| ... | ... | @@ -24206,16 +25762,13 @@ bool ir_has_side_effects(IrInstruction *instruction) { |
| 24206 | 25762 | case IrInstructionIdReturnAddress: |
| 24207 | 25763 | case IrInstructionIdFrameAddress: |
| 24208 | 25764 | case IrInstructionIdHandle: |
| 24209 | | case IrInstructionIdTestErr: |
| 24210 | | case IrInstructionIdUnwrapErrCode: |
| 24211 | | case IrInstructionIdOptionalWrap: |
| 24212 | | case IrInstructionIdErrWrapCode: |
| 24213 | | case IrInstructionIdErrWrapPayload: |
| 25765 | case IrInstructionIdTestErrSrc: |
| 25766 | case IrInstructionIdTestErrGen: |
| 24214 | 25767 | case IrInstructionIdFnProto: |
| 24215 | 25768 | case IrInstructionIdTestComptime: |
| 24216 | 25769 | case IrInstructionIdPtrCastSrc: |
| 24217 | 25770 | case IrInstructionIdPtrCastGen: |
| 24218 | | case IrInstructionIdBitCast: |
| 25771 | case IrInstructionIdBitCastSrc: |
| 24219 | 25772 | case IrInstructionIdBitCastGen: |
| 24220 | 25773 | case IrInstructionIdWidenOrShorten: |
| 24221 | 25774 | case IrInstructionIdPtrToInt: |
| ... | ... | @@ -24233,6 +25786,8 @@ bool ir_has_side_effects(IrInstruction *instruction) { |
| 24233 | 25786 | case IrInstructionIdTypeInfo: |
| 24234 | 25787 | case IrInstructionIdTypeId: |
| 24235 | 25788 | case IrInstructionIdAlignCast: |
| 25789 | case IrInstructionIdImplicitCast: |
| 25790 | case IrInstructionIdResolveResult: |
| 24236 | 25791 | case IrInstructionIdOpaqueType: |
| 24237 | 25792 | case IrInstructionIdArgType: |
| 24238 | 25793 | case IrInstructionIdTagType: |
| ... | ... | @@ -24257,9 +25812,11 @@ bool ir_has_side_effects(IrInstruction *instruction) { |
| 24257 | 25812 | case IrInstructionIdFromBytes: |
| 24258 | 25813 | case IrInstructionIdToBytes: |
| 24259 | 25814 | case IrInstructionIdEnumToInt: |
| 24260 | | case IrInstructionIdVectorToArray: |
| 24261 | 25815 | case IrInstructionIdArrayToVector: |
| 24262 | 25816 | case IrInstructionIdHasDecl: |
| 25817 | case IrInstructionIdAllocaSrc: |
| 25818 | case IrInstructionIdAllocaGen: |
| 25819 | case IrInstructionIdResultPtr: |
| 24263 | 25820 | return false; |
| 24264 | 25821 | |
| 24265 | 25822 | case IrInstructionIdAsm: |
| ... | ... | @@ -24271,8 +25828,21 @@ bool ir_has_side_effects(IrInstruction *instruction) { |
| 24271 | 25828 | { |
| 24272 | 25829 | IrInstructionUnwrapErrPayload *unwrap_err_payload_instruction = |
| 24273 | 25830 | (IrInstructionUnwrapErrPayload *)instruction; |
| 24274 | | return unwrap_err_payload_instruction->safety_check_on; |
| 25831 | return unwrap_err_payload_instruction->safety_check_on || |
| 25832 | unwrap_err_payload_instruction->initializing; |
| 24275 | 25833 | } |
| 25834 | case IrInstructionIdUnwrapErrCode: |
| 25835 | return reinterpret_cast<IrInstructionUnwrapErrCode *>(instruction)->initializing; |
| 25836 | case IrInstructionIdUnionFieldPtr: |
| 25837 | return reinterpret_cast<IrInstructionUnionFieldPtr *>(instruction)->initializing; |
| 25838 | case IrInstructionIdErrWrapPayload: |
| 25839 | return reinterpret_cast<IrInstructionErrWrapPayload *>(instruction)->result_loc != nullptr; |
| 25840 | case IrInstructionIdErrWrapCode: |
| 25841 | return reinterpret_cast<IrInstructionErrWrapCode *>(instruction)->result_loc != nullptr; |
| 25842 | case IrInstructionIdLoadPtrGen: |
| 25843 | return reinterpret_cast<IrInstructionLoadPtrGen *>(instruction)->result_loc != nullptr; |
| 25844 | case IrInstructionIdRefGen: |
| 25845 | return reinterpret_cast<IrInstructionRefGen *>(instruction)->result_loc != nullptr; |
| 24276 | 25846 | } |
| 24277 | 25847 | zig_unreachable(); |
| 24278 | 25848 | } |