00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022 #include "config.h"
00023 #include "system.h"
00024 #include "coretypes.h"
00025 #include "tree.h"
00026 #include "tree-gimple.h"
00027 #include "tree-iterator.h"
00028 #include "ggc.h"
00029
00030
00031
00032
00033
00034 static GTY ((deletable (""))) tree stmt_list_cache;
00035
00036 tree
00037 alloc_stmt_list (void)
00038 {
00039 tree list = stmt_list_cache;
00040 if (list)
00041 {
00042 stmt_list_cache = TREE_CHAIN (list);
00043 memset (list, 0, sizeof(struct tree_common));
00044 TREE_SET_CODE (list, STATEMENT_LIST);
00045 }
00046 else
00047 list = make_node (STATEMENT_LIST);
00048 TREE_TYPE (list) = void_type_node;
00049 return list;
00050 }
00051
00052 void
00053 free_stmt_list (tree t)
00054 {
00055 gcc_assert (!STATEMENT_LIST_HEAD (t));
00056 gcc_assert (!STATEMENT_LIST_TAIL (t));
00057 TREE_CHAIN (t) = stmt_list_cache;
00058 stmt_list_cache = t;
00059 }
00060
00061
00062
00063 void
00064 tsi_link_before (tree_stmt_iterator *i, tree t, enum tsi_iterator_update mode)
00065 {
00066 struct tree_statement_list_node *head, *tail, *cur;
00067
00068
00069 gcc_assert (t != i->container);
00070
00071 if (TREE_CODE (t) == STATEMENT_LIST)
00072 {
00073 head = STATEMENT_LIST_HEAD (t);
00074 tail = STATEMENT_LIST_TAIL (t);
00075 STATEMENT_LIST_HEAD (t) = NULL;
00076 STATEMENT_LIST_TAIL (t) = NULL;
00077
00078 free_stmt_list (t);
00079
00080
00081 if (!head || !tail)
00082 {
00083 gcc_assert (head == tail);
00084 return;
00085 }
00086 }
00087 else
00088 {
00089 head = ggc_alloc (sizeof (*head));
00090 head->prev = NULL;
00091 head->next = NULL;
00092 head->stmt = t;
00093 tail = head;
00094 }
00095
00096 TREE_SIDE_EFFECTS (i->container) = 1;
00097
00098 cur = i->ptr;
00099
00100
00101 if (cur)
00102 {
00103 head->prev = cur->prev;
00104 if (head->prev)
00105 head->prev->next = head;
00106 else
00107 STATEMENT_LIST_HEAD (i->container) = head;
00108 tail->next = cur;
00109 cur->prev = tail;
00110 }
00111 else
00112 {
00113 gcc_assert (!STATEMENT_LIST_TAIL (i->container));
00114 STATEMENT_LIST_HEAD (i->container) = head;
00115 STATEMENT_LIST_TAIL (i->container) = tail;
00116 }
00117
00118
00119 switch (mode)
00120 {
00121 case TSI_NEW_STMT:
00122 case TSI_CONTINUE_LINKING:
00123 case TSI_CHAIN_START:
00124 i->ptr = head;
00125 break;
00126 case TSI_CHAIN_END:
00127 i->ptr = tail;
00128 break;
00129 case TSI_SAME_STMT:
00130 gcc_assert (cur);
00131 break;
00132 }
00133 }
00134
00135
00136
00137 void
00138 tsi_link_after (tree_stmt_iterator *i, tree t, enum tsi_iterator_update mode)
00139 {
00140 struct tree_statement_list_node *head, *tail, *cur;
00141
00142
00143 gcc_assert (t != i->container);
00144
00145 if (TREE_CODE (t) == STATEMENT_LIST)
00146 {
00147 head = STATEMENT_LIST_HEAD (t);
00148 tail = STATEMENT_LIST_TAIL (t);
00149 STATEMENT_LIST_HEAD (t) = NULL;
00150 STATEMENT_LIST_TAIL (t) = NULL;
00151
00152 free_stmt_list (t);
00153
00154
00155 if (!head || !tail)
00156 {
00157 gcc_assert (head == tail);
00158 return;
00159 }
00160 }
00161 else
00162 {
00163 head = ggc_alloc (sizeof (*head));
00164 head->prev = NULL;
00165 head->next = NULL;
00166 head->stmt = t;
00167 tail = head;
00168 }
00169
00170 TREE_SIDE_EFFECTS (i->container) = 1;
00171
00172 cur = i->ptr;
00173
00174
00175 if (cur)
00176 {
00177 tail->next = cur->next;
00178 if (tail->next)
00179 tail->next->prev = tail;
00180 else
00181 STATEMENT_LIST_TAIL (i->container) = tail;
00182 head->prev = cur;
00183 cur->next = head;
00184 }
00185 else
00186 {
00187 gcc_assert (!STATEMENT_LIST_TAIL (i->container));
00188 STATEMENT_LIST_HEAD (i->container) = head;
00189 STATEMENT_LIST_TAIL (i->container) = tail;
00190 }
00191
00192
00193 switch (mode)
00194 {
00195 case TSI_NEW_STMT:
00196 case TSI_CHAIN_START:
00197 i->ptr = head;
00198 break;
00199 case TSI_CONTINUE_LINKING:
00200 case TSI_CHAIN_END:
00201 i->ptr = tail;
00202 break;
00203 case TSI_SAME_STMT:
00204 gcc_assert (cur);
00205 break;
00206 }
00207 }
00208
00209
00210
00211
00212 void
00213 tsi_delink (tree_stmt_iterator *i)
00214 {
00215 struct tree_statement_list_node *cur, *next, *prev;
00216
00217 cur = i->ptr;
00218 next = cur->next;
00219 prev = cur->prev;
00220
00221 if (prev)
00222 prev->next = next;
00223 else
00224 STATEMENT_LIST_HEAD (i->container) = next;
00225 if (next)
00226 next->prev = prev;
00227 else
00228 STATEMENT_LIST_TAIL (i->container) = prev;
00229
00230 if (!next && !prev)
00231 TREE_SIDE_EFFECTS (i->container) = 0;
00232
00233 i->ptr = next;
00234 }
00235
00236
00237
00238
00239 tree
00240 tsi_split_statement_list_after (const tree_stmt_iterator *i)
00241 {
00242 struct tree_statement_list_node *cur, *next;
00243 tree old_sl, new_sl;
00244
00245 cur = i->ptr;
00246
00247 gcc_assert (cur);
00248 next = cur->next;
00249
00250 old_sl = i->container;
00251 new_sl = alloc_stmt_list ();
00252 TREE_SIDE_EFFECTS (new_sl) = 1;
00253
00254 STATEMENT_LIST_HEAD (new_sl) = next;
00255 STATEMENT_LIST_TAIL (new_sl) = STATEMENT_LIST_TAIL (old_sl);
00256 STATEMENT_LIST_TAIL (old_sl) = cur;
00257 cur->next = NULL;
00258 next->prev = NULL;
00259
00260 return new_sl;
00261 }
00262
00263
00264
00265
00266 tree
00267 tsi_split_statement_list_before (tree_stmt_iterator *i)
00268 {
00269 struct tree_statement_list_node *cur, *prev;
00270 tree old_sl, new_sl;
00271
00272 cur = i->ptr;
00273
00274 gcc_assert (cur);
00275 prev = cur->prev;
00276
00277 old_sl = i->container;
00278 new_sl = alloc_stmt_list ();
00279 TREE_SIDE_EFFECTS (new_sl) = 1;
00280 i->container = new_sl;
00281
00282 STATEMENT_LIST_HEAD (new_sl) = cur;
00283 STATEMENT_LIST_TAIL (new_sl) = STATEMENT_LIST_TAIL (old_sl);
00284 STATEMENT_LIST_TAIL (old_sl) = prev;
00285 cur->prev = NULL;
00286 prev->next = NULL;
00287
00288 return new_sl;
00289 }
00290
00291
00292
00293
00294 tree
00295 expr_first (tree expr)
00296 {
00297 if (expr == NULL_TREE)
00298 return expr;
00299
00300 if (TREE_CODE (expr) == STATEMENT_LIST)
00301 {
00302 struct tree_statement_list_node *n = STATEMENT_LIST_HEAD (expr);
00303 return n ? n->stmt : NULL_TREE;
00304 }
00305
00306 while (TREE_CODE (expr) == COMPOUND_EXPR)
00307 expr = TREE_OPERAND (expr, 0);
00308 return expr;
00309 }
00310
00311
00312
00313
00314 tree
00315 expr_last (tree expr)
00316 {
00317 if (expr == NULL_TREE)
00318 return expr;
00319
00320 if (TREE_CODE (expr) == STATEMENT_LIST)
00321 {
00322 struct tree_statement_list_node *n = STATEMENT_LIST_TAIL (expr);
00323 return n ? n->stmt : NULL_TREE;
00324 }
00325
00326 while (TREE_CODE (expr) == COMPOUND_EXPR)
00327 expr = TREE_OPERAND (expr, 1);
00328 return expr;
00329 }
00330
00331
00332
00333
00334 tree
00335 expr_only (tree expr)
00336 {
00337 if (expr == NULL_TREE)
00338 return NULL_TREE;
00339
00340 if (TREE_CODE (expr) == STATEMENT_LIST)
00341 {
00342 struct tree_statement_list_node *n = STATEMENT_LIST_TAIL (expr);
00343 if (n && STATEMENT_LIST_HEAD (expr) == n)
00344 return n->stmt;
00345 else
00346 return NULL_TREE;
00347 }
00348
00349 if (TREE_CODE (expr) == COMPOUND_EXPR)
00350 return NULL_TREE;
00351
00352 return expr;
00353 }
00354
00355 #include "gt-tree-iterator.h"