OSDN Git Service

Merge in xfails from PR14107.
[pf3gnuchains/gcc-fork.git] / gcc / c-gimplify.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-gimple.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 *STMT_P by making any necessary allocation
837    and initialization explicit.  */
838
839 static enum gimplify_status
840 gimplify_decl_stmt (tree *stmt_p)
841 {
842   tree stmt = *stmt_p;
843   tree decl = DECL_STMT_DECL (stmt);
844   tree pre = NULL_TREE;
845   tree post = NULL_TREE;
846
847   if (TREE_TYPE (decl) == error_mark_node)
848     {
849       *stmt_p = NULL;
850       return GS_ERROR;
851     }
852     
853   if (TREE_CODE (decl) == TYPE_DECL)
854     {
855       tree type = TREE_TYPE (decl);
856       if (TYPE_SIZE_UNIT (type)
857           && !TREE_CONSTANT (TYPE_SIZE_UNIT (type)))
858         {
859           /* This is a variable-sized array type.  Simplify its size.  */
860           tree temp = TYPE_SIZE_UNIT (type);
861           gimplify_expr (&temp, &pre, &post, is_gimple_val, fb_rvalue);
862         }
863     }
864
865   if (TREE_CODE (decl) == VAR_DECL && !DECL_EXTERNAL (decl))
866     {
867       tree init = DECL_INITIAL (decl);
868
869       if (!TREE_CONSTANT (DECL_SIZE (decl)))
870         {
871           tree pt_type = build_pointer_type (TREE_TYPE (decl));
872           tree alloc, size;
873
874           /* This is a variable-sized decl.  Simplify its size and mark it
875              for deferred expansion.  Note that mudflap depends on the format
876              of the emitted code: see mx_register_decls().  */
877
878           size = get_initialized_tmp_var (DECL_SIZE_UNIT (decl), &pre, &post);
879           DECL_DEFER_OUTPUT (decl) = 1;
880           alloc = build_function_call_expr
881             (implicit_built_in_decls[BUILT_IN_STACK_ALLOC],
882              tree_cons (NULL_TREE,
883                         build1 (ADDR_EXPR, pt_type, decl),
884                         tree_cons (NULL_TREE, size, NULL_TREE)));
885           append_to_compound_expr (alloc, &pre);
886         }
887
888       if (init && init != error_mark_node)
889         {
890           if (!TREE_STATIC (decl))
891             {
892               /* Do not warn about int x = x; as it is a GCC extension
893                  to turn off this warning but only if warn_init_self
894                  is zero.  */
895               if (init == decl && !warn_init_self)
896                 TREE_NO_WARNING (decl) = 1;
897               
898               DECL_INITIAL (decl) = NULL_TREE;
899               init = build (MODIFY_EXPR, void_type_node, decl, init);
900               if (stmts_are_full_exprs_p ())
901                 init = build1 (CLEANUP_POINT_EXPR, void_type_node, init);
902               append_to_compound_expr (init, &pre);
903             }
904           else
905             {
906               /* We must still examine initializers for static variables
907                  as they may contain a label address.  */
908               walk_tree (&init, force_labels_r, NULL, NULL);
909             }
910         }
911
912       /* This decl isn't mentioned in the enclosing block, so add it to the
913          list of temps.  FIXME it seems a bit of a kludge to say that
914          anonymous artificial vars aren't pushed, but everything else is.  */
915       if (DECL_ARTIFICIAL (decl) && DECL_NAME (decl) == NULL_TREE)
916         gimple_add_tmp_var (decl);
917     }
918
919   append_to_compound_expr (post, &pre);
920   *stmt_p = pre;
921   return GS_OK;
922 }
923
924 /* Gimplification of expression trees.  */
925
926 /* Gimplify a C99 compound literal expression.  This just means adding the
927    DECL_STMT before the current EXPR_STMT and using its anonymous decl
928    instead.  */
929
930 static enum gimplify_status
931 gimplify_compound_literal_expr (tree *expr_p)
932 {
933   tree decl_s = COMPOUND_LITERAL_EXPR_DECL_STMT (*expr_p);
934   tree decl = DECL_STMT_DECL (decl_s);
935
936   /* This decl isn't mentioned in the enclosing block, so add it to the
937      list of temps.  FIXME it seems a bit of a kludge to say that
938      anonymous artificial vars aren't pushed, but everything else is.  */
939   if (DECL_NAME (decl) == NULL_TREE)
940     gimple_add_tmp_var (decl);
941
942   gimplify_decl_stmt (&decl_s);
943   *expr_p = decl_s ? decl_s : decl;
944   return GS_OK;
945 }
946
947 /* Do C-specific gimplification.  Args are as for gimplify_expr.  */
948
949 int
950 c_gimplify_expr (tree *expr_p, tree *pre_p ATTRIBUTE_UNUSED,
951                  tree *post_p ATTRIBUTE_UNUSED)
952 {
953   enum tree_code code = TREE_CODE (*expr_p);
954
955   if (STATEMENT_CODE_P (code))
956     return c_gimplify_stmt (expr_p);
957
958   switch (code)
959     {
960     case COMPOUND_LITERAL_EXPR:
961       return gimplify_compound_literal_expr (expr_p);
962
963     case STMT_EXPR:
964       return gimplify_stmt_expr (expr_p);
965
966     default:
967       return GS_UNHANDLED;
968     }
969 }
970
971 /* Returns the final EXPR_STMT which represents the return value of a
972    STMT_EXPR, or NULL_TREE if none.  */
973
974 tree
975 stmt_expr_last_stmt (tree stmt_expr)
976 {
977   tree body = STMT_EXPR_STMT (stmt_expr);
978   tree last_stmt, substmt;
979
980   /* Splice the last expression out of the STMT chain.  */
981   last_stmt = NULL_TREE;
982   for (substmt = COMPOUND_BODY (body); substmt;
983        substmt = TREE_CHAIN (substmt))
984     if (TREE_CODE (substmt) != SCOPE_STMT)
985       last_stmt = substmt;
986
987   if (last_stmt == NULL_TREE
988       || TREE_CODE (last_stmt) != EXPR_STMT
989       || (TREE_TYPE (last_stmt)
990           && VOID_TYPE_P (TREE_TYPE (last_stmt))))
991     {
992       location_t loc;
993       if (last_stmt && EXPR_LOCUS (last_stmt))
994         loc = *EXPR_LOCUS (last_stmt);
995       else if (EXPR_LOCUS (stmt_expr))
996         loc = *EXPR_LOCUS (stmt_expr);
997       else
998         loc = input_location;
999       warning ("%Hstatement-expressions should end with a "
1000                "non-void expression", &loc);
1001       last_stmt = NULL_TREE;
1002     }
1003
1004 #if defined ENABLE_CHECKING
1005   if (last_stmt && !is_last_stmt_of_scope (last_stmt))
1006     abort ();
1007 #endif
1008
1009   return last_stmt;
1010 }
1011
1012 /* Gimplify a STMT_EXPR.  EXPR_P points to the expression to gimplify.
1013    After gimplification, if the STMT_EXPR returns a value, EXPR_P will
1014    point to a new temporary that holds that value; otherwise it will be
1015    null.
1016
1017    PRE_P points to the list where side effects that must happen before
1018      *EXPR_P should be stored.  */
1019
1020 static enum gimplify_status
1021 gimplify_stmt_expr (tree *expr_p)
1022 {
1023   tree body = STMT_EXPR_STMT (*expr_p);
1024
1025   if (VOID_TYPE_P (TREE_TYPE (*expr_p)))
1026     {
1027       *expr_p = body;
1028       return c_gimplify_stmt (expr_p);
1029     }
1030   else
1031     {
1032       tree last_stmt = stmt_expr_last_stmt (*expr_p);
1033       tree last_expr = NULL_TREE;
1034
1035       if (last_stmt)
1036         {
1037           last_expr = EXPR_STMT_EXPR (last_stmt);
1038
1039           if (stmts_are_full_exprs_p ())
1040             last_expr = build1 (CLEANUP_POINT_EXPR, TREE_TYPE (last_expr),
1041                                 last_expr);
1042           EXPR_STMT_EXPR (last_stmt) = NULL_TREE;
1043         }
1044
1045       /* Genericize the block.  */
1046       c_gimplify_stmt (&body);
1047
1048       /* Now retrofit that last expression into the BIND_EXPR.  */
1049       if (last_expr)
1050         {
1051           tree *sub_p;
1052
1053           if (!STMT_EXPR_NO_SCOPE (*expr_p))
1054             {
1055               /* Our BIND_EXPR will always be hidden within
1056                  a STATEMENT_LIST.  Discard that.  */
1057               body = expr_first (body);
1058               sub_p = &BIND_EXPR_BODY (body);
1059
1060               /* Append the last expression to the end of the BIND_EXPR.
1061                  We'll now re-process this, and let voidify_wrapper_expr
1062                  do its job.  */
1063               append_to_statement_list_force (last_expr, sub_p);
1064               TREE_TYPE (body) = TREE_TYPE (last_expr);
1065             }
1066           else
1067             append_to_compound_expr (last_expr, &body);
1068         }
1069
1070       *expr_p = body;
1071       return GS_OK;
1072     }
1073 }
1074
1075 /* Code generation.  */
1076
1077 /* Miscellaneous helpers.  */
1078
1079 #if defined ENABLE_CHECKING
1080 /*  Return nonzero if STMT is the last statement of its scope.  */
1081
1082 static int
1083 is_last_stmt_of_scope (tree stmt)
1084 {
1085   return (TREE_CHAIN (stmt) == NULL_TREE
1086           || (TREE_CODE (TREE_CHAIN (stmt)) == SCOPE_STMT
1087               && SCOPE_END_P (TREE_CHAIN (stmt))));
1088 }
1089 #endif