Merged trunk at revision 161680 into branch.
[official-gcc.git] / gcc / cp / cp-gimplify.c
blobfa897bfa2b89f7c89c66ad84f967797dbd3cf60d
1 /* C++-specific tree lowering bits; see also c-gimplify.c and tree-gimple.c.
3 Copyright (C) 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009
4 Free Software Foundation, Inc.
5 Contributed by Jason Merrill <jason@redhat.com>
7 This file is part of GCC.
9 GCC is free software; you can redistribute it and/or modify it under
10 the terms of the GNU General Public License as published by the Free
11 Software Foundation; either version 3, or (at your option) any later
12 version.
14 GCC is distributed in the hope that it will be useful, but WITHOUT ANY
15 WARRANTY; without even the implied warranty of MERCHANTABILITY or
16 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
17 for more details.
19 You should have received a copy of the GNU General Public License
20 along with GCC; see the file COPYING3. If not see
21 <http://www.gnu.org/licenses/>. */
23 #include "config.h"
24 #include "system.h"
25 #include "coretypes.h"
26 #include "tm.h"
27 #include "tree.h"
28 #include "cp-tree.h"
29 #include "c-family/c-common.h"
30 #include "toplev.h"
31 #include "tree-iterator.h"
32 #include "gimple.h"
33 #include "hashtab.h"
34 #include "pointer-set.h"
35 #include "flags.h"
37 /* Local declarations. */
39 enum bc_t { bc_break = 0, bc_continue = 1 };
41 /* Stack of labels which are targets for "break" or "continue",
42 linked through TREE_CHAIN. */
43 static tree bc_label[2];
45 /* Begin a scope which can be exited by a break or continue statement. BC
46 indicates which.
48 Just creates a label and pushes it into the current context. */
50 static tree
51 begin_bc_block (enum bc_t bc)
53 tree label = create_artificial_label (input_location);
54 TREE_CHAIN (label) = bc_label[bc];
55 bc_label[bc] = label;
56 return label;
59 /* Finish a scope which can be exited by a break or continue statement.
60 LABEL was returned from the most recent call to begin_bc_block. BODY is
61 an expression for the contents of the scope.
63 If we saw a break (or continue) in the scope, append a LABEL_EXPR to
64 body. Otherwise, just forget the label. */
66 static gimple_seq
67 finish_bc_block (enum bc_t bc, tree label, gimple_seq body)
69 gcc_assert (label == bc_label[bc]);
71 if (TREE_USED (label))
73 gimple_seq_add_stmt (&body, gimple_build_label (label));
76 bc_label[bc] = TREE_CHAIN (label);
77 TREE_CHAIN (label) = NULL_TREE;
78 return body;
81 /* Get the LABEL_EXPR to represent a break or continue statement
82 in the current block scope. BC indicates which. */
84 static tree
85 get_bc_label (enum bc_t bc)
87 tree label = bc_label[bc];
89 if (label == NULL_TREE)
91 if (bc == bc_break)
92 error ("break statement not within loop or switch");
93 else
94 error ("continue statement not within loop or switch");
96 return NULL_TREE;
99 /* Mark the label used for finish_bc_block. */
100 TREE_USED (label) = 1;
101 return label;
104 /* Genericize a TRY_BLOCK. */
106 static void
107 genericize_try_block (tree *stmt_p)
109 tree body = TRY_STMTS (*stmt_p);
110 tree cleanup = TRY_HANDLERS (*stmt_p);
112 *stmt_p = build2 (TRY_CATCH_EXPR, void_type_node, body, cleanup);
115 /* Genericize a HANDLER by converting to a CATCH_EXPR. */
117 static void
118 genericize_catch_block (tree *stmt_p)
120 tree type = HANDLER_TYPE (*stmt_p);
121 tree body = HANDLER_BODY (*stmt_p);
123 /* FIXME should the caught type go in TREE_TYPE? */
124 *stmt_p = build2 (CATCH_EXPR, void_type_node, type, body);
127 /* A terser interface for building a representation of an exception
128 specification. */
130 static tree
131 build_gimple_eh_filter_tree (tree body, tree allowed, tree failure)
133 tree t;
135 /* FIXME should the allowed types go in TREE_TYPE? */
136 t = build2 (EH_FILTER_EXPR, void_type_node, allowed, NULL_TREE);
137 append_to_statement_list (failure, &EH_FILTER_FAILURE (t));
139 t = build2 (TRY_CATCH_EXPR, void_type_node, NULL_TREE, t);
140 append_to_statement_list (body, &TREE_OPERAND (t, 0));
142 return t;
145 /* Genericize an EH_SPEC_BLOCK by converting it to a
146 TRY_CATCH_EXPR/EH_FILTER_EXPR pair. */
148 static void
149 genericize_eh_spec_block (tree *stmt_p)
151 tree body = EH_SPEC_STMTS (*stmt_p);
152 tree allowed = EH_SPEC_RAISES (*stmt_p);
153 tree failure = build_call_n (call_unexpected_node, 1, build_exc_ptr ());
155 *stmt_p = build_gimple_eh_filter_tree (body, allowed, failure);
156 TREE_NO_WARNING (*stmt_p) = true;
157 TREE_NO_WARNING (TREE_OPERAND (*stmt_p, 1)) = true;
160 /* Genericize an IF_STMT by turning it into a COND_EXPR. */
162 static void
163 genericize_if_stmt (tree *stmt_p)
165 tree stmt, cond, then_, else_;
166 location_t locus = EXPR_LOCATION (*stmt_p);
168 stmt = *stmt_p;
169 cond = IF_COND (stmt);
170 then_ = THEN_CLAUSE (stmt);
171 else_ = ELSE_CLAUSE (stmt);
173 if (!then_)
174 then_ = build_empty_stmt (locus);
175 if (!else_)
176 else_ = build_empty_stmt (locus);
178 if (integer_nonzerop (cond) && !TREE_SIDE_EFFECTS (else_))
179 stmt = then_;
180 else if (integer_zerop (cond) && !TREE_SIDE_EFFECTS (then_))
181 stmt = else_;
182 else
183 stmt = build3 (COND_EXPR, void_type_node, cond, then_, else_);
184 if (CAN_HAVE_LOCATION_P (stmt) && !EXPR_HAS_LOCATION (stmt))
185 SET_EXPR_LOCATION (stmt, locus);
186 *stmt_p = stmt;
189 /* Build a generic representation of one of the C loop forms. COND is the
190 loop condition or NULL_TREE. BODY is the (possibly compound) statement
191 controlled by the loop. INCR is the increment expression of a for-loop,
192 or NULL_TREE. COND_IS_FIRST indicates whether the condition is
193 evaluated before the loop body as in while and for loops, or after the
194 loop body as in do-while loops. */
196 static gimple_seq
197 gimplify_cp_loop (tree cond, tree body, tree incr, bool cond_is_first)
199 gimple top, entry, stmt;
200 gimple_seq stmt_list, body_seq, incr_seq, exit_seq;
201 tree cont_block, break_block;
202 location_t stmt_locus;
204 stmt_locus = input_location;
205 stmt_list = NULL;
206 body_seq = NULL;
207 incr_seq = NULL;
208 exit_seq = NULL;
209 entry = NULL;
211 break_block = begin_bc_block (bc_break);
212 cont_block = begin_bc_block (bc_continue);
214 /* If condition is zero don't generate a loop construct. */
215 if (cond && integer_zerop (cond))
217 top = NULL;
218 if (cond_is_first)
220 stmt = gimple_build_goto (get_bc_label (bc_break));
221 gimple_set_location (stmt, stmt_locus);
222 gimple_seq_add_stmt (&stmt_list, stmt);
225 else
227 /* If we use a LOOP_EXPR here, we have to feed the whole thing
228 back through the main gimplifier to lower it. Given that we
229 have to gimplify the loop body NOW so that we can resolve
230 break/continue stmts, seems easier to just expand to gotos. */
231 top = gimple_build_label (create_artificial_label (stmt_locus));
233 /* If we have an exit condition, then we build an IF with gotos either
234 out of the loop, or to the top of it. If there's no exit condition,
235 then we just build a jump back to the top. */
236 if (cond && !integer_nonzerop (cond))
238 if (cond != error_mark_node)
240 gimplify_expr (&cond, &exit_seq, NULL, is_gimple_val, fb_rvalue);
241 stmt = gimple_build_cond (NE_EXPR, cond,
242 build_int_cst (TREE_TYPE (cond), 0),
243 gimple_label_label (top),
244 get_bc_label (bc_break));
245 gimple_seq_add_stmt (&exit_seq, stmt);
248 if (cond_is_first)
250 if (incr)
252 entry = gimple_build_label
253 (create_artificial_label (stmt_locus));
254 stmt = gimple_build_goto (gimple_label_label (entry));
256 else
257 stmt = gimple_build_goto (get_bc_label (bc_continue));
258 gimple_set_location (stmt, stmt_locus);
259 gimple_seq_add_stmt (&stmt_list, stmt);
262 else
264 stmt = gimple_build_goto (gimple_label_label (top));
265 gimple_seq_add_stmt (&exit_seq, stmt);
269 gimplify_stmt (&body, &body_seq);
270 gimplify_stmt (&incr, &incr_seq);
272 body_seq = finish_bc_block (bc_continue, cont_block, body_seq);
274 gimple_seq_add_stmt (&stmt_list, top);
275 gimple_seq_add_seq (&stmt_list, body_seq);
276 gimple_seq_add_seq (&stmt_list, incr_seq);
277 gimple_seq_add_stmt (&stmt_list, entry);
278 gimple_seq_add_seq (&stmt_list, exit_seq);
280 annotate_all_with_location (stmt_list, stmt_locus);
282 return finish_bc_block (bc_break, break_block, stmt_list);
285 /* Gimplify a FOR_STMT node. Move the stuff in the for-init-stmt into the
286 prequeue and hand off to gimplify_cp_loop. */
288 static void
289 gimplify_for_stmt (tree *stmt_p, gimple_seq *pre_p)
291 tree stmt = *stmt_p;
293 if (FOR_INIT_STMT (stmt))
294 gimplify_and_add (FOR_INIT_STMT (stmt), pre_p);
296 gimple_seq_add_seq (pre_p,
297 gimplify_cp_loop (FOR_COND (stmt), FOR_BODY (stmt),
298 FOR_EXPR (stmt), 1));
299 *stmt_p = NULL_TREE;
302 /* Gimplify a WHILE_STMT node. */
304 static void
305 gimplify_while_stmt (tree *stmt_p, gimple_seq *pre_p)
307 tree stmt = *stmt_p;
308 gimple_seq_add_seq (pre_p,
309 gimplify_cp_loop (WHILE_COND (stmt), WHILE_BODY (stmt),
310 NULL_TREE, 1));
311 *stmt_p = NULL_TREE;
314 /* Gimplify a DO_STMT node. */
316 static void
317 gimplify_do_stmt (tree *stmt_p, gimple_seq *pre_p)
319 tree stmt = *stmt_p;
320 gimple_seq_add_seq (pre_p,
321 gimplify_cp_loop (DO_COND (stmt), DO_BODY (stmt),
322 NULL_TREE, 0));
323 *stmt_p = NULL_TREE;
326 /* Genericize a SWITCH_STMT by turning it into a SWITCH_EXPR. */
328 static void
329 gimplify_switch_stmt (tree *stmt_p, gimple_seq *pre_p)
331 tree stmt = *stmt_p;
332 tree break_block, body, t;
333 location_t stmt_locus = input_location;
334 gimple_seq seq = NULL;
336 break_block = begin_bc_block (bc_break);
338 body = SWITCH_STMT_BODY (stmt);
339 if (!body)
340 body = build_empty_stmt (stmt_locus);
342 t = build3 (SWITCH_EXPR, SWITCH_STMT_TYPE (stmt),
343 SWITCH_STMT_COND (stmt), body, NULL_TREE);
344 SET_EXPR_LOCATION (t, stmt_locus);
345 gimplify_and_add (t, &seq);
347 seq = finish_bc_block (bc_break, break_block, seq);
348 gimple_seq_add_seq (pre_p, seq);
349 *stmt_p = NULL_TREE;
352 /* Hook into the middle of gimplifying an OMP_FOR node. This is required
353 in order to properly gimplify CONTINUE statements. Here we merely
354 manage the continue stack; the rest of the job is performed by the
355 regular gimplifier. */
357 static enum gimplify_status
358 cp_gimplify_omp_for (tree *expr_p, gimple_seq *pre_p)
360 tree for_stmt = *expr_p;
361 tree cont_block;
362 gimple stmt;
363 gimple_seq seq = NULL;
365 /* Protect ourselves from recursion. */
366 if (OMP_FOR_GIMPLIFYING_P (for_stmt))
367 return GS_UNHANDLED;
368 OMP_FOR_GIMPLIFYING_P (for_stmt) = 1;
370 /* Note that while technically the continue label is enabled too soon
371 here, we should have already diagnosed invalid continues nested within
372 statement expressions within the INIT, COND, or INCR expressions. */
373 cont_block = begin_bc_block (bc_continue);
375 gimplify_and_add (for_stmt, &seq);
376 stmt = gimple_seq_last_stmt (seq);
377 if (gimple_code (stmt) == GIMPLE_OMP_FOR)
378 gimple_omp_set_body (stmt, finish_bc_block (bc_continue, cont_block,
379 gimple_omp_body (stmt)));
380 else
381 seq = finish_bc_block (bc_continue, cont_block, seq);
382 gimple_seq_add_seq (pre_p, seq);
384 OMP_FOR_GIMPLIFYING_P (for_stmt) = 0;
386 return GS_ALL_DONE;
389 /* Gimplify an EXPR_STMT node. */
391 static void
392 gimplify_expr_stmt (tree *stmt_p)
394 tree stmt = EXPR_STMT_EXPR (*stmt_p);
396 if (stmt == error_mark_node)
397 stmt = NULL;
399 /* Gimplification of a statement expression will nullify the
400 statement if all its side effects are moved to *PRE_P and *POST_P.
402 In this case we will not want to emit the gimplified statement.
403 However, we may still want to emit a warning, so we do that before
404 gimplification. */
405 if (stmt && warn_unused_value)
407 if (!TREE_SIDE_EFFECTS (stmt))
409 if (!IS_EMPTY_STMT (stmt)
410 && !VOID_TYPE_P (TREE_TYPE (stmt))
411 && !TREE_NO_WARNING (stmt))
412 warning (OPT_Wunused_value, "statement with no effect");
414 else
415 warn_if_unused_value (stmt, input_location);
418 if (stmt == NULL_TREE)
419 stmt = alloc_stmt_list ();
421 *stmt_p = stmt;
424 /* Gimplify initialization from an AGGR_INIT_EXPR. */
426 static void
427 cp_gimplify_init_expr (tree *expr_p, gimple_seq *pre_p, gimple_seq *post_p)
429 tree from = TREE_OPERAND (*expr_p, 1);
430 tree to = TREE_OPERAND (*expr_p, 0);
431 tree t;
433 /* What about code that pulls out the temp and uses it elsewhere? I
434 think that such code never uses the TARGET_EXPR as an initializer. If
435 I'm wrong, we'll abort because the temp won't have any RTL. In that
436 case, I guess we'll need to replace references somehow. */
437 if (TREE_CODE (from) == TARGET_EXPR)
438 from = TARGET_EXPR_INITIAL (from);
440 /* Look through any COMPOUND_EXPRs, since build_compound_expr pushes them
441 inside the TARGET_EXPR. */
442 for (t = from; t; )
444 tree sub = TREE_CODE (t) == COMPOUND_EXPR ? TREE_OPERAND (t, 0) : t;
446 /* If we are initializing from an AGGR_INIT_EXPR, drop the INIT_EXPR and
447 replace the slot operand with our target.
449 Should we add a target parm to gimplify_expr instead? No, as in this
450 case we want to replace the INIT_EXPR. */
451 if (TREE_CODE (sub) == AGGR_INIT_EXPR
452 || TREE_CODE (sub) == VEC_INIT_EXPR)
454 gimplify_expr (&to, pre_p, post_p, is_gimple_lvalue, fb_lvalue);
455 if (TREE_CODE (sub) == AGGR_INIT_EXPR)
456 AGGR_INIT_EXPR_SLOT (sub) = to;
457 else
458 VEC_INIT_EXPR_SLOT (sub) = to;
459 *expr_p = from;
461 /* The initialization is now a side-effect, so the container can
462 become void. */
463 if (from != sub)
464 TREE_TYPE (from) = void_type_node;
467 if (t == sub)
468 break;
469 else
470 t = TREE_OPERAND (t, 1);
475 /* Gimplify a MUST_NOT_THROW_EXPR. */
477 static enum gimplify_status
478 gimplify_must_not_throw_expr (tree *expr_p, gimple_seq *pre_p)
480 tree stmt = *expr_p;
481 tree temp = voidify_wrapper_expr (stmt, NULL);
482 tree body = TREE_OPERAND (stmt, 0);
483 gimple_seq try_ = NULL;
484 gimple_seq catch_ = NULL;
485 gimple mnt;
487 gimplify_and_add (body, &try_);
488 mnt = gimple_build_eh_must_not_throw (terminate_node);
489 gimplify_seq_add_stmt (&catch_, mnt);
490 mnt = gimple_build_try (try_, catch_, GIMPLE_TRY_CATCH);
492 gimplify_seq_add_stmt (pre_p, mnt);
493 if (temp)
495 *expr_p = temp;
496 return GS_OK;
499 *expr_p = NULL;
500 return GS_ALL_DONE;
503 /* Do C++-specific gimplification. Args are as for gimplify_expr. */
506 cp_gimplify_expr (tree *expr_p, gimple_seq *pre_p, gimple_seq *post_p)
508 int saved_stmts_are_full_exprs_p = 0;
509 enum tree_code code = TREE_CODE (*expr_p);
510 enum gimplify_status ret;
512 if (STATEMENT_CODE_P (code))
514 saved_stmts_are_full_exprs_p = stmts_are_full_exprs_p ();
515 current_stmt_tree ()->stmts_are_full_exprs_p
516 = STMT_IS_FULL_EXPR_P (*expr_p);
519 switch (code)
521 case PTRMEM_CST:
522 *expr_p = cplus_expand_constant (*expr_p);
523 ret = GS_OK;
524 break;
526 case AGGR_INIT_EXPR:
527 simplify_aggr_init_expr (expr_p);
528 ret = GS_OK;
529 break;
531 case VEC_INIT_EXPR:
533 location_t loc = input_location;
534 gcc_assert (EXPR_HAS_LOCATION (*expr_p));
535 input_location = EXPR_LOCATION (*expr_p);
536 *expr_p = build_vec_init (VEC_INIT_EXPR_SLOT (*expr_p), NULL_TREE,
537 VEC_INIT_EXPR_INIT (*expr_p), false, 1,
538 tf_warning_or_error);
539 ret = GS_OK;
540 input_location = loc;
542 break;
544 case THROW_EXPR:
545 /* FIXME communicate throw type to back end, probably by moving
546 THROW_EXPR into ../tree.def. */
547 *expr_p = TREE_OPERAND (*expr_p, 0);
548 ret = GS_OK;
549 break;
551 case MUST_NOT_THROW_EXPR:
552 ret = gimplify_must_not_throw_expr (expr_p, pre_p);
553 break;
555 /* We used to do this for MODIFY_EXPR as well, but that's unsafe; the
556 LHS of an assignment might also be involved in the RHS, as in bug
557 25979. */
558 case INIT_EXPR:
559 cp_gimplify_init_expr (expr_p, pre_p, post_p);
560 if (TREE_CODE (*expr_p) != INIT_EXPR)
561 return GS_OK;
562 /* Otherwise fall through. */
563 case MODIFY_EXPR:
565 /* If the back end isn't clever enough to know that the lhs and rhs
566 types are the same, add an explicit conversion. */
567 tree op0 = TREE_OPERAND (*expr_p, 0);
568 tree op1 = TREE_OPERAND (*expr_p, 1);
570 if (!error_operand_p (op0)
571 && !error_operand_p (op1)
572 && (TYPE_STRUCTURAL_EQUALITY_P (TREE_TYPE (op0))
573 || TYPE_STRUCTURAL_EQUALITY_P (TREE_TYPE (op1)))
574 && !useless_type_conversion_p (TREE_TYPE (op1), TREE_TYPE (op0)))
575 TREE_OPERAND (*expr_p, 1) = build1 (VIEW_CONVERT_EXPR,
576 TREE_TYPE (op0), op1);
578 else if ((is_gimple_lvalue (op1) || INDIRECT_REF_P (op1))
579 && !(TREE_CODE (op1) == CALL_EXPR
580 && CALL_EXPR_RETURN_SLOT_OPT (op1))
581 && is_really_empty_class (TREE_TYPE (op0)))
583 /* Remove any copies of empty classes. We check that the RHS
584 has a simple form so that TARGET_EXPRs and CONSTRUCTORs get
585 reduced properly, and we leave the return slot optimization
586 alone because it isn't a copy.
588 Also drop volatile variables on the RHS to avoid infinite
589 recursion from gimplify_expr trying to load the value. */
590 if (!TREE_SIDE_EFFECTS (op1)
591 || (DECL_P (op1) && TREE_THIS_VOLATILE (op1)))
592 *expr_p = op0;
593 else
594 *expr_p = build2 (COMPOUND_EXPR, TREE_TYPE (*expr_p),
595 op0, op1);
598 ret = GS_OK;
599 break;
601 case EMPTY_CLASS_EXPR:
602 /* We create an empty CONSTRUCTOR with RECORD_TYPE. */
603 *expr_p = build_constructor (TREE_TYPE (*expr_p), NULL);
604 ret = GS_OK;
605 break;
607 case BASELINK:
608 *expr_p = BASELINK_FUNCTIONS (*expr_p);
609 ret = GS_OK;
610 break;
612 case TRY_BLOCK:
613 genericize_try_block (expr_p);
614 ret = GS_OK;
615 break;
617 case HANDLER:
618 genericize_catch_block (expr_p);
619 ret = GS_OK;
620 break;
622 case EH_SPEC_BLOCK:
623 genericize_eh_spec_block (expr_p);
624 ret = GS_OK;
625 break;
627 case USING_STMT:
628 gcc_unreachable ();
630 case FOR_STMT:
631 gimplify_for_stmt (expr_p, pre_p);
632 ret = GS_OK;
633 break;
635 case WHILE_STMT:
636 gimplify_while_stmt (expr_p, pre_p);
637 ret = GS_OK;
638 break;
640 case DO_STMT:
641 gimplify_do_stmt (expr_p, pre_p);
642 ret = GS_OK;
643 break;
645 case SWITCH_STMT:
646 gimplify_switch_stmt (expr_p, pre_p);
647 ret = GS_OK;
648 break;
650 case OMP_FOR:
651 ret = cp_gimplify_omp_for (expr_p, pre_p);
652 break;
654 case CONTINUE_STMT:
655 gimple_seq_add_stmt (pre_p, gimple_build_predict (PRED_CONTINUE, NOT_TAKEN));
656 gimple_seq_add_stmt (pre_p, gimple_build_goto (get_bc_label (bc_continue)));
657 *expr_p = NULL_TREE;
658 ret = GS_ALL_DONE;
659 break;
661 case BREAK_STMT:
662 gimple_seq_add_stmt (pre_p, gimple_build_goto (get_bc_label (bc_break)));
663 *expr_p = NULL_TREE;
664 ret = GS_ALL_DONE;
665 break;
667 case EXPR_STMT:
668 gimplify_expr_stmt (expr_p);
669 ret = GS_OK;
670 break;
672 case UNARY_PLUS_EXPR:
674 tree arg = TREE_OPERAND (*expr_p, 0);
675 tree type = TREE_TYPE (*expr_p);
676 *expr_p = (TREE_TYPE (arg) != type) ? fold_convert (type, arg)
677 : arg;
678 ret = GS_OK;
680 break;
682 default:
683 ret = (enum gimplify_status) c_gimplify_expr (expr_p, pre_p, post_p);
684 break;
687 /* Restore saved state. */
688 if (STATEMENT_CODE_P (code))
689 current_stmt_tree ()->stmts_are_full_exprs_p
690 = saved_stmts_are_full_exprs_p;
692 return ret;
695 static inline bool
696 is_invisiref_parm (const_tree t)
698 return ((TREE_CODE (t) == PARM_DECL || TREE_CODE (t) == RESULT_DECL)
699 && DECL_BY_REFERENCE (t));
702 /* Return true if the uid in both int tree maps are equal. */
705 cxx_int_tree_map_eq (const void *va, const void *vb)
707 const struct cxx_int_tree_map *a = (const struct cxx_int_tree_map *) va;
708 const struct cxx_int_tree_map *b = (const struct cxx_int_tree_map *) vb;
709 return (a->uid == b->uid);
712 /* Hash a UID in a cxx_int_tree_map. */
714 unsigned int
715 cxx_int_tree_map_hash (const void *item)
717 return ((const struct cxx_int_tree_map *)item)->uid;
720 struct cp_genericize_data
722 struct pointer_set_t *p_set;
723 VEC (tree, heap) *bind_expr_stack;
726 /* Perform any pre-gimplification lowering of C++ front end trees to
727 GENERIC. */
729 static tree
730 cp_genericize_r (tree *stmt_p, int *walk_subtrees, void *data)
732 tree stmt = *stmt_p;
733 struct cp_genericize_data *wtd = (struct cp_genericize_data *) data;
734 struct pointer_set_t *p_set = wtd->p_set;
736 if (is_invisiref_parm (stmt)
737 /* Don't dereference parms in a thunk, pass the references through. */
738 && !(DECL_THUNK_P (current_function_decl)
739 && TREE_CODE (stmt) == PARM_DECL))
741 *stmt_p = convert_from_reference (stmt);
742 *walk_subtrees = 0;
743 return NULL;
746 /* Map block scope extern declarations to visible declarations with the
747 same name and type in outer scopes if any. */
748 if (cp_function_chain->extern_decl_map
749 && (TREE_CODE (stmt) == FUNCTION_DECL || TREE_CODE (stmt) == VAR_DECL)
750 && DECL_EXTERNAL (stmt))
752 struct cxx_int_tree_map *h, in;
753 in.uid = DECL_UID (stmt);
754 h = (struct cxx_int_tree_map *)
755 htab_find_with_hash (cp_function_chain->extern_decl_map,
756 &in, in.uid);
757 if (h)
759 *stmt_p = h->to;
760 *walk_subtrees = 0;
761 return NULL;
765 /* Other than invisiref parms, don't walk the same tree twice. */
766 if (pointer_set_contains (p_set, stmt))
768 *walk_subtrees = 0;
769 return NULL_TREE;
772 if (TREE_CODE (stmt) == ADDR_EXPR
773 && is_invisiref_parm (TREE_OPERAND (stmt, 0)))
775 *stmt_p = convert (TREE_TYPE (stmt), TREE_OPERAND (stmt, 0));
776 *walk_subtrees = 0;
778 else if (TREE_CODE (stmt) == RETURN_EXPR
779 && TREE_OPERAND (stmt, 0)
780 && is_invisiref_parm (TREE_OPERAND (stmt, 0)))
781 /* Don't dereference an invisiref RESULT_DECL inside a RETURN_EXPR. */
782 *walk_subtrees = 0;
783 else if (TREE_CODE (stmt) == OMP_CLAUSE)
784 switch (OMP_CLAUSE_CODE (stmt))
786 case OMP_CLAUSE_LASTPRIVATE:
787 /* Don't dereference an invisiref in OpenMP clauses. */
788 if (is_invisiref_parm (OMP_CLAUSE_DECL (stmt)))
790 *walk_subtrees = 0;
791 if (OMP_CLAUSE_LASTPRIVATE_STMT (stmt))
792 cp_walk_tree (&OMP_CLAUSE_LASTPRIVATE_STMT (stmt),
793 cp_genericize_r, data, NULL);
795 break;
796 case OMP_CLAUSE_PRIVATE:
797 case OMP_CLAUSE_SHARED:
798 case OMP_CLAUSE_FIRSTPRIVATE:
799 case OMP_CLAUSE_COPYIN:
800 case OMP_CLAUSE_COPYPRIVATE:
801 /* Don't dereference an invisiref in OpenMP clauses. */
802 if (is_invisiref_parm (OMP_CLAUSE_DECL (stmt)))
803 *walk_subtrees = 0;
804 break;
805 case OMP_CLAUSE_REDUCTION:
806 gcc_assert (!is_invisiref_parm (OMP_CLAUSE_DECL (stmt)));
807 break;
808 default:
809 break;
811 else if (IS_TYPE_OR_DECL_P (stmt))
812 *walk_subtrees = 0;
814 /* Due to the way voidify_wrapper_expr is written, we don't get a chance
815 to lower this construct before scanning it, so we need to lower these
816 before doing anything else. */
817 else if (TREE_CODE (stmt) == CLEANUP_STMT)
818 *stmt_p = build2 (CLEANUP_EH_ONLY (stmt) ? TRY_CATCH_EXPR
819 : TRY_FINALLY_EXPR,
820 void_type_node,
821 CLEANUP_BODY (stmt),
822 CLEANUP_EXPR (stmt));
824 else if (TREE_CODE (stmt) == IF_STMT)
826 genericize_if_stmt (stmt_p);
827 /* *stmt_p has changed, tail recurse to handle it again. */
828 return cp_genericize_r (stmt_p, walk_subtrees, data);
831 /* COND_EXPR might have incompatible types in branches if one or both
832 arms are bitfields. Fix it up now. */
833 else if (TREE_CODE (stmt) == COND_EXPR)
835 tree type_left
836 = (TREE_OPERAND (stmt, 1)
837 ? is_bitfield_expr_with_lowered_type (TREE_OPERAND (stmt, 1))
838 : NULL_TREE);
839 tree type_right
840 = (TREE_OPERAND (stmt, 2)
841 ? is_bitfield_expr_with_lowered_type (TREE_OPERAND (stmt, 2))
842 : NULL_TREE);
843 if (type_left
844 && !useless_type_conversion_p (TREE_TYPE (stmt),
845 TREE_TYPE (TREE_OPERAND (stmt, 1))))
847 TREE_OPERAND (stmt, 1)
848 = fold_convert (type_left, TREE_OPERAND (stmt, 1));
849 gcc_assert (useless_type_conversion_p (TREE_TYPE (stmt),
850 type_left));
852 if (type_right
853 && !useless_type_conversion_p (TREE_TYPE (stmt),
854 TREE_TYPE (TREE_OPERAND (stmt, 2))))
856 TREE_OPERAND (stmt, 2)
857 = fold_convert (type_right, TREE_OPERAND (stmt, 2));
858 gcc_assert (useless_type_conversion_p (TREE_TYPE (stmt),
859 type_right));
863 else if (TREE_CODE (stmt) == BIND_EXPR)
865 VEC_safe_push (tree, heap, wtd->bind_expr_stack, stmt);
866 cp_walk_tree (&BIND_EXPR_BODY (stmt),
867 cp_genericize_r, data, NULL);
868 VEC_pop (tree, wtd->bind_expr_stack);
871 else if (TREE_CODE (stmt) == USING_STMT)
873 tree block = NULL_TREE;
875 /* Get the innermost inclosing GIMPLE_BIND that has a non NULL
876 BLOCK, and append an IMPORTED_DECL to its
877 BLOCK_VARS chained list. */
878 if (wtd->bind_expr_stack)
880 int i;
881 for (i = VEC_length (tree, wtd->bind_expr_stack) - 1; i >= 0; i--)
882 if ((block = BIND_EXPR_BLOCK (VEC_index (tree,
883 wtd->bind_expr_stack, i))))
884 break;
886 if (block)
888 tree using_directive;
889 gcc_assert (TREE_OPERAND (stmt, 0));
891 using_directive = make_node (IMPORTED_DECL);
892 TREE_TYPE (using_directive) = void_type_node;
894 IMPORTED_DECL_ASSOCIATED_DECL (using_directive)
895 = TREE_OPERAND (stmt, 0);
896 TREE_CHAIN (using_directive) = BLOCK_VARS (block);
897 BLOCK_VARS (block) = using_directive;
899 /* The USING_STMT won't appear in GENERIC. */
900 *stmt_p = build1 (NOP_EXPR, void_type_node, integer_zero_node);
901 *walk_subtrees = 0;
904 else if (TREE_CODE (stmt) == DECL_EXPR
905 && TREE_CODE (DECL_EXPR_DECL (stmt)) == USING_DECL)
907 /* Using decls inside DECL_EXPRs are just dropped on the floor. */
908 *stmt_p = build1 (NOP_EXPR, void_type_node, integer_zero_node);
909 *walk_subtrees = 0;
912 pointer_set_insert (p_set, *stmt_p);
914 return NULL;
917 void
918 cp_genericize (tree fndecl)
920 tree t;
921 struct cp_genericize_data wtd;
923 /* Fix up the types of parms passed by invisible reference. */
924 for (t = DECL_ARGUMENTS (fndecl); t; t = TREE_CHAIN (t))
925 if (TREE_ADDRESSABLE (TREE_TYPE (t)))
927 /* If a function's arguments are copied to create a thunk,
928 then DECL_BY_REFERENCE will be set -- but the type of the
929 argument will be a pointer type, so we will never get
930 here. */
931 gcc_assert (!DECL_BY_REFERENCE (t));
932 gcc_assert (DECL_ARG_TYPE (t) != TREE_TYPE (t));
933 TREE_TYPE (t) = DECL_ARG_TYPE (t);
934 DECL_BY_REFERENCE (t) = 1;
935 TREE_ADDRESSABLE (t) = 0;
936 relayout_decl (t);
939 /* Do the same for the return value. */
940 if (TREE_ADDRESSABLE (TREE_TYPE (DECL_RESULT (fndecl))))
942 t = DECL_RESULT (fndecl);
943 TREE_TYPE (t) = build_reference_type (TREE_TYPE (t));
944 DECL_BY_REFERENCE (t) = 1;
945 TREE_ADDRESSABLE (t) = 0;
946 relayout_decl (t);
949 /* If we're a clone, the body is already GIMPLE. */
950 if (DECL_CLONED_FUNCTION_P (fndecl))
951 return;
953 /* We do want to see every occurrence of the parms, so we can't just use
954 walk_tree's hash functionality. */
955 wtd.p_set = pointer_set_create ();
956 wtd.bind_expr_stack = NULL;
957 cp_walk_tree (&DECL_SAVED_TREE (fndecl), cp_genericize_r, &wtd, NULL);
958 pointer_set_destroy (wtd.p_set);
959 VEC_free (tree, heap, wtd.bind_expr_stack);
961 /* Do everything else. */
962 c_genericize (fndecl);
964 gcc_assert (bc_label[bc_break] == NULL);
965 gcc_assert (bc_label[bc_continue] == NULL);
968 /* Build code to apply FN to each member of ARG1 and ARG2. FN may be
969 NULL if there is in fact nothing to do. ARG2 may be null if FN
970 actually only takes one argument. */
972 static tree
973 cxx_omp_clause_apply_fn (tree fn, tree arg1, tree arg2)
975 tree defparm, parm, t;
976 int i = 0;
977 int nargs;
978 tree *argarray;
980 if (fn == NULL)
981 return NULL;
983 nargs = list_length (DECL_ARGUMENTS (fn));
984 argarray = XALLOCAVEC (tree, nargs);
986 defparm = TREE_CHAIN (TYPE_ARG_TYPES (TREE_TYPE (fn)));
987 if (arg2)
988 defparm = TREE_CHAIN (defparm);
990 if (TREE_CODE (TREE_TYPE (arg1)) == ARRAY_TYPE)
992 tree inner_type = TREE_TYPE (arg1);
993 tree start1, end1, p1;
994 tree start2 = NULL, p2 = NULL;
995 tree ret = NULL, lab;
997 start1 = arg1;
998 start2 = arg2;
1001 inner_type = TREE_TYPE (inner_type);
1002 start1 = build4 (ARRAY_REF, inner_type, start1,
1003 size_zero_node, NULL, NULL);
1004 if (arg2)
1005 start2 = build4 (ARRAY_REF, inner_type, start2,
1006 size_zero_node, NULL, NULL);
1008 while (TREE_CODE (inner_type) == ARRAY_TYPE);
1009 start1 = build_fold_addr_expr_loc (input_location, start1);
1010 if (arg2)
1011 start2 = build_fold_addr_expr_loc (input_location, start2);
1013 end1 = TYPE_SIZE_UNIT (TREE_TYPE (arg1));
1014 end1 = build2 (POINTER_PLUS_EXPR, TREE_TYPE (start1), start1, end1);
1016 p1 = create_tmp_var (TREE_TYPE (start1), NULL);
1017 t = build2 (MODIFY_EXPR, TREE_TYPE (p1), p1, start1);
1018 append_to_statement_list (t, &ret);
1020 if (arg2)
1022 p2 = create_tmp_var (TREE_TYPE (start2), NULL);
1023 t = build2 (MODIFY_EXPR, TREE_TYPE (p2), p2, start2);
1024 append_to_statement_list (t, &ret);
1027 lab = create_artificial_label (input_location);
1028 t = build1 (LABEL_EXPR, void_type_node, lab);
1029 append_to_statement_list (t, &ret);
1031 argarray[i++] = p1;
1032 if (arg2)
1033 argarray[i++] = p2;
1034 /* Handle default arguments. */
1035 for (parm = defparm; parm && parm != void_list_node;
1036 parm = TREE_CHAIN (parm), i++)
1037 argarray[i] = convert_default_arg (TREE_VALUE (parm),
1038 TREE_PURPOSE (parm), fn, i);
1039 t = build_call_a (fn, i, argarray);
1040 t = fold_convert (void_type_node, t);
1041 t = fold_build_cleanup_point_expr (TREE_TYPE (t), t);
1042 append_to_statement_list (t, &ret);
1044 t = TYPE_SIZE_UNIT (inner_type);
1045 t = build2 (POINTER_PLUS_EXPR, TREE_TYPE (p1), p1, t);
1046 t = build2 (MODIFY_EXPR, TREE_TYPE (p1), p1, t);
1047 append_to_statement_list (t, &ret);
1049 if (arg2)
1051 t = TYPE_SIZE_UNIT (inner_type);
1052 t = build2 (POINTER_PLUS_EXPR, TREE_TYPE (p2), p2, t);
1053 t = build2 (MODIFY_EXPR, TREE_TYPE (p2), p2, t);
1054 append_to_statement_list (t, &ret);
1057 t = build2 (NE_EXPR, boolean_type_node, p1, end1);
1058 t = build3 (COND_EXPR, void_type_node, t, build_and_jump (&lab), NULL);
1059 append_to_statement_list (t, &ret);
1061 return ret;
1063 else
1065 argarray[i++] = build_fold_addr_expr_loc (input_location, arg1);
1066 if (arg2)
1067 argarray[i++] = build_fold_addr_expr_loc (input_location, arg2);
1068 /* Handle default arguments. */
1069 for (parm = defparm; parm && parm != void_list_node;
1070 parm = TREE_CHAIN (parm), i++)
1071 argarray[i] = convert_default_arg (TREE_VALUE (parm),
1072 TREE_PURPOSE (parm),
1073 fn, i);
1074 t = build_call_a (fn, i, argarray);
1075 t = fold_convert (void_type_node, t);
1076 return fold_build_cleanup_point_expr (TREE_TYPE (t), t);
1080 /* Return code to initialize DECL with its default constructor, or
1081 NULL if there's nothing to do. */
1083 tree
1084 cxx_omp_clause_default_ctor (tree clause, tree decl,
1085 tree outer ATTRIBUTE_UNUSED)
1087 tree info = CP_OMP_CLAUSE_INFO (clause);
1088 tree ret = NULL;
1090 if (info)
1091 ret = cxx_omp_clause_apply_fn (TREE_VEC_ELT (info, 0), decl, NULL);
1093 return ret;
1096 /* Return code to initialize DST with a copy constructor from SRC. */
1098 tree
1099 cxx_omp_clause_copy_ctor (tree clause, tree dst, tree src)
1101 tree info = CP_OMP_CLAUSE_INFO (clause);
1102 tree ret = NULL;
1104 if (info)
1105 ret = cxx_omp_clause_apply_fn (TREE_VEC_ELT (info, 0), dst, src);
1106 if (ret == NULL)
1107 ret = build2 (MODIFY_EXPR, TREE_TYPE (dst), dst, src);
1109 return ret;
1112 /* Similarly, except use an assignment operator instead. */
1114 tree
1115 cxx_omp_clause_assign_op (tree clause, tree dst, tree src)
1117 tree info = CP_OMP_CLAUSE_INFO (clause);
1118 tree ret = NULL;
1120 if (info)
1121 ret = cxx_omp_clause_apply_fn (TREE_VEC_ELT (info, 2), dst, src);
1122 if (ret == NULL)
1123 ret = build2 (MODIFY_EXPR, TREE_TYPE (dst), dst, src);
1125 return ret;
1128 /* Return code to destroy DECL. */
1130 tree
1131 cxx_omp_clause_dtor (tree clause, tree decl)
1133 tree info = CP_OMP_CLAUSE_INFO (clause);
1134 tree ret = NULL;
1136 if (info)
1137 ret = cxx_omp_clause_apply_fn (TREE_VEC_ELT (info, 1), decl, NULL);
1139 return ret;
1142 /* True if OpenMP should privatize what this DECL points to rather
1143 than the DECL itself. */
1145 bool
1146 cxx_omp_privatize_by_reference (const_tree decl)
1148 return is_invisiref_parm (decl);
1151 /* True if OpenMP sharing attribute of DECL is predetermined. */
1153 enum omp_clause_default_kind
1154 cxx_omp_predetermined_sharing (tree decl)
1156 tree type;
1158 /* Static data members are predetermined as shared. */
1159 if (TREE_STATIC (decl))
1161 tree ctx = CP_DECL_CONTEXT (decl);
1162 if (TYPE_P (ctx) && MAYBE_CLASS_TYPE_P (ctx))
1163 return OMP_CLAUSE_DEFAULT_SHARED;
1166 type = TREE_TYPE (decl);
1167 if (TREE_CODE (type) == REFERENCE_TYPE)
1169 if (!is_invisiref_parm (decl))
1170 return OMP_CLAUSE_DEFAULT_UNSPECIFIED;
1171 type = TREE_TYPE (type);
1173 if (TREE_CODE (decl) == RESULT_DECL && DECL_NAME (decl))
1175 /* NVR doesn't preserve const qualification of the
1176 variable's type. */
1177 tree outer = outer_curly_brace_block (current_function_decl);
1178 tree var;
1180 if (outer)
1181 for (var = BLOCK_VARS (outer); var; var = TREE_CHAIN (var))
1182 if (DECL_NAME (decl) == DECL_NAME (var)
1183 && (TYPE_MAIN_VARIANT (type)
1184 == TYPE_MAIN_VARIANT (TREE_TYPE (var))))
1186 if (TYPE_READONLY (TREE_TYPE (var)))
1187 type = TREE_TYPE (var);
1188 break;
1193 if (type == error_mark_node)
1194 return OMP_CLAUSE_DEFAULT_UNSPECIFIED;
1196 /* Variables with const-qualified type having no mutable member
1197 are predetermined shared. */
1198 if (TYPE_READONLY (type) && !cp_has_mutable_p (type))
1199 return OMP_CLAUSE_DEFAULT_SHARED;
1201 return OMP_CLAUSE_DEFAULT_UNSPECIFIED;
1204 /* Finalize an implicitly determined clause. */
1206 void
1207 cxx_omp_finish_clause (tree c)
1209 tree decl, inner_type;
1210 bool make_shared = false;
1212 if (OMP_CLAUSE_CODE (c) != OMP_CLAUSE_FIRSTPRIVATE)
1213 return;
1215 decl = OMP_CLAUSE_DECL (c);
1216 decl = require_complete_type (decl);
1217 inner_type = TREE_TYPE (decl);
1218 if (decl == error_mark_node)
1219 make_shared = true;
1220 else if (TREE_CODE (TREE_TYPE (decl)) == REFERENCE_TYPE)
1222 if (is_invisiref_parm (decl))
1223 inner_type = TREE_TYPE (inner_type);
1224 else
1226 error ("%qE implicitly determined as %<firstprivate%> has reference type",
1227 decl);
1228 make_shared = true;
1232 /* We're interested in the base element, not arrays. */
1233 while (TREE_CODE (inner_type) == ARRAY_TYPE)
1234 inner_type = TREE_TYPE (inner_type);
1236 /* Check for special function availability by building a call to one.
1237 Save the results, because later we won't be in the right context
1238 for making these queries. */
1239 if (!make_shared
1240 && CLASS_TYPE_P (inner_type)
1241 && cxx_omp_create_clause_info (c, inner_type, false, true, false))
1242 make_shared = true;
1244 if (make_shared)
1245 OMP_CLAUSE_CODE (c) = OMP_CLAUSE_SHARED;