tree pop_stmt_list (tree t) { tree u = NULL_TREE; /* Pop statement lists until we reach the target level. The extra nestings will be due to outstanding cleanups. */ while (1) { u = stmt_list_stack->pop (); if (!stmt_list_stack->is_empty ()) { tree x = stmt_list_stack->last (); STATEMENT_LIST_HAS_LABEL (x) |= STATEMENT_LIST_HAS_LABEL (u); } if (t == u) break; } gcc_assert (u != NULL_TREE); /* If the statement list is completely empty, just return it. This is just as good small as build_empty_stmt, with the advantage that statement lists are merged when they appended to one another. So using the STATEMENT_LIST avoids pathological buildup of EMPTY_STMT_P statements. */ if (TREE_SIDE_EFFECTS (t)) { tree_stmt_iterator i = tsi_start (t); /* If the statement list contained exactly one statement, then extract it immediately. */ if (tsi_one_before_end_p (i)) { u = tsi_stmt (i); tsi_delink (&i); free_stmt_list (t); t = u; } } return t; }
void tsi_link_before (tree_stmt_iterator *i, tree t, enum tsi_iterator_update mode) { struct tree_statement_list_node *head, *tail, *cur; /* Die on looping. */ gcc_assert (t != i->container); if (TREE_CODE (t) == STATEMENT_LIST) { head = STATEMENT_LIST_HEAD (t); tail = STATEMENT_LIST_TAIL (t); STATEMENT_LIST_HEAD (t) = NULL; STATEMENT_LIST_TAIL (t) = NULL; free_stmt_list (t); /* Empty statement lists need no work. */ if (!head || !tail) { gcc_assert (head == tail); return; } } else { head = ggc_alloc (sizeof (*head)); head->prev = NULL; head->next = NULL; head->stmt = t; tail = head; } TREE_SIDE_EFFECTS (i->container) = 1; cur = i->ptr; /* Link it into the list. */ if (cur) { head->prev = cur->prev; if (head->prev) head->prev->next = head; else STATEMENT_LIST_HEAD (i->container) = head; tail->next = cur; cur->prev = tail; } else { head->prev = STATEMENT_LIST_TAIL (i->container); if (head->prev) head->prev->next = head; else STATEMENT_LIST_HEAD (i->container) = head; STATEMENT_LIST_TAIL (i->container) = tail; } /* Update the iterator, if requested. */ switch (mode) { case TSI_NEW_STMT: case TSI_CONTINUE_LINKING: case TSI_CHAIN_START: i->ptr = head; break; case TSI_CHAIN_END: i->ptr = tail; break; case TSI_SAME_STMT: break; } }