2005-01-20 Michael Koch <konqueror@gmx.de>
[official-gcc.git] / gcc / c-gimplify.c
blob7334621106aaf7005566dde32231826fe150e130
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>
10 This file is part of GCC.
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.
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.
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. */
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"
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.
56 Language-independent trees are based on the SIMPLE intermediate
57 representation used in the McCAT compiler framework:
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.
67 http://www-acaps.cs.mcgill.ca/info/McCAT/McCAT.html
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. */
73 /* Local declarations. */
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);
90 enum bc_t { bc_break = 0, bc_continue = 1 };
91 static tree begin_bc_block (enum bc_t);
92 static tree finish_bc_block (tree, tree);
93 static tree build_bc_goto (enum bc_t);
95 static struct c_gimplify_ctx
97 /* For handling break and continue. */
98 tree current_bc_label;
99 tree bc_id[2];
100 } *ctxp;
102 static void
103 push_context (void)
105 if (ctxp)
106 abort ();
107 ctxp = (struct c_gimplify_ctx *) xcalloc (1, sizeof (struct c_gimplify_ctx));
108 ctxp->bc_id[bc_continue] = get_identifier ("continue");
109 ctxp->bc_id[bc_break] = get_identifier ("break");
112 static void
113 pop_context (void)
115 if (!ctxp || ctxp->current_bc_label)
116 abort ();
117 free (ctxp);
118 ctxp = NULL;
121 /* Gimplification of statement trees. */
123 /* Convert the tree representation of FNDECL from C frontend trees to
124 GENERIC. */
126 void
127 c_genericize (tree fndecl)
129 FILE *dump_file;
130 int local_dump_flags;
131 struct cgraph_node *cgn;
133 /* Dump the C-specific tree IR. */
134 dump_file = dump_begin (TDI_original, &local_dump_flags);
135 if (dump_file)
137 fprintf (dump_file, "\n;; Function %s",
138 lang_hooks.decl_printable_name (fndecl, 2));
139 fprintf (dump_file, " (%s)\n",
140 IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (fndecl)));
141 fprintf (dump_file, ";; enabled by -%s\n", dump_flag_name (TDI_original));
142 fprintf (dump_file, "\n");
144 if (local_dump_flags & TDF_RAW)
145 dump_node (DECL_SAVED_TREE (fndecl),
146 TDF_SLIM | local_dump_flags, dump_file);
147 else
148 print_c_tree (dump_file, DECL_SAVED_TREE (fndecl));
149 fprintf (dump_file, "\n");
151 dump_end (TDI_original, dump_file);
154 /* Go ahead and gimplify for now. */
155 push_context ();
156 gimplify_cleanup_stmts (fndecl);
157 gimplify_function_tree (fndecl);
158 pop_context ();
160 /* Dump the genericized tree IR. */
161 dump_function (TDI_generic, fndecl);
163 /* Genericize all nested functions now. We do things in this order so
164 that items like VLA sizes are expanded properly in the context of
165 the correct function. */
166 cgn = cgraph_node (fndecl);
167 for (cgn = cgn->nested; cgn ; cgn = cgn->next_nested)
168 c_genericize (cgn->decl);
171 /* Genericize a CLEANUP_STMT. This just turns into a TRY_FINALLY or
172 TRY_CATCH depending on whether it's EH-only. */
174 static tree
175 gimplify_cleanup_stmt (tree *stmt_p, int *walk_subtrees,
176 void *data ATTRIBUTE_UNUSED)
178 tree stmt = *stmt_p;
180 if (DECL_P (stmt) || TYPE_P (stmt))
181 *walk_subtrees = 0;
182 else if (TREE_CODE (stmt) == CLEANUP_STMT)
183 *stmt_p = build (CLEANUP_EH_ONLY (stmt) ? TRY_CATCH_EXPR : TRY_FINALLY_EXPR,
184 void_type_node, CLEANUP_BODY (stmt), CLEANUP_EXPR (stmt));
186 return NULL;
189 static void
190 gimplify_cleanup_stmts (tree fndecl)
192 walk_tree (&DECL_SAVED_TREE (fndecl), gimplify_cleanup_stmt, NULL, NULL);
195 /* Entry point for the tree lowering pass. Recursively scan
196 *STMT_P and convert it to a GIMPLE tree. */
199 c_gimplify_stmt (tree *stmt_p)
201 tree stmt = *stmt_p;
202 tree pre, post;
203 int saved_stmts_are_full_exprs_p;
204 location_t stmt_locus;
205 enum gimplify_status ret;
207 /* PRE and POST are tree chains that contain the side-effects of the
208 gimplified tree. For instance, given the expression tree:
210 c = ++a * 3 + b++;
212 After gimplification, the tree will be re-written as:
214 a = a + 1;
215 t1 = a * 3; <-- PRE
216 c = t1 + b;
217 b = b + 1; <-- POST */
219 /* Set up context appropriately for handling this statement. */
220 saved_stmts_are_full_exprs_p = stmts_are_full_exprs_p ();
221 prep_stmt (stmt);
222 stmt_locus = input_location;
224 pre = NULL_TREE;
225 post = NULL_TREE;
227 switch (TREE_CODE (stmt))
229 case FOR_STMT:
230 ret = gimplify_for_stmt (&stmt, &pre);
231 break;
233 case WHILE_STMT:
234 ret = gimplify_while_stmt (&stmt);
235 break;
237 case DO_STMT:
238 ret = gimplify_do_stmt (&stmt);
239 break;
241 case IF_STMT:
242 ret = gimplify_if_stmt (&stmt);
243 break;
245 case SWITCH_STMT:
246 ret = gimplify_switch_stmt (&stmt);
247 break;
249 case EXPR_STMT:
250 ret = gimplify_expr_stmt (&stmt);
251 break;
253 case RETURN_STMT:
254 ret = gimplify_return_stmt (&stmt);
255 break;
257 case DECL_STMT:
258 ret = gimplify_decl_stmt (&stmt);
259 break;
261 case CONTINUE_STMT:
262 stmt = build_bc_goto (bc_continue);
263 ret = GS_OK;
264 break;
266 case BREAK_STMT:
267 stmt = build_bc_goto (bc_break);
268 ret = GS_OK;
269 break;
271 default:
272 if (lang_gimplify_stmt && (*lang_gimplify_stmt) (&stmt))
274 ret = GS_OK;
275 break;
278 fprintf (stderr, "unhandled statement node in c_gimplify_stmt:\n");
279 debug_tree (stmt);
280 abort ();
281 break;
284 switch (ret)
286 case GS_ERROR:
287 goto cont;
288 case GS_OK:
289 gimplify_stmt (&stmt);
290 break;
291 case GS_ALL_DONE:
292 break;
293 default:
294 abort ();
297 /* PRE and POST now contain a list of statements for all the
298 side-effects in STMT. */
300 append_to_statement_list (stmt, &pre);
301 append_to_statement_list (post, &pre);
302 annotate_all_with_locus (&pre, stmt_locus);
303 cont:
304 /* Restore saved state. */
305 current_stmt_tree ()->stmts_are_full_exprs_p = saved_stmts_are_full_exprs_p;
306 *stmt_p = pre;
308 return GS_ALL_DONE;
311 static void
312 add_block_to_enclosing (tree block)
314 tree enclosing;
316 for (enclosing = gimple_current_bind_expr ();
317 enclosing; enclosing = TREE_CHAIN (enclosing))
318 if (BIND_EXPR_BLOCK (enclosing))
319 break;
321 enclosing = BIND_EXPR_BLOCK (enclosing);
322 BLOCK_SUBBLOCKS (enclosing) = chainon (BLOCK_SUBBLOCKS (enclosing), block);
325 /* Genericize a scope by creating a new BIND_EXPR.
326 BLOCK is either a BLOCK representing the scope or a chain of _DECLs.
327 In the latter case, we need to create a new BLOCK and add it to the
328 BLOCK_SUBBLOCKS of the enclosing block.
329 BODY is a chain of C _STMT nodes for the contents of the scope, to be
330 genericized. */
332 tree
333 c_build_bind_expr (tree block, tree body)
335 tree decls, bind;
337 if (block == NULL_TREE)
338 decls = NULL_TREE;
339 else if (TREE_CODE (block) == BLOCK)
340 decls = BLOCK_VARS (block);
341 else
343 decls = block;
344 if (DECL_ARTIFICIAL (decls))
345 block = NULL_TREE;
346 else
348 block = make_node (BLOCK);
349 BLOCK_VARS (block) = decls;
350 add_block_to_enclosing (block);
354 if (!body)
355 body = build_empty_stmt ();
356 if (decls || block)
358 bind = build (BIND_EXPR, void_type_node, decls, body, block);
359 TREE_SIDE_EFFECTS (bind) = 1;
361 else
362 bind = body;
364 return bind;
367 /* Gimplify an EXPR_STMT node.
369 STMT is the statement node.
371 PRE_P points to the list where side effects that must happen before
372 STMT should be stored.
374 POST_P points to the list where side effects that must happen after
375 STMT should be stored. */
377 static enum gimplify_status
378 gimplify_expr_stmt (tree *stmt_p)
380 tree stmt = EXPR_STMT_EXPR (*stmt_p);
382 if (stmt == error_mark_node)
383 stmt = NULL;
385 /* Gimplification of a statement expression will nullify the
386 statement if all its side effects are moved to *PRE_P and *POST_P.
388 In this case we will not want to emit the gimplified statement.
389 However, we may still want to emit a warning, so we do that before
390 gimplification. */
391 if (stmt && (extra_warnings || warn_unused_value))
393 if (!TREE_SIDE_EFFECTS (stmt))
395 if (!IS_EMPTY_STMT (stmt)
396 && !VOID_TYPE_P (TREE_TYPE (stmt))
397 && !TREE_NO_WARNING (stmt))
398 warning ("statement with no effect");
400 else if (warn_unused_value)
402 /* Kludge for 20020220-2.c. warn_if_unused_value shouldn't use
403 the stmt file location info. */
404 set_file_and_line_for_stmt (input_location);
405 warn_if_unused_value (stmt);
409 if (stmt == NULL_TREE)
410 stmt = build_empty_stmt ();
411 else if (stmts_are_full_exprs_p ())
412 stmt = build1 (CLEANUP_POINT_EXPR, void_type_node, stmt);
414 *stmt_p = stmt;
416 return GS_OK;
419 /* Begin a scope which can be exited by a break or continue statement. BC
420 indicates which.
422 Just creates a label and pushes it into the current context. */
424 static tree
425 begin_bc_block (enum bc_t bc)
427 tree label = create_artificial_label ();
428 DECL_NAME (label) = ctxp->bc_id[bc];
429 TREE_CHAIN (label) = ctxp->current_bc_label;
430 ctxp->current_bc_label = label;
431 return label;
434 /* Finish a scope which can be exited by a break or continue statement.
435 LABEL was returned from the most recent call to begin_bc_block. BODY is
436 an expression for the contents of the scope.
438 If we saw a break (or continue) in the scope, append a LABEL_EXPR to
439 body. Otherwise, just forget the label. */
441 static tree
442 finish_bc_block (tree label, tree body)
444 if (label != ctxp->current_bc_label)
445 abort ();
447 if (TREE_USED (label))
449 tree t, sl = NULL;
451 /* Clear the name so flow can delete the label. */
452 DECL_NAME (label) = NULL_TREE;
453 t = build1 (LABEL_EXPR, void_type_node, label);
455 append_to_statement_list (body, &sl);
456 append_to_statement_list (t, &sl);
457 body = sl;
460 ctxp->current_bc_label = TREE_CHAIN (label);
461 TREE_CHAIN (label) = NULL_TREE;
462 return body;
465 /* Build a GOTO_EXPR to represent a break or continue statement. BC
466 indicates which. */
468 static tree
469 build_bc_goto (enum bc_t bc)
471 tree label;
472 tree target_name = ctxp->bc_id[bc];
474 /* Look for the appropriate type of label. */
475 for (label = ctxp->current_bc_label;
476 label;
477 label = TREE_CHAIN (label))
478 if (DECL_NAME (label) == target_name)
479 break;
481 if (label == NULL_TREE)
483 if (bc == bc_break)
484 error ("break statement not within loop or switch");
485 else
486 error ("continue statement not within loop or switch");
488 return NULL_TREE;
491 /* Mark the label used for finish_bc_block. */
492 TREE_USED (label) = 1;
493 return build1 (GOTO_EXPR, void_type_node, label);
496 /* Build a generic representation of one of the C loop forms. COND is the
497 loop condition or NULL_TREE. BODY is the (possibly compound) statement
498 controlled by the loop. INCR is the increment expression of a for-loop,
499 or NULL_TREE. COND_IS_FIRST indicates whether the condition is
500 evaluated before the loop body as in while and for loops, or after the
501 loop body as in do-while loops. */
503 static tree
504 gimplify_c_loop (tree cond, tree body, tree incr, bool cond_is_first)
506 tree top, entry, exit, cont_block, break_block, stmt_list, t;
507 location_t stmt_locus;
509 stmt_locus = input_location;
511 /* Detect do { ... } while (0) and don't generate loop construct. */
512 if (!cond_is_first && cond && integer_zerop (cond))
513 top = cond = NULL;
514 else
516 /* If we use a LOOP_EXPR here, we have to feed the whole thing
517 back through the main gimplifier to lower it. Given that we
518 have to gimplify the loop body NOW so that we can resolve
519 break/continue stmts, seems easier to just expand to gotos. */
520 top = build1 (LABEL_EXPR, void_type_node, NULL_TREE);
523 break_block = begin_bc_block (bc_break);
525 if (top)
527 /* If we have an exit condition, then we build an IF with gotos either
528 out of the loop, or to the top of it. If there's no exit condition,
529 then we just build a jump back to the top. */
530 exit = build_and_jump (&LABEL_EXPR_LABEL (top));
531 if (cond)
533 t = build_bc_goto (bc_break);
534 exit = build (COND_EXPR, void_type_node, cond, exit, t);
535 exit = fold (exit);
536 gimplify_stmt (&exit);
539 else
540 exit = NULL_TREE;
542 cont_block = begin_bc_block (bc_continue);
544 gimplify_stmt (&body);
545 if (incr && stmts_are_full_exprs_p ())
546 incr = fold (build1 (CLEANUP_POINT_EXPR, void_type_node, incr));
547 gimplify_stmt (&incr);
549 body = finish_bc_block (cont_block, body);
551 stmt_list = NULL;
553 if (cond_is_first && cond)
555 entry = build1 (LABEL_EXPR, void_type_node, NULL_TREE);
556 t = build_and_jump (&LABEL_EXPR_LABEL (entry));
557 append_to_statement_list (t, &stmt_list);
559 else
560 entry = NULL_TREE;
562 append_to_statement_list (top, &stmt_list);
563 append_to_statement_list (body, &stmt_list);
564 append_to_statement_list (incr, &stmt_list);
565 append_to_statement_list (entry, &stmt_list);
566 append_to_statement_list (exit, &stmt_list);
568 annotate_all_with_locus (&stmt_list, stmt_locus);
570 return finish_bc_block (break_block, stmt_list);
573 /* Gimplify a FOR_STMT node. Move the stuff in the for-init-stmt into the
574 prequeue and hand off to gimplify_c_loop. */
576 static enum gimplify_status
577 gimplify_for_stmt (tree *stmt_p, tree *pre_p)
579 tree stmt = *stmt_p;
581 if (FOR_INIT_STMT (stmt))
583 gimplify_stmt (&FOR_INIT_STMT (stmt));
584 append_to_statement_list (FOR_INIT_STMT (stmt), pre_p);
586 *stmt_p = gimplify_c_loop (FOR_COND (stmt), FOR_BODY (stmt),
587 FOR_EXPR (stmt), 1);
589 return GS_ALL_DONE;
592 /* Gimplify a WHILE_STMT node. */
594 static enum gimplify_status
595 gimplify_while_stmt (tree *stmt_p)
597 tree stmt = *stmt_p;
598 *stmt_p = gimplify_c_loop (WHILE_COND (stmt), WHILE_BODY (stmt),
599 NULL_TREE, 1);
600 return GS_ALL_DONE;
603 /* Gimplify a DO_STMT node. */
605 static enum gimplify_status
606 gimplify_do_stmt (tree *stmt_p)
608 tree stmt = *stmt_p;
609 *stmt_p = gimplify_c_loop (DO_COND (stmt), DO_BODY (stmt),
610 NULL_TREE, 0);
611 return GS_ALL_DONE;
614 /* Genericize an IF_STMT by turning it into a COND_EXPR. */
616 static enum gimplify_status
617 gimplify_if_stmt (tree *stmt_p)
619 tree stmt, then_, else_;
621 stmt = *stmt_p;
622 then_ = THEN_CLAUSE (stmt);
623 else_ = ELSE_CLAUSE (stmt);
625 if (!then_)
626 then_ = build_empty_stmt ();
627 if (!else_)
628 else_ = build_empty_stmt ();
630 stmt = build (COND_EXPR, void_type_node, IF_COND (stmt), then_, else_);
631 *stmt_p = stmt;
633 return GS_OK;
636 /* Genericize a SWITCH_STMT by turning it into a SWITCH_EXPR. */
638 static enum gimplify_status
639 gimplify_switch_stmt (tree *stmt_p)
641 tree stmt = *stmt_p;
642 tree break_block, body;
643 location_t stmt_locus = input_location;
645 break_block = begin_bc_block (bc_break);
647 body = SWITCH_BODY (stmt);
648 if (!body)
649 body = build_empty_stmt ();
651 *stmt_p = build (SWITCH_EXPR, SWITCH_TYPE (stmt), SWITCH_COND (stmt),
652 body, NULL_TREE);
653 annotate_with_locus (*stmt_p, stmt_locus);
654 gimplify_stmt (stmt_p);
656 *stmt_p = finish_bc_block (break_block, *stmt_p);
657 return GS_ALL_DONE;
660 /* Genericize a RETURN_STMT by turning it into a RETURN_EXPR. */
662 static enum gimplify_status
663 gimplify_return_stmt (tree *stmt_p)
665 tree expr = RETURN_STMT_EXPR (*stmt_p);
666 expr = build1 (RETURN_EXPR, void_type_node, expr);
667 if (stmts_are_full_exprs_p ())
668 expr = build1 (CLEANUP_POINT_EXPR, void_type_node, expr);
669 *stmt_p = expr;
670 return GS_OK;
673 /* Gimplifies a DECL_STMT node *STMT_P by making any necessary allocation
674 and initialization explicit. */
676 static enum gimplify_status
677 gimplify_decl_stmt (tree *stmt_p)
679 tree stmt = *stmt_p;
680 tree decl = DECL_STMT_DECL (stmt);
681 tree pre = NULL_TREE;
682 tree post = NULL_TREE;
684 if (TREE_TYPE (decl) == error_mark_node)
686 *stmt_p = NULL;
687 return GS_ERROR;
690 if (TREE_CODE (decl) == TYPE_DECL)
692 tree type = TREE_TYPE (decl);
693 if (TYPE_SIZE_UNIT (type)
694 && !TREE_CONSTANT (TYPE_SIZE_UNIT (type)))
696 /* This is a variable-sized array type. Simplify its size. */
697 tree temp = TYPE_SIZE_UNIT (type);
698 gimplify_expr (&temp, &pre, &post, is_gimple_val, fb_rvalue);
702 if (TREE_CODE (decl) == VAR_DECL && !DECL_EXTERNAL (decl))
704 tree init = DECL_INITIAL (decl);
706 if (!TREE_CONSTANT (DECL_SIZE (decl)))
708 tree pt_type = build_pointer_type (TREE_TYPE (decl));
709 tree alloc, size;
711 /* This is a variable-sized decl. Simplify its size and mark it
712 for deferred expansion. Note that mudflap depends on the format
713 of the emitted code: see mx_register_decls(). */
715 size = get_initialized_tmp_var (DECL_SIZE_UNIT (decl), &pre, &post);
716 DECL_DEFER_OUTPUT (decl) = 1;
717 alloc = build_function_call_expr
718 (implicit_built_in_decls[BUILT_IN_STACK_ALLOC],
719 tree_cons (NULL_TREE,
720 build1 (ADDR_EXPR, pt_type, decl),
721 tree_cons (NULL_TREE, size, NULL_TREE)));
722 append_to_compound_expr (alloc, &pre);
725 if (init && init != error_mark_node)
727 if (!TREE_STATIC (decl))
729 /* Do not warn about int x = x; as it is a GCC extension
730 to turn off this warning but only if warn_init_self
731 is zero. */
732 if (init == decl && !warn_init_self)
733 TREE_NO_WARNING (decl) = 1;
735 DECL_INITIAL (decl) = NULL_TREE;
736 init = build (MODIFY_EXPR, void_type_node, decl, init);
737 if (stmts_are_full_exprs_p ())
738 init = build1 (CLEANUP_POINT_EXPR, void_type_node, init);
739 append_to_compound_expr (init, &pre);
741 else
743 /* We must still examine initializers for static variables
744 as they may contain a label address. */
745 walk_tree (&init, force_labels_r, NULL, NULL);
749 /* This decl isn't mentioned in the enclosing block, so add it to the
750 list of temps. FIXME it seems a bit of a kludge to say that
751 anonymous artificial vars aren't pushed, but everything else is. */
752 if (DECL_ARTIFICIAL (decl) && DECL_NAME (decl) == NULL_TREE)
753 gimple_add_tmp_var (decl);
756 append_to_compound_expr (post, &pre);
757 *stmt_p = pre;
758 return GS_OK;
761 /* Gimplification of expression trees. */
763 /* Gimplify a C99 compound literal expression. This just means adding the
764 DECL_STMT before the current EXPR_STMT and using its anonymous decl
765 instead. */
767 static enum gimplify_status
768 gimplify_compound_literal_expr (tree *expr_p)
770 tree decl_s = COMPOUND_LITERAL_EXPR_DECL_STMT (*expr_p);
771 tree decl = DECL_STMT_DECL (decl_s);
773 /* This decl isn't mentioned in the enclosing block, so add it to the
774 list of temps. FIXME it seems a bit of a kludge to say that
775 anonymous artificial vars aren't pushed, but everything else is. */
776 if (DECL_NAME (decl) == NULL_TREE)
777 gimple_add_tmp_var (decl);
779 gimplify_decl_stmt (&decl_s);
780 *expr_p = decl_s ? decl_s : decl;
781 return GS_OK;
784 /* Do C-specific gimplification. Args are as for gimplify_expr. */
787 c_gimplify_expr (tree *expr_p, tree *pre_p ATTRIBUTE_UNUSED,
788 tree *post_p ATTRIBUTE_UNUSED)
790 enum tree_code code = TREE_CODE (*expr_p);
792 if (STATEMENT_CODE_P (code))
793 return c_gimplify_stmt (expr_p);
795 switch (code)
797 case COMPOUND_LITERAL_EXPR:
798 return gimplify_compound_literal_expr (expr_p);
800 default:
801 return GS_UNHANDLED;