| ... | @@ -6339,7 +6339,9 @@ static IrInstruction *ir_gen_asm_expr(IrBuilder *irb, Scope *scope, AstNode *nod | ... | @@ -6339,7 +6339,9 @@ static IrInstruction *ir_gen_asm_expr(IrBuilder *irb, Scope *scope, AstNode *nod |
| 6339 | input_list, output_types, output_vars, return_count, is_volatile); | 6339 | input_list, output_types, output_vars, return_count, is_volatile); |
| 6340 | } | 6340 | } |
| 6341 | | 6341 | |
| 6342 | static IrInstruction *ir_gen_if_optional_expr(IrBuilder *irb, Scope *scope, AstNode *node) { | 6342 | static IrInstruction *ir_gen_if_optional_expr(IrBuilder *irb, Scope *scope, AstNode *node, LVal lval, |
| | 6343 | ResultLoc *result_loc) |
| | 6344 | { |
| 6343 | assert(node->type == NodeTypeIfOptional); | 6345 | assert(node->type == NodeTypeIfOptional); |
| 6344 | | 6346 | |
| 6345 | Buf *var_symbol = node->data.test_expr.var_symbol; | 6347 | Buf *var_symbol = node->data.test_expr.var_symbol; |
| ... | @@ -6365,7 +6367,23 @@ static IrInstruction *ir_gen_if_optional_expr(IrBuilder *irb, Scope *scope, AstN | ... | @@ -6365,7 +6367,23 @@ static IrInstruction *ir_gen_if_optional_expr(IrBuilder *irb, Scope *scope, AstN |
| 6365 | } else { | 6367 | } else { |
| 6366 | is_comptime = ir_build_test_comptime(irb, scope, node, is_non_null); | 6368 | is_comptime = ir_build_test_comptime(irb, scope, node, is_non_null); |
| 6367 | } | 6369 | } |
| 6368 | ir_build_cond_br(irb, scope, node, is_non_null, then_block, else_block, is_comptime); | 6370 | IrInstruction *cond_br_inst = ir_build_cond_br(irb, scope, node, is_non_null, |
| | 6371 | then_block, else_block, is_comptime); |
| | 6372 | |
| | 6373 | ResultLocPeerParent *peer_parent = allocate<ResultLocPeerParent>(1); |
| | 6374 | peer_parent->base.id = ResultLocIdPeerParent; |
| | 6375 | peer_parent->base.source_instruction = cond_br_inst; |
| | 6376 | peer_parent->parent = result_loc; |
| | 6377 | peer_parent->peer_count = 2; |
| | 6378 | peer_parent->peers = allocate<ResultLocPeer>(2); |
| | 6379 | peer_parent->peers[0].base.id = ResultLocIdPeer; |
| | 6380 | peer_parent->peers[0].base.source_instruction = cond_br_inst; |
| | 6381 | peer_parent->peers[0].parent = peer_parent; |
| | 6382 | peer_parent->peers[0].next_bb = else_block; |
| | 6383 | peer_parent->peers[1].base.id = ResultLocIdPeer; |
| | 6384 | peer_parent->peers[1].base.source_instruction = cond_br_inst; |
| | 6385 | peer_parent->peers[1].parent = peer_parent; |
| | 6386 | peer_parent->peers[1].next_bb = endif_block; |
| 6369 | | 6387 | |
| 6370 | ir_set_cursor_at_end_and_append_block(irb, then_block); | 6388 | ir_set_cursor_at_end_and_append_block(irb, then_block); |
| 6371 | | 6389 | |
| ... | @@ -6384,7 +6402,8 @@ static IrInstruction *ir_gen_if_optional_expr(IrBuilder *irb, Scope *scope, AstN | ... | @@ -6384,7 +6402,8 @@ static IrInstruction *ir_gen_if_optional_expr(IrBuilder *irb, Scope *scope, AstN |
| 6384 | } else { | 6402 | } else { |
| 6385 | var_scope = subexpr_scope; | 6403 | var_scope = subexpr_scope; |
| 6386 | } | 6404 | } |
| 6387 | IrInstruction *then_expr_result = ir_gen_node(irb, then_node, var_scope); | 6405 | IrInstruction *then_expr_result = ir_gen_node_extra(irb, then_node, var_scope, lval, |
| | 6406 | &peer_parent->peers[0].base); |
| 6388 | if (then_expr_result == irb->codegen->invalid_instruction) | 6407 | if (then_expr_result == irb->codegen->invalid_instruction) |
| 6389 | return then_expr_result; | 6408 | return then_expr_result; |
| 6390 | IrBasicBlock *after_then_block = irb->current_basic_block; | 6409 | IrBasicBlock *after_then_block = irb->current_basic_block; |
| ... | @@ -6394,7 +6413,7 @@ static IrInstruction *ir_gen_if_optional_expr(IrBuilder *irb, Scope *scope, AstN | ... | @@ -6394,7 +6413,7 @@ static IrInstruction *ir_gen_if_optional_expr(IrBuilder *irb, Scope *scope, AstN |
| 6394 | ir_set_cursor_at_end_and_append_block(irb, else_block); | 6413 | ir_set_cursor_at_end_and_append_block(irb, else_block); |
| 6395 | IrInstruction *else_expr_result; | 6414 | IrInstruction *else_expr_result; |
| 6396 | if (else_node) { | 6415 | if (else_node) { |
| 6397 | else_expr_result = ir_gen_node(irb, else_node, subexpr_scope); | 6416 | else_expr_result = ir_gen_node_extra(irb, else_node, subexpr_scope, lval, &peer_parent->peers[1].base); |
| 6398 | if (else_expr_result == irb->codegen->invalid_instruction) | 6417 | if (else_expr_result == irb->codegen->invalid_instruction) |
| 6399 | return else_expr_result; | 6418 | return else_expr_result; |
| 6400 | } else { | 6419 | } else { |
| ... | @@ -6412,10 +6431,13 @@ static IrInstruction *ir_gen_if_optional_expr(IrBuilder *irb, Scope *scope, AstN | ... | @@ -6412,10 +6431,13 @@ static IrInstruction *ir_gen_if_optional_expr(IrBuilder *irb, Scope *scope, AstN |
| 6412 | incoming_blocks[0] = after_then_block; | 6431 | incoming_blocks[0] = after_then_block; |
| 6413 | incoming_blocks[1] = after_else_block; | 6432 | incoming_blocks[1] = after_else_block; |
| 6414 | | 6433 | |
| 6415 | return ir_build_phi(irb, scope, node, 2, incoming_blocks, incoming_values); | 6434 | IrInstruction *phi = ir_build_phi(irb, scope, node, 2, incoming_blocks, incoming_values); |
| | 6435 | return ir_expr_wrap(irb, scope, phi, result_loc); |
| 6416 | } | 6436 | } |
| 6417 | | 6437 | |
| 6418 | static IrInstruction *ir_gen_if_err_expr(IrBuilder *irb, Scope *scope, AstNode *node) { | 6438 | static IrInstruction *ir_gen_if_err_expr(IrBuilder *irb, Scope *scope, AstNode *node, LVal lval, |
| | 6439 | ResultLoc *result_loc) |
| | 6440 | { |
| 6419 | assert(node->type == NodeTypeIfErrorExpr); | 6441 | assert(node->type == NodeTypeIfErrorExpr); |
| 6420 | | 6442 | |
| 6421 | AstNode *target_node = node->data.if_err_expr.target_node; | 6443 | AstNode *target_node = node->data.if_err_expr.target_node; |
| ... | @@ -6439,7 +6461,22 @@ static IrInstruction *ir_gen_if_err_expr(IrBuilder *irb, Scope *scope, AstNode * | ... | @@ -6439,7 +6461,22 @@ static IrInstruction *ir_gen_if_err_expr(IrBuilder *irb, Scope *scope, AstNode * |
| 6439 | | 6461 | |
| 6440 | bool force_comptime = ir_should_inline(irb->exec, scope); | 6462 | bool force_comptime = ir_should_inline(irb->exec, scope); |
| 6441 | IrInstruction *is_comptime = force_comptime ? ir_build_const_bool(irb, scope, node, true) : ir_build_test_comptime(irb, scope, node, is_err); | 6463 | IrInstruction *is_comptime = force_comptime ? ir_build_const_bool(irb, scope, node, true) : ir_build_test_comptime(irb, scope, node, is_err); |
| 6442 | ir_build_cond_br(irb, scope, node, is_err, else_block, ok_block, is_comptime); | 6464 | IrInstruction *cond_br_inst = ir_build_cond_br(irb, scope, node, is_err, else_block, ok_block, is_comptime); |
| | 6465 | |
| | 6466 | ResultLocPeerParent *peer_parent = allocate<ResultLocPeerParent>(1); |
| | 6467 | peer_parent->base.id = ResultLocIdPeerParent; |
| | 6468 | peer_parent->base.source_instruction = cond_br_inst; |
| | 6469 | peer_parent->parent = result_loc; |
| | 6470 | peer_parent->peer_count = 2; |
| | 6471 | peer_parent->peers = allocate<ResultLocPeer>(2); |
| | 6472 | peer_parent->peers[0].base.id = ResultLocIdPeer; |
| | 6473 | peer_parent->peers[0].base.source_instruction = cond_br_inst; |
| | 6474 | peer_parent->peers[0].parent = peer_parent; |
| | 6475 | peer_parent->peers[0].next_bb = else_block; |
| | 6476 | peer_parent->peers[1].base.id = ResultLocIdPeer; |
| | 6477 | peer_parent->peers[1].base.source_instruction = cond_br_inst; |
| | 6478 | peer_parent->peers[1].parent = peer_parent; |
| | 6479 | peer_parent->peers[1].next_bb = endif_block; |
| 6443 | | 6480 | |
| 6444 | ir_set_cursor_at_end_and_append_block(irb, ok_block); | 6481 | ir_set_cursor_at_end_and_append_block(irb, ok_block); |
| 6445 | | 6482 | |
| ... | @@ -6459,7 +6496,8 @@ static IrInstruction *ir_gen_if_err_expr(IrBuilder *irb, Scope *scope, AstNode * | ... | @@ -6459,7 +6496,8 @@ static IrInstruction *ir_gen_if_err_expr(IrBuilder *irb, Scope *scope, AstNode * |
| 6459 | } else { | 6496 | } else { |
| 6460 | var_scope = subexpr_scope; | 6497 | var_scope = subexpr_scope; |
| 6461 | } | 6498 | } |
| 6462 | IrInstruction *then_expr_result = ir_gen_node(irb, then_node, var_scope); | 6499 | IrInstruction *then_expr_result = ir_gen_node_extra(irb, then_node, var_scope, lval, |
| | 6500 | &peer_parent->peers[0].base); |
| 6463 | if (then_expr_result == irb->codegen->invalid_instruction) | 6501 | if (then_expr_result == irb->codegen->invalid_instruction) |
| 6464 | return then_expr_result; | 6502 | return then_expr_result; |
| 6465 | IrBasicBlock *after_then_block = irb->current_basic_block; | 6503 | IrBasicBlock *after_then_block = irb->current_basic_block; |
| ... | @@ -6483,7 +6521,7 @@ static IrInstruction *ir_gen_if_err_expr(IrBuilder *irb, Scope *scope, AstNode * | ... | @@ -6483,7 +6521,7 @@ static IrInstruction *ir_gen_if_err_expr(IrBuilder *irb, Scope *scope, AstNode * |
| 6483 | } else { | 6521 | } else { |
| 6484 | err_var_scope = subexpr_scope; | 6522 | err_var_scope = subexpr_scope; |
| 6485 | } | 6523 | } |
| 6486 | else_expr_result = ir_gen_node(irb, else_node, err_var_scope); | 6524 | else_expr_result = ir_gen_node_extra(irb, else_node, err_var_scope, lval, &peer_parent->peers[1].base); |
| 6487 | if (else_expr_result == irb->codegen->invalid_instruction) | 6525 | if (else_expr_result == irb->codegen->invalid_instruction) |
| 6488 | return else_expr_result; | 6526 | return else_expr_result; |
| 6489 | } else { | 6527 | } else { |
| ... | @@ -6501,7 +6539,8 @@ static IrInstruction *ir_gen_if_err_expr(IrBuilder *irb, Scope *scope, AstNode * | ... | @@ -6501,7 +6539,8 @@ static IrInstruction *ir_gen_if_err_expr(IrBuilder *irb, Scope *scope, AstNode * |
| 6501 | incoming_blocks[0] = after_then_block; | 6539 | incoming_blocks[0] = after_then_block; |
| 6502 | incoming_blocks[1] = after_else_block; | 6540 | incoming_blocks[1] = after_else_block; |
| 6503 | | 6541 | |
| 6504 | return ir_build_phi(irb, scope, node, 2, incoming_blocks, incoming_values); | 6542 | IrInstruction *phi = ir_build_phi(irb, scope, node, 2, incoming_blocks, incoming_values); |
| | 6543 | return ir_expr_wrap(irb, scope, phi, result_loc); |
| 6505 | } | 6544 | } |
| 6506 | | 6545 | |
| 6507 | static bool ir_gen_switch_prong_expr(IrBuilder *irb, Scope *scope, AstNode *switch_node, AstNode *prong_node, | 6546 | static bool ir_gen_switch_prong_expr(IrBuilder *irb, Scope *scope, AstNode *switch_node, AstNode *prong_node, |
| ... | @@ -7866,9 +7905,9 @@ static IrInstruction *ir_gen_node_raw(IrBuilder *irb, AstNode *node, Scope *scop | ... | @@ -7866,9 +7905,9 @@ static IrInstruction *ir_gen_node_raw(IrBuilder *irb, AstNode *node, Scope *scop |
| 7866 | case NodeTypeNullLiteral: | 7905 | case NodeTypeNullLiteral: |
| 7867 | return ir_lval_wrap(irb, scope, ir_gen_null_literal(irb, scope, node), lval, result_loc); | 7906 | return ir_lval_wrap(irb, scope, ir_gen_null_literal(irb, scope, node), lval, result_loc); |
| 7868 | case NodeTypeIfErrorExpr: | 7907 | case NodeTypeIfErrorExpr: |
| 7869 | return ir_lval_wrap(irb, scope, ir_gen_if_err_expr(irb, scope, node), lval, result_loc); | 7908 | return ir_gen_if_err_expr(irb, scope, node, lval, result_loc); |
| 7870 | case NodeTypeIfOptional: | 7909 | case NodeTypeIfOptional: |
| 7871 | return ir_lval_wrap(irb, scope, ir_gen_if_optional_expr(irb, scope, node), lval, result_loc); | 7910 | return ir_gen_if_optional_expr(irb, scope, node, lval, result_loc); |
| 7872 | case NodeTypeSwitchExpr: | 7911 | case NodeTypeSwitchExpr: |
| 7873 | return ir_gen_switch_expr(irb, scope, node, lval, result_loc); | 7912 | return ir_gen_switch_expr(irb, scope, node, lval, result_loc); |
| 7874 | case NodeTypeCompTime: | 7913 | case NodeTypeCompTime: |