c-common.def (CASE_LABEL): 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 CONTINUE_STMT:
268 stmt = build_bc_goto (bc_continue);
269 ret = GS_OK;
270 break;
271
272 case BREAK_STMT:
273 stmt = build_bc_goto (bc_break);
274 ret = GS_OK;
275 break;
276
277 default:
278 if (lang_gimplify_stmt && (*lang_gimplify_stmt) (&stmt))
279 {
280 ret = GS_OK;
281 break;
282 }
283
284 fprintf (stderr, "unhandled statement node in c_gimplify_stmt:\n");
285 debug_tree (stmt);
286 abort ();
287 break;
288 }
289
290 switch (ret)
291 {
292 case GS_ERROR:
293 goto cont;
294 case GS_OK:
295 gimplify_stmt (&stmt);
296 break;
297 case GS_ALL_DONE:
298 break;
299 default:
300 abort ();
301 }
302
303 /* PRE and POST now contain a list of statements for all the
304 side-effects in STMT. */
305
306 append_to_statement_list (stmt, &pre);
307 append_to_statement_list (post, &pre);
308 annotate_all_with_locus (&pre, stmt_locus);
309 cont:
310 /* Restore saved state. */
311 current_stmt_tree ()->stmts_are_full_exprs_p = saved_stmts_are_full_exprs_p;
312 *stmt_p = pre;
313
314 return GS_ALL_DONE;
315 }
316
317 static void
318 add_block_to_enclosing (tree block)
319 {
320 tree enclosing;
321
322 for (enclosing = gimple_current_bind_expr ();
323 enclosing; enclosing = TREE_CHAIN (enclosing))
324 if (BIND_EXPR_BLOCK (enclosing))
325 break;
326
327 enclosing = BIND_EXPR_BLOCK (enclosing);
328 BLOCK_SUBBLOCKS (enclosing) = chainon (BLOCK_SUBBLOCKS (enclosing), block);
329 }
330
331 /* Genericize a scope by creating a new BIND_EXPR.
332 BLOCK is either a BLOCK representing the scope or a chain of _DECLs.
333 In the latter case, we need to create a new BLOCK and add it to the
334 BLOCK_SUBBLOCKS of the enclosing block.
335 BODY is a chain of C _STMT nodes for the contents of the scope, to be
336 genericized. */
337
338 tree
339 c_build_bind_expr (tree block, tree body)
340 {
341 tree decls, bind;
342
343 if (block == NULL_TREE)
344 decls = NULL_TREE;
345 else if (TREE_CODE (block) == BLOCK)
346 decls = BLOCK_VARS (block);
347 else
348 {
349 decls = block;
350 if (DECL_ARTIFICIAL (decls))
351 block = NULL_TREE;
352 else
353 {
354 block = make_node (BLOCK);
355 BLOCK_VARS (block) = decls;
356 add_block_to_enclosing (block);
357 }
358 }
359
360 if (!body)
361 body = build_empty_stmt ();
362 if (decls || block)
363 {
364 bind = build (BIND_EXPR, void_type_node, decls, body, block);
365 TREE_SIDE_EFFECTS (bind) = 1;
366 }
367 else
368 bind = body;
369
370 return bind;
371 }
372
373 /* Gimplify an EXPR_STMT node.
374
375 STMT is the statement node.
376
377 PRE_P points to the list where side effects that must happen before
378 STMT should be stored.
379
380 POST_P points to the list where side effects that must happen after
381 STMT should be stored. */
382
383 static enum gimplify_status
384 gimplify_expr_stmt (tree *stmt_p)
385 {
386 tree stmt = EXPR_STMT_EXPR (*stmt_p);
387
388 if (stmt == error_mark_node)
389 stmt = NULL;
390
391 /* Gimplification of a statement expression will nullify the
392 statement if all its side effects are moved to *PRE_P and *POST_P.
393
394 In this case we will not want to emit the gimplified statement.
395 However, we may still want to emit a warning, so we do that before
396 gimplification. */
397 if (stmt && (extra_warnings || warn_unused_value))
398 {
399 if (!TREE_SIDE_EFFECTS (stmt))
400 {
401 if (!IS_EMPTY_STMT (stmt)
402 && !VOID_TYPE_P (TREE_TYPE (stmt))
403 && !TREE_NO_WARNING (stmt))
404 warning ("statement with no effect");
405 }
406 else if (warn_unused_value)
407 {
408 /* Kludge for 20020220-2.c. warn_if_unused_value shouldn't use
409 the stmt file location info. */
410 set_file_and_line_for_stmt (input_location);
411 warn_if_unused_value (stmt);
412 }
413 }
414
415 if (stmt == NULL_TREE)
416 stmt = build_empty_stmt ();
417 else if (stmts_are_full_exprs_p ())
418 stmt = build1 (CLEANUP_POINT_EXPR, void_type_node, stmt);
419
420 *stmt_p = stmt;
421
422 return GS_OK;
423 }
424
425 /* If the condition for a loop (or the like) is a decl, it will be a
426 TREE_LIST where the TREE_PURPOSE is a DECL_STMT and the TREE_VALUE is
427 a use of the decl. Turn such a thing into a COMPOUND_EXPR. */
428
429 static void
430 gimplify_condition (tree *cond_p)
431 {
432 tree cond = *cond_p;
433 if (cond && TREE_CODE (cond) == TREE_LIST)
434 {
435 tree decl = TREE_PURPOSE (cond);
436 tree value = TREE_VALUE (cond);
437 gimplify_stmt (&decl);
438 *cond_p = build (COMPOUND_EXPR, TREE_TYPE (value), decl, value);
439 }
440 }
441
442 /* Begin a scope which can be exited by a break or continue statement. BC
443 indicates which.
444
445 Just creates a label and pushes it into the current context. */
446
447 static tree
448 begin_bc_block (enum bc_t bc)
449 {
450 tree label = create_artificial_label ();
451 DECL_NAME (label) = ctxp->bc_id[bc];
452 TREE_CHAIN (label) = ctxp->current_bc_label;
453 ctxp->current_bc_label = label;
454 return label;
455 }
456
457 /* Finish a scope which can be exited by a break or continue statement.
458 LABEL was returned from the most recent call to begin_bc_block. BODY is
459 an expression for the contents of the scope.
460
461 If we saw a break (or continue) in the scope, append a LABEL_EXPR to
462 body. Otherwise, just forget the label. */
463
464 static tree
465 finish_bc_block (tree label, tree body)
466 {
467 if (label != ctxp->current_bc_label)
468 abort ();
469
470 if (TREE_USED (label))
471 {
472 tree t, sl = NULL;
473
474 /* Clear the name so flow can delete the label. */
475 DECL_NAME (label) = NULL_TREE;
476 t = build1 (LABEL_EXPR, void_type_node, label);
477
478 append_to_statement_list (body, &sl);
479 append_to_statement_list (t, &sl);
480 body = sl;
481 }
482
483 ctxp->current_bc_label = TREE_CHAIN (label);
484 TREE_CHAIN (label) = NULL_TREE;
485 return body;
486 }
487
488 /* Build a GOTO_EXPR to represent a break or continue statement. BC
489 indicates which. */
490
491 static tree
492 build_bc_goto (enum bc_t bc)
493 {
494 tree label;
495 tree target_name = ctxp->bc_id[bc];
496
497 /* Look for the appropriate type of label. */
498 for (label = ctxp->current_bc_label;
499 label;
500 label = TREE_CHAIN (label))
501 if (DECL_NAME (label) == target_name)
502 break;
503
504 if (label == NULL_TREE)
505 {
506 if (bc == bc_break)
507 error ("break statement not within loop or switch");
508 else
509 error ("continue statement not within loop or switch");
510
511 return NULL_TREE;
512 }
513
514 /* Mark the label used for finish_bc_block. */
515 TREE_USED (label) = 1;
516 return build1 (GOTO_EXPR, void_type_node, label);
517 }
518
519 /* Build a generic representation of one of the C loop forms. COND is the
520 loop condition or NULL_TREE. BODY is the (possibly compound) statement
521 controlled by the loop. INCR is the increment expression of a for-loop,
522 or NULL_TREE. COND_IS_FIRST indicates whether the condition is
523 evaluated before the loop body as in while and for loops, or after the
524 loop body as in do-while loops. */
525
526 static tree
527 gimplify_c_loop (tree cond, tree body, tree incr, bool cond_is_first)
528 {
529 tree top, entry, exit, cont_block, break_block, stmt_list, t;
530 location_t stmt_locus;
531
532 stmt_locus = input_location;
533
534 /* Detect do { ... } while (0) and don't generate loop construct. */
535 if (!cond_is_first && cond && integer_zerop (cond))
536 top = cond = NULL;
537 else
538 {
539 /* If we use a LOOP_EXPR here, we have to feed the whole thing
540 back through the main gimplifier to lower it. Given that we
541 have to gimplify the loop body NOW so that we can resolve
542 break/continue stmts, seems easier to just expand to gotos. */
543 top = build1 (LABEL_EXPR, void_type_node, NULL_TREE);
544 }
545
546 break_block = begin_bc_block (bc_break);
547
548 if (top)
549 {
550 /* If we have an exit condition, then we build an IF with gotos either
551 out of the loop, or to the top of it. If there's no exit condition,
552 then we just build a jump back to the top. */
553 exit = build_and_jump (&LABEL_EXPR_LABEL (top));
554 if (cond)
555 {
556 gimplify_condition (&cond);
557 t = build_bc_goto (bc_break);
558 exit = build (COND_EXPR, void_type_node, cond, exit, t);
559 exit = fold (exit);
560 gimplify_stmt (&exit);
561 }
562 }
563 else
564 exit = NULL_TREE;
565
566 cont_block = begin_bc_block (bc_continue);
567
568 gimplify_stmt (&body);
569 if (incr && stmts_are_full_exprs_p ())
570 incr = fold (build1 (CLEANUP_POINT_EXPR, void_type_node, incr));
571 gimplify_stmt (&incr);
572
573 body = finish_bc_block (cont_block, body);
574
575 stmt_list = NULL;
576
577 if (cond_is_first && cond)
578 {
579 entry = build1 (LABEL_EXPR, void_type_node, NULL_TREE);
580 t = build_and_jump (&LABEL_EXPR_LABEL (entry));
581 append_to_statement_list (t, &stmt_list);
582 }
583 else
584 entry = NULL_TREE;
585
586 append_to_statement_list (top, &stmt_list);
587 append_to_statement_list (body, &stmt_list);
588 append_to_statement_list (incr, &stmt_list);
589 append_to_statement_list (entry, &stmt_list);
590 append_to_statement_list (exit, &stmt_list);
591
592 annotate_all_with_locus (&stmt_list, stmt_locus);
593
594 return finish_bc_block (break_block, stmt_list);
595 }
596
597 /* Gimplify a FOR_STMT node. Move the stuff in the for-init-stmt into the
598 prequeue and hand off to gimplify_c_loop. */
599
600 static enum gimplify_status
601 gimplify_for_stmt (tree *stmt_p, tree *pre_p)
602 {
603 tree stmt = *stmt_p;
604
605 if (FOR_INIT_STMT (stmt))
606 {
607 gimplify_stmt (&FOR_INIT_STMT (stmt));
608 append_to_statement_list (FOR_INIT_STMT (stmt), pre_p);
609 }
610 *stmt_p = gimplify_c_loop (FOR_COND (stmt), FOR_BODY (stmt),
611 FOR_EXPR (stmt), 1);
612
613 return GS_ALL_DONE;
614 }
615
616 /* Gimplify a WHILE_STMT node. */
617
618 static enum gimplify_status
619 gimplify_while_stmt (tree *stmt_p)
620 {
621 tree stmt = *stmt_p;
622 *stmt_p = gimplify_c_loop (WHILE_COND (stmt), WHILE_BODY (stmt),
623 NULL_TREE, 1);
624 return GS_ALL_DONE;
625 }
626
627 /* Gimplify a DO_STMT node. */
628
629 static enum gimplify_status
630 gimplify_do_stmt (tree *stmt_p)
631 {
632 tree stmt = *stmt_p;
633 *stmt_p = gimplify_c_loop (DO_COND (stmt), DO_BODY (stmt),
634 NULL_TREE, 0);
635 return GS_ALL_DONE;
636 }
637
638 /* Genericize an IF_STMT by turning it into a COND_EXPR. */
639
640 static enum gimplify_status
641 gimplify_if_stmt (tree *stmt_p)
642 {
643 tree stmt, then_, else_;
644
645 stmt = *stmt_p;
646 then_ = THEN_CLAUSE (stmt);
647 else_ = ELSE_CLAUSE (stmt);
648
649 if (!then_)
650 then_ = build_empty_stmt ();
651 if (!else_)
652 else_ = build_empty_stmt ();
653
654 stmt = build (COND_EXPR, void_type_node, IF_COND (stmt), then_, else_);
655 gimplify_condition (& TREE_OPERAND (stmt, 0));
656 *stmt_p = stmt;
657
658 return GS_OK;
659 }
660
661 /* Genericize a SWITCH_STMT by turning it into a SWITCH_EXPR. */
662
663 static enum gimplify_status
664 gimplify_switch_stmt (tree *stmt_p)
665 {
666 tree stmt = *stmt_p;
667 tree break_block, body;
668 location_t stmt_locus = input_location;
669
670 break_block = begin_bc_block (bc_break);
671
672 gimplify_condition (&SWITCH_COND (stmt));
673
674 body = SWITCH_BODY (stmt);
675 if (!body)
676 body = build_empty_stmt ();
677
678 *stmt_p = build (SWITCH_EXPR, SWITCH_TYPE (stmt), SWITCH_COND (stmt),
679 body, NULL_TREE);
680 annotate_with_locus (*stmt_p, stmt_locus);
681 gimplify_stmt (stmt_p);
682
683 *stmt_p = finish_bc_block (break_block, *stmt_p);
684 return GS_ALL_DONE;
685 }
686
687 /* Genericize a RETURN_STMT by turning it into a RETURN_EXPR. */
688
689 static enum gimplify_status
690 gimplify_return_stmt (tree *stmt_p)
691 {
692 tree expr = RETURN_STMT_EXPR (*stmt_p);
693 expr = build1 (RETURN_EXPR, void_type_node, expr);
694 if (stmts_are_full_exprs_p ())
695 expr = build1 (CLEANUP_POINT_EXPR, void_type_node, expr);
696 *stmt_p = expr;
697 return GS_OK;
698 }
699
700 /* Gimplifies a DECL_STMT node *STMT_P by making any necessary allocation
701 and initialization explicit. */
702
703 static enum gimplify_status
704 gimplify_decl_stmt (tree *stmt_p)
705 {
706 tree stmt = *stmt_p;
707 tree decl = DECL_STMT_DECL (stmt);
708 tree pre = NULL_TREE;
709 tree post = NULL_TREE;
710
711 if (TREE_TYPE (decl) == error_mark_node)
712 {
713 *stmt_p = NULL;
714 return GS_ERROR;
715 }
716
717 if (TREE_CODE (decl) == TYPE_DECL)
718 {
719 tree type = TREE_TYPE (decl);
720 if (TYPE_SIZE_UNIT (type)
721 && !TREE_CONSTANT (TYPE_SIZE_UNIT (type)))
722 {
723 /* This is a variable-sized array type. Simplify its size. */
724 tree temp = TYPE_SIZE_UNIT (type);
725 gimplify_expr (&temp, &pre, &post, is_gimple_val, fb_rvalue);
726 }
727 }
728
729 if (TREE_CODE (decl) == VAR_DECL && !DECL_EXTERNAL (decl))
730 {
731 tree init = DECL_INITIAL (decl);
732
733 if (!TREE_CONSTANT (DECL_SIZE (decl)))
734 {
735 tree pt_type = build_pointer_type (TREE_TYPE (decl));
736 tree alloc, size;
737
738 /* This is a variable-sized decl. Simplify its size and mark it
739 for deferred expansion. Note that mudflap depends on the format
740 of the emitted code: see mx_register_decls(). */
741
742 size = get_initialized_tmp_var (DECL_SIZE_UNIT (decl), &pre, &post);
743 DECL_DEFER_OUTPUT (decl) = 1;
744 alloc = build_function_call_expr
745 (implicit_built_in_decls[BUILT_IN_STACK_ALLOC],
746 tree_cons (NULL_TREE,
747 build1 (ADDR_EXPR, pt_type, decl),
748 tree_cons (NULL_TREE, size, NULL_TREE)));
749 append_to_compound_expr (alloc, &pre);
750 }
751
752 if (init && init != error_mark_node)
753 {
754 if (!TREE_STATIC (decl))
755 {
756 /* Do not warn about int x = x; as it is a GCC extension
757 to turn off this warning but only if warn_init_self
758 is zero. */
759 if (init == decl && !warn_init_self)
760 TREE_NO_WARNING (decl) = 1;
761
762 DECL_INITIAL (decl) = NULL_TREE;
763 init = build (MODIFY_EXPR, void_type_node, decl, init);
764 if (stmts_are_full_exprs_p ())
765 init = build1 (CLEANUP_POINT_EXPR, void_type_node, init);
766 append_to_compound_expr (init, &pre);
767 }
768 else
769 {
770 /* We must still examine initializers for static variables
771 as they may contain a label address. */
772 walk_tree (&init, force_labels_r, NULL, NULL);
773 }
774 }
775
776 /* This decl isn't mentioned in the enclosing block, so add it to the
777 list of temps. FIXME it seems a bit of a kludge to say that
778 anonymous artificial vars aren't pushed, but everything else is. */
779 if (DECL_ARTIFICIAL (decl) && DECL_NAME (decl) == NULL_TREE)
780 gimple_add_tmp_var (decl);
781 }
782
783 append_to_compound_expr (post, &pre);
784 *stmt_p = pre;
785 return GS_OK;
786 }
787
788 /* Gimplification of expression trees. */
789
790 /* Gimplify a C99 compound literal expression. This just means adding the
791 DECL_STMT before the current EXPR_STMT and using its anonymous decl
792 instead. */
793
794 static enum gimplify_status
795 gimplify_compound_literal_expr (tree *expr_p)
796 {
797 tree decl_s = COMPOUND_LITERAL_EXPR_DECL_STMT (*expr_p);
798 tree decl = DECL_STMT_DECL (decl_s);
799
800 /* This decl isn't mentioned in the enclosing block, so add it to the
801 list of temps. FIXME it seems a bit of a kludge to say that
802 anonymous artificial vars aren't pushed, but everything else is. */
803 if (DECL_NAME (decl) == NULL_TREE)
804 gimple_add_tmp_var (decl);
805
806 gimplify_decl_stmt (&decl_s);
807 *expr_p = decl_s ? decl_s : decl;
808 return GS_OK;
809 }
810
811 /* Do C-specific gimplification. Args are as for gimplify_expr. */
812
813 int
814 c_gimplify_expr (tree *expr_p, tree *pre_p ATTRIBUTE_UNUSED,
815 tree *post_p ATTRIBUTE_UNUSED)
816 {
817 enum tree_code code = TREE_CODE (*expr_p);
818
819 if (STATEMENT_CODE_P (code))
820 return c_gimplify_stmt (expr_p);
821
822 switch (code)
823 {
824 case COMPOUND_LITERAL_EXPR:
825 return gimplify_compound_literal_expr (expr_p);
826
827 default:
828 return GS_UNHANDLED;
829 }
830 }