c-common.def (ASM_STMT): Remove.
[gcc.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_compound_literal_expr (tree *);
84 static void gimplify_cleanup_stmts (tree);
85 static tree gimplify_c_loop (tree, tree, tree, bool);
86 static void push_context (void);
87 static void pop_context (void);
88 static void add_block_to_enclosing (tree);
89 static void gimplify_condition (tree *);
90
91 enum bc_t { bc_break = 0, bc_continue = 1 };
92 static tree begin_bc_block (enum bc_t);
93 static tree finish_bc_block (tree, tree);
94 static tree build_bc_goto (enum bc_t);
95
96 static struct c_gimplify_ctx
97 {
98 /* For handling break and continue. */
99 tree current_bc_label;
100 tree bc_id[2];
101 } *ctxp;
102
103 static void
104 push_context (void)
105 {
106 if (ctxp)
107 abort ();
108 ctxp = (struct c_gimplify_ctx *) xcalloc (1, sizeof (struct c_gimplify_ctx));
109 ctxp->bc_id[bc_continue] = get_identifier ("continue");
110 ctxp->bc_id[bc_break] = get_identifier ("break");
111 }
112
113 static void
114 pop_context (void)
115 {
116 if (!ctxp || ctxp->current_bc_label)
117 abort ();
118 free (ctxp);
119 ctxp = NULL;
120 }
121
122 /* Gimplification of statement trees. */
123
124 /* Convert the tree representation of FNDECL from C frontend trees to
125 GENERIC. */
126
127 void
128 c_genericize (tree fndecl)
129 {
130 FILE *dump_file;
131 int local_dump_flags;
132 struct cgraph_node *cgn;
133
134 /* Dump the C-specific tree IR. */
135 dump_file = dump_begin (TDI_original, &local_dump_flags);
136 if (dump_file)
137 {
138 fprintf (dump_file, "\n;; Function %s",
139 lang_hooks.decl_printable_name (fndecl, 2));
140 fprintf (dump_file, " (%s)\n",
141 IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (fndecl)));
142 fprintf (dump_file, ";; enabled by -%s\n", dump_flag_name (TDI_original));
143 fprintf (dump_file, "\n");
144
145 if (local_dump_flags & TDF_RAW)
146 dump_node (DECL_SAVED_TREE (fndecl),
147 TDF_SLIM | local_dump_flags, dump_file);
148 else
149 print_c_tree (dump_file, DECL_SAVED_TREE (fndecl));
150 fprintf (dump_file, "\n");
151
152 dump_end (TDI_original, dump_file);
153 }
154
155 /* Go ahead and gimplify for now. */
156 push_context ();
157 gimplify_cleanup_stmts (fndecl);
158 gimplify_function_tree (fndecl);
159 pop_context ();
160
161 /* Dump the genericized tree IR. */
162 dump_function (TDI_generic, fndecl);
163
164 /* Genericize all nested functions now. We do things in this order so
165 that items like VLA sizes are expanded properly in the context of
166 the correct function. */
167 cgn = cgraph_node (fndecl);
168 for (cgn = cgn->nested; cgn ; cgn = cgn->next_nested)
169 c_genericize (cgn->decl);
170 }
171
172 /* Genericize a CLEANUP_STMT. This just turns into a TRY_FINALLY or
173 TRY_CATCH depending on whether it's EH-only. */
174
175 static tree
176 gimplify_cleanup_stmt (tree *stmt_p, int *walk_subtrees,
177 void *data ATTRIBUTE_UNUSED)
178 {
179 tree stmt = *stmt_p;
180
181 if (DECL_P (stmt) || TYPE_P (stmt))
182 *walk_subtrees = 0;
183 else if (TREE_CODE (stmt) == CLEANUP_STMT)
184 *stmt_p = build (CLEANUP_EH_ONLY (stmt) ? TRY_CATCH_EXPR : TRY_FINALLY_EXPR,
185 void_type_node, CLEANUP_BODY (stmt), CLEANUP_EXPR (stmt));
186
187 return NULL;
188 }
189
190 static void
191 gimplify_cleanup_stmts (tree fndecl)
192 {
193 walk_tree (&DECL_SAVED_TREE (fndecl), gimplify_cleanup_stmt, NULL, NULL);
194 }
195
196 /* Entry point for the tree lowering pass. Recursively scan
197 *STMT_P and convert it to a GIMPLE tree. */
198
199 int
200 c_gimplify_stmt (tree *stmt_p)
201 {
202 tree stmt = *stmt_p;
203 tree pre, post;
204 int saved_stmts_are_full_exprs_p;
205 location_t stmt_locus;
206 enum gimplify_status ret;
207
208 /* PRE and POST are tree chains that contain the side-effects of the
209 gimplified tree. For instance, given the expression tree:
210
211 c = ++a * 3 + b++;
212
213 After gimplification, the tree will be re-written as:
214
215 a = a + 1;
216 t1 = a * 3; <-- PRE
217 c = t1 + b;
218 b = b + 1; <-- POST */
219
220 /* Set up context appropriately for handling this statement. */
221 saved_stmts_are_full_exprs_p = stmts_are_full_exprs_p ();
222 prep_stmt (stmt);
223 stmt_locus = input_location;
224
225 pre = NULL_TREE;
226 post = NULL_TREE;
227
228 switch (TREE_CODE (stmt))
229 {
230 case COMPOUND_STMT:
231 stmt = COMPOUND_BODY (stmt);
232 ret = GS_OK;
233 break;
234
235 case FOR_STMT:
236 ret = gimplify_for_stmt (&stmt, &pre);
237 break;
238
239 case WHILE_STMT:
240 ret = gimplify_while_stmt (&stmt);
241 break;
242
243 case DO_STMT:
244 ret = gimplify_do_stmt (&stmt);
245 break;
246
247 case IF_STMT:
248 ret = gimplify_if_stmt (&stmt);
249 break;
250
251 case SWITCH_STMT:
252 ret = gimplify_switch_stmt (&stmt);
253 break;
254
255 case EXPR_STMT:
256 ret = gimplify_expr_stmt (&stmt);
257 break;
258
259 case RETURN_STMT:
260 ret = gimplify_return_stmt (&stmt);
261 break;
262
263 case DECL_STMT:
264 ret = gimplify_decl_stmt (&stmt);
265 break;
266
267 case CASE_LABEL:
268 {
269 tree label = create_artificial_label ();
270 stmt = build (CASE_LABEL_EXPR, void_type_node,
271 CASE_LOW (stmt), CASE_HIGH (stmt), label);
272 ret = GS_OK;
273 }
274 break;
275
276 case CONTINUE_STMT:
277 stmt = build_bc_goto (bc_continue);
278 ret = GS_OK;
279 break;
280
281 case BREAK_STMT:
282 stmt = build_bc_goto (bc_break);
283 ret = GS_OK;
284 break;
285
286 default:
287 if (lang_gimplify_stmt && (*lang_gimplify_stmt) (&stmt))
288 {
289 ret = GS_OK;
290 break;
291 }
292
293 fprintf (stderr, "unhandled statement node in c_gimplify_stmt:\n");
294 debug_tree (stmt);
295 abort ();
296 break;
297 }
298
299 switch (ret)
300 {
301 case GS_ERROR:
302 goto cont;
303 case GS_OK:
304 gimplify_stmt (&stmt);
305 break;
306 case GS_ALL_DONE:
307 break;
308 default:
309 abort ();
310 }
311
312 /* PRE and POST now contain a list of statements for all the
313 side-effects in STMT. */
314
315 append_to_statement_list (stmt, &pre);
316 append_to_statement_list (post, &pre);
317 annotate_all_with_locus (&pre, stmt_locus);
318 cont:
319 /* Restore saved state. */
320 current_stmt_tree ()->stmts_are_full_exprs_p = saved_stmts_are_full_exprs_p;
321 *stmt_p = pre;
322
323 return GS_ALL_DONE;
324 }
325
326 static void
327 add_block_to_enclosing (tree block)
328 {
329 tree enclosing;
330
331 for (enclosing = gimple_current_bind_expr ();
332 enclosing; enclosing = TREE_CHAIN (enclosing))
333 if (BIND_EXPR_BLOCK (enclosing))
334 break;
335
336 enclosing = BIND_EXPR_BLOCK (enclosing);
337 BLOCK_SUBBLOCKS (enclosing) = chainon (BLOCK_SUBBLOCKS (enclosing), block);
338 }
339
340 /* Genericize a scope by creating a new BIND_EXPR.
341 BLOCK is either a BLOCK representing the scope or a chain of _DECLs.
342 In the latter case, we need to create a new BLOCK and add it to the
343 BLOCK_SUBBLOCKS of the enclosing block.
344 BODY is a chain of C _STMT nodes for the contents of the scope, to be
345 genericized. */
346
347 tree
348 c_build_bind_expr (tree block, tree body)
349 {
350 tree decls, bind;
351
352 if (block == NULL_TREE)
353 decls = NULL_TREE;
354 else if (TREE_CODE (block) == BLOCK)
355 decls = BLOCK_VARS (block);
356 else
357 {
358 decls = block;
359 if (DECL_ARTIFICIAL (decls))
360 block = NULL_TREE;
361 else
362 {
363 block = make_node (BLOCK);
364 BLOCK_VARS (block) = decls;
365 add_block_to_enclosing (block);
366 }
367 }
368
369 if (!body)
370 body = build_empty_stmt ();
371 if (decls || block)
372 {
373 bind = build (BIND_EXPR, void_type_node, decls, body, block);
374 TREE_SIDE_EFFECTS (bind) = 1;
375 }
376 else
377 bind = body;
378
379 return bind;
380 }
381
382 /* Gimplify an EXPR_STMT node.
383
384 STMT is the statement node.
385
386 PRE_P points to the list where side effects that must happen before
387 STMT should be stored.
388
389 POST_P points to the list where side effects that must happen after
390 STMT should be stored. */
391
392 static enum gimplify_status
393 gimplify_expr_stmt (tree *stmt_p)
394 {
395 tree stmt = EXPR_STMT_EXPR (*stmt_p);
396
397 if (stmt == error_mark_node)
398 stmt = NULL;
399
400 /* Gimplification of a statement expression will nullify the
401 statement if all its side effects are moved to *PRE_P and *POST_P.
402
403 In this case we will not want to emit the gimplified statement.
404 However, we may still want to emit a warning, so we do that before
405 gimplification. */
406 if (stmt && (extra_warnings || warn_unused_value))
407 {
408 if (!TREE_SIDE_EFFECTS (stmt))
409 {
410 if (!IS_EMPTY_STMT (stmt)
411 && !VOID_TYPE_P (TREE_TYPE (stmt))
412 && !TREE_NO_WARNING (stmt))
413 warning ("statement with no effect");
414 }
415 else if (warn_unused_value)
416 {
417 /* Kludge for 20020220-2.c. warn_if_unused_value shouldn't use
418 the stmt file location info. */
419 set_file_and_line_for_stmt (input_location);
420 warn_if_unused_value (stmt);
421 }
422 }
423
424 if (stmt == NULL_TREE)
425 stmt = build_empty_stmt ();
426 else if (stmts_are_full_exprs_p ())
427 stmt = build1 (CLEANUP_POINT_EXPR, void_type_node, stmt);
428
429 *stmt_p = stmt;
430
431 return GS_OK;
432 }
433
434 /* If the condition for a loop (or the like) is a decl, it will be a
435 TREE_LIST where the TREE_PURPOSE is a DECL_STMT and the TREE_VALUE is
436 a use of the decl. Turn such a thing into a COMPOUND_EXPR. */
437
438 static void
439 gimplify_condition (tree *cond_p)
440 {
441 tree cond = *cond_p;
442 if (cond && TREE_CODE (cond) == TREE_LIST)
443 {
444 tree decl = TREE_PURPOSE (cond);
445 tree value = TREE_VALUE (cond);
446 gimplify_stmt (&decl);
447 *cond_p = build (COMPOUND_EXPR, TREE_TYPE (value), decl, value);
448 }
449 }
450
451 /* Begin a scope which can be exited by a break or continue statement. BC
452 indicates which.
453
454 Just creates a label and pushes it into the current context. */
455
456 static tree
457 begin_bc_block (enum bc_t bc)
458 {
459 tree label = create_artificial_label ();
460 DECL_NAME (label) = ctxp->bc_id[bc];
461 TREE_CHAIN (label) = ctxp->current_bc_label;
462 ctxp->current_bc_label = label;
463 return label;
464 }
465
466 /* Finish a scope which can be exited by a break or continue statement.
467 LABEL was returned from the most recent call to begin_bc_block. BODY is
468 an expression for the contents of the scope.
469
470 If we saw a break (or continue) in the scope, append a LABEL_EXPR to
471 body. Otherwise, just forget the label. */
472
473 static tree
474 finish_bc_block (tree label, tree body)
475 {
476 if (label != ctxp->current_bc_label)
477 abort ();
478
479 if (TREE_USED (label))
480 {
481 tree t, sl = NULL;
482
483 /* Clear the name so flow can delete the label. */
484 DECL_NAME (label) = NULL_TREE;
485 t = build1 (LABEL_EXPR, void_type_node, label);
486
487 append_to_statement_list (body, &sl);
488 append_to_statement_list (t, &sl);
489 body = sl;
490 }
491
492 ctxp->current_bc_label = TREE_CHAIN (label);
493 TREE_CHAIN (label) = NULL_TREE;
494 return body;
495 }
496
497 /* Build a GOTO_EXPR to represent a break or continue statement. BC
498 indicates which. */
499
500 static tree
501 build_bc_goto (enum bc_t bc)
502 {
503 tree label;
504 tree target_name = ctxp->bc_id[bc];
505
506 /* Look for the appropriate type of label. */
507 for (label = ctxp->current_bc_label;
508 label;
509 label = TREE_CHAIN (label))
510 if (DECL_NAME (label) == target_name)
511 break;
512
513 if (label == NULL_TREE)
514 {
515 if (bc == bc_break)
516 error ("break statement not within loop or switch");
517 else
518 error ("continue statement not within loop or switch");
519
520 return NULL_TREE;
521 }
522
523 /* Mark the label used for finish_bc_block. */
524 TREE_USED (label) = 1;
525 return build1 (GOTO_EXPR, void_type_node, label);
526 }
527
528 /* Build a generic representation of one of the C loop forms. COND is the
529 loop condition or NULL_TREE. BODY is the (possibly compound) statement
530 controlled by the loop. INCR is the increment expression of a for-loop,
531 or NULL_TREE. COND_IS_FIRST indicates whether the condition is
532 evaluated before the loop body as in while and for loops, or after the
533 loop body as in do-while loops. */
534
535 static tree
536 gimplify_c_loop (tree cond, tree body, tree incr, bool cond_is_first)
537 {
538 tree top, entry, exit, cont_block, break_block, stmt_list, t;
539 location_t stmt_locus;
540
541 stmt_locus = input_location;
542
543 /* Detect do { ... } while (0) and don't generate loop construct. */
544 if (!cond_is_first && cond && integer_zerop (cond))
545 top = cond = NULL;
546 else
547 {
548 /* If we use a LOOP_EXPR here, we have to feed the whole thing
549 back through the main gimplifier to lower it. Given that we
550 have to gimplify the loop body NOW so that we can resolve
551 break/continue stmts, seems easier to just expand to gotos. */
552 top = build1 (LABEL_EXPR, void_type_node, NULL_TREE);
553 }
554
555 break_block = begin_bc_block (bc_break);
556
557 if (top)
558 {
559 /* If we have an exit condition, then we build an IF with gotos either
560 out of the loop, or to the top of it. If there's no exit condition,
561 then we just build a jump back to the top. */
562 exit = build_and_jump (&LABEL_EXPR_LABEL (top));
563 if (cond)
564 {
565 gimplify_condition (&cond);
566 t = build_bc_goto (bc_break);
567 exit = build (COND_EXPR, void_type_node, cond, exit, t);
568 exit = fold (exit);
569 gimplify_stmt (&exit);
570 }
571 }
572 else
573 exit = NULL_TREE;
574
575 cont_block = begin_bc_block (bc_continue);
576
577 gimplify_stmt (&body);
578 if (incr && stmts_are_full_exprs_p ())
579 incr = fold (build1 (CLEANUP_POINT_EXPR, void_type_node, incr));
580 gimplify_stmt (&incr);
581
582 body = finish_bc_block (cont_block, body);
583
584 stmt_list = NULL;
585
586 if (cond_is_first && cond)
587 {
588 entry = build1 (LABEL_EXPR, void_type_node, NULL_TREE);
589 t = build_and_jump (&LABEL_EXPR_LABEL (entry));
590 append_to_statement_list (t, &stmt_list);
591 }
592 else
593 entry = NULL_TREE;
594
595 append_to_statement_list (top, &stmt_list);
596 append_to_statement_list (body, &stmt_list);
597 append_to_statement_list (incr, &stmt_list);
598 append_to_statement_list (entry, &stmt_list);
599 append_to_statement_list (exit, &stmt_list);
600
601 annotate_all_with_locus (&stmt_list, stmt_locus);
602
603 return finish_bc_block (break_block, stmt_list);
604 }
605
606 /* Gimplify a FOR_STMT node. Move the stuff in the for-init-stmt into the
607 prequeue and hand off to gimplify_c_loop. */
608
609 static enum gimplify_status
610 gimplify_for_stmt (tree *stmt_p, tree *pre_p)
611 {
612 tree stmt = *stmt_p;
613
614 if (FOR_INIT_STMT (stmt))
615 {
616 gimplify_stmt (&FOR_INIT_STMT (stmt));
617 append_to_statement_list (FOR_INIT_STMT (stmt), pre_p);
618 }
619 *stmt_p = gimplify_c_loop (FOR_COND (stmt), FOR_BODY (stmt),
620 FOR_EXPR (stmt), 1);
621
622 return GS_ALL_DONE;
623 }
624
625 /* Gimplify a WHILE_STMT node. */
626
627 static enum gimplify_status
628 gimplify_while_stmt (tree *stmt_p)
629 {
630 tree stmt = *stmt_p;
631 *stmt_p = gimplify_c_loop (WHILE_COND (stmt), WHILE_BODY (stmt),
632 NULL_TREE, 1);
633 return GS_ALL_DONE;
634 }
635
636 /* Gimplify a DO_STMT node. */
637
638 static enum gimplify_status
639 gimplify_do_stmt (tree *stmt_p)
640 {
641 tree stmt = *stmt_p;
642 *stmt_p = gimplify_c_loop (DO_COND (stmt), DO_BODY (stmt),
643 NULL_TREE, 0);
644 return GS_ALL_DONE;
645 }
646
647 /* Genericize an IF_STMT by turning it into a COND_EXPR. */
648
649 static enum gimplify_status
650 gimplify_if_stmt (tree *stmt_p)
651 {
652 tree stmt, then_, else_;
653
654 stmt = *stmt_p;
655 then_ = THEN_CLAUSE (stmt);
656 else_ = ELSE_CLAUSE (stmt);
657
658 if (!then_)
659 then_ = build_empty_stmt ();
660 if (!else_)
661 else_ = build_empty_stmt ();
662
663 stmt = build (COND_EXPR, void_type_node, IF_COND (stmt), then_, else_);
664 gimplify_condition (& TREE_OPERAND (stmt, 0));
665 *stmt_p = stmt;
666
667 return GS_OK;
668 }
669
670 /* Genericize a SWITCH_STMT by turning it into a SWITCH_EXPR. */
671
672 static enum gimplify_status
673 gimplify_switch_stmt (tree *stmt_p)
674 {
675 tree stmt = *stmt_p;
676 tree break_block, body;
677 location_t stmt_locus = input_location;
678
679 break_block = begin_bc_block (bc_break);
680
681 gimplify_condition (&SWITCH_COND (stmt));
682
683 body = SWITCH_BODY (stmt);
684 if (!body)
685 body = build_empty_stmt ();
686
687 *stmt_p = build (SWITCH_EXPR, SWITCH_TYPE (stmt), SWITCH_COND (stmt),
688 body, NULL_TREE);
689 annotate_with_locus (*stmt_p, stmt_locus);
690 gimplify_stmt (stmt_p);
691
692 *stmt_p = finish_bc_block (break_block, *stmt_p);
693 return GS_ALL_DONE;
694 }
695
696 /* Genericize a RETURN_STMT by turning it into a RETURN_EXPR. */
697
698 static enum gimplify_status
699 gimplify_return_stmt (tree *stmt_p)
700 {
701 tree expr = RETURN_STMT_EXPR (*stmt_p);
702 expr = build1 (RETURN_EXPR, void_type_node, expr);
703 if (stmts_are_full_exprs_p ())
704 expr = build1 (CLEANUP_POINT_EXPR, void_type_node, expr);
705 *stmt_p = expr;
706 return GS_OK;
707 }
708
709 /* Gimplifies a DECL_STMT node *STMT_P by making any necessary allocation
710 and initialization explicit. */
711
712 static enum gimplify_status
713 gimplify_decl_stmt (tree *stmt_p)
714 {
715 tree stmt = *stmt_p;
716 tree decl = DECL_STMT_DECL (stmt);
717 tree pre = NULL_TREE;
718 tree post = NULL_TREE;
719
720 if (TREE_TYPE (decl) == error_mark_node)
721 {
722 *stmt_p = NULL;
723 return GS_ERROR;
724 }
725
726 if (TREE_CODE (decl) == TYPE_DECL)
727 {
728 tree type = TREE_TYPE (decl);
729 if (TYPE_SIZE_UNIT (type)
730 && !TREE_CONSTANT (TYPE_SIZE_UNIT (type)))
731 {
732 /* This is a variable-sized array type. Simplify its size. */
733 tree temp = TYPE_SIZE_UNIT (type);
734 gimplify_expr (&temp, &pre, &post, is_gimple_val, fb_rvalue);
735 }
736 }
737
738 if (TREE_CODE (decl) == VAR_DECL && !DECL_EXTERNAL (decl))
739 {
740 tree init = DECL_INITIAL (decl);
741
742 if (!TREE_CONSTANT (DECL_SIZE (decl)))
743 {
744 tree pt_type = build_pointer_type (TREE_TYPE (decl));
745 tree alloc, size;
746
747 /* This is a variable-sized decl. Simplify its size and mark it
748 for deferred expansion. Note that mudflap depends on the format
749 of the emitted code: see mx_register_decls(). */
750
751 size = get_initialized_tmp_var (DECL_SIZE_UNIT (decl), &pre, &post);
752 DECL_DEFER_OUTPUT (decl) = 1;
753 alloc = build_function_call_expr
754 (implicit_built_in_decls[BUILT_IN_STACK_ALLOC],
755 tree_cons (NULL_TREE,
756 build1 (ADDR_EXPR, pt_type, decl),
757 tree_cons (NULL_TREE, size, NULL_TREE)));
758 append_to_compound_expr (alloc, &pre);
759 }
760
761 if (init && init != error_mark_node)
762 {
763 if (!TREE_STATIC (decl))
764 {
765 /* Do not warn about int x = x; as it is a GCC extension
766 to turn off this warning but only if warn_init_self
767 is zero. */
768 if (init == decl && !warn_init_self)
769 TREE_NO_WARNING (decl) = 1;
770
771 DECL_INITIAL (decl) = NULL_TREE;
772 init = build (MODIFY_EXPR, void_type_node, decl, init);
773 if (stmts_are_full_exprs_p ())
774 init = build1 (CLEANUP_POINT_EXPR, void_type_node, init);
775 append_to_compound_expr (init, &pre);
776 }
777 else
778 {
779 /* We must still examine initializers for static variables
780 as they may contain a label address. */
781 walk_tree (&init, force_labels_r, NULL, NULL);
782 }
783 }
784
785 /* This decl isn't mentioned in the enclosing block, so add it to the
786 list of temps. FIXME it seems a bit of a kludge to say that
787 anonymous artificial vars aren't pushed, but everything else is. */
788 if (DECL_ARTIFICIAL (decl) && DECL_NAME (decl) == NULL_TREE)
789 gimple_add_tmp_var (decl);
790 }
791
792 append_to_compound_expr (post, &pre);
793 *stmt_p = pre;
794 return GS_OK;
795 }
796
797 /* Gimplification of expression trees. */
798
799 /* Gimplify a C99 compound literal expression. This just means adding the
800 DECL_STMT before the current EXPR_STMT and using its anonymous decl
801 instead. */
802
803 static enum gimplify_status
804 gimplify_compound_literal_expr (tree *expr_p)
805 {
806 tree decl_s = COMPOUND_LITERAL_EXPR_DECL_STMT (*expr_p);
807 tree decl = DECL_STMT_DECL (decl_s);
808
809 /* This decl isn't mentioned in the enclosing block, so add it to the
810 list of temps. FIXME it seems a bit of a kludge to say that
811 anonymous artificial vars aren't pushed, but everything else is. */
812 if (DECL_NAME (decl) == NULL_TREE)
813 gimple_add_tmp_var (decl);
814
815 gimplify_decl_stmt (&decl_s);
816 *expr_p = decl_s ? decl_s : decl;
817 return GS_OK;
818 }
819
820 /* Do C-specific gimplification. Args are as for gimplify_expr. */
821
822 int
823 c_gimplify_expr (tree *expr_p, tree *pre_p ATTRIBUTE_UNUSED,
824 tree *post_p ATTRIBUTE_UNUSED)
825 {
826 enum tree_code code = TREE_CODE (*expr_p);
827
828 if (STATEMENT_CODE_P (code))
829 return c_gimplify_stmt (expr_p);
830
831 switch (code)
832 {
833 case COMPOUND_LITERAL_EXPR:
834 return gimplify_compound_literal_expr (expr_p);
835
836 default:
837 return GS_UNHANDLED;
838 }
839 }