Block* find_block_that_exit_point_will_reach(Term* term) { ca_assert(is_exit_point(term)); Block* block = term->owningBlock; // 'return' exits to nearest major block. if (term->function == FUNCS.return_func) { while (is_minor_block(block)) { Block* parent = get_parent_block(block); if (parent == NULL) return block; block = parent; } return block; } // 'case_condition_bool' exits the current if-block. if (term->function == FUNCS.case_condition_bool) return get_parent_block(term->owningBlock); // Otherwise, exit to nearest for-loop. while (!is_for_loop(block) && !is_while_loop(block)) { Block* parent = get_parent_block(block); if (parent == NULL) return block; block = parent; } return block; }
Block* find_enclosing_loop(Block* block) { while (true) { if (block == NULL) return NULL; if (is_while_loop(block) || is_for_loop(block)) return block; if (is_major_block(block)) return NULL; block = get_parent_block(block); } return NULL; }
bool is_loop(Block* block) { return is_for_loop(block) || is_while_loop(block); }