| ... | ... | @@ -157,7 +157,8 @@ enum UndefAllowed { |
| 157 | 157 | }; |
| 158 | 158 | |
| 159 | 159 | 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); |
| 160 | static IrInstruction *ir_gen_node_extra(IrBuilder *irb, AstNode *node, Scope *scope, LVal lval, |
| 161 | ResultLoc *result_loc); |
| 161 | 162 | static IrInstruction *ir_analyze_instruction(IrAnalyze *ira, IrInstruction *instruction); |
| 162 | 163 | static IrInstruction *ir_implicit_cast(IrAnalyze *ira, IrInstruction *value, ZigType *expected_type); |
| 163 | 164 | static IrInstruction *ir_get_deref(IrAnalyze *ira, IrInstruction *source_instruction, IrInstruction *ptr); |
| ... | ... | @@ -475,8 +476,16 @@ static constexpr IrInstructionId ir_instruction_id(IrInstructionVarPtr *) { |
| 475 | 476 | return IrInstructionIdVarPtr; |
| 476 | 477 | } |
| 477 | 478 | |
| 478 | | static constexpr IrInstructionId ir_instruction_id(IrInstructionCall *) { |
| 479 | | return IrInstructionIdCall; |
| 479 | static constexpr IrInstructionId ir_instruction_id(IrInstructionReturnPtr *) { |
| 480 | return IrInstructionIdReturnPtr; |
| 481 | } |
| 482 | |
| 483 | static constexpr IrInstructionId ir_instruction_id(IrInstructionCallSrc *) { |
| 484 | return IrInstructionIdCallSrc; |
| 485 | } |
| 486 | |
| 487 | static constexpr IrInstructionId ir_instruction_id(IrInstructionCallGen *) { |
| 488 | return IrInstructionIdCallGen; |
| 480 | 489 | } |
| 481 | 490 | |
| 482 | 491 | static constexpr IrInstructionId ir_instruction_id(IrInstructionConst *) { |
| ... | ... | @@ -1019,6 +1028,14 @@ static constexpr IrInstructionId ir_instruction_id(IrInstructionUndeclaredIdent |
| 1019 | 1028 | return IrInstructionIdUndeclaredIdent; |
| 1020 | 1029 | } |
| 1021 | 1030 | |
| 1031 | static constexpr IrInstructionId ir_instruction_id(IrInstructionAllocaSrc *) { |
| 1032 | return IrInstructionIdAllocaSrc; |
| 1033 | } |
| 1034 | |
| 1035 | static constexpr IrInstructionId ir_instruction_id(IrInstructionAllocaGen *) { |
| 1036 | return IrInstructionIdAllocaGen; |
| 1037 | } |
| 1038 | |
| 1022 | 1039 | template<typename T> |
| 1023 | 1040 | static T *ir_create_instruction(IrBuilder *irb, Scope *scope, AstNode *source_node) { |
| 1024 | 1041 | T *special_instruction = allocate<T>(1); |
| ... | ... | @@ -1254,6 +1271,13 @@ static IrInstruction *ir_build_var_ptr(IrBuilder *irb, Scope *scope, AstNode *so |
| 1254 | 1271 | return ir_build_var_ptr_x(irb, scope, source_node, var, nullptr); |
| 1255 | 1272 | } |
| 1256 | 1273 | |
| 1274 | static IrInstruction *ir_build_return_ptr(IrAnalyze *ira, IrInstruction *source_instruction, ZigType *ty) { |
| 1275 | IrInstructionReturnPtr *instruction = ir_build_instruction<IrInstructionReturnPtr>(&ira->new_irb, |
| 1276 | source_instruction->scope, source_instruction->source_node); |
| 1277 | instruction->base.value.type = ty; |
| 1278 | return &instruction->base; |
| 1279 | } |
| 1280 | |
| 1257 | 1281 | static IrInstruction *ir_build_elem_ptr(IrBuilder *irb, Scope *scope, AstNode *source_node, IrInstruction *array_ptr, |
| 1258 | 1282 | IrInstruction *elem_index, bool safety_check_on, PtrLen ptr_len) |
| 1259 | 1283 | { |
| ... | ... | @@ -1320,12 +1344,12 @@ static IrInstruction *ir_build_union_field_ptr(IrBuilder *irb, Scope *scope, Ast |
| 1320 | 1344 | return &instruction->base; |
| 1321 | 1345 | } |
| 1322 | 1346 | |
| 1323 | | static IrInstruction *ir_build_call(IrBuilder *irb, Scope *scope, AstNode *source_node, |
| 1347 | static IrInstruction *ir_build_call_src(IrBuilder *irb, Scope *scope, AstNode *source_node, |
| 1324 | 1348 | ZigFn *fn_entry, IrInstruction *fn_ref, size_t arg_count, IrInstruction **args, |
| 1325 | 1349 | bool is_comptime, FnInline fn_inline, bool is_async, IrInstruction *async_allocator, |
| 1326 | | IrInstruction *new_stack) |
| 1350 | IrInstruction *new_stack, ResultLoc *result_loc) |
| 1327 | 1351 | { |
| 1328 | | IrInstructionCall *call_instruction = ir_build_instruction<IrInstructionCall>(irb, scope, source_node); |
| 1352 | IrInstructionCallSrc *call_instruction = ir_build_instruction<IrInstructionCallSrc>(irb, scope, source_node); |
| 1329 | 1353 | call_instruction->fn_entry = fn_entry; |
| 1330 | 1354 | call_instruction->fn_ref = fn_ref; |
| 1331 | 1355 | call_instruction->is_comptime = is_comptime; |
| ... | ... | @@ -1335,6 +1359,7 @@ static IrInstruction *ir_build_call(IrBuilder *irb, Scope *scope, AstNode *sourc |
| 1335 | 1359 | call_instruction->is_async = is_async; |
| 1336 | 1360 | call_instruction->async_allocator = async_allocator; |
| 1337 | 1361 | call_instruction->new_stack = new_stack; |
| 1362 | call_instruction->result_loc = result_loc; |
| 1338 | 1363 | |
| 1339 | 1364 | if (fn_ref != nullptr) ir_ref_instruction(fn_ref, irb->current_basic_block); |
| 1340 | 1365 | for (size_t i = 0; i < arg_count; i += 1) |
| ... | ... | @@ -1345,6 +1370,33 @@ static IrInstruction *ir_build_call(IrBuilder *irb, Scope *scope, AstNode *sourc |
| 1345 | 1370 | return &call_instruction->base; |
| 1346 | 1371 | } |
| 1347 | 1372 | |
| 1373 | static IrInstruction *ir_build_call_gen(IrAnalyze *ira, IrInstruction *source_instruction, |
| 1374 | ZigFn *fn_entry, IrInstruction *fn_ref, size_t arg_count, IrInstruction **args, |
| 1375 | FnInline fn_inline, bool is_async, IrInstruction *async_allocator, IrInstruction *new_stack, |
| 1376 | IrInstruction *result_loc) |
| 1377 | { |
| 1378 | IrInstructionCallGen *call_instruction = ir_build_instruction<IrInstructionCallGen>(&ira->new_irb, |
| 1379 | source_instruction->scope, source_instruction->source_node); |
| 1380 | call_instruction->fn_entry = fn_entry; |
| 1381 | call_instruction->fn_ref = fn_ref; |
| 1382 | call_instruction->fn_inline = fn_inline; |
| 1383 | call_instruction->args = args; |
| 1384 | call_instruction->arg_count = arg_count; |
| 1385 | call_instruction->is_async = is_async; |
| 1386 | call_instruction->async_allocator = async_allocator; |
| 1387 | call_instruction->new_stack = new_stack; |
| 1388 | call_instruction->result_loc = result_loc; |
| 1389 | |
| 1390 | if (fn_ref != nullptr) ir_ref_instruction(fn_ref, ira->new_irb.current_basic_block); |
| 1391 | for (size_t i = 0; i < arg_count; i += 1) |
| 1392 | ir_ref_instruction(args[i], ira->new_irb.current_basic_block); |
| 1393 | if (async_allocator != nullptr) ir_ref_instruction(async_allocator, ira->new_irb.current_basic_block); |
| 1394 | if (new_stack != nullptr) ir_ref_instruction(new_stack, ira->new_irb.current_basic_block); |
| 1395 | if (result_loc != nullptr) ir_ref_instruction(result_loc, ira->new_irb.current_basic_block); |
| 1396 | |
| 1397 | return &call_instruction->base; |
| 1398 | } |
| 1399 | |
| 1348 | 1400 | static IrInstruction *ir_build_phi(IrBuilder *irb, Scope *scope, AstNode *source_node, |
| 1349 | 1401 | size_t incoming_count, IrBasicBlock **incoming_blocks, IrInstruction **incoming_values) |
| 1350 | 1402 | { |
| ... | ... | @@ -1511,7 +1563,7 @@ static IrInstruction *ir_build_store_ptr(IrBuilder *irb, Scope *scope, AstNode * |
| 1511 | 1563 | } |
| 1512 | 1564 | |
| 1513 | 1565 | static IrInstruction *ir_build_var_decl_src(IrBuilder *irb, Scope *scope, AstNode *source_node, |
| 1514 | | ZigVar *var, IrInstruction *var_type, IrInstruction *align_value, IrInstruction *init_value) |
| 1566 | ZigVar *var, IrInstruction *var_type, IrInstruction *align_value, IrInstruction *ptr) |
| 1515 | 1567 | { |
| 1516 | 1568 | IrInstructionDeclVarSrc *decl_var_instruction = ir_build_instruction<IrInstructionDeclVarSrc>(irb, scope, source_node); |
| 1517 | 1569 | decl_var_instruction->base.value.special = ConstValSpecialStatic; |
| ... | ... | @@ -1519,26 +1571,26 @@ static IrInstruction *ir_build_var_decl_src(IrBuilder *irb, Scope *scope, AstNod |
| 1519 | 1571 | decl_var_instruction->var = var; |
| 1520 | 1572 | decl_var_instruction->var_type = var_type; |
| 1521 | 1573 | decl_var_instruction->align_value = align_value; |
| 1522 | | decl_var_instruction->init_value = init_value; |
| 1574 | decl_var_instruction->ptr = ptr; |
| 1523 | 1575 | |
| 1524 | 1576 | if (var_type != nullptr) ir_ref_instruction(var_type, irb->current_basic_block); |
| 1525 | 1577 | if (align_value != nullptr) ir_ref_instruction(align_value, irb->current_basic_block); |
| 1526 | | ir_ref_instruction(init_value, irb->current_basic_block); |
| 1578 | ir_ref_instruction(ptr, irb->current_basic_block); |
| 1527 | 1579 | |
| 1528 | 1580 | return &decl_var_instruction->base; |
| 1529 | 1581 | } |
| 1530 | 1582 | |
| 1531 | 1583 | static IrInstruction *ir_build_var_decl_gen(IrAnalyze *ira, IrInstruction *source_instruction, |
| 1532 | | ZigVar *var, IrInstruction *init_value) |
| 1584 | ZigVar *var, IrInstruction *var_ptr) |
| 1533 | 1585 | { |
| 1534 | 1586 | IrInstructionDeclVarGen *decl_var_instruction = ir_build_instruction<IrInstructionDeclVarGen>(&ira->new_irb, |
| 1535 | 1587 | source_instruction->scope, source_instruction->source_node); |
| 1536 | 1588 | decl_var_instruction->base.value.special = ConstValSpecialStatic; |
| 1537 | 1589 | decl_var_instruction->base.value.type = ira->codegen->builtin_types.entry_void; |
| 1538 | 1590 | decl_var_instruction->var = var; |
| 1539 | | decl_var_instruction->init_value = init_value; |
| 1591 | decl_var_instruction->var_ptr = var_ptr; |
| 1540 | 1592 | |
| 1541 | | ir_ref_instruction(init_value, ira->new_irb.current_basic_block); |
| 1593 | ir_ref_instruction(var_ptr, ira->new_irb.current_basic_block); |
| 1542 | 1594 | |
| 1543 | 1595 | return &decl_var_instruction->base; |
| 1544 | 1596 | } |
| ... | ... | @@ -3109,6 +3161,32 @@ static IrInstruction *ir_build_assert_non_null(IrAnalyze *ira, IrInstruction *so |
| 3109 | 3161 | return &instruction->base; |
| 3110 | 3162 | } |
| 3111 | 3163 | |
| 3164 | static IrInstruction *ir_build_alloca_src(IrBuilder *irb, Scope *scope, AstNode *source_node, |
| 3165 | IrInstruction *align, const char *name_hint, IrInstruction *is_comptime) |
| 3166 | { |
| 3167 | IrInstructionAllocaSrc *instruction = ir_build_instruction<IrInstructionAllocaSrc>(irb, scope, source_node); |
| 3168 | instruction->base.is_gen = true; |
| 3169 | instruction->align = align; |
| 3170 | instruction->name_hint = name_hint; |
| 3171 | instruction->is_comptime = is_comptime; |
| 3172 | |
| 3173 | if (align != nullptr) ir_ref_instruction(align, irb->current_basic_block); |
| 3174 | if (is_comptime != nullptr) ir_ref_instruction(is_comptime, irb->current_basic_block); |
| 3175 | |
| 3176 | return &instruction->base; |
| 3177 | } |
| 3178 | |
| 3179 | static IrInstructionAllocaGen *ir_create_alloca_gen(IrAnalyze *ira, IrInstruction *source_instruction, |
| 3180 | uint32_t align, const char *name_hint) |
| 3181 | { |
| 3182 | IrInstructionAllocaGen *instruction = ir_create_instruction<IrInstructionAllocaGen>(&ira->new_irb, |
| 3183 | source_instruction->scope, source_instruction->source_node); |
| 3184 | instruction->align = align; |
| 3185 | instruction->name_hint = name_hint; |
| 3186 | |
| 3187 | return instruction; |
| 3188 | } |
| 3189 | |
| 3112 | 3190 | static void ir_count_defers(IrBuilder *irb, Scope *inner_scope, Scope *outer_scope, size_t *results) { |
| 3113 | 3191 | results[ReturnKindUnconditional] = 0; |
| 3114 | 3192 | results[ReturnKindError] = 0; |
| ... | ... | @@ -3321,12 +3399,15 @@ static IrInstruction *ir_gen_return(IrBuilder *irb, Scope *scope, AstNode *node, |
| 3321 | 3399 | switch (node->data.return_expr.kind) { |
| 3322 | 3400 | case ReturnKindUnconditional: |
| 3323 | 3401 | { |
| 3402 | ResultLocReturn *result_loc_ret = allocate<ResultLocReturn>(1); |
| 3403 | result_loc_ret->base.id = ResultLocIdReturn; |
| 3404 | |
| 3324 | 3405 | IrInstruction *return_value; |
| 3325 | 3406 | if (expr_node) { |
| 3326 | 3407 | // Temporarily set this so that if we return a type it gets the name of the function |
| 3327 | 3408 | ZigFn *prev_name_fn = irb->exec->name_fn; |
| 3328 | 3409 | irb->exec->name_fn = exec_fn_entry(irb->exec); |
| 3329 | | return_value = ir_gen_node(irb, expr_node, scope); |
| 3410 | return_value = ir_gen_node_extra(irb, expr_node, scope, LValNone, &result_loc_ret->base); |
| 3330 | 3411 | irb->exec->name_fn = prev_name_fn; |
| 3331 | 3412 | if (return_value == irb->codegen->invalid_instruction) |
| 3332 | 3413 | return irb->codegen->invalid_instruction; |
| ... | ... | @@ -3373,17 +3454,21 @@ static IrInstruction *ir_gen_return(IrBuilder *irb, Scope *scope, AstNode *node, |
| 3373 | 3454 | ir_build_br(irb, scope, node, ret_stmt_block, is_comptime); |
| 3374 | 3455 | |
| 3375 | 3456 | ir_set_cursor_at_end_and_append_block(irb, ret_stmt_block); |
| 3376 | | return ir_gen_async_return(irb, scope, node, return_value, false); |
| 3457 | IrInstruction *result = ir_gen_async_return(irb, scope, node, return_value, false); |
| 3458 | result_loc_ret->base.source_instruction = result; |
| 3459 | return result; |
| 3377 | 3460 | } else { |
| 3378 | 3461 | // generate unconditional defers |
| 3379 | 3462 | ir_gen_defers_for_block(irb, scope, outer_scope, false); |
| 3380 | | return ir_gen_async_return(irb, scope, node, return_value, false); |
| 3463 | IrInstruction *result = ir_gen_async_return(irb, scope, node, return_value, false); |
| 3464 | result_loc_ret->base.source_instruction = result; |
| 3465 | return result; |
| 3381 | 3466 | } |
| 3382 | 3467 | } |
| 3383 | 3468 | case ReturnKindError: |
| 3384 | 3469 | { |
| 3385 | 3470 | assert(expr_node); |
| 3386 | | IrInstruction *err_union_ptr = ir_gen_node_extra(irb, expr_node, scope, LValPtr); |
| 3471 | IrInstruction *err_union_ptr = ir_gen_node_extra(irb, expr_node, scope, LValPtr, nullptr); |
| 3387 | 3472 | if (err_union_ptr == irb->codegen->invalid_instruction) |
| 3388 | 3473 | return irb->codegen->invalid_instruction; |
| 3389 | 3474 | IrInstruction *err_union_val = ir_build_load_ptr(irb, scope, node, err_union_ptr); |
| ... | ... | @@ -3592,7 +3677,7 @@ static IrInstruction *ir_gen_bin_op_id(IrBuilder *irb, Scope *scope, AstNode *no |
| 3592 | 3677 | } |
| 3593 | 3678 | |
| 3594 | 3679 | static IrInstruction *ir_gen_assign(IrBuilder *irb, Scope *scope, AstNode *node) { |
| 3595 | | IrInstruction *lvalue = ir_gen_node_extra(irb, node->data.bin_op_expr.op1, scope, LValPtr); |
| 3680 | IrInstruction *lvalue = ir_gen_node_extra(irb, node->data.bin_op_expr.op1, scope, LValPtr, nullptr); |
| 3596 | 3681 | IrInstruction *rvalue = ir_gen_node(irb, node->data.bin_op_expr.op2, scope); |
| 3597 | 3682 | |
| 3598 | 3683 | if (lvalue == irb->codegen->invalid_instruction || rvalue == irb->codegen->invalid_instruction) |
| ... | ... | @@ -3603,7 +3688,7 @@ static IrInstruction *ir_gen_assign(IrBuilder *irb, Scope *scope, AstNode *node) |
| 3603 | 3688 | } |
| 3604 | 3689 | |
| 3605 | 3690 | static IrInstruction *ir_gen_assign_op(IrBuilder *irb, Scope *scope, AstNode *node, IrBinOp op_id) { |
| 3606 | | IrInstruction *lvalue = ir_gen_node_extra(irb, node->data.bin_op_expr.op1, scope, LValPtr); |
| 3691 | IrInstruction *lvalue = ir_gen_node_extra(irb, node->data.bin_op_expr.op1, scope, LValPtr, nullptr); |
| 3607 | 3692 | if (lvalue == irb->codegen->invalid_instruction) |
| 3608 | 3693 | return lvalue; |
| 3609 | 3694 | IrInstruction *op1 = ir_build_load_ptr(irb, scope, node->data.bin_op_expr.op1, lvalue); |
| ... | ... | @@ -3705,7 +3790,7 @@ static IrInstruction *ir_gen_orelse(IrBuilder *irb, Scope *parent_scope, AstNode |
| 3705 | 3790 | AstNode *op1_node = node->data.bin_op_expr.op1; |
| 3706 | 3791 | AstNode *op2_node = node->data.bin_op_expr.op2; |
| 3707 | 3792 | |
| 3708 | | IrInstruction *maybe_ptr = ir_gen_node_extra(irb, op1_node, parent_scope, LValPtr); |
| 3793 | IrInstruction *maybe_ptr = ir_gen_node_extra(irb, op1_node, parent_scope, LValPtr, nullptr); |
| 3709 | 3794 | if (maybe_ptr == irb->codegen->invalid_instruction) |
| 3710 | 3795 | return irb->codegen->invalid_instruction; |
| 3711 | 3796 | |
| ... | ... | @@ -3968,7 +4053,7 @@ static IrInstruction *ir_gen_array_access(IrBuilder *irb, Scope *scope, AstNode |
| 3968 | 4053 | assert(node->type == NodeTypeArrayAccessExpr); |
| 3969 | 4054 | |
| 3970 | 4055 | AstNode *array_ref_node = node->data.array_access_expr.array_ref_expr; |
| 3971 | | IrInstruction *array_ref_instruction = ir_gen_node_extra(irb, array_ref_node, scope, LValPtr); |
| 4056 | IrInstruction *array_ref_instruction = ir_gen_node_extra(irb, array_ref_node, scope, LValPtr, nullptr); |
| 3972 | 4057 | if (array_ref_instruction == irb->codegen->invalid_instruction) |
| 3973 | 4058 | return array_ref_instruction; |
| 3974 | 4059 | |
| ... | ... | @@ -3991,7 +4076,7 @@ static IrInstruction *ir_gen_field_access(IrBuilder *irb, Scope *scope, AstNode |
| 3991 | 4076 | AstNode *container_ref_node = node->data.field_access_expr.struct_expr; |
| 3992 | 4077 | Buf *field_name = node->data.field_access_expr.field_name; |
| 3993 | 4078 | |
| 3994 | | IrInstruction *container_ref_instruction = ir_gen_node_extra(irb, container_ref_node, scope, LValPtr); |
| 4079 | IrInstruction *container_ref_instruction = ir_gen_node_extra(irb, container_ref_node, scope, LValPtr, nullptr); |
| 3995 | 4080 | if (container_ref_instruction == irb->codegen->invalid_instruction) |
| 3996 | 4081 | return container_ref_instruction; |
| 3997 | 4082 | |
| ... | ... | @@ -4041,7 +4126,9 @@ static IrInstruction *ir_gen_this(IrBuilder *irb, Scope *orig_scope, AstNode *no |
| 4041 | 4126 | zig_unreachable(); |
| 4042 | 4127 | } |
| 4043 | 4128 | |
| 4044 | | static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNode *node, LVal lval) { |
| 4129 | static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNode *node, LVal lval, |
| 4130 | ResultLoc *result_loc) |
| 4131 | { |
| 4045 | 4132 | assert(node->type == NodeTypeFnCallExpr); |
| 4046 | 4133 | |
| 4047 | 4134 | AstNode *fn_ref_expr = node->data.fn_call_expr.fn_ref_expr; |
| ... | ... | @@ -4625,7 +4712,7 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo |
| 4625 | 4712 | case BuiltinFnIdField: |
| 4626 | 4713 | { |
| 4627 | 4714 | AstNode *arg0_node = node->data.fn_call_expr.params.at(0); |
| 4628 | | IrInstruction *arg0_value = ir_gen_node_extra(irb, arg0_node, scope, LValPtr); |
| 4715 | IrInstruction *arg0_value = ir_gen_node_extra(irb, arg0_node, scope, LValPtr, nullptr); |
| 4629 | 4716 | if (arg0_value == irb->codegen->invalid_instruction) |
| 4630 | 4717 | return arg0_value; |
| 4631 | 4718 | |
| ... | ... | @@ -4855,7 +4942,8 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo |
| 4855 | 4942 | } |
| 4856 | 4943 | FnInline fn_inline = (builtin_fn->id == BuiltinFnIdInlineCall) ? FnInlineAlways : FnInlineNever; |
| 4857 | 4944 | |
| 4858 | | IrInstruction *call = ir_build_call(irb, scope, node, nullptr, fn_ref, arg_count, args, false, fn_inline, false, nullptr, nullptr); |
| 4945 | IrInstruction *call = ir_build_call_src(irb, scope, node, nullptr, fn_ref, arg_count, args, false, |
| 4946 | fn_inline, false, nullptr, nullptr, result_loc); |
| 4859 | 4947 | return ir_lval_wrap(irb, scope, call, lval); |
| 4860 | 4948 | } |
| 4861 | 4949 | case BuiltinFnIdNewStackCall: |
| ... | ... | @@ -4885,7 +4973,8 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo |
| 4885 | 4973 | return args[i]; |
| 4886 | 4974 | } |
| 4887 | 4975 | |
| 4888 | | IrInstruction *call = ir_build_call(irb, scope, node, nullptr, fn_ref, arg_count, args, false, FnInlineAuto, false, nullptr, new_stack); |
| 4976 | IrInstruction *call = ir_build_call_src(irb, scope, node, nullptr, fn_ref, arg_count, args, false, |
| 4977 | FnInlineAuto, false, nullptr, new_stack, result_loc); |
| 4889 | 4978 | return ir_lval_wrap(irb, scope, call, lval); |
| 4890 | 4979 | } |
| 4891 | 4980 | case BuiltinFnIdTypeId: |
| ... | ... | @@ -5148,11 +5237,13 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo |
| 5148 | 5237 | zig_unreachable(); |
| 5149 | 5238 | } |
| 5150 | 5239 | |
| 5151 | | static IrInstruction *ir_gen_fn_call(IrBuilder *irb, Scope *scope, AstNode *node, LVal lval) { |
| 5240 | static IrInstruction *ir_gen_fn_call(IrBuilder *irb, Scope *scope, AstNode *node, LVal lval, |
| 5241 | ResultLoc *result_loc) |
| 5242 | { |
| 5152 | 5243 | assert(node->type == NodeTypeFnCallExpr); |
| 5153 | 5244 | |
| 5154 | 5245 | if (node->data.fn_call_expr.is_builtin) |
| 5155 | | return ir_gen_builtin_fn_call(irb, scope, node, lval); |
| 5246 | return ir_gen_builtin_fn_call(irb, scope, node, lval, result_loc); |
| 5156 | 5247 | |
| 5157 | 5248 | AstNode *fn_ref_node = node->data.fn_call_expr.fn_ref_expr; |
| 5158 | 5249 | IrInstruction *fn_ref = ir_gen_node(irb, fn_ref_node, scope); |
| ... | ... | @@ -5178,8 +5269,8 @@ static IrInstruction *ir_gen_fn_call(IrBuilder *irb, Scope *scope, AstNode *node |
| 5178 | 5269 | } |
| 5179 | 5270 | } |
| 5180 | 5271 | |
| 5181 | | IrInstruction *fn_call = ir_build_call(irb, scope, node, nullptr, fn_ref, arg_count, args, false, FnInlineAuto, |
| 5182 | | is_async, async_allocator, nullptr); |
| 5272 | IrInstruction *fn_call = ir_build_call_src(irb, scope, node, nullptr, fn_ref, arg_count, args, false, FnInlineAuto, |
| 5273 | is_async, async_allocator, nullptr, result_loc); |
| 5183 | 5274 | return ir_lval_wrap(irb, scope, fn_call, lval); |
| 5184 | 5275 | } |
| 5185 | 5276 | |
| ... | ... | @@ -5244,7 +5335,7 @@ static IrInstruction *ir_gen_prefix_op_id_lval(IrBuilder *irb, Scope *scope, Ast |
| 5244 | 5335 | assert(node->type == NodeTypePrefixOpExpr); |
| 5245 | 5336 | AstNode *expr_node = node->data.prefix_op_expr.primary_expr; |
| 5246 | 5337 | |
| 5247 | | IrInstruction *value = ir_gen_node_extra(irb, expr_node, scope, lval); |
| 5338 | IrInstruction *value = ir_gen_node_extra(irb, expr_node, scope, lval, nullptr); |
| 5248 | 5339 | if (value == irb->codegen->invalid_instruction) |
| 5249 | 5340 | return value; |
| 5250 | 5341 | |
| ... | ... | @@ -5339,7 +5430,7 @@ static IrInstruction *ir_gen_pointer_type(IrBuilder *irb, Scope *scope, AstNode |
| 5339 | 5430 | static IrInstruction *ir_gen_catch_unreachable(IrBuilder *irb, Scope *scope, AstNode *source_node, AstNode *expr_node, |
| 5340 | 5431 | LVal lval) |
| 5341 | 5432 | { |
| 5342 | | IrInstruction *err_union_ptr = ir_gen_node_extra(irb, expr_node, scope, LValPtr); |
| 5433 | IrInstruction *err_union_ptr = ir_gen_node_extra(irb, expr_node, scope, LValPtr, nullptr); |
| 5343 | 5434 | if (err_union_ptr == irb->codegen->invalid_instruction) |
| 5344 | 5435 | return irb->codegen->invalid_instruction; |
| 5345 | 5436 | |
| ... | ... | @@ -5384,7 +5475,7 @@ static IrInstruction *ir_gen_prefix_op_expr(IrBuilder *irb, Scope *scope, AstNod |
| 5384 | 5475 | return ir_lval_wrap(irb, scope, ir_gen_prefix_op_id(irb, scope, node, IrUnOpOptional), lval); |
| 5385 | 5476 | case PrefixOpAddrOf: { |
| 5386 | 5477 | AstNode *expr_node = node->data.prefix_op_expr.primary_expr; |
| 5387 | | return ir_lval_wrap(irb, scope, ir_gen_node_extra(irb, expr_node, scope, LValPtr), lval); |
| 5478 | return ir_lval_wrap(irb, scope, ir_gen_node_extra(irb, expr_node, scope, LValPtr, nullptr), lval); |
| 5388 | 5479 | } |
| 5389 | 5480 | } |
| 5390 | 5481 | zig_unreachable(); |
| ... | ... | @@ -5486,17 +5577,27 @@ static IrInstruction *ir_gen_var_decl(IrBuilder *irb, Scope *scope, AstNode *nod |
| 5486 | 5577 | // Parser should ensure that this never happens |
| 5487 | 5578 | assert(variable_declaration->threadlocal_tok == nullptr); |
| 5488 | 5579 | |
| 5580 | IrInstruction *alloca = ir_build_alloca_src(irb, scope, node, align_value, |
| 5581 | buf_ptr(variable_declaration->symbol), is_comptime); |
| 5582 | |
| 5583 | // Create a result location for the initialization expression. |
| 5584 | ResultLocVar *result_loc_var = allocate<ResultLocVar>(1); |
| 5585 | result_loc_var->base.id = ResultLocIdVar; |
| 5586 | result_loc_var->base.source_instruction = alloca; |
| 5587 | result_loc_var->var = var; |
| 5588 | |
| 5489 | 5589 | // Temporarily set the name of the IrExecutable to the VariableDeclaration |
| 5490 | 5590 | // so that the struct or enum from the init expression inherits the name. |
| 5491 | 5591 | Buf *old_exec_name = irb->exec->name; |
| 5492 | 5592 | irb->exec->name = variable_declaration->symbol; |
| 5493 | | IrInstruction *init_value = ir_gen_node(irb, variable_declaration->expr, scope); |
| 5593 | IrInstruction *init_value = ir_gen_node_extra(irb, variable_declaration->expr, scope, LValNone, |
| 5594 | &result_loc_var->base); |
| 5494 | 5595 | irb->exec->name = old_exec_name; |
| 5495 | 5596 | |
| 5496 | 5597 | if (init_value == irb->codegen->invalid_instruction) |
| 5497 | 5598 | return init_value; |
| 5498 | 5599 | |
| 5499 | | return ir_build_var_decl_src(irb, scope, node, var, type_instruction, align_value, init_value); |
| 5600 | return ir_build_var_decl_src(irb, scope, node, var, type_instruction, align_value, alloca); |
| 5500 | 5601 | } |
| 5501 | 5602 | |
| 5502 | 5603 | static IrInstruction *ir_gen_while_expr(IrBuilder *irb, Scope *scope, AstNode *node) { |
| ... | ... | @@ -5534,7 +5635,8 @@ static IrInstruction *ir_gen_while_expr(IrBuilder *irb, Scope *scope, AstNode *n |
| 5534 | 5635 | } else { |
| 5535 | 5636 | payload_scope = subexpr_scope; |
| 5536 | 5637 | } |
| 5537 | | IrInstruction *err_val_ptr = ir_gen_node_extra(irb, node->data.while_expr.condition, subexpr_scope, LValPtr); |
| 5638 | IrInstruction *err_val_ptr = ir_gen_node_extra(irb, node->data.while_expr.condition, subexpr_scope, |
| 5639 | LValPtr, nullptr); |
| 5538 | 5640 | if (err_val_ptr == irb->codegen->invalid_instruction) |
| 5539 | 5641 | return err_val_ptr; |
| 5540 | 5642 | IrInstruction *err_val = ir_build_load_ptr(irb, scope, node->data.while_expr.condition, err_val_ptr); |
| ... | ... | @@ -5621,7 +5723,8 @@ static IrInstruction *ir_gen_while_expr(IrBuilder *irb, Scope *scope, AstNode *n |
| 5621 | 5723 | ZigVar *payload_var = ir_create_var(irb, symbol_node, subexpr_scope, var_symbol, |
| 5622 | 5724 | true, false, false, is_comptime); |
| 5623 | 5725 | Scope *child_scope = payload_var->child_scope; |
| 5624 | | IrInstruction *maybe_val_ptr = ir_gen_node_extra(irb, node->data.while_expr.condition, subexpr_scope, LValPtr); |
| 5726 | IrInstruction *maybe_val_ptr = ir_gen_node_extra(irb, node->data.while_expr.condition, subexpr_scope, |
| 5727 | LValPtr, nullptr); |
| 5625 | 5728 | if (maybe_val_ptr == irb->codegen->invalid_instruction) |
| 5626 | 5729 | return maybe_val_ptr; |
| 5627 | 5730 | IrInstruction *maybe_val = ir_build_load_ptr(irb, scope, node->data.while_expr.condition, maybe_val_ptr); |
| ... | ... | @@ -5775,7 +5878,7 @@ static IrInstruction *ir_gen_for_expr(IrBuilder *irb, Scope *parent_scope, AstNo |
| 5775 | 5878 | } |
| 5776 | 5879 | assert(elem_node->type == NodeTypeSymbol); |
| 5777 | 5880 | |
| 5778 | | IrInstruction *array_val_ptr = ir_gen_node_extra(irb, array_node, parent_scope, LValPtr); |
| 5881 | IrInstruction *array_val_ptr = ir_gen_node_extra(irb, array_node, parent_scope, LValPtr, nullptr); |
| 5779 | 5882 | if (array_val_ptr == irb->codegen->invalid_instruction) |
| 5780 | 5883 | return array_val_ptr; |
| 5781 | 5884 | |
| ... | ... | @@ -6182,7 +6285,7 @@ static IrInstruction *ir_gen_if_optional_expr(IrBuilder *irb, Scope *scope, AstN |
| 6182 | 6285 | AstNode *else_node = node->data.test_expr.else_node; |
| 6183 | 6286 | bool var_is_ptr = node->data.test_expr.var_is_ptr; |
| 6184 | 6287 | |
| 6185 | | IrInstruction *maybe_val_ptr = ir_gen_node_extra(irb, expr_node, scope, LValPtr); |
| 6288 | IrInstruction *maybe_val_ptr = ir_gen_node_extra(irb, expr_node, scope, LValPtr, nullptr); |
| 6186 | 6289 | if (maybe_val_ptr == irb->codegen->invalid_instruction) |
| 6187 | 6290 | return maybe_val_ptr; |
| 6188 | 6291 | |
| ... | ... | @@ -6261,7 +6364,7 @@ static IrInstruction *ir_gen_if_err_expr(IrBuilder *irb, Scope *scope, AstNode * |
| 6261 | 6364 | Buf *var_symbol = node->data.if_err_expr.var_symbol; |
| 6262 | 6365 | Buf *err_symbol = node->data.if_err_expr.err_symbol; |
| 6263 | 6366 | |
| 6264 | | IrInstruction *err_val_ptr = ir_gen_node_extra(irb, target_node, scope, LValPtr); |
| 6367 | IrInstruction *err_val_ptr = ir_gen_node_extra(irb, target_node, scope, LValPtr, nullptr); |
| 6265 | 6368 | if (err_val_ptr == irb->codegen->invalid_instruction) |
| 6266 | 6369 | return err_val_ptr; |
| 6267 | 6370 | |
| ... | ... | @@ -6397,7 +6500,7 @@ static IrInstruction *ir_gen_switch_expr(IrBuilder *irb, Scope *scope, AstNode * |
| 6397 | 6500 | assert(node->type == NodeTypeSwitchExpr); |
| 6398 | 6501 | |
| 6399 | 6502 | AstNode *target_node = node->data.switch_expr.expr; |
| 6400 | | IrInstruction *target_value_ptr = ir_gen_node_extra(irb, target_node, scope, LValPtr); |
| 6503 | IrInstruction *target_value_ptr = ir_gen_node_extra(irb, target_node, scope, LValPtr, nullptr); |
| 6401 | 6504 | if (target_value_ptr == irb->codegen->invalid_instruction) |
| 6402 | 6505 | return target_value_ptr; |
| 6403 | 6506 | IrInstruction *target_value = ir_build_switch_target(irb, scope, node, target_value_ptr); |
| ... | ... | @@ -6597,7 +6700,7 @@ static IrInstruction *ir_gen_comptime(IrBuilder *irb, Scope *parent_scope, AstNo |
| 6597 | 6700 | assert(node->type == NodeTypeCompTime); |
| 6598 | 6701 | |
| 6599 | 6702 | Scope *child_scope = create_comptime_scope(irb->codegen, node, parent_scope); |
| 6600 | | return ir_gen_node_extra(irb, node->data.comptime_expr.expr, child_scope, lval); |
| 6703 | return ir_gen_node_extra(irb, node->data.comptime_expr.expr, child_scope, lval, nullptr); |
| 6601 | 6704 | } |
| 6602 | 6705 | |
| 6603 | 6706 | static IrInstruction *ir_gen_return_from_block(IrBuilder *irb, Scope *break_scope, AstNode *node, ScopeBlock *block_scope) { |
| ... | ... | @@ -6776,7 +6879,7 @@ static IrInstruction *ir_gen_slice(IrBuilder *irb, Scope *scope, AstNode *node) |
| 6776 | 6879 | AstNode *start_node = slice_expr->start; |
| 6777 | 6880 | AstNode *end_node = slice_expr->end; |
| 6778 | 6881 | |
| 6779 | | IrInstruction *ptr_value = ir_gen_node_extra(irb, array_node, scope, LValPtr); |
| 6882 | IrInstruction *ptr_value = ir_gen_node_extra(irb, array_node, scope, LValPtr, nullptr); |
| 6780 | 6883 | if (ptr_value == irb->codegen->invalid_instruction) |
| 6781 | 6884 | return irb->codegen->invalid_instruction; |
| 6782 | 6885 | |
| ... | ... | @@ -6814,7 +6917,7 @@ static IrInstruction *ir_gen_catch(IrBuilder *irb, Scope *parent_scope, AstNode |
| 6814 | 6917 | } |
| 6815 | 6918 | |
| 6816 | 6919 | |
| 6817 | | IrInstruction *err_union_ptr = ir_gen_node_extra(irb, op1_node, parent_scope, LValPtr); |
| 6920 | IrInstruction *err_union_ptr = ir_gen_node_extra(irb, op1_node, parent_scope, LValPtr, nullptr); |
| 6818 | 6921 | if (err_union_ptr == irb->codegen->invalid_instruction) |
| 6819 | 6922 | return irb->codegen->invalid_instruction; |
| 6820 | 6923 | |
| ... | ... | @@ -7560,7 +7663,7 @@ static IrInstruction *ir_gen_suspend(IrBuilder *irb, Scope *parent_scope, AstNod |
| 7560 | 7663 | } |
| 7561 | 7664 | |
| 7562 | 7665 | static IrInstruction *ir_gen_node_raw(IrBuilder *irb, AstNode *node, Scope *scope, |
| 7563 | | LVal lval) |
| 7666 | LVal lval, ResultLoc *result_loc) |
| 7564 | 7667 | { |
| 7565 | 7668 | assert(scope); |
| 7566 | 7669 | switch (node->type) { |
| ... | ... | @@ -7576,7 +7679,7 @@ static IrInstruction *ir_gen_node_raw(IrBuilder *irb, AstNode *node, Scope *scop |
| 7576 | 7679 | case NodeTypeBlock: |
| 7577 | 7680 | return ir_lval_wrap(irb, scope, ir_gen_block(irb, scope, node), lval); |
| 7578 | 7681 | case NodeTypeGroupedExpr: |
| 7579 | | return ir_gen_node_raw(irb, node->data.grouped_expr, scope, lval); |
| 7682 | return ir_gen_node_raw(irb, node->data.grouped_expr, scope, lval, result_loc); |
| 7580 | 7683 | case NodeTypeBinOpExpr: |
| 7581 | 7684 | return ir_lval_wrap(irb, scope, ir_gen_bin_op(irb, scope, node), lval); |
| 7582 | 7685 | case NodeTypeIntLiteral: |
| ... | ... | @@ -7588,7 +7691,7 @@ static IrInstruction *ir_gen_node_raw(IrBuilder *irb, AstNode *node, Scope *scop |
| 7588 | 7691 | case NodeTypeSymbol: |
| 7589 | 7692 | return ir_gen_symbol(irb, scope, node, lval); |
| 7590 | 7693 | case NodeTypeFnCallExpr: |
| 7591 | | return ir_gen_fn_call(irb, scope, node, lval); |
| 7694 | return ir_gen_fn_call(irb, scope, node, lval, result_loc); |
| 7592 | 7695 | case NodeTypeIfBoolExpr: |
| 7593 | 7696 | return ir_lval_wrap(irb, scope, ir_gen_if_bool_expr(irb, scope, node), lval); |
| 7594 | 7697 | case NodeTypePrefixOpExpr: |
| ... | ... | @@ -7617,7 +7720,7 @@ static IrInstruction *ir_gen_node_raw(IrBuilder *irb, AstNode *node, Scope *scop |
| 7617 | 7720 | } |
| 7618 | 7721 | case NodeTypePtrDeref: { |
| 7619 | 7722 | AstNode *expr_node = node->data.ptr_deref_expr.target; |
| 7620 | | IrInstruction *value = ir_gen_node_extra(irb, expr_node, scope, lval); |
| 7723 | IrInstruction *value = ir_gen_node_extra(irb, expr_node, scope, lval, nullptr); |
| 7621 | 7724 | if (value == irb->codegen->invalid_instruction) |
| 7622 | 7725 | return value; |
| 7623 | 7726 | |
| ... | ... | @@ -7629,7 +7732,7 @@ static IrInstruction *ir_gen_node_raw(IrBuilder *irb, AstNode *node, Scope *scop |
| 7629 | 7732 | case NodeTypeUnwrapOptional: { |
| 7630 | 7733 | AstNode *expr_node = node->data.unwrap_optional.expr; |
| 7631 | 7734 | |
| 7632 | | IrInstruction *maybe_ptr = ir_gen_node_extra(irb, expr_node, scope, LValPtr); |
| 7735 | IrInstruction *maybe_ptr = ir_gen_node_extra(irb, expr_node, scope, LValPtr, nullptr); |
| 7633 | 7736 | if (maybe_ptr == irb->codegen->invalid_instruction) |
| 7634 | 7737 | return irb->codegen->invalid_instruction; |
| 7635 | 7738 | |
| ... | ... | @@ -7697,14 +7800,23 @@ static IrInstruction *ir_gen_node_raw(IrBuilder *irb, AstNode *node, Scope *scop |
| 7697 | 7800 | zig_unreachable(); |
| 7698 | 7801 | } |
| 7699 | 7802 | |
| 7700 | | static IrInstruction *ir_gen_node_extra(IrBuilder *irb, AstNode *node, Scope *scope, LVal lval) { |
| 7701 | | IrInstruction *result = ir_gen_node_raw(irb, node, scope, lval); |
| 7803 | static IrInstruction *ir_gen_node_extra(IrBuilder *irb, AstNode *node, Scope *scope, LVal lval, |
| 7804 | ResultLoc *result_loc) |
| 7805 | { |
| 7806 | if (result_loc == nullptr) { |
| 7807 | // Create a result location indicating there is none - but if one gets created |
| 7808 | // it will be properly distributed. |
| 7809 | ResultLocNone *result_loc_none = allocate<ResultLocNone>(1); |
| 7810 | result_loc_none->base.id = ResultLocIdNone; |
| 7811 | result_loc = &result_loc_none->base; |
| 7812 | } |
| 7813 | IrInstruction *result = ir_gen_node_raw(irb, node, scope, lval, result_loc); |
| 7702 | 7814 | irb->exec->invalid = irb->exec->invalid || (result == irb->codegen->invalid_instruction); |
| 7703 | 7815 | return result; |
| 7704 | 7816 | } |
| 7705 | 7817 | |
| 7706 | 7818 | static IrInstruction *ir_gen_node(IrBuilder *irb, AstNode *node, Scope *scope) { |
| 7707 | | return ir_gen_node_extra(irb, node, scope, LValNone); |
| 7819 | return ir_gen_node_extra(irb, node, scope, LValNone, nullptr); |
| 7708 | 7820 | } |
| 7709 | 7821 | |
| 7710 | 7822 | static void invalidate_exec(IrExecutable *exec) { |
| ... | ... | @@ -7837,7 +7949,7 @@ bool ir_gen(CodeGen *codegen, AstNode *node, Scope *scope, IrExecutable *ir_exec |
| 7837 | 7949 | irb->exec->coro_final_cleanup_block = ir_create_basic_block(irb, scope, "FinalCleanup"); |
| 7838 | 7950 | } |
| 7839 | 7951 | |
| 7840 | | IrInstruction *result = ir_gen_node_extra(irb, node, scope, LValNone); |
| 7952 | IrInstruction *result = ir_gen_node_extra(irb, node, scope, LValNone, nullptr); |
| 7841 | 7953 | assert(result); |
| 7842 | 7954 | if (irb->exec->invalid) |
| 7843 | 7955 | return false; |
| ... | ... | @@ -7946,7 +8058,10 @@ bool ir_gen(CodeGen *codegen, AstNode *node, Scope *scope, IrExecutable *ir_exec |
| 7946 | 8058 | // non-allocating. Basically coroutines are not supported right now until they are reworked. |
| 7947 | 8059 | args[3] = ir_build_const_usize(irb, scope, node, 1); // new_size |
| 7948 | 8060 | args[4] = ir_build_const_usize(irb, scope, node, 1); // new_align |
| 7949 | | ir_build_call(irb, scope, node, nullptr, shrink_fn, arg_count, args, false, FnInlineAuto, false, nullptr, nullptr); |
| 8061 | ResultLocNone *result_loc_none = allocate<ResultLocNone>(1); |
| 8062 | result_loc_none->base.id = ResultLocIdNone; |
| 8063 | ir_build_call_src(irb, scope, node, nullptr, shrink_fn, arg_count, args, false, FnInlineAuto, false, nullptr, |
| 8064 | nullptr, &result_loc_none->base); |
| 7950 | 8065 | |
| 7951 | 8066 | IrBasicBlock *resume_block = ir_create_basic_block(irb, scope, "Resume"); |
| 7952 | 8067 | ir_build_cond_br(irb, scope, node, resume_awaiter, resume_block, irb->exec->coro_suspend_block, const_bool_false); |
| ... | ... | @@ -13641,12 +13756,6 @@ static IrInstruction *ir_analyze_instruction_decl_var(IrAnalyze *ira, |
| 13641 | 13756 | Error err; |
| 13642 | 13757 | ZigVar *var = decl_var_instruction->var; |
| 13643 | 13758 | |
| 13644 | | IrInstruction *init_value = decl_var_instruction->init_value->child; |
| 13645 | | if (type_is_invalid(init_value->value.type)) { |
| 13646 | | var->var_type = ira->codegen->builtin_types.entry_invalid; |
| 13647 | | return ira->codegen->invalid_instruction; |
| 13648 | | } |
| 13649 | | |
| 13650 | 13759 | ZigType *explicit_type = nullptr; |
| 13651 | 13760 | IrInstruction *var_type = nullptr; |
| 13652 | 13761 | if (decl_var_instruction->var_type != nullptr) { |
| ... | ... | @@ -13661,12 +13770,19 @@ static IrInstruction *ir_analyze_instruction_decl_var(IrAnalyze *ira, |
| 13661 | 13770 | |
| 13662 | 13771 | AstNode *source_node = decl_var_instruction->base.source_node; |
| 13663 | 13772 | |
| 13664 | | IrInstruction *casted_init_value = ir_implicit_cast(ira, init_value, explicit_type); |
| 13665 | 13773 | bool is_comptime_var = ir_get_var_is_comptime(var); |
| 13666 | 13774 | |
| 13667 | 13775 | bool var_class_requires_const = false; |
| 13668 | 13776 | |
| 13669 | | ZigType *result_type = casted_init_value->value.type; |
| 13777 | IrInstruction *var_ptr = decl_var_instruction->ptr->child; |
| 13778 | if (type_is_invalid(var_ptr->value.type)) { |
| 13779 | var->var_type = ira->codegen->builtin_types.entry_invalid; |
| 13780 | return ira->codegen->invalid_instruction; |
| 13781 | } |
| 13782 | |
| 13783 | assert(var_ptr->value.type->id == ZigTypeIdPointer); |
| 13784 | |
| 13785 | ZigType *result_type = var_ptr->value.type->data.pointer.child_type; |
| 13670 | 13786 | if (type_is_invalid(result_type)) { |
| 13671 | 13787 | result_type = ira->codegen->builtin_types.entry_invalid; |
| 13672 | 13788 | } else if (result_type->id == ZigTypeIdUnreachable || result_type->id == ZigTypeIdOpaque) { |
| ... | ... | @@ -13675,6 +13791,14 @@ static IrInstruction *ir_analyze_instruction_decl_var(IrAnalyze *ira, |
| 13675 | 13791 | result_type = ira->codegen->builtin_types.entry_invalid; |
| 13676 | 13792 | } |
| 13677 | 13793 | |
| 13794 | ConstExprValue *init_val = nullptr; |
| 13795 | if (instr_is_comptime(var_ptr) && var_ptr->value.data.x_ptr.mut != ConstPtrMutRuntimeVar) { |
| 13796 | init_val = const_ptr_pointee(ira, ira->codegen, &var_ptr->value, decl_var_instruction->base.source_node); |
| 13797 | if (is_comptime_var) { |
| 13798 | var->const_value = init_val; |
| 13799 | } |
| 13800 | } |
| 13801 | |
| 13678 | 13802 | switch (type_requires_comptime(ira->codegen, result_type)) { |
| 13679 | 13803 | case ReqCompTimeInvalid: |
| 13680 | 13804 | result_type = ira->codegen->builtin_types.entry_invalid; |
| ... | ... | @@ -13689,18 +13813,20 @@ static IrInstruction *ir_analyze_instruction_decl_var(IrAnalyze *ira, |
| 13689 | 13813 | } |
| 13690 | 13814 | break; |
| 13691 | 13815 | case ReqCompTimeNo: |
| 13692 | | if (casted_init_value->value.special == ConstValSpecialStatic && |
| 13693 | | casted_init_value->value.type->id == ZigTypeIdFn && |
| 13694 | | casted_init_value->value.data.x_ptr.special != ConstPtrSpecialHardCodedAddr && |
| 13695 | | casted_init_value->value.data.x_ptr.data.fn.fn_entry->fn_inline == FnInlineAlways) |
| 13696 | | { |
| 13697 | | var_class_requires_const = true; |
| 13698 | | if (!var->src_is_const && !is_comptime_var) { |
| 13699 | | ErrorMsg *msg = ir_add_error_node(ira, source_node, |
| 13700 | | buf_sprintf("functions marked inline must be stored in const or comptime var")); |
| 13701 | | AstNode *proto_node = casted_init_value->value.data.x_ptr.data.fn.fn_entry->proto_node; |
| 13702 | | add_error_note(ira->codegen, msg, proto_node, buf_sprintf("declared here")); |
| 13703 | | result_type = ira->codegen->builtin_types.entry_invalid; |
| 13816 | if (init_val != nullptr) { |
| 13817 | if (init_val->special == ConstValSpecialStatic && |
| 13818 | init_val->type->id == ZigTypeIdFn && |
| 13819 | init_val->data.x_ptr.special != ConstPtrSpecialHardCodedAddr && |
| 13820 | init_val->data.x_ptr.data.fn.fn_entry->fn_inline == FnInlineAlways) |
| 13821 | { |
| 13822 | var_class_requires_const = true; |
| 13823 | if (!var->src_is_const && !is_comptime_var) { |
| 13824 | ErrorMsg *msg = ir_add_error_node(ira, source_node, |
| 13825 | buf_sprintf("functions marked inline must be stored in const or comptime var")); |
| 13826 | AstNode *proto_node = init_val->data.x_ptr.data.fn.fn_entry->proto_node; |
| 13827 | add_error_note(ira->codegen, msg, proto_node, buf_sprintf("declared here")); |
| 13828 | result_type = ira->codegen->builtin_types.entry_invalid; |
| 13829 | } |
| 13704 | 13830 | } |
| 13705 | 13831 | } |
| 13706 | 13832 | break; |
| ... | ... | @@ -13747,11 +13873,11 @@ static IrInstruction *ir_analyze_instruction_decl_var(IrAnalyze *ira, |
| 13747 | 13873 | } |
| 13748 | 13874 | } |
| 13749 | 13875 | |
| 13750 | | if (casted_init_value->value.special != ConstValSpecialRuntime) { |
| 13876 | if (init_val != nullptr && init_val->special != ConstValSpecialRuntime) { |
| 13751 | 13877 | if (var->mem_slot_index != SIZE_MAX) { |
| 13752 | 13878 | assert(var->mem_slot_index < ira->exec_context.mem_slot_list.length); |
| 13753 | 13879 | ConstExprValue *mem_slot = ira->exec_context.mem_slot_list.at(var->mem_slot_index); |
| 13754 | | copy_const_val(mem_slot, &casted_init_value->value, !is_comptime_var || var->gen_is_const); |
| 13880 | copy_const_val(mem_slot, init_val, !is_comptime_var || var->gen_is_const); |
| 13755 | 13881 | |
| 13756 | 13882 | if (is_comptime_var || (var_class_requires_const && var->gen_is_const)) { |
| 13757 | 13883 | return ir_const_void(ira, &decl_var_instruction->base); |
| ... | ... | @@ -13768,7 +13894,7 @@ static IrInstruction *ir_analyze_instruction_decl_var(IrAnalyze *ira, |
| 13768 | 13894 | if (fn_entry) |
| 13769 | 13895 | fn_entry->variable_list.append(var); |
| 13770 | 13896 | |
| 13771 | | return ir_build_var_decl_gen(ira, &decl_var_instruction->base, var, casted_init_value); |
| 13897 | return ir_build_var_decl_gen(ira, &decl_var_instruction->base, var, var_ptr); |
| 13772 | 13898 | } |
| 13773 | 13899 | |
| 13774 | 13900 | static VarLinkage global_linkage_to_var_linkage(GlobalLinkageId id) { |
| ... | ... | @@ -14076,7 +14202,67 @@ IrInstruction *ir_get_implicit_allocator(IrAnalyze *ira, IrInstruction *source_i |
| 14076 | 14202 | zig_unreachable(); |
| 14077 | 14203 | } |
| 14078 | 14204 | |
| 14079 | | static IrInstruction *ir_analyze_async_call(IrAnalyze *ira, IrInstructionCall *call_instruction, ZigFn *fn_entry, |
| 14205 | static IrInstruction *ir_analyze_alloca(IrAnalyze *ira, IrInstruction *source_inst, ZigType *var_type, |
| 14206 | uint32_t align, const char *name_hint, bool force_comptime) |
| 14207 | { |
| 14208 | Error err; |
| 14209 | |
| 14210 | ConstExprValue *pointee = create_const_vals(1); |
| 14211 | pointee->special = ConstValSpecialUndef; |
| 14212 | |
| 14213 | IrInstructionAllocaGen *result = ir_create_alloca_gen(ira, source_inst, align, name_hint); |
| 14214 | result->base.value.special = force_comptime ? ConstValSpecialStatic : ConstValSpecialRuntime; |
| 14215 | result->base.value.data.x_ptr.special = ConstPtrSpecialRef; |
| 14216 | result->base.value.data.x_ptr.mut = force_comptime ? ConstPtrMutComptimeVar : ConstPtrMutRuntimeVar; |
| 14217 | result->base.value.data.x_ptr.data.ref.pointee = pointee; |
| 14218 | |
| 14219 | if ((err = type_resolve(ira->codegen, var_type, ResolveStatusZeroBitsKnown))) |
| 14220 | return ira->codegen->invalid_instruction; |
| 14221 | assert(result->base.value.data.x_ptr.special != ConstPtrSpecialInvalid); |
| 14222 | |
| 14223 | pointee->type = var_type; |
| 14224 | result->base.value.type = get_pointer_to_type_extra(ira->codegen, var_type, false, false, |
| 14225 | PtrLenSingle, align, 0, 0, false); |
| 14226 | |
| 14227 | ZigFn *fn_entry = exec_fn_entry(ira->new_irb.exec); |
| 14228 | if (fn_entry != nullptr) { |
| 14229 | fn_entry->alloca_gen_list.append(result); |
| 14230 | } |
| 14231 | result->base.is_gen = true; |
| 14232 | return &result->base; |
| 14233 | } |
| 14234 | |
| 14235 | static IrInstruction *ir_resolve_result_loc(IrAnalyze *ira, ResultLoc *result_loc, ZigType *elem_type) { |
| 14236 | switch (result_loc->id) { |
| 14237 | case ResultLocIdInvalid: |
| 14238 | zig_unreachable(); |
| 14239 | case ResultLocIdNone: |
| 14240 | return nullptr; |
| 14241 | case ResultLocIdVar: { |
| 14242 | // TODO implicit cast? |
| 14243 | //ResultLocVar *result_loc_var = reinterpret_cast<ResultLocVar *>(result_loc); |
| 14244 | assert(result_loc->source_instruction->id == IrInstructionIdAllocaSrc); |
| 14245 | IrInstructionAllocaSrc *alloca_src = |
| 14246 | reinterpret_cast<IrInstructionAllocaSrc *>(result_loc->source_instruction); |
| 14247 | if (alloca_src->base.child == nullptr) { |
| 14248 | uint32_t align = 0; // TODO |
| 14249 | bool force_comptime = false; // TODO |
| 14250 | IrInstruction *alloca_gen = ir_analyze_alloca(ira, result_loc->source_instruction, elem_type, align, |
| 14251 | alloca_src->name_hint, force_comptime); |
| 14252 | alloca_src->base.child = alloca_gen; |
| 14253 | } |
| 14254 | return alloca_src->base.child; |
| 14255 | } |
| 14256 | case ResultLocIdReturn: { |
| 14257 | //ResultLocReturn *result_loc_ret = reinterpret_cast<ResultLocReturn *>(result_loc); |
| 14258 | // TODO implicit cast? |
| 14259 | return ir_build_return_ptr(ira, result_loc->source_instruction, elem_type); |
| 14260 | } |
| 14261 | } |
| 14262 | zig_unreachable(); |
| 14263 | } |
| 14264 | |
| 14265 | static IrInstruction *ir_analyze_async_call(IrAnalyze *ira, IrInstructionCallSrc *call_instruction, ZigFn *fn_entry, |
| 14080 | 14266 | ZigType *fn_type, IrInstruction *fn_ref, IrInstruction **casted_args, size_t arg_count, |
| 14081 | 14267 | IrInstruction *async_allocator_inst) |
| 14082 | 14268 | { |
| ... | ... | @@ -14109,8 +14295,10 @@ static IrInstruction *ir_analyze_async_call(IrAnalyze *ira, IrInstructionCall *c |
| 14109 | 14295 | ZigType *promise_type = get_promise_type(ira->codegen, return_type); |
| 14110 | 14296 | ZigType *async_return_type = get_error_union_type(ira->codegen, alloc_fn_error_set_type, promise_type); |
| 14111 | 14297 | |
| 14112 | | IrInstruction *result = ir_build_call(&ira->new_irb, call_instruction->base.scope, call_instruction->base.source_node, |
| 14113 | | fn_entry, fn_ref, arg_count, casted_args, false, FnInlineAuto, true, async_allocator_inst, nullptr); |
| 14298 | IrInstruction *result_loc = ir_resolve_result_loc(ira, call_instruction->result_loc, async_return_type); |
| 14299 | |
| 14300 | IrInstruction *result = ir_build_call_gen(ira, &call_instruction->base, fn_entry, fn_ref, arg_count, |
| 14301 | casted_args, FnInlineAuto, true, async_allocator_inst, nullptr, result_loc); |
| 14114 | 14302 | result->value.type = async_return_type; |
| 14115 | 14303 | return result; |
| 14116 | 14304 | } |
| ... | ... | @@ -14416,7 +14604,7 @@ static IrInstruction *ir_analyze_store_ptr(IrAnalyze *ira, IrInstruction *source |
| 14416 | 14604 | return result; |
| 14417 | 14605 | } |
| 14418 | 14606 | |
| 14419 | | static IrInstruction *ir_analyze_fn_call(IrAnalyze *ira, IrInstructionCall *call_instruction, |
| 14607 | static IrInstruction *ir_analyze_fn_call(IrAnalyze *ira, IrInstructionCallSrc *call_instruction, |
| 14420 | 14608 | ZigFn *fn_entry, ZigType *fn_type, IrInstruction *fn_ref, |
| 14421 | 14609 | IrInstruction *first_arg_ptr, bool comptime_fn_call, FnInline fn_inline) |
| 14422 | 14610 | { |
| ... | ... | @@ -14861,19 +15049,17 @@ static IrInstruction *ir_analyze_fn_call(IrAnalyze *ira, IrInstructionCall *call |
| 14861 | 15049 | if (call_instruction->is_async) { |
| 14862 | 15050 | IrInstruction *result = ir_analyze_async_call(ira, call_instruction, impl_fn, impl_fn->type_entry, |
| 14863 | 15051 | fn_ref, casted_args, impl_param_count, async_allocator_inst); |
| 14864 | | ir_add_alloca(ira, result, result->value.type); |
| 14865 | 15052 | return ir_finish_anal(ira, result); |
| 14866 | 15053 | } |
| 14867 | 15054 | |
| 14868 | 15055 | assert(async_allocator_inst == nullptr); |
| 14869 | | IrInstruction *new_call_instruction = ir_build_call(&ira->new_irb, |
| 14870 | | call_instruction->base.scope, call_instruction->base.source_node, |
| 14871 | | impl_fn, nullptr, impl_param_count, casted_args, false, fn_inline, |
| 14872 | | call_instruction->is_async, nullptr, casted_new_stack); |
| 15056 | IrInstruction *result_loc = ir_resolve_result_loc(ira, call_instruction->result_loc, |
| 15057 | impl_fn_type_id->return_type); |
| 15058 | IrInstruction *new_call_instruction = ir_build_call_gen(ira, &call_instruction->base, |
| 15059 | impl_fn, nullptr, impl_param_count, casted_args, fn_inline, |
| 15060 | call_instruction->is_async, nullptr, casted_new_stack, result_loc); |
| 14873 | 15061 | new_call_instruction->value.type = impl_fn_type_id->return_type; |
| 14874 | 15062 | |
| 14875 | | ir_add_alloca(ira, new_call_instruction, impl_fn_type_id->return_type); |
| 14876 | | |
| 14877 | 15063 | return ir_finish_anal(ira, new_call_instruction); |
| 14878 | 15064 | } |
| 14879 | 15065 | |
| ... | ... | @@ -14957,7 +15143,6 @@ static IrInstruction *ir_analyze_fn_call(IrAnalyze *ira, IrInstructionCall *call |
| 14957 | 15143 | |
| 14958 | 15144 | IrInstruction *result = ir_analyze_async_call(ira, call_instruction, fn_entry, fn_type, fn_ref, |
| 14959 | 15145 | casted_args, call_param_count, async_allocator_inst); |
| 14960 | | ir_add_alloca(ira, result, result->value.type); |
| 14961 | 15146 | return ir_finish_anal(ira, result); |
| 14962 | 15147 | } |
| 14963 | 15148 | |
| ... | ... | @@ -14967,15 +15152,14 @@ static IrInstruction *ir_analyze_fn_call(IrAnalyze *ira, IrInstructionCall *call |
| 14967 | 15152 | return ira->codegen->invalid_instruction; |
| 14968 | 15153 | } |
| 14969 | 15154 | |
| 14970 | | IrInstruction *new_call_instruction = ir_build_call(&ira->new_irb, |
| 14971 | | call_instruction->base.scope, call_instruction->base.source_node, |
| 14972 | | fn_entry, fn_ref, call_param_count, casted_args, false, fn_inline, false, nullptr, casted_new_stack); |
| 15155 | IrInstruction *result_loc = ir_resolve_result_loc(ira, call_instruction->result_loc, return_type); |
| 15156 | IrInstruction *new_call_instruction = ir_build_call_gen(ira, &call_instruction->base, fn_entry, fn_ref, |
| 15157 | call_param_count, casted_args, fn_inline, false, nullptr, casted_new_stack, result_loc); |
| 14973 | 15158 | new_call_instruction->value.type = return_type; |
| 14974 | | ir_add_alloca(ira, new_call_instruction, return_type); |
| 14975 | 15159 | return ir_finish_anal(ira, new_call_instruction); |
| 14976 | 15160 | } |
| 14977 | 15161 | |
| 14978 | | static IrInstruction *ir_analyze_instruction_call(IrAnalyze *ira, IrInstructionCall *call_instruction) { |
| 15162 | static IrInstruction *ir_analyze_instruction_call(IrAnalyze *ira, IrInstructionCallSrc *call_instruction) { |
| 14979 | 15163 | IrInstruction *fn_ref = call_instruction->fn_ref->child; |
| 14980 | 15164 | if (type_is_invalid(fn_ref->value.type)) |
| 14981 | 15165 | return ira->codegen->invalid_instruction; |
| ... | ... | @@ -23304,6 +23488,9 @@ static IrInstruction *ir_analyze_instruction_nocast(IrAnalyze *ira, IrInstructio |
| 23304 | 23488 | case IrInstructionIdResizeSlice: |
| 23305 | 23489 | case IrInstructionIdLoadPtrGen: |
| 23306 | 23490 | case IrInstructionIdBitCastGen: |
| 23491 | case IrInstructionIdCallGen: |
| 23492 | case IrInstructionIdReturnPtr: |
| 23493 | case IrInstructionIdAllocaGen: |
| 23307 | 23494 | zig_unreachable(); |
| 23308 | 23495 | |
| 23309 | 23496 | case IrInstructionIdReturn: |
| ... | ... | @@ -23326,8 +23513,8 @@ static IrInstruction *ir_analyze_instruction_nocast(IrAnalyze *ira, IrInstructio |
| 23326 | 23513 | return ir_analyze_instruction_var_ptr(ira, (IrInstructionVarPtr *)instruction); |
| 23327 | 23514 | case IrInstructionIdFieldPtr: |
| 23328 | 23515 | return ir_analyze_instruction_field_ptr(ira, (IrInstructionFieldPtr *)instruction); |
| 23329 | | case IrInstructionIdCall: |
| 23330 | | return ir_analyze_instruction_call(ira, (IrInstructionCall *)instruction); |
| 23516 | case IrInstructionIdCallSrc: |
| 23517 | return ir_analyze_instruction_call(ira, (IrInstructionCallSrc *)instruction); |
| 23331 | 23518 | case IrInstructionIdBr: |
| 23332 | 23519 | return ir_analyze_instruction_br(ira, (IrInstructionBr *)instruction); |
| 23333 | 23520 | case IrInstructionIdCondBr: |
| ... | ... | @@ -23580,13 +23767,15 @@ static IrInstruction *ir_analyze_instruction_nocast(IrAnalyze *ira, IrInstructio |
| 23580 | 23767 | return ir_analyze_instruction_has_decl(ira, (IrInstructionHasDecl *)instruction); |
| 23581 | 23768 | case IrInstructionIdUndeclaredIdent: |
| 23582 | 23769 | return ir_analyze_instruction_undeclared_ident(ira, (IrInstructionUndeclaredIdent *)instruction); |
| 23770 | case IrInstructionIdAllocaSrc: |
| 23771 | return nullptr; |
| 23583 | 23772 | } |
| 23584 | 23773 | zig_unreachable(); |
| 23585 | 23774 | } |
| 23586 | 23775 | |
| 23587 | 23776 | static IrInstruction *ir_analyze_instruction(IrAnalyze *ira, IrInstruction *old_instruction) { |
| 23588 | 23777 | IrInstruction *new_instruction = ir_analyze_instruction_nocast(ira, old_instruction); |
| 23589 | | ir_assert(new_instruction->value.type != nullptr, old_instruction); |
| 23778 | ir_assert(new_instruction->value.type != nullptr || new_instruction->value.type != nullptr, old_instruction); |
| 23590 | 23779 | old_instruction->child = new_instruction; |
| 23591 | 23780 | return new_instruction; |
| 23592 | 23781 | } |
| ... | ... | @@ -23637,13 +23826,15 @@ ZigType *ir_analyze(CodeGen *codegen, IrExecutable *old_exec, IrExecutable *new_ |
| 23637 | 23826 | } |
| 23638 | 23827 | |
| 23639 | 23828 | IrInstruction *new_instruction = ir_analyze_instruction(ira, old_instruction); |
| 23640 | | if (type_is_invalid(new_instruction->value.type) && ir_should_inline(new_exec, old_instruction->scope)) { |
| 23641 | | return ira->codegen->builtin_types.entry_invalid; |
| 23642 | | } |
| 23829 | if (new_instruction != nullptr) { |
| 23830 | if (type_is_invalid(new_instruction->value.type) && ir_should_inline(new_exec, old_instruction->scope)) { |
| 23831 | return ira->codegen->builtin_types.entry_invalid; |
| 23832 | } |
| 23643 | 23833 | |
| 23644 | | // unreachable instructions do their own control flow. |
| 23645 | | if (new_instruction->value.type->id == ZigTypeIdUnreachable) |
| 23646 | | continue; |
| 23834 | // unreachable instructions do their own control flow. |
| 23835 | if (new_instruction->value.type->id == ZigTypeIdUnreachable) |
| 23836 | continue; |
| 23837 | } |
| 23647 | 23838 | |
| 23648 | 23839 | ira->instruction_index += 1; |
| 23649 | 23840 | } |
| ... | ... | @@ -23668,7 +23859,8 @@ bool ir_has_side_effects(IrInstruction *instruction) { |
| 23668 | 23859 | case IrInstructionIdDeclVarSrc: |
| 23669 | 23860 | case IrInstructionIdDeclVarGen: |
| 23670 | 23861 | case IrInstructionIdStorePtr: |
| 23671 | | case IrInstructionIdCall: |
| 23862 | case IrInstructionIdCallSrc: |
| 23863 | case IrInstructionIdCallGen: |
| 23672 | 23864 | case IrInstructionIdReturn: |
| 23673 | 23865 | case IrInstructionIdUnreachable: |
| 23674 | 23866 | case IrInstructionIdSetCold: |
| ... | ... | @@ -23731,6 +23923,7 @@ bool ir_has_side_effects(IrInstruction *instruction) { |
| 23731 | 23923 | case IrInstructionIdFieldPtr: |
| 23732 | 23924 | case IrInstructionIdElemPtr: |
| 23733 | 23925 | case IrInstructionIdVarPtr: |
| 23926 | case IrInstructionIdReturnPtr: |
| 23734 | 23927 | case IrInstructionIdTypeOf: |
| 23735 | 23928 | case IrInstructionIdToPtrType: |
| 23736 | 23929 | case IrInstructionIdPtrTypeChild: |
| ... | ... | @@ -23818,6 +24011,8 @@ bool ir_has_side_effects(IrInstruction *instruction) { |
| 23818 | 24011 | case IrInstructionIdVectorToArray: |
| 23819 | 24012 | case IrInstructionIdArrayToVector: |
| 23820 | 24013 | case IrInstructionIdHasDecl: |
| 24014 | case IrInstructionIdAllocaSrc: |
| 24015 | case IrInstructionIdAllocaGen: |
| 23821 | 24016 | return false; |
| 23822 | 24017 | |
| 23823 | 24018 | case IrInstructionIdAsm: |