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
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
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
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
29 #include "coretypes.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"
47 #include "tree-dump.h"
48 #include "c-pretty-print.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_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
);
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
*);
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
);
102 static struct c_gimplify_ctx
104 /* For handling break and continue. */
105 tree current_bc_label
;
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");
122 if (!ctxp
|| ctxp
->current_bc_label
)
128 /* Gimplification of statement trees. */
130 /* Convert the tree representation of FNDECL from C frontend trees to
134 c_genericize (tree fndecl
)
137 int local_dump_flags
;
138 struct cgraph_node
*cgn
;
140 /* Dump the C-specific tree IR. */
141 dump_file
= dump_begin (TDI_original
, &local_dump_flags
);
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");
151 if (local_dump_flags
& TDF_RAW
)
152 dump_node (DECL_SAVED_TREE (fndecl
),
153 TDF_SLIM
| local_dump_flags
, dump_file
);
155 print_c_tree (dump_file
, DECL_SAVED_TREE (fndecl
));
156 fprintf (dump_file
, "\n");
158 dump_end (TDI_original
, dump_file
);
161 /* Go ahead and gimplify for now. */
163 gimplify_function_tree (fndecl
);
166 /* Dump the genericized tree IR. */
167 dump_function (TDI_generic
, fndecl
);
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
);
177 /* Entry point for the tree lowering pass. Recursively scan
178 *STMT_P and convert it to a GIMPLE tree. */
181 c_gimplify_stmt (tree
*stmt_p
)
184 tree outer_pre
= NULL_TREE
;
186 /* PRE and POST are tree chains that contain the side-effects of the
187 gimplified tree. For instance, given the expression tree:
191 After gimplification, the tree will be re-written as:
196 b = b + 1; <-- POST */
198 for (stmt
= *stmt_p
; stmt
&& stmt
!= error_mark_node
; stmt
= next
)
201 int saved_stmts_are_full_exprs_p
;
202 location_t stmt_locus
;
203 enum gimplify_status ret
;
205 /* Set up context appropriately for handling this statement. */
206 saved_stmts_are_full_exprs_p
= stmts_are_full_exprs_p ();
208 stmt_locus
= input_location
;
213 next
= TREE_CHAIN (stmt
);
215 switch (TREE_CODE (stmt
))
218 stmt
= COMPOUND_BODY (stmt
);
223 ret
= gimplify_block (&stmt
, &next
);
227 ret
= gimplify_for_stmt (&stmt
, &next
);
231 ret
= gimplify_while_stmt (&stmt
);
235 ret
= gimplify_do_stmt (&stmt
);
239 ret
= gimplify_if_stmt (&stmt
);
243 ret
= gimplify_switch_stmt (&stmt
);
247 ret
= gimplify_expr_stmt (&stmt
);
251 ret
= gimplify_return_stmt (&stmt
);
255 ret
= gimplify_decl_stmt (&stmt
);
259 stmt
= build1 (LABEL_EXPR
, void_type_node
, LABEL_STMT_LABEL (stmt
));
264 stmt
= build1 (GOTO_EXPR
, void_type_node
, GOTO_DESTINATION (stmt
));
270 tree label
= create_artificial_label ();
271 stmt
= build (CASE_LABEL_EXPR
, void_type_node
,
272 CASE_LOW (stmt
), CASE_HIGH (stmt
), label
);
278 stmt
= build_bc_goto (bc_continue
);
283 stmt
= build_bc_goto (bc_break
);
288 ret
= gimplify_cleanup (&stmt
, &next
);
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
);
304 if (lang_gimplify_stmt
&& (*lang_gimplify_stmt
) (&stmt
, &next
))
310 fprintf (stderr
, "unhandled statement node in c_gimplify_stmt:\n");
321 gimplify_stmt (&stmt
);
329 /* PRE and POST now contain a list of statements for all the
330 side-effects in STMT. */
332 append_to_statement_list (stmt
, &pre
);
333 append_to_statement_list (post
, &pre
);
334 annotate_all_with_locus (&pre
, stmt_locus
);
336 append_to_statement_list (pre
, &outer_pre
);
338 /* Restore saved state. */
339 current_stmt_tree ()->stmts_are_full_exprs_p
340 = saved_stmts_are_full_exprs_p
;
342 append_to_statement_list (stmt
, &outer_pre
);
349 add_block_to_enclosing (tree block
)
353 for (enclosing
= gimple_current_bind_expr ();
354 enclosing
; enclosing
= TREE_CHAIN (enclosing
))
355 if (BIND_EXPR_BLOCK (enclosing
))
358 enclosing
= BIND_EXPR_BLOCK (enclosing
);
359 BLOCK_SUBBLOCKS (enclosing
) = chainon (BLOCK_SUBBLOCKS (enclosing
), block
);
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
370 c_build_bind_expr (tree block
, tree body
)
374 if (block
== NULL_TREE
)
376 else if (TREE_CODE (block
) == BLOCK
)
377 decls
= BLOCK_VARS (block
);
381 if (DECL_ARTIFICIAL (decls
))
385 block
= make_node (BLOCK
);
386 BLOCK_VARS (block
) = decls
;
387 add_block_to_enclosing (block
);
392 body
= build_empty_stmt ();
394 bind
= build (BIND_EXPR
, void_type_node
, decls
, body
, block
);
395 TREE_SIDE_EFFECTS (bind
) = 1;
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
405 static enum gimplify_status
406 gimplify_block (tree
*stmt_p
, tree
*next_p
)
412 location_t stmt_locus
;
414 if (!SCOPE_BEGIN_P (*stmt_p
))
416 /* Can wind up mismatched with syntax errors. */
417 if (!errorcount
&& !sorrycount
)
423 block
= SCOPE_STMT_BLOCK (*stmt_p
);
425 /* Find the matching ending SCOPE_STMT. */
427 for (p
= &TREE_CHAIN (*stmt_p
);; p
= &TREE_CHAIN (*p
))
431 if (TREE_CODE (*p
) == SCOPE_STMT
)
433 if (SCOPE_BEGIN_P (*p
))
435 else if (--depth
== 0)
440 stmt_locus
= input_location
;
443 if (SCOPE_STMT_BLOCK (*p
) != block
)
446 stmt_locus
= *EXPR_LOCUS (*p
);
447 *next_p
= TREE_CHAIN (*p
);
452 /* Can wind up mismatched with syntax errors. */
453 if (!errorcount
&& !sorrycount
)
457 bind
= c_build_bind_expr (block
, TREE_CHAIN (*stmt_p
));
459 input_location
= stmt_locus
;
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
468 static enum gimplify_status
469 gimplify_cleanup (tree
*stmt_p
, tree
*next_p
)
472 tree body
= TREE_CHAIN (stmt
);
473 tree cleanup
= CLEANUP_EXPR (stmt
);
475 = (CLEANUP_EH_ONLY (stmt
) ? TRY_CATCH_EXPR
: TRY_FINALLY_EXPR
);
478 body
= build_empty_stmt ();
480 cleanup
= build_empty_stmt ();
482 *stmt_p
= build (code
, void_type_node
, body
, cleanup
);
488 /* Gimplify an EXPR_STMT node.
490 STMT is the statement node.
492 PRE_P points to the list where side effects that must happen before
493 STMT should be stored.
495 POST_P points to the list where side effects that must happen after
496 STMT should be stored. */
498 static enum gimplify_status
499 gimplify_expr_stmt (tree
*stmt_p
)
501 tree stmt
= EXPR_STMT_EXPR (*stmt_p
);
503 if (stmt
== error_mark_node
)
506 /* Gimplification of a statement expression will nullify the
507 statement if all its side effects are moved to *PRE_P and *POST_P.
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
512 if (stmt
&& (extra_warnings
|| warn_unused_value
))
514 if (!TREE_SIDE_EFFECTS (stmt
))
516 if (!IS_EMPTY_STMT (stmt
)
517 && !VOID_TYPE_P (TREE_TYPE (stmt
))
518 && !TREE_NO_WARNING (stmt
))
519 warning ("statement with no effect");
521 else if (warn_unused_value
)
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
);
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
);
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. */
545 gimplify_condition (tree
*cond_p
)
548 if (cond
&& TREE_CODE (cond
) == TREE_LIST
)
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
);
557 /* Begin a scope which can be exited by a break or continue statement. BC
560 Just creates a label and pushes it into the current context. */
563 begin_bc_block (enum bc_t bc
)
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
;
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.
576 If we saw a break (or continue) in the scope, append a LABEL_EXPR to
577 body. Otherwise, just forget the label. */
580 finish_bc_block (tree label
, tree body
)
582 if (label
!= ctxp
->current_bc_label
)
585 if (TREE_USED (label
))
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
);
593 append_to_statement_list (body
, &sl
);
594 append_to_statement_list (t
, &sl
);
598 ctxp
->current_bc_label
= TREE_CHAIN (label
);
599 TREE_CHAIN (label
) = NULL_TREE
;
603 /* Build a GOTO_EXPR to represent a break or continue statement. BC
607 build_bc_goto (enum bc_t bc
)
610 tree target_name
= ctxp
->bc_id
[bc
];
612 /* Look for the appropriate type of label. */
613 for (label
= ctxp
->current_bc_label
;
615 label
= TREE_CHAIN (label
))
616 if (DECL_NAME (label
) == target_name
)
619 if (label
== NULL_TREE
)
622 error ("break statement not within loop or switch");
624 error ("continue statement not within loop or switch");
629 /* Mark the label used for finish_bc_block. */
630 TREE_USED (label
) = 1;
631 return build1 (GOTO_EXPR
, void_type_node
, label
);
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. */
642 gimplify_c_loop (tree cond
, tree body
, tree incr
, bool cond_is_first
)
644 tree top
, entry
, exit
, cont_block
, break_block
, stmt_list
, t
;
645 location_t stmt_locus
;
647 stmt_locus
= input_location
;
649 /* Detect do { ... } while (0) and don't generate loop construct. */
650 if (!cond_is_first
&& cond
&& integer_zerop (cond
))
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
);
661 break_block
= begin_bc_block (bc_break
);
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
));
671 gimplify_condition (&cond
);
672 t
= build_bc_goto (bc_break
);
673 exit
= build (COND_EXPR
, void_type_node
, cond
, exit
, t
);
675 gimplify_stmt (&exit
);
681 cont_block
= begin_bc_block (bc_continue
);
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
);
688 body
= finish_bc_block (cont_block
, body
);
692 if (cond_is_first
&& cond
)
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
);
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
);
707 annotate_all_with_locus (&stmt_list
, stmt_locus
);
709 return finish_bc_block (break_block
, stmt_list
);
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. */
715 static enum gimplify_status
716 gimplify_for_stmt (tree
*stmt_p
, tree
*next_p
)
719 tree init
= FOR_INIT_STMT (stmt
);
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
);
729 *next_p
= TREE_CHAIN (stmt
);
730 TREE_CHAIN (stmt
) = NULL_TREE
;
731 c_gimplify_stmt (stmt_p
);
734 *stmt_p
= gimplify_c_loop (FOR_COND (stmt
), FOR_BODY (stmt
),
740 /* Gimplify a WHILE_STMT node. */
742 static enum gimplify_status
743 gimplify_while_stmt (tree
*stmt_p
)
746 *stmt_p
= gimplify_c_loop (WHILE_COND (stmt
), WHILE_BODY (stmt
),
751 /* Gimplify a DO_STMT node. */
753 static enum gimplify_status
754 gimplify_do_stmt (tree
*stmt_p
)
757 *stmt_p
= gimplify_c_loop (DO_COND (stmt
), DO_BODY (stmt
),
762 /* Genericize an IF_STMT by turning it into a COND_EXPR. */
764 static enum gimplify_status
765 gimplify_if_stmt (tree
*stmt_p
)
767 tree stmt
, then_
, else_
;
771 then_
= THEN_CLAUSE (stmt
);
772 else_
= ELSE_CLAUSE (stmt
);
775 then_
= build_empty_stmt ();
777 else_
= build_empty_stmt ();
779 stmt
= build (COND_EXPR
, void_type_node
, IF_COND (stmt
), then_
, else_
);
780 gimplify_condition (& TREE_OPERAND (stmt
, 0));
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_
))
788 stmt_p
= &COND_EXPR_ELSE (stmt
);
797 /* Genericize a SWITCH_STMT by turning it into a SWITCH_EXPR. */
799 static enum gimplify_status
800 gimplify_switch_stmt (tree
*stmt_p
)
803 tree break_block
, body
;
804 location_t stmt_locus
= input_location
;
806 break_block
= begin_bc_block (bc_break
);
808 gimplify_condition (&SWITCH_COND (stmt
));
810 body
= SWITCH_BODY (stmt
);
812 body
= build_empty_stmt ();
814 *stmt_p
= build (SWITCH_EXPR
, SWITCH_TYPE (stmt
), SWITCH_COND (stmt
),
816 annotate_with_locus (*stmt_p
, stmt_locus
);
817 gimplify_stmt (stmt_p
);
819 *stmt_p
= finish_bc_block (break_block
, *stmt_p
);
823 /* Genericize a RETURN_STMT by turning it into a RETURN_EXPR. */
825 static enum gimplify_status
826 gimplify_return_stmt (tree
*stmt_p
)
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
);
836 /* Gimplifies a DECL_STMT node T.
838 If a declaration V has an initial value I, create an expression 'V = I'
839 and insert it after the DECL_STMT.
841 PRE_P is a queue for effects that should happen before the DECL_STMT.
843 MID_P is a queue for effects that should happen after the DECL_STMT,
844 but before uses of the initialized decl.
846 POST_P is a queue for effects that should happen after uses of the
849 Usually these last two will be the same, but they may need to be
850 different if the DECL_STMT is somehow embedded in an expression. */
852 static enum gimplify_status
853 gimplify_decl_stmt (tree
*stmt_p
)
856 tree decl
= DECL_STMT_DECL (stmt
);
857 tree pre
= NULL_TREE
;
858 tree post
= NULL_TREE
;
860 if (TREE_TYPE (decl
) == error_mark_node
)
866 if (TREE_CODE (decl
) == TYPE_DECL
)
868 tree type
= TREE_TYPE (decl
);
869 if (TYPE_SIZE_UNIT (type
)
870 && !TREE_CONSTANT (TYPE_SIZE_UNIT (type
)))
872 /* This is a variable-sized array type. Simplify its size. */
873 tree temp
= TYPE_SIZE_UNIT (type
);
874 gimplify_expr (&temp
, &pre
, &post
, is_gimple_val
, fb_rvalue
);
878 if (TREE_CODE (decl
) == VAR_DECL
&& !DECL_EXTERNAL (decl
))
880 tree init
= DECL_INITIAL (decl
);
882 if (!TREE_CONSTANT (DECL_SIZE (decl
)))
884 tree pt_type
= build_pointer_type (TREE_TYPE (decl
));
887 /* This is a variable-sized decl. Simplify its size and mark it
888 for deferred expansion. Note that mudflap depends on the format
889 of the emitted code: see mx_register_decls(). */
891 size
= get_initialized_tmp_var (DECL_SIZE_UNIT (decl
), &pre
, &post
);
892 DECL_DEFER_OUTPUT (decl
) = 1;
893 alloc
= build_function_call_expr
894 (implicit_built_in_decls
[BUILT_IN_STACK_ALLOC
],
895 tree_cons (NULL_TREE
,
896 build1 (ADDR_EXPR
, pt_type
, decl
),
897 tree_cons (NULL_TREE
, size
, NULL_TREE
)));
898 append_to_compound_expr (alloc
, &pre
);
901 if (init
&& init
!= error_mark_node
)
903 if (!TREE_STATIC (decl
))
905 /* Do not warn about int x = x; as it is a GCC extension
906 to turn off this warning but only if warn_init_self
908 if (init
== decl
&& !warn_init_self
)
909 TREE_NO_WARNING (decl
) = 1;
911 DECL_INITIAL (decl
) = NULL_TREE
;
912 init
= build (MODIFY_EXPR
, void_type_node
, decl
, init
);
913 if (stmts_are_full_exprs_p ())
914 init
= build1 (CLEANUP_POINT_EXPR
, void_type_node
, init
);
915 append_to_compound_expr (init
, &pre
);
919 /* We must still examine initializers for static variables
920 as they may contain a label address. */
921 walk_tree (&init
, force_labels_r
, NULL
, NULL
);
925 /* This decl isn't mentioned in the enclosing block, so add it to the
926 list of temps. FIXME it seems a bit of a kludge to say that
927 anonymous artificial vars aren't pushed, but everything else is. */
928 if (DECL_ARTIFICIAL (decl
) && DECL_NAME (decl
) == NULL_TREE
)
929 gimple_add_tmp_var (decl
);
932 append_to_compound_expr (post
, &pre
);
937 /* Gimplification of expression trees. */
939 /* Gimplify a C99 compound literal expression. This just means adding the
940 DECL_STMT before the current EXPR_STMT and using its anonymous decl
943 static enum gimplify_status
944 gimplify_compound_literal_expr (tree
*expr_p
)
946 tree decl_s
= COMPOUND_LITERAL_EXPR_DECL_STMT (*expr_p
);
947 tree decl
= DECL_STMT_DECL (decl_s
);
949 /* This decl isn't mentioned in the enclosing block, so add it to the
950 list of temps. FIXME it seems a bit of a kludge to say that
951 anonymous artificial vars aren't pushed, but everything else is. */
952 if (DECL_NAME (decl
) == NULL_TREE
)
953 gimple_add_tmp_var (decl
);
955 gimplify_decl_stmt (&decl_s
);
956 *expr_p
= decl_s
? decl_s
: decl
;
960 /* Do C-specific gimplification. Args are as for gimplify_expr. */
963 c_gimplify_expr (tree
*expr_p
, tree
*pre_p ATTRIBUTE_UNUSED
,
964 tree
*post_p ATTRIBUTE_UNUSED
)
966 enum tree_code code
= TREE_CODE (*expr_p
);
968 if (STATEMENT_CODE_P (code
))
969 return c_gimplify_stmt (expr_p
);
973 case COMPOUND_LITERAL_EXPR
:
974 return gimplify_compound_literal_expr (expr_p
);
977 return gimplify_stmt_expr (expr_p
);
984 /* Returns the final EXPR_STMT which represents the return value of a
985 STMT_EXPR, or NULL_TREE if none. */
988 stmt_expr_last_stmt (tree stmt_expr
)
990 tree body
= STMT_EXPR_STMT (stmt_expr
);
991 tree last_stmt
, substmt
;
993 /* Splice the last expression out of the STMT chain. */
994 last_stmt
= NULL_TREE
;
995 for (substmt
= COMPOUND_BODY (body
); substmt
;
996 substmt
= TREE_CHAIN (substmt
))
997 if (TREE_CODE (substmt
) != SCOPE_STMT
)
1000 if (last_stmt
== NULL_TREE
1001 || TREE_CODE (last_stmt
) != EXPR_STMT
1002 || (TREE_TYPE (last_stmt
)
1003 && VOID_TYPE_P (TREE_TYPE (last_stmt
))))
1006 if (last_stmt
&& EXPR_LOCUS (last_stmt
))
1007 loc
= *EXPR_LOCUS (last_stmt
);
1008 else if (EXPR_LOCUS (stmt_expr
))
1009 loc
= *EXPR_LOCUS (stmt_expr
);
1011 loc
= input_location
;
1012 warning ("%Hstatement-expressions should end with a "
1013 "non-void expression", &loc
);
1014 last_stmt
= NULL_TREE
;
1017 #if defined ENABLE_CHECKING
1018 if (last_stmt
&& !is_last_stmt_of_scope (last_stmt
))
1025 /* Gimplify a STMT_EXPR. EXPR_P points to the expression to gimplify.
1026 After gimplification, if the STMT_EXPR returns a value, EXPR_P will
1027 point to a new temporary that holds that value; otherwise it will be
1030 PRE_P points to the list where side effects that must happen before
1031 *EXPR_P should be stored. */
1033 static enum gimplify_status
1034 gimplify_stmt_expr (tree
*expr_p
)
1036 tree body
= STMT_EXPR_STMT (*expr_p
);
1038 if (VOID_TYPE_P (TREE_TYPE (*expr_p
)))
1041 return c_gimplify_stmt (expr_p
);
1045 tree last_stmt
= stmt_expr_last_stmt (*expr_p
);
1046 tree last_expr
= NULL_TREE
;
1050 last_expr
= EXPR_STMT_EXPR (last_stmt
);
1052 if (stmts_are_full_exprs_p ())
1053 last_expr
= build1 (CLEANUP_POINT_EXPR
, TREE_TYPE (last_expr
),
1055 EXPR_STMT_EXPR (last_stmt
) = NULL_TREE
;
1058 /* Genericize the block. */
1059 c_gimplify_stmt (&body
);
1061 /* Now retrofit that last expression into the BIND_EXPR. */
1066 if (!STMT_EXPR_NO_SCOPE (*expr_p
))
1068 /* Our BIND_EXPR will always be hidden within
1069 a STATEMENT_LIST. Discard that. */
1070 body
= expr_first (body
);
1071 sub_p
= &BIND_EXPR_BODY (body
);
1073 /* Append the last expression to the end of the BIND_EXPR.
1074 We'll now re-process this, and let voidify_wrapper_expr
1076 append_to_statement_list_force (last_expr
, sub_p
);
1077 TREE_TYPE (body
) = TREE_TYPE (last_expr
);
1080 append_to_compound_expr (last_expr
, &body
);
1088 /* Code generation. */
1090 /* Miscellaneous helpers. */
1092 #if defined ENABLE_CHECKING
1093 /* Return nonzero if STMT is the last statement of its scope. */
1096 is_last_stmt_of_scope (tree stmt
)
1098 return (TREE_CHAIN (stmt
) == NULL_TREE
1099 || (TREE_CODE (TREE_CHAIN (stmt
)) == SCOPE_STMT
1100 && SCOPE_END_P (TREE_CHAIN (stmt
))));