1 /* C++-specific tree lowering bits; see also c-gimplify.c and tree-gimple.c.
3 Copyright (C) 2002, 2003, 2004, 2005 Free Software Foundation, Inc.
4 Contributed by Jason Merrill <jason@redhat.com>
6 This file is part of GCC.
8 GCC is free software; you can redistribute it and/or modify it under
9 the terms of the GNU General Public License as published by the Free
10 Software Foundation; either version 2, or (at your option) any later
13 GCC is distributed in the hope that it will be useful, but WITHOUT ANY
14 WARRANTY; without even the implied warranty of MERCHANTABILITY or
15 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
18 You should have received a copy of the GNU General Public License
19 along with GCC; see the file COPYING. If not, write to the Free
20 Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA
25 #include "coretypes.h"
31 #include "tree-gimple.h"
33 #include "pointer-set.h"
36 /* Local declarations. */
38 enum bc_t
{ bc_break
= 0, bc_continue
= 1 };
40 static struct cp_gimplify_ctx
42 /* Stack of labels which are targets for "break" or "continue",
43 linked through TREE_CHAIN. */
44 tree current_label
[2];
51 ctxp
= ((struct cp_gimplify_ctx
*)
52 xcalloc (1, sizeof (struct cp_gimplify_ctx
)));
59 && !ctxp
->current_label
[0]
60 && !ctxp
->current_label
[1]);
65 /* Begin a scope which can be exited by a break or continue statement. BC
68 Just creates a label and pushes it into the current context. */
71 begin_bc_block (enum bc_t bc
)
73 tree label
= create_artificial_label ();
74 TREE_CHAIN (label
) = ctxp
->current_label
[bc
];
75 ctxp
->current_label
[bc
] = label
;
79 /* Finish a scope which can be exited by a break or continue statement.
80 LABEL was returned from the most recent call to begin_bc_block. BODY is
81 an expression for the contents of the scope.
83 If we saw a break (or continue) in the scope, append a LABEL_EXPR to
84 body. Otherwise, just forget the label. */
87 finish_bc_block (enum bc_t bc
, tree label
, tree body
)
89 gcc_assert (label
== ctxp
->current_label
[bc
]);
91 if (TREE_USED (label
))
95 t
= build1 (LABEL_EXPR
, void_type_node
, label
);
97 append_to_statement_list (body
, &sl
);
98 append_to_statement_list (t
, &sl
);
102 ctxp
->current_label
[bc
] = TREE_CHAIN (label
);
103 TREE_CHAIN (label
) = NULL_TREE
;
107 /* Build a GOTO_EXPR to represent a break or continue statement. BC
111 build_bc_goto (enum bc_t bc
)
113 tree label
= ctxp
->current_label
[bc
];
115 if (label
== NULL_TREE
)
118 error ("break statement not within loop or switch");
120 error ("continue statement not within loop or switch");
125 /* Mark the label used for finish_bc_block. */
126 TREE_USED (label
) = 1;
127 return build1 (GOTO_EXPR
, void_type_node
, label
);
130 /* Genericize a TRY_BLOCK. */
133 genericize_try_block (tree
*stmt_p
)
135 tree body
= TRY_STMTS (*stmt_p
);
136 tree cleanup
= TRY_HANDLERS (*stmt_p
);
138 gimplify_stmt (&body
);
140 if (CLEANUP_P (*stmt_p
))
141 /* A cleanup is an expression, so it doesn't need to be genericized. */;
143 gimplify_stmt (&cleanup
);
145 *stmt_p
= build2 (TRY_CATCH_EXPR
, void_type_node
, body
, cleanup
);
148 /* Genericize a HANDLER by converting to a CATCH_EXPR. */
151 genericize_catch_block (tree
*stmt_p
)
153 tree type
= HANDLER_TYPE (*stmt_p
);
154 tree body
= HANDLER_BODY (*stmt_p
);
156 gimplify_stmt (&body
);
158 /* FIXME should the caught type go in TREE_TYPE? */
159 *stmt_p
= build2 (CATCH_EXPR
, void_type_node
, type
, body
);
162 /* Genericize an EH_SPEC_BLOCK by converting it to a
163 TRY_CATCH_EXPR/EH_FILTER_EXPR pair. */
166 genericize_eh_spec_block (tree
*stmt_p
)
168 tree body
= EH_SPEC_STMTS (*stmt_p
);
169 tree allowed
= EH_SPEC_RAISES (*stmt_p
);
170 tree failure
= build_call (call_unexpected_node
,
171 tree_cons (NULL_TREE
, build_exc_ptr (),
173 gimplify_stmt (&body
);
175 *stmt_p
= gimple_build_eh_filter (body
, allowed
, failure
);
178 /* Genericize an IF_STMT by turning it into a COND_EXPR. */
181 gimplify_if_stmt (tree
*stmt_p
)
183 tree stmt
, cond
, then_
, else_
;
186 cond
= IF_COND (stmt
);
187 then_
= THEN_CLAUSE (stmt
);
188 else_
= ELSE_CLAUSE (stmt
);
191 then_
= build_empty_stmt ();
193 else_
= build_empty_stmt ();
195 if (integer_nonzerop (cond
) && !TREE_SIDE_EFFECTS (else_
))
197 else if (integer_zerop (cond
) && !TREE_SIDE_EFFECTS (then_
))
200 stmt
= build3 (COND_EXPR
, void_type_node
, cond
, then_
, else_
);
204 /* Build a generic representation of one of the C loop forms. COND is the
205 loop condition or NULL_TREE. BODY is the (possibly compound) statement
206 controlled by the loop. INCR is the increment expression of a for-loop,
207 or NULL_TREE. COND_IS_FIRST indicates whether the condition is
208 evaluated before the loop body as in while and for loops, or after the
209 loop body as in do-while loops. */
212 gimplify_cp_loop (tree cond
, tree body
, tree incr
, bool cond_is_first
)
214 tree top
, entry
, exit
, cont_block
, break_block
, stmt_list
, t
;
215 location_t stmt_locus
;
217 stmt_locus
= input_location
;
218 stmt_list
= NULL_TREE
;
221 break_block
= begin_bc_block (bc_break
);
222 cont_block
= begin_bc_block (bc_continue
);
224 /* If condition is zero don't generate a loop construct. */
225 if (cond
&& integer_zerop (cond
))
231 t
= build_bc_goto (bc_break
);
232 append_to_statement_list (t
, &stmt_list
);
237 /* If we use a LOOP_EXPR here, we have to feed the whole thing
238 back through the main gimplifier to lower it. Given that we
239 have to gimplify the loop body NOW so that we can resolve
240 break/continue stmts, seems easier to just expand to gotos. */
241 top
= build1 (LABEL_EXPR
, void_type_node
, NULL_TREE
);
243 /* If we have an exit condition, then we build an IF with gotos either
244 out of the loop, or to the top of it. If there's no exit condition,
245 then we just build a jump back to the top. */
246 exit
= build_and_jump (&LABEL_EXPR_LABEL (top
));
247 if (cond
&& !integer_nonzerop (cond
))
249 t
= build_bc_goto (bc_break
);
250 exit
= build3 (COND_EXPR
, void_type_node
, cond
, exit
, t
);
252 gimplify_stmt (&exit
);
258 entry
= build1 (LABEL_EXPR
, void_type_node
, NULL_TREE
);
259 t
= build_and_jump (&LABEL_EXPR_LABEL (entry
));
262 t
= build_bc_goto (bc_continue
);
263 append_to_statement_list (t
, &stmt_list
);
268 gimplify_stmt (&body
);
269 gimplify_stmt (&incr
);
271 body
= finish_bc_block (bc_continue
, cont_block
, body
);
273 append_to_statement_list (top
, &stmt_list
);
274 append_to_statement_list (body
, &stmt_list
);
275 append_to_statement_list (incr
, &stmt_list
);
276 append_to_statement_list (entry
, &stmt_list
);
277 append_to_statement_list (exit
, &stmt_list
);
279 annotate_all_with_locus (&stmt_list
, stmt_locus
);
281 return finish_bc_block (bc_break
, break_block
, stmt_list
);
284 /* Gimplify a FOR_STMT node. Move the stuff in the for-init-stmt into the
285 prequeue and hand off to gimplify_cp_loop. */
288 gimplify_for_stmt (tree
*stmt_p
, tree
*pre_p
)
292 if (FOR_INIT_STMT (stmt
))
293 gimplify_and_add (FOR_INIT_STMT (stmt
), pre_p
);
295 *stmt_p
= gimplify_cp_loop (FOR_COND (stmt
), FOR_BODY (stmt
),
299 /* Gimplify a WHILE_STMT node. */
302 gimplify_while_stmt (tree
*stmt_p
)
305 *stmt_p
= gimplify_cp_loop (WHILE_COND (stmt
), WHILE_BODY (stmt
),
309 /* Gimplify a DO_STMT node. */
312 gimplify_do_stmt (tree
*stmt_p
)
315 *stmt_p
= gimplify_cp_loop (DO_COND (stmt
), DO_BODY (stmt
),
319 /* Genericize a SWITCH_STMT by turning it into a SWITCH_EXPR. */
322 gimplify_switch_stmt (tree
*stmt_p
)
325 tree break_block
, body
;
326 location_t stmt_locus
= input_location
;
328 break_block
= begin_bc_block (bc_break
);
330 body
= SWITCH_STMT_BODY (stmt
);
332 body
= build_empty_stmt ();
334 *stmt_p
= build3 (SWITCH_EXPR
, SWITCH_STMT_TYPE (stmt
),
335 SWITCH_STMT_COND (stmt
), body
, NULL_TREE
);
336 SET_EXPR_LOCATION (*stmt_p
, stmt_locus
);
337 gimplify_stmt (stmt_p
);
339 *stmt_p
= finish_bc_block (bc_break
, break_block
, *stmt_p
);
342 /* Gimplify an EXPR_STMT node. */
345 gimplify_expr_stmt (tree
*stmt_p
)
347 tree stmt
= EXPR_STMT_EXPR (*stmt_p
);
349 if (stmt
== error_mark_node
)
352 /* Gimplification of a statement expression will nullify the
353 statement if all its side effects are moved to *PRE_P and *POST_P.
355 In this case we will not want to emit the gimplified statement.
356 However, we may still want to emit a warning, so we do that before
358 if (stmt
&& (extra_warnings
|| warn_unused_value
))
360 if (!TREE_SIDE_EFFECTS (stmt
))
362 if (!IS_EMPTY_STMT (stmt
)
363 && !VOID_TYPE_P (TREE_TYPE (stmt
))
364 && !TREE_NO_WARNING (stmt
))
365 warning (0, "statement with no effect");
367 else if (warn_unused_value
)
368 warn_if_unused_value (stmt
, input_location
);
371 if (stmt
== NULL_TREE
)
372 stmt
= alloc_stmt_list ();
377 /* Gimplify initialization from an AGGR_INIT_EXPR. */
380 cp_gimplify_init_expr (tree
*expr_p
, tree
*pre_p
, tree
*post_p
)
382 tree from
= TREE_OPERAND (*expr_p
, 1);
383 tree to
= TREE_OPERAND (*expr_p
, 0);
386 /* If we are initializing something from a TARGET_EXPR, strip the
387 TARGET_EXPR and initialize it directly. */
388 /* What about code that pulls out the temp and uses it elsewhere? I
389 think that such code never uses the TARGET_EXPR as an initializer. If
390 I'm wrong, we'll abort because the temp won't have any RTL. In that
391 case, I guess we'll need to replace references somehow. */
392 if (TREE_CODE (from
) == TARGET_EXPR
)
393 from
= TARGET_EXPR_INITIAL (from
);
394 if (TREE_CODE (from
) == CLEANUP_POINT_EXPR
)
395 from
= TREE_OPERAND (from
, 0);
397 /* Look through any COMPOUND_EXPRs. */
398 sub
= expr_last (from
);
400 /* If we are initializing from an AGGR_INIT_EXPR, drop the INIT_EXPR and
401 replace the slot operand with our target.
403 Should we add a target parm to gimplify_expr instead? No, as in this
404 case we want to replace the INIT_EXPR. */
405 if (TREE_CODE (sub
) == AGGR_INIT_EXPR
)
407 gimplify_expr (&to
, pre_p
, post_p
, is_gimple_lvalue
, fb_lvalue
);
408 TREE_OPERAND (sub
, 2) = to
;
411 /* The initialization is now a side-effect, so the container can
414 TREE_TYPE (from
) = void_type_node
;
418 /* Gimplify a MUST_NOT_THROW_EXPR. */
421 gimplify_must_not_throw_expr (tree
*expr_p
, tree
*pre_p
)
424 tree temp
= voidify_wrapper_expr (stmt
, NULL
);
425 tree body
= TREE_OPERAND (stmt
, 0);
427 gimplify_stmt (&body
);
429 stmt
= gimple_build_eh_filter (body
, NULL_TREE
,
430 build_call (terminate_node
, NULL_TREE
));
434 append_to_statement_list (stmt
, pre_p
);
441 /* Do C++-specific gimplification. Args are as for gimplify_expr. */
444 cp_gimplify_expr (tree
*expr_p
, tree
*pre_p
, tree
*post_p
)
446 int saved_stmts_are_full_exprs_p
= 0;
447 enum tree_code code
= TREE_CODE (*expr_p
);
448 enum gimplify_status ret
;
450 if (STATEMENT_CODE_P (code
))
452 saved_stmts_are_full_exprs_p
= stmts_are_full_exprs_p ();
453 current_stmt_tree ()->stmts_are_full_exprs_p
454 = STMT_IS_FULL_EXPR_P (*expr_p
);
460 *expr_p
= cplus_expand_constant (*expr_p
);
465 simplify_aggr_init_expr (expr_p
);
470 /* FIXME communicate throw type to backend, probably by moving
471 THROW_EXPR into ../tree.def. */
472 *expr_p
= TREE_OPERAND (*expr_p
, 0);
476 case MUST_NOT_THROW_EXPR
:
477 gimplify_must_not_throw_expr (expr_p
, pre_p
);
483 cp_gimplify_init_expr (expr_p
, pre_p
, post_p
);
487 case EMPTY_CLASS_EXPR
:
488 /* We create an INTEGER_CST with RECORD_TYPE and value zero. */
489 *expr_p
= build_int_cst (TREE_TYPE (*expr_p
), 0);
494 *expr_p
= BASELINK_FUNCTIONS (*expr_p
);
499 genericize_try_block (expr_p
);
504 genericize_catch_block (expr_p
);
509 genericize_eh_spec_block (expr_p
);
514 /* Just ignore for now. Eventually we will want to pass this on to
516 *expr_p
= build_empty_stmt ();
521 gimplify_if_stmt (expr_p
);
526 gimplify_for_stmt (expr_p
, pre_p
);
531 gimplify_while_stmt (expr_p
);
536 gimplify_do_stmt (expr_p
);
541 gimplify_switch_stmt (expr_p
);
546 *expr_p
= build_bc_goto (bc_continue
);
551 *expr_p
= build_bc_goto (bc_break
);
556 gimplify_expr_stmt (expr_p
);
560 case UNARY_PLUS_EXPR
:
562 tree arg
= TREE_OPERAND (*expr_p
, 0);
563 tree type
= TREE_TYPE (*expr_p
);
564 *expr_p
= (TREE_TYPE (arg
) != type
) ? fold_convert (type
, arg
)
571 ret
= c_gimplify_expr (expr_p
, pre_p
, post_p
);
575 /* Restore saved state. */
576 if (STATEMENT_CODE_P (code
))
577 current_stmt_tree ()->stmts_are_full_exprs_p
578 = saved_stmts_are_full_exprs_p
;
584 is_invisiref_parm (tree t
)
586 return ((TREE_CODE (t
) == PARM_DECL
|| TREE_CODE (t
) == RESULT_DECL
)
587 && DECL_BY_REFERENCE (t
));
590 /* Perform any pre-gimplification lowering of C++ front end trees to
594 cp_genericize_r (tree
*stmt_p
, int *walk_subtrees
, void *data
)
597 struct pointer_set_t
*p_set
= (struct pointer_set_t
*) data
;
599 if (is_invisiref_parm (stmt
))
601 *stmt_p
= convert_from_reference (stmt
);
606 /* Other than invisiref parms, don't walk the same tree twice. */
607 if (pointer_set_contains (p_set
, stmt
))
613 if (TREE_CODE (stmt
) == ADDR_EXPR
614 && is_invisiref_parm (TREE_OPERAND (stmt
, 0)))
616 *stmt_p
= convert (TREE_TYPE (stmt
), TREE_OPERAND (stmt
, 0));
619 else if (TREE_CODE (stmt
) == RETURN_EXPR
620 && TREE_OPERAND (stmt
, 0)
621 && is_invisiref_parm (TREE_OPERAND (stmt
, 0)))
622 /* Don't dereference an invisiref RESULT_DECL inside a RETURN_EXPR. */
624 else if (IS_TYPE_OR_DECL_P (stmt
))
627 /* Due to the way voidify_wrapper_expr is written, we don't get a chance
628 to lower this construct before scanning it, so we need to lower these
629 before doing anything else. */
630 else if (TREE_CODE (stmt
) == CLEANUP_STMT
)
631 *stmt_p
= build2 (CLEANUP_EH_ONLY (stmt
) ? TRY_CATCH_EXPR
635 CLEANUP_EXPR (stmt
));
637 pointer_set_insert (p_set
, *stmt_p
);
643 cp_genericize (tree fndecl
)
646 struct pointer_set_t
*p_set
;
648 /* Fix up the types of parms passed by invisible reference. */
649 for (t
= DECL_ARGUMENTS (fndecl
); t
; t
= TREE_CHAIN (t
))
650 if (TREE_ADDRESSABLE (TREE_TYPE (t
)))
652 /* If a function's arguments are copied to create a thunk,
653 then DECL_BY_REFERENCE will be set -- but the type of the
654 argument will be a pointer type, so we will never get
656 gcc_assert (!DECL_BY_REFERENCE (t
));
657 gcc_assert (DECL_ARG_TYPE (t
) != TREE_TYPE (t
));
658 TREE_TYPE (t
) = DECL_ARG_TYPE (t
);
659 DECL_BY_REFERENCE (t
) = 1;
660 TREE_ADDRESSABLE (t
) = 0;
664 /* Do the same for the return value. */
665 if (TREE_ADDRESSABLE (TREE_TYPE (DECL_RESULT (fndecl
))))
667 t
= DECL_RESULT (fndecl
);
668 TREE_TYPE (t
) = build_reference_type (TREE_TYPE (t
));
669 DECL_BY_REFERENCE (t
) = 1;
670 TREE_ADDRESSABLE (t
) = 0;
674 /* If we're a clone, the body is already GIMPLE. */
675 if (DECL_CLONED_FUNCTION_P (fndecl
))
678 /* We do want to see every occurrence of the parms, so we can't just use
679 walk_tree's hash functionality. */
680 p_set
= pointer_set_create ();
681 walk_tree (&DECL_SAVED_TREE (fndecl
), cp_genericize_r
, p_set
, NULL
);
682 pointer_set_destroy (p_set
);
684 /* Do everything else. */
686 c_genericize (fndecl
);