| /* Iterator routines for manipulating GENERIC tree statement list. -*- C++ -*- |
| Copyright (C) 2003-2022 Free Software Foundation, Inc. |
| Contributed by Andrew MacLeod <amacleod@redhat.com> |
| |
| This file is part of GCC. |
| |
| GCC is free software; you can redistribute it and/or modify |
| it under the terms of the GNU General Public License as published by |
| the Free Software Foundation; either version 3, or (at your option) |
| any later version. |
| |
| GCC is distributed in the hope that it will be useful, |
| but WITHOUT ANY WARRANTY; without even the implied warranty of |
| MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
| GNU General Public License for more details. |
| |
| You should have received a copy of the GNU General Public License |
| along with GCC; see the file COPYING3. If not see |
| <http://www.gnu.org/licenses/>. */ |
| |
| |
| /* This file is dependent upon the implementation of tree's. It provides an |
| abstract interface to the tree objects such that if all tree creation and |
| manipulations are done through this interface, we can easily change the |
| implementation of tree's, and not impact other code. */ |
| |
| #ifndef GCC_TREE_ITERATOR_H |
| #define GCC_TREE_ITERATOR_H 1 |
| |
| /* Iterator object for GENERIC or GIMPLE TREE statements. */ |
| |
| struct tree_stmt_iterator { |
| struct tree_statement_list_node *ptr; |
| tree container; |
| |
| /* No need for user-defined constructors, the implicit definitions (or |
| aggregate initialization) are fine. */ |
| |
| bool operator== (tree_stmt_iterator b) const |
| { return b.ptr == ptr && b.container == container; } |
| bool operator!= (tree_stmt_iterator b) const { return !(*this == b); } |
| tree_stmt_iterator &operator++ () { ptr = ptr->next; return *this; } |
| tree_stmt_iterator &operator-- () { ptr = ptr->prev; return *this; } |
| tree_stmt_iterator operator++ (int) |
| { tree_stmt_iterator x = *this; ++*this; return x; } |
| tree_stmt_iterator operator-- (int) |
| { tree_stmt_iterator x = *this; --*this; return x; } |
| tree &operator* () { return ptr->stmt; } |
| tree operator* () const { return ptr->stmt; } |
| }; |
| |
| static inline tree_stmt_iterator |
| tsi_start (tree t) |
| { |
| tree_stmt_iterator i; |
| |
| i.ptr = STATEMENT_LIST_HEAD (t); |
| i.container = t; |
| |
| return i; |
| } |
| |
| static inline tree_stmt_iterator |
| tsi_last (tree t) |
| { |
| tree_stmt_iterator i; |
| |
| i.ptr = STATEMENT_LIST_TAIL (t); |
| i.container = t; |
| |
| return i; |
| } |
| |
| static inline bool |
| tsi_end_p (tree_stmt_iterator i) |
| { |
| return i.ptr == NULL; |
| } |
| |
| static inline bool |
| tsi_one_before_end_p (tree_stmt_iterator i) |
| { |
| return i.ptr != NULL && i.ptr->next == NULL; |
| } |
| |
| static inline void |
| tsi_next (tree_stmt_iterator *i) |
| { |
| ++(*i); |
| } |
| |
| static inline void |
| tsi_prev (tree_stmt_iterator *i) |
| { |
| --(*i); |
| } |
| |
| static inline tree * |
| tsi_stmt_ptr (tree_stmt_iterator i) |
| { |
| return &(*i); |
| } |
| |
| static inline tree |
| tsi_stmt (tree_stmt_iterator i) |
| { |
| return *i; |
| } |
| |
| /* Make tree_stmt_iterator work as a C++ range, e.g. |
| for (tree stmt : tsi_range (stmt_list)) { ... } */ |
| class tsi_range |
| { |
| tree t; |
| public: |
| tsi_range (tree t): t(t) { } |
| tree_stmt_iterator begin() const { return tsi_start (t); } |
| tree_stmt_iterator end() const { return { nullptr, t }; } |
| }; |
| |
| enum tsi_iterator_update |
| { |
| TSI_NEW_STMT, /* Only valid when single statement is added, move |
| iterator to it. */ |
| TSI_SAME_STMT, /* Leave the iterator at the same statement. */ |
| TSI_CHAIN_START, /* Only valid when chain of statements is added, move |
| iterator to the first statement in the chain. */ |
| TSI_CHAIN_END, /* Only valid when chain of statements is added, move |
| iterator to the last statement in the chain. */ |
| TSI_CONTINUE_LINKING /* Move iterator to whatever position is suitable for |
| linking other statements/chains of statements in |
| the same direction. */ |
| }; |
| |
| extern void tsi_link_before (tree_stmt_iterator *, tree, |
| enum tsi_iterator_update); |
| extern void tsi_link_after (tree_stmt_iterator *, tree, |
| enum tsi_iterator_update); |
| |
| extern void tsi_delink (tree_stmt_iterator *); |
| |
| extern tree alloc_stmt_list (void); |
| extern void free_stmt_list (tree); |
| extern void append_to_statement_list (tree, tree *); |
| extern void append_to_statement_list_force (tree, tree *); |
| extern tree expr_first (tree); |
| extern tree expr_last (tree); |
| extern tree expr_single (tree); |
| |
| #endif /* GCC_TREE_ITERATOR_H */ |