| ... | ... | @@ -1709,6 +1709,24 @@ static IrInstruction *ir_build_alignof(IrBuilder *irb, Scope *scope, AstNode *so |
| 1709 | 1709 | return &instruction->base; |
| 1710 | 1710 | } |
| 1711 | 1711 | |
| 1712 | static void ir_count_defers(IrBuilder *irb, Scope *inner_scope, Scope *outer_scope, size_t *results) { |
| 1713 | results[ReturnKindUnconditional] = 0; |
| 1714 | results[ReturnKindError] = 0; |
| 1715 | results[ReturnKindMaybe] = 0; |
| 1716 | |
| 1717 | while (inner_scope != outer_scope) { |
| 1718 | assert(inner_scope); |
| 1719 | if (inner_scope->id == ScopeIdDefer) { |
| 1720 | AstNode *defer_node = inner_scope->source_node; |
| 1721 | assert(defer_node->type == NodeTypeDefer); |
| 1722 | ReturnKind defer_kind = defer_node->data.defer.kind; |
| 1723 | results[defer_kind] += 1; |
| 1724 | |
| 1725 | } |
| 1726 | inner_scope = inner_scope->parent; |
| 1727 | } |
| 1728 | } |
| 1729 | |
| 1712 | 1730 | static void ir_gen_defers_for_block(IrBuilder *irb, Scope *inner_scope, Scope *outer_scope, |
| 1713 | 1731 | bool gen_error_defers, bool gen_maybe_defers) |
| 1714 | 1732 | { |
| ... | ... | @@ -1762,8 +1780,22 @@ static IrInstruction *ir_gen_return(IrBuilder *irb, Scope *scope, AstNode *node, |
| 1762 | 1780 | return_value = ir_build_const_void(irb, scope, node); |
| 1763 | 1781 | } |
| 1764 | 1782 | |
| 1765 | | // TODO conditionally gen maybe defers and error defers |
| 1766 | | ir_gen_defers_for_block(irb, scope, outer_scope, false, false); |
| 1783 | size_t defer_counts[3]; |
| 1784 | ir_count_defers(irb, scope, outer_scope, defer_counts); |
| 1785 | if (defer_counts[ReturnKindError] > 0) { |
| 1786 | // TODO in this situation we need to make a conditional |
| 1787 | // branch on the return value. we potentially must make multiple conditional branches, |
| 1788 | // if unconditional defers are interleaved with error defers. |
| 1789 | zig_panic("TODO handle error defers"); |
| 1790 | } else if (defer_counts[ReturnKindMaybe] > 0) { |
| 1791 | // TODO in this situation we need to make a conditional |
| 1792 | // branch on the maybe value. we potentially must make multiple conditional branches, |
| 1793 | // if unconditional defers are interleaved with error defers. |
| 1794 | zig_panic("TODO handle maybe defers"); |
| 1795 | } else { |
| 1796 | // generate unconditional defers |
| 1797 | ir_gen_defers_for_block(irb, scope, outer_scope, false, false); |
| 1798 | } |
| 1767 | 1799 | return ir_build_return(irb, scope, node, return_value); |
| 1768 | 1800 | } |
| 1769 | 1801 | case ReturnKindError: |