OSDN Git Service

* gfortran.texi: Use @table @emph instead of @itemize @emph.
[pf3gnuchains/gcc-fork.git] / gcc / c-simplify.c
1 /* Tree lowering pass.  This pass gimplifies the tree representation built
2    by the C-based front ends.  The structure of gimplified, or
3    language-independent, trees is dictated by the grammar described in this
4    file.
5    Copyright (C) 2002, 2003 Free Software Foundation, Inc.
6    Lowering of expressions contributed by Sebastian Pop <s.pop@laposte.net>
7    Re-written to support lowering of whole function trees, documentation
8    and miscellaneous cleanups by Diego Novillo <dnovillo@redhat.com>
9
10 This file is part of GCC.
11
12 GCC is free software; you can redistribute it and/or modify it under
13 the terms of the GNU General Public License as published by the Free
14 Software Foundation; either version 2, or (at your option) any later
15 version.
16
17 GCC is distributed in the hope that it will be useful, but WITHOUT ANY
18 WARRANTY; without even the implied warranty of MERCHANTABILITY or
19 FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
20 for more details.
21
22 You should have received a copy of the GNU General Public License
23 along with GCC; see the file COPYING.  If not, write to the Free
24 Software Foundation, 59 Temple Place - Suite 330, Boston, MA
25 02111-1307, USA.  */
26
27 #include "config.h"
28 #include "system.h"
29 #include "coretypes.h"
30 #include "tm.h"
31 #include "tree.h"
32 #include "errors.h"
33 #include "varray.h"
34 #include "c-tree.h"
35 #include "c-common.h"
36 #include "tree-simple.h"
37 #include "hard-reg-set.h"
38 #include "basic-block.h"
39 #include "tree-flow.h"
40 #include "tree-inline.h"
41 #include "diagnostic.h"
42 #include "langhooks.h"
43 #include "langhooks-def.h"
44 #include "flags.h"
45 #include "rtl.h"
46 #include "toplev.h"
47 #include "tree-dump.h"
48 #include "c-pretty-print.h"
49 #include "cgraph.h"
50
51
52 /*  The gimplification pass converts the language-dependent trees
53     (ld-trees) emitted by the parser into language-independent trees
54     (li-trees) that are the target of SSA analysis and transformations.
55
56     Language-independent trees are based on the SIMPLE intermediate
57     representation used in the McCAT compiler framework:
58
59     "Designing the McCAT Compiler Based on a Family of Structured
60     Intermediate Representations,"
61     L. Hendren, C. Donawa, M. Emami, G. Gao, Justiani, and B. Sridharan,
62     Proceedings of the 5th International Workshop on Languages and
63     Compilers for Parallel Computing, no. 757 in Lecture Notes in
64     Computer Science, New Haven, Connecticut, pp. 406-420,
65     Springer-Verlag, August 3-5, 1992.
66
67     http://www-acaps.cs.mcgill.ca/info/McCAT/McCAT.html
68
69     Basically, we walk down gimplifying the nodes that we encounter.  As we
70     walk back up, we check that they fit our constraints, and copy them
71     into temporaries if not.  */
72
73 /* Local declarations.  */
74
75 static enum gimplify_status gimplify_expr_stmt (tree *);
76 static enum gimplify_status gimplify_decl_stmt (tree *);
77 static enum gimplify_status gimplify_for_stmt (tree *, tree *);
78 static enum gimplify_status gimplify_while_stmt (tree *);
79 static enum gimplify_status gimplify_do_stmt (tree *);
80 static enum gimplify_status gimplify_if_stmt (tree *);
81 static enum gimplify_status gimplify_switch_stmt (tree *);
82 static enum gimplify_status gimplify_return_stmt (tree *);
83 static enum gimplify_status gimplify_stmt_expr (tree *);
84 static enum gimplify_status gimplify_compound_literal_expr (tree *);
85 #if defined ENABLE_CHECKING
86 static int is_last_stmt_of_scope (tree);
87 #endif
88 static enum gimplify_status gimplify_block (tree *, tree *);
89 static enum gimplify_status gimplify_cleanup (tree *, tree *);
90 static tree gimplify_c_loop (tree, tree, tree, bool);
91 static void push_context (void);
92 static void pop_context (void);
93 static tree c_build_bind_expr (tree, tree);
94 static void add_block_to_enclosing (tree);
95 static void gimplify_condition (tree *);
96
97 enum bc_t { bc_break = 0, bc_continue = 1 };
98 static tree begin_bc_block (enum bc_t);
99 static tree finish_bc_block (tree, tree);
100 static tree build_bc_goto (enum bc_t);
101
102 static struct c_gimplify_ctx
103 {
104   /* For handling break and continue.  */
105   tree current_bc_label;
106   tree bc_id[2];
107 } *ctxp;
108
109 static void
110 push_context (void)
111 {
112   if (ctxp)
113     abort ();
114   ctxp = (struct c_gimplify_ctx *) xcalloc (1, sizeof (struct c_gimplify_ctx));
115   ctxp->bc_id[bc_continue] = get_identifier ("continue");
116   ctxp->bc_id[bc_break] = get_identifier ("break");
117 }
118
119 static void
120 pop_context (void)
121 {
122   if (!ctxp || ctxp->current_bc_label)
123     abort ();
124   free (ctxp);
125   ctxp = NULL;
126 }
127
128 /* Gimplification of statement trees.  */
129
130 /* Convert the tree representation of FNDECL from C frontend trees to
131    GENERIC.  */
132
133 void
134 c_genericize (tree fndecl)
135 {
136   FILE *dump_file;
137   int local_dump_flags;
138   struct cgraph_node *cgn;
139
140   /* Dump the C-specific tree IR.  */
141   dump_file = dump_begin (TDI_original, &local_dump_flags);
142   if (dump_file)
143     {
144       fprintf (dump_file, "\n;; Function %s",
145                (*lang_hooks.decl_printable_name) (fndecl, 2));
146       fprintf (dump_file, " (%s)\n",
147                IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (fndecl)));
148       fprintf (dump_file, ";; enabled by -%s\n", dump_flag_name (TDI_original));
149       fprintf (dump_file, "\n");
150
151       if (local_dump_flags & TDF_RAW)
152         dump_node (DECL_SAVED_TREE (fndecl),
153                    TDF_SLIM | local_dump_flags, dump_file);
154       else
155         print_c_tree (dump_file, DECL_SAVED_TREE (fndecl));
156       fprintf (dump_file, "\n");
157
158       dump_end (TDI_original, dump_file);
159     }
160
161   /* Go ahead and gimplify for now.  */
162   push_context ();
163   gimplify_function_tree (fndecl);
164   pop_context ();
165
166   /* Dump the genericized tree IR.  */
167   dump_function (TDI_generic, fndecl);
168
169   /* Genericize all nested functions now.  We do things in this order so
170      that items like VLA sizes are expanded properly in the context of
171      the correct function.  */
172   cgn = cgraph_node (fndecl);
173   for (cgn = cgn->nested; cgn ; cgn = cgn->next_nested)
174     c_genericize (cgn->decl);
175 }
176
177 /*  Entry point for the tree lowering pass.  Recursively scan
178     *STMT_P and convert it to a GIMPLE tree.  */
179
180 int
181 c_gimplify_stmt (tree *stmt_p)
182 {
183   tree stmt, next;
184   tree outer_pre = NULL_TREE;
185
186   /* PRE and POST are tree chains that contain the side-effects of the
187      gimplified tree.  For instance, given the expression tree:
188
189                 c = ++a * 3 + b++;
190
191      After gimplification, the tree will be re-written as:
192
193                 a = a + 1;
194                 t1 = a * 3;     <-- PRE
195                 c = t1 + b;
196                 b = b + 1;      <-- POST  */
197
198   for (stmt = *stmt_p; stmt && stmt != error_mark_node; stmt = next)
199     {
200       tree pre, post;
201       int saved_stmts_are_full_exprs_p;
202       location_t stmt_locus;
203       enum gimplify_status ret;
204
205       /* Set up context appropriately for handling this statement.  */
206       saved_stmts_are_full_exprs_p = stmts_are_full_exprs_p ();
207       prep_stmt (stmt);
208       stmt_locus = input_location;
209
210       pre = NULL_TREE;
211       post = NULL_TREE;
212
213       next = TREE_CHAIN (stmt);
214
215       switch (TREE_CODE (stmt))
216         {
217         case COMPOUND_STMT:
218           stmt = COMPOUND_BODY (stmt);
219           ret = GS_OK;
220           break;
221
222         case SCOPE_STMT:
223           ret = gimplify_block (&stmt, &next);
224           break;
225
226         case FOR_STMT:
227           ret = gimplify_for_stmt (&stmt, &next);
228           break;
229
230         case WHILE_STMT:
231           ret = gimplify_while_stmt (&stmt);
232           break;
233
234         case DO_STMT:
235           ret = gimplify_do_stmt (&stmt);
236           break;
237
238         case IF_STMT:
239           ret = gimplify_if_stmt (&stmt);
240           break;
241
242         case SWITCH_STMT:
243           ret = gimplify_switch_stmt (&stmt);
244           break;
245
246         case EXPR_STMT:
247           ret = gimplify_expr_stmt (&stmt);
248           break;
249
250         case RETURN_STMT:
251           ret = gimplify_return_stmt (&stmt);
252           break;
253
254         case DECL_STMT:
255           ret = gimplify_decl_stmt (&stmt);
256           break;
257
258         case LABEL_STMT:
259           stmt = build1 (LABEL_EXPR, void_type_node, LABEL_STMT_LABEL (stmt));
260           ret = GS_OK;
261           break;
262
263         case GOTO_STMT:
264           stmt = build1 (GOTO_EXPR, void_type_node, GOTO_DESTINATION (stmt));
265           ret = GS_OK;
266           break;
267
268         case CASE_LABEL:
269           {
270             tree label = create_artificial_label ();
271             stmt = build (CASE_LABEL_EXPR, void_type_node,
272                           CASE_LOW (stmt), CASE_HIGH (stmt), label);
273             ret = GS_OK;
274           }
275           break;
276
277         case CONTINUE_STMT:
278           stmt = build_bc_goto (bc_continue);
279           ret = GS_OK;
280           break;
281
282         case BREAK_STMT:
283           stmt = build_bc_goto (bc_break);
284           ret = GS_OK;
285           break;
286
287         case CLEANUP_STMT:
288           ret = gimplify_cleanup (&stmt, &next);
289           break;
290
291         case ASM_STMT:
292           {
293             tree new_stmt = build (ASM_EXPR, void_type_node, ASM_STRING (stmt),
294                                    ASM_OUTPUTS (stmt), ASM_INPUTS (stmt),
295                                    ASM_CLOBBERS (stmt));
296             ASM_INPUT_P (new_stmt) = ASM_INPUT_P (stmt);
297             ASM_VOLATILE_P (new_stmt) = ASM_VOLATILE_P (stmt);
298             stmt = new_stmt;
299             ret = GS_OK;
300           }
301           break;
302
303         default:
304           if (lang_gimplify_stmt && (*lang_gimplify_stmt) (&stmt, &next))
305             {
306               ret = GS_OK;
307               break;
308             }
309
310           fprintf (stderr, "unhandled statement node in c_gimplify_stmt:\n");
311           debug_tree (stmt);
312           abort ();
313           break;
314         }
315
316       switch (ret)
317         {
318         case GS_ERROR:
319           goto cont;
320         case GS_OK:
321           gimplify_stmt (&stmt);
322           break;
323         case GS_ALL_DONE:
324           break;
325         default:
326           abort ();
327         }
328
329       /* PRE and POST now contain a list of statements for all the
330          side-effects in STMT.  */
331
332       append_to_statement_list (stmt, &pre);
333       append_to_statement_list (post, &pre);
334       annotate_all_with_locus (&pre, stmt_locus);
335
336       append_to_statement_list (pre, &outer_pre);
337     cont:
338       /* Restore saved state.  */
339       current_stmt_tree ()->stmts_are_full_exprs_p
340         = saved_stmts_are_full_exprs_p;
341     }
342   append_to_statement_list (stmt, &outer_pre);
343   *stmt_p = outer_pre;
344
345   return GS_ALL_DONE;
346 }
347
348 static void
349 add_block_to_enclosing (tree block)
350 {
351   tree enclosing;
352
353   for (enclosing = gimple_current_bind_expr ();
354        enclosing; enclosing = TREE_CHAIN (enclosing))
355     if (BIND_EXPR_BLOCK (enclosing))
356       break;
357
358   enclosing = BIND_EXPR_BLOCK (enclosing);
359   BLOCK_SUBBLOCKS (enclosing) = chainon (BLOCK_SUBBLOCKS (enclosing), block);
360 }
361
362 /* Genericize a scope by creating a new BIND_EXPR.
363    BLOCK is either a BLOCK representing the scope or a chain of _DECLs.
364      In the latter case, we need to create a new BLOCK and add it to the
365      BLOCK_SUBBLOCKS of the enclosing block.
366    BODY is a chain of C _STMT nodes for the contents of the scope, to be
367      genericized.  */
368
369 static tree
370 c_build_bind_expr (tree block, tree body)
371 {
372   tree decls, bind;
373
374   if (block == NULL_TREE)
375     decls = NULL_TREE;
376   else if (TREE_CODE (block) == BLOCK)
377     decls = BLOCK_VARS (block);
378   else
379     {
380       decls = block;
381       if (DECL_ARTIFICIAL (decls))
382         block = NULL_TREE;
383       else
384         {
385           block = make_node (BLOCK);
386           BLOCK_VARS (block) = decls;
387           add_block_to_enclosing (block);
388         }
389     }
390
391   if (!body)
392     body = build_empty_stmt ();
393
394   bind = build (BIND_EXPR, void_type_node, decls, body, block);
395   TREE_SIDE_EFFECTS (bind) = 1;
396
397   return bind;
398 }
399
400 /* Genericize a syntactic block by removing the bracketing SCOPE_STMTs and
401    wrapping the intervening code in a BIND_EXPR.  This function assumes
402    that matching SCOPE_STMTs will always appear in the same statement
403    sequence.  */
404
405 static enum gimplify_status
406 gimplify_block (tree *stmt_p, tree *next_p)
407 {
408   tree *p;
409   tree block;
410   tree bind;
411   int depth;
412   location_t stmt_locus;
413
414   if (!SCOPE_BEGIN_P (*stmt_p))
415     {
416       /* Can wind up mismatched with syntax errors.  */
417       if (!errorcount && !sorrycount)
418         abort ();
419       *stmt_p = NULL;
420       return GS_ERROR;
421     }
422
423   block = SCOPE_STMT_BLOCK (*stmt_p);
424
425   /* Find the matching ending SCOPE_STMT.  */
426   depth = 1;
427   for (p = &TREE_CHAIN (*stmt_p);; p = &TREE_CHAIN (*p))
428     {
429       if (*p == NULL)
430         break;
431       if (TREE_CODE (*p) == SCOPE_STMT)
432         {
433           if (SCOPE_BEGIN_P (*p))
434             ++depth;
435           else if (--depth == 0)
436             break;
437         }
438     }
439
440   stmt_locus = input_location;
441   if (*p)
442     {
443       if (SCOPE_STMT_BLOCK (*p) != block)
444         abort ();
445       if (EXPR_LOCUS (*p))
446         stmt_locus = *EXPR_LOCUS (*p);
447       *next_p = TREE_CHAIN (*p);
448       *p = NULL_TREE;
449     }
450   else
451     {
452       /* Can wind up mismatched with syntax errors.  */
453       if (!errorcount && !sorrycount)
454         abort ();
455     }
456
457   bind = c_build_bind_expr (block, TREE_CHAIN (*stmt_p));
458   *stmt_p = bind;
459   input_location = stmt_locus;
460
461   return GS_OK;
462 }
463
464 /* Genericize a CLEANUP_STMT.  Just wrap everything from here to the end of
465    the block in a TRY_FINALLY_EXPR.  Or a TRY_CATCH_EXPR, if it's an
466    EH-only cleanup.  */
467
468 static enum gimplify_status
469 gimplify_cleanup (tree *stmt_p, tree *next_p)
470 {
471   tree stmt = *stmt_p;
472   tree body = TREE_CHAIN (stmt);
473   tree cleanup = CLEANUP_EXPR (stmt);
474   enum tree_code code
475     = (CLEANUP_EH_ONLY (stmt) ? TRY_CATCH_EXPR : TRY_FINALLY_EXPR);
476
477   if (!body)
478     body = build_empty_stmt ();
479   if (!cleanup)
480     cleanup = build_empty_stmt ();
481
482   *stmt_p = build (code, void_type_node, body, cleanup);
483   *next_p = NULL_TREE;
484
485   return GS_OK;
486 }
487
488 /*  Gimplify an EXPR_STMT node.
489
490     STMT is the statement node.
491
492     PRE_P points to the list where side effects that must happen before
493         STMT should be stored.
494
495     POST_P points to the list where side effects that must happen after
496         STMT should be stored.  */
497
498 static enum gimplify_status
499 gimplify_expr_stmt (tree *stmt_p)
500 {
501   tree stmt = EXPR_STMT_EXPR (*stmt_p);
502
503   if (stmt == error_mark_node)
504     stmt = NULL;
505
506   /* Gimplification of a statement expression will nullify the
507      statement if all its side effects are moved to *PRE_P and *POST_P.
508
509      In this case we will not want to emit the gimplified statement.
510      However, we may still want to emit a warning, so we do that before
511      gimplification.  */
512   if (stmt && (extra_warnings || warn_unused_value))
513     {
514       if (!TREE_SIDE_EFFECTS (stmt))
515         {
516           if (!IS_EMPTY_STMT (stmt)
517               && !VOID_TYPE_P (TREE_TYPE (stmt))
518               && !TREE_NO_WARNING (stmt))
519             warning ("statement with no effect");
520         }
521       else if (warn_unused_value)
522         {
523           /* Kludge for 20020220-2.c.  warn_if_unused_value shouldn't use
524              the stmt file location info.  */
525           set_file_and_line_for_stmt (input_location);
526           warn_if_unused_value (stmt);
527         }
528     }
529
530   if (stmt == NULL_TREE)
531     stmt = build_empty_stmt ();
532   else if (stmts_are_full_exprs_p ())
533     stmt = build1 (CLEANUP_POINT_EXPR, void_type_node, stmt);
534
535   *stmt_p = stmt;
536
537   return GS_OK;
538 }
539
540 /* If the condition for a loop (or the like) is a decl, it will be a
541    TREE_LIST where the TREE_PURPOSE is a DECL_STMT and the TREE_VALUE is
542    a use of the decl.  Turn such a thing into a COMPOUND_EXPR.  */
543
544 static void
545 gimplify_condition (tree *cond_p)
546 {
547   tree cond = *cond_p;
548   if (cond && TREE_CODE (cond) == TREE_LIST)
549     {
550       tree decl = TREE_PURPOSE (cond);
551       tree value = TREE_VALUE (cond);
552       c_gimplify_stmt (&decl);
553       *cond_p = build (COMPOUND_EXPR, TREE_TYPE (value), decl, value);
554     }
555 }
556
557 /* Begin a scope which can be exited by a break or continue statement.  BC
558    indicates which.
559
560    Just creates a label and pushes it into the current context.  */
561
562 static tree
563 begin_bc_block (enum bc_t bc)
564 {
565   tree label = create_artificial_label ();
566   DECL_NAME (label) = ctxp->bc_id[bc];
567   TREE_CHAIN (label) = ctxp->current_bc_label;
568   ctxp->current_bc_label = label;
569   return label;
570 }
571
572 /* Finish a scope which can be exited by a break or continue statement.
573    LABEL was returned from the most recent call to begin_bc_block.  BODY is
574    an expression for the contents of the scope.
575
576    If we saw a break (or continue) in the scope, append a LABEL_EXPR to
577    body.  Otherwise, just forget the label.  */
578
579 static tree
580 finish_bc_block (tree label, tree body)
581 {
582   if (label != ctxp->current_bc_label)
583     abort ();
584
585   if (TREE_USED (label))
586     {
587       tree t, sl = NULL;
588
589       /* Clear the name so flow can delete the label.  */
590       DECL_NAME (label) = NULL_TREE;
591       t = build1 (LABEL_EXPR, void_type_node, label);
592
593       append_to_statement_list (body, &sl);
594       append_to_statement_list (t, &sl);
595       body = sl;
596     }
597
598   ctxp->current_bc_label = TREE_CHAIN (label);
599   TREE_CHAIN (label) = NULL_TREE;
600   return body;
601 }
602
603 /* Build a GOTO_EXPR to represent a break or continue statement.  BC
604    indicates which.  */
605
606 static tree
607 build_bc_goto (enum bc_t bc)
608 {
609   tree label;
610   tree target_name = ctxp->bc_id[bc];
611
612   /* Look for the appropriate type of label.  */
613   for (label = ctxp->current_bc_label;
614        label;
615        label = TREE_CHAIN (label))
616     if (DECL_NAME (label) == target_name)
617       break;
618
619   if (label == NULL_TREE)
620     {
621       if (bc == bc_break)
622         error ("break statement not within loop or switch");
623       else
624         error ("continue statement not within loop or switch");
625
626       return NULL_TREE;
627     }
628
629   /* Mark the label used for finish_bc_block.  */
630   TREE_USED (label) = 1;
631   return build1 (GOTO_EXPR, void_type_node, label);
632 }
633
634 /* Build a generic representation of one of the C loop forms.  COND is the
635    loop condition or NULL_TREE.  BODY is the (possibly compound) statement
636    controlled by the loop.  INCR is the increment expression of a for-loop,
637    or NULL_TREE.  COND_IS_FIRST indicates whether the condition is
638    evaluated before the loop body as in while and for loops, or after the
639    loop body as in do-while loops.  */
640
641 static tree
642 gimplify_c_loop (tree cond, tree body, tree incr, bool cond_is_first)
643 {
644   tree top, entry, exit, cont_block, break_block, stmt_list, t;
645   location_t stmt_locus;
646
647   stmt_locus = input_location;
648
649   /* Detect do { ... } while (0) and don't generate loop construct.  */
650   if (!cond_is_first && cond && integer_zerop (cond))
651     top = cond = NULL;
652   else
653     {
654       /* If we use a LOOP_EXPR here, we have to feed the whole thing
655          back through the main gimplifier to lower it.  Given that we
656          have to gimplify the loop body NOW so that we can resolve
657          break/continue stmts, seems easier to just expand to gotos.  */
658       top = build1 (LABEL_EXPR, void_type_node, NULL_TREE);
659     }
660
661   break_block = begin_bc_block (bc_break);
662
663   if (top)
664     {
665       /* If we have an exit condition, then we build an IF with gotos either
666          out of the loop, or to the top of it.  If there's no exit condition,
667          then we just build a jump back to the top.  */
668       exit = build_and_jump (&LABEL_EXPR_LABEL (top));
669       if (cond)
670         {
671           gimplify_condition (&cond);
672           t = build_bc_goto (bc_break);
673           exit = build (COND_EXPR, void_type_node, cond, exit, t);
674           exit = fold (exit);
675           gimplify_stmt (&exit);
676         }
677     }
678   else
679     exit = NULL_TREE;
680
681   cont_block = begin_bc_block (bc_continue);
682
683   gimplify_stmt (&body);
684   if (incr && stmts_are_full_exprs_p ())
685     incr = fold (build1 (CLEANUP_POINT_EXPR, void_type_node, incr));
686   gimplify_stmt (&incr);
687
688   body = finish_bc_block (cont_block, body);
689
690   stmt_list = NULL;
691
692   if (cond_is_first && cond)
693     {
694       entry = build1 (LABEL_EXPR, void_type_node, NULL_TREE);
695       t = build_and_jump (&LABEL_EXPR_LABEL (entry));
696       append_to_statement_list (t, &stmt_list);
697     }
698   else
699     entry = NULL_TREE;
700
701   append_to_statement_list (top, &stmt_list);
702   append_to_statement_list (body, &stmt_list);
703   append_to_statement_list (incr, &stmt_list);
704   append_to_statement_list (entry, &stmt_list);
705   append_to_statement_list (exit, &stmt_list);
706
707   annotate_all_with_locus (&stmt_list, stmt_locus);
708
709   return finish_bc_block (break_block, stmt_list);
710 }
711
712 /* Gimplify a FOR_STMT node.  Move the stuff in the for-init-stmt into the
713    prequeue and hand off to gimplify_c_loop.  */
714
715 static enum gimplify_status
716 gimplify_for_stmt (tree *stmt_p, tree *next_p)
717 {
718   tree stmt = *stmt_p;
719   tree init = FOR_INIT_STMT (stmt);
720
721   if (init)
722     {
723       /* Reorganize the statements so that we do the right thing with a
724          CLEANUP_STMT.  We want the FOR_STMT and nothing else to be in the
725          scope of the cleanup, so play with pointers to accomplish that. */
726       FOR_INIT_STMT (stmt) = NULL_TREE;
727       chainon (init, stmt);
728       *stmt_p = init;
729       *next_p = TREE_CHAIN (stmt);
730       TREE_CHAIN (stmt) = NULL_TREE;
731       c_gimplify_stmt (stmt_p);
732     }
733   else
734     *stmt_p = gimplify_c_loop (FOR_COND (stmt), FOR_BODY (stmt),
735                                FOR_EXPR (stmt), 1);
736
737   return GS_ALL_DONE;
738 }
739
740 /* Gimplify a WHILE_STMT node.  */
741
742 static enum gimplify_status
743 gimplify_while_stmt (tree *stmt_p)
744 {
745   tree stmt = *stmt_p;
746   *stmt_p = gimplify_c_loop (WHILE_COND (stmt), WHILE_BODY (stmt),
747                              NULL_TREE, 1);
748   return GS_ALL_DONE;
749 }
750
751 /* Gimplify a DO_STMT node.  */
752
753 static enum gimplify_status
754 gimplify_do_stmt (tree *stmt_p)
755 {
756   tree stmt = *stmt_p;
757   *stmt_p = gimplify_c_loop (DO_COND (stmt), DO_BODY (stmt),
758                              NULL_TREE, 0);
759   return GS_ALL_DONE;
760 }
761
762 /* Genericize an IF_STMT by turning it into a COND_EXPR.  */
763
764 static enum gimplify_status
765 gimplify_if_stmt (tree *stmt_p)
766 {
767   tree stmt, then_, else_;
768
769   stmt = *stmt_p;
770  restart:
771   then_ = THEN_CLAUSE (stmt);
772   else_ = ELSE_CLAUSE (stmt);
773
774   if (!then_)
775     then_ = build_empty_stmt ();
776   if (!else_)
777     else_ = build_empty_stmt ();
778
779   stmt = build (COND_EXPR, void_type_node, IF_COND (stmt), then_, else_);
780   gimplify_condition (& TREE_OPERAND (stmt, 0));
781   *stmt_p = stmt;
782
783   /* Handle properly nested if-else chains via iteration instead of
784      mutual recursion between gimplify.c and c-simplify.c.  */
785   annotate_with_locus (stmt, input_location);
786   if (TREE_CODE (else_) == IF_STMT && !TREE_CHAIN (else_))
787     {
788       stmt_p = &COND_EXPR_ELSE (stmt);
789       stmt = else_;
790       prep_stmt (stmt);
791       goto restart;
792     }
793
794   return GS_OK;
795 }
796
797 /* Genericize a SWITCH_STMT by turning it into a SWITCH_EXPR.  */
798
799 static enum gimplify_status
800 gimplify_switch_stmt (tree *stmt_p)
801 {
802   tree stmt = *stmt_p;
803   tree break_block, body;
804   location_t stmt_locus = input_location;
805
806   break_block = begin_bc_block (bc_break);
807
808   gimplify_condition (&SWITCH_COND (stmt));
809
810   body = SWITCH_BODY (stmt);
811   if (!body)
812     body = build_empty_stmt ();
813
814   *stmt_p = build (SWITCH_EXPR, SWITCH_TYPE (stmt), SWITCH_COND (stmt),
815                    body, NULL_TREE);
816   annotate_with_locus (*stmt_p, stmt_locus);
817   gimplify_stmt (stmt_p);
818
819   *stmt_p = finish_bc_block (break_block, *stmt_p);
820   return GS_ALL_DONE;
821 }
822
823 /* Genericize a RETURN_STMT by turning it into a RETURN_EXPR.  */
824
825 static enum gimplify_status
826 gimplify_return_stmt (tree *stmt_p)
827 {
828   tree expr = RETURN_STMT_EXPR (*stmt_p);
829   expr = build1 (RETURN_EXPR, void_type_node, expr);
830   if (stmts_are_full_exprs_p ())
831     expr = build1 (CLEANUP_POINT_EXPR, void_type_node, expr);
832   *stmt_p = expr;
833   return GS_OK;
834 }
835
836 /* Gimplifies a DECL_STMT node T.
837
838    If a declaration V has an initial value I, create an expression 'V = I'
839    and insert it after the DECL_STMT.
840
841    PRE_P is a queue for effects that should happen before the DECL_STMT.
842
843    MID_P is a queue for effects that should happen after the DECL_STMT,
844    but before uses of the initialized decl.
845
846    POST_P is a queue for effects that should happen after uses of the
847    initialized decl.
848
849    Usually these last two will be the same, but they may need to be
850    different if the DECL_STMT is somehow embedded in an expression.  */
851
852 static enum gimplify_status
853 gimplify_decl_stmt (tree *stmt_p)
854 {
855   tree stmt = *stmt_p;
856   tree decl = DECL_STMT_DECL (stmt);
857   tree pre = NULL_TREE;
858   tree post = NULL_TREE;
859
860   if (TREE_TYPE (decl) == error_mark_node)
861     {
862       *stmt_p = NULL;
863       return GS_ERROR;
864     }
865     
866   if (TREE_CODE (decl) == TYPE_DECL)
867     {
868       tree type = TREE_TYPE (decl);
869       if (TYPE_SIZE_UNIT (type)
870           && !TREE_CONSTANT (TYPE_SIZE_UNIT (type)))
871         {
872           /* This is a variable-sized array type.  Simplify its size.  */
873           tree temp = TYPE_SIZE_UNIT (type);
874           gimplify_expr (&temp, &pre, &post, is_gimple_val, fb_rvalue);
875         }
876     }
877
878   if (TREE_CODE (decl) == VAR_DECL && !DECL_EXTERNAL (decl))
879     {
880       tree init = DECL_INITIAL (decl);
881
882       if (!TREE_CONSTANT (DECL_SIZE (decl)))
883         {
884           tree pt_type = build_pointer_type (TREE_TYPE (decl));
885           tree alloc, size;
886
887           /* This is a variable-sized decl.  Simplify its size and mark it
888              for deferred expansion.  Note that mudflap depends on the format
889              of the emitted code: see mx_register_decls().  */
890
891           size = get_initialized_tmp_var (DECL_SIZE_UNIT (decl), &pre, &post);
892           DECL_DEFER_OUTPUT (decl) = 1;
893           alloc = build_function_call_expr
894             (implicit_built_in_decls[BUILT_IN_STACK_ALLOC],
895              tree_cons (NULL_TREE,
896                         build1 (ADDR_EXPR, pt_type, decl),
897                         tree_cons (NULL_TREE, size, NULL_TREE)));
898           append_to_compound_expr (alloc, &pre);
899         }
900
901       if (init && init != error_mark_node)
902         {
903           if (!TREE_STATIC (decl))
904             {
905               /* Do not warn about int x = x; as it is a GCC extension
906                  to turn off this warning but only if warn_init_self
907                  is zero.  */
908               if (init == decl && !warn_init_self)
909                 TREE_NO_WARNING (decl) = 1;
910               
911               DECL_INITIAL (decl) = NULL_TREE;
912               init = build (MODIFY_EXPR, void_type_node, decl, init);
913               if (stmts_are_full_exprs_p ())
914                 init = build1 (CLEANUP_POINT_EXPR, void_type_node, init);
915               append_to_compound_expr (init, &pre);
916             }
917           else
918             {
919               /* We must still examine initializers for static variables
920                  as they may contain a label address.  */
921               walk_tree (&init, force_labels_r, NULL, NULL);
922             }
923         }
924
925       /* This decl isn't mentioned in the enclosing block, so add it to the
926          list of temps.  FIXME it seems a bit of a kludge to say that
927          anonymous artificial vars aren't pushed, but everything else is.  */
928       if (DECL_ARTIFICIAL (decl) && DECL_NAME (decl) == NULL_TREE)
929         gimple_add_tmp_var (decl);
930     }
931
932   append_to_compound_expr (post, &pre);
933   *stmt_p = pre;
934   return GS_OK;
935 }
936
937 /* Gimplification of expression trees.  */
938
939 /* Gimplify a C99 compound literal expression.  This just means adding the
940    DECL_STMT before the current EXPR_STMT and using its anonymous decl
941    instead.  */
942
943 static enum gimplify_status
944 gimplify_compound_literal_expr (tree *expr_p)
945 {
946   tree decl_s = COMPOUND_LITERAL_EXPR_DECL_STMT (*expr_p);
947   tree decl = DECL_STMT_DECL (decl_s);
948
949   /* This decl isn't mentioned in the enclosing block, so add it to the
950      list of temps.  FIXME it seems a bit of a kludge to say that
951      anonymous artificial vars aren't pushed, but everything else is.  */
952   if (DECL_NAME (decl) == NULL_TREE)
953     gimple_add_tmp_var (decl);
954
955   gimplify_decl_stmt (&decl_s);
956   *expr_p = decl_s ? decl_s : decl;
957   return GS_OK;
958 }
959
960 /* Do C-specific gimplification.  Args are as for gimplify_expr.  */
961
962 int
963 c_gimplify_expr (tree *expr_p, tree *pre_p ATTRIBUTE_UNUSED,
964                  tree *post_p ATTRIBUTE_UNUSED)
965 {
966   enum tree_code code = TREE_CODE (*expr_p);
967
968   if (STATEMENT_CODE_P (code))
969     return c_gimplify_stmt (expr_p);
970
971   switch (code)
972     {
973     case COMPOUND_LITERAL_EXPR:
974       return gimplify_compound_literal_expr (expr_p);
975
976     case STMT_EXPR:
977       return gimplify_stmt_expr (expr_p);
978
979     default:
980       return GS_UNHANDLED;
981     }
982 }
983
984 /* Returns the final EXPR_STMT which represents the return value of a
985    STMT_EXPR, or NULL_TREE if none.  */
986
987 tree
988 stmt_expr_last_stmt (tree stmt_expr)
989 {
990   tree body = STMT_EXPR_STMT (stmt_expr);
991   tree last_stmt, substmt;
992
993   /* Splice the last expression out of the STMT chain.  */
994   last_stmt = NULL_TREE;
995   for (substmt = COMPOUND_BODY (body); substmt;
996        substmt = TREE_CHAIN (substmt))
997     if (TREE_CODE (substmt) != SCOPE_STMT)
998       last_stmt = substmt;
999
1000   if (last_stmt == NULL_TREE
1001       || TREE_CODE (last_stmt) != EXPR_STMT
1002       || (TREE_TYPE (last_stmt)
1003           && VOID_TYPE_P (TREE_TYPE (last_stmt))))
1004     {
1005       location_t loc;
1006       if (last_stmt && EXPR_LOCUS (last_stmt))
1007         loc = *EXPR_LOCUS (last_stmt);
1008       else if (EXPR_LOCUS (stmt_expr))
1009         loc = *EXPR_LOCUS (stmt_expr);
1010       else
1011         loc = input_location;
1012       warning ("%Hstatement-expressions should end with a "
1013                "non-void expression", &loc);
1014       last_stmt = NULL_TREE;
1015     }
1016
1017 #if defined ENABLE_CHECKING
1018   if (last_stmt && !is_last_stmt_of_scope (last_stmt))
1019     abort ();
1020 #endif
1021
1022   return last_stmt;
1023 }
1024
1025 /* Gimplify a STMT_EXPR.  EXPR_P points to the expression to gimplify.
1026    After gimplification, if the STMT_EXPR returns a value, EXPR_P will
1027    point to a new temporary that holds that value; otherwise it will be
1028    null.
1029
1030    PRE_P points to the list where side effects that must happen before
1031      *EXPR_P should be stored.  */
1032
1033 static enum gimplify_status
1034 gimplify_stmt_expr (tree *expr_p)
1035 {
1036   tree body = STMT_EXPR_STMT (*expr_p);
1037
1038   if (VOID_TYPE_P (TREE_TYPE (*expr_p)))
1039     {
1040       *expr_p = body;
1041       return c_gimplify_stmt (expr_p);
1042     }
1043   else
1044     {
1045       tree last_stmt = stmt_expr_last_stmt (*expr_p);
1046       tree last_expr = NULL_TREE;
1047
1048       if (last_stmt)
1049         {
1050           last_expr = EXPR_STMT_EXPR (last_stmt);
1051
1052           if (stmts_are_full_exprs_p ())
1053             last_expr = build1 (CLEANUP_POINT_EXPR, TREE_TYPE (last_expr),
1054                                 last_expr);
1055           EXPR_STMT_EXPR (last_stmt) = NULL_TREE;
1056         }
1057
1058       /* Genericize the block.  */
1059       c_gimplify_stmt (&body);
1060
1061       /* Now retrofit that last expression into the BIND_EXPR.  */
1062       if (last_expr)
1063         {
1064           tree *sub_p;
1065
1066           if (!STMT_EXPR_NO_SCOPE (*expr_p))
1067             {
1068               /* Our BIND_EXPR will always be hidden within
1069                  a STATEMENT_LIST.  Discard that.  */
1070               body = expr_first (body);
1071               sub_p = &BIND_EXPR_BODY (body);
1072
1073               /* Append the last expression to the end of the BIND_EXPR.
1074                  We'll now re-process this, and let voidify_wrapper_expr
1075                  do its job.  */
1076               append_to_statement_list_force (last_expr, sub_p);
1077               TREE_TYPE (body) = TREE_TYPE (last_expr);
1078             }
1079           else
1080             append_to_compound_expr (last_expr, &body);
1081         }
1082
1083       *expr_p = body;
1084       return GS_OK;
1085     }
1086 }
1087
1088 /* Code generation.  */
1089
1090 /* Miscellaneous helpers.  */
1091
1092 #if defined ENABLE_CHECKING
1093 /*  Return nonzero if STMT is the last statement of its scope.  */
1094
1095 static int
1096 is_last_stmt_of_scope (tree stmt)
1097 {
1098   return (TREE_CHAIN (stmt) == NULL_TREE
1099           || (TREE_CODE (TREE_CHAIN (stmt)) == SCOPE_STMT
1100               && SCOPE_END_P (TREE_CHAIN (stmt))));
1101 }
1102 #endif