1 /* C++-specific tree lowering bits; see also c-gimplify.c and tree-gimple.c.
3 Copyright (C) 2002, 2003, 2004, 2005, 2006 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 /* Stack of labels which are targets for "break" or "continue",
41 linked through TREE_CHAIN. */
42 static tree bc_label[2];
44 /* Begin a scope which can be exited by a break or continue statement. BC
47 Just creates a label and pushes it into the current context. */
50 begin_bc_block (enum bc_t bc)
52 tree label = create_artificial_label ();
53 TREE_CHAIN (label) = bc_label[bc];
58 /* Finish a scope which can be exited by a break or continue statement.
59 LABEL was returned from the most recent call to begin_bc_block. BODY is
60 an expression for the contents of the scope.
62 If we saw a break (or continue) in the scope, append a LABEL_EXPR to
63 body. Otherwise, just forget the label. */
66 finish_bc_block (enum bc_t bc, tree label, tree body)
68 gcc_assert (label == bc_label[bc]);
70 if (TREE_USED (label))
74 t = build1 (LABEL_EXPR, void_type_node, label);
76 append_to_statement_list (body, &sl);
77 append_to_statement_list (t, &sl);
81 bc_label[bc] = TREE_CHAIN (label);
82 TREE_CHAIN (label) = NULL_TREE;
86 /* Build a GOTO_EXPR to represent a break or continue statement. BC
90 build_bc_goto (enum bc_t bc)
92 tree label = bc_label[bc];
94 if (label == NULL_TREE)
97 error ("break statement not within loop or switch");
99 error ("continue statement not within loop or switch");
104 /* Mark the label used for finish_bc_block. */
105 TREE_USED (label) = 1;
106 return build1 (GOTO_EXPR, void_type_node, label);
109 /* Genericize a TRY_BLOCK. */
112 genericize_try_block (tree *stmt_p)
114 tree body = TRY_STMTS (*stmt_p);
115 tree cleanup = TRY_HANDLERS (*stmt_p);
117 gimplify_stmt (&body);
119 if (CLEANUP_P (*stmt_p))
120 /* A cleanup is an expression, so it doesn't need to be genericized. */;
122 gimplify_stmt (&cleanup);
124 *stmt_p = build2 (TRY_CATCH_EXPR, void_type_node, body, cleanup);
127 /* Genericize a HANDLER by converting to a CATCH_EXPR. */
130 genericize_catch_block (tree *stmt_p)
132 tree type = HANDLER_TYPE (*stmt_p);
133 tree body = HANDLER_BODY (*stmt_p);
135 gimplify_stmt (&body);
137 /* FIXME should the caught type go in TREE_TYPE? */
138 *stmt_p = build2 (CATCH_EXPR, void_type_node, type, body);
141 /* Genericize an EH_SPEC_BLOCK by converting it to a
142 TRY_CATCH_EXPR/EH_FILTER_EXPR pair. */
145 genericize_eh_spec_block (tree *stmt_p)
147 tree body = EH_SPEC_STMTS (*stmt_p);
148 tree allowed = EH_SPEC_RAISES (*stmt_p);
149 tree failure = build_call (call_unexpected_node,
150 tree_cons (NULL_TREE, build_exc_ptr (),
152 gimplify_stmt (&body);
154 *stmt_p = gimple_build_eh_filter (body, allowed, failure);
157 /* Genericize an IF_STMT by turning it into a COND_EXPR. */
160 gimplify_if_stmt (tree *stmt_p)
162 tree stmt, cond, then_, else_;
165 cond = IF_COND (stmt);
166 then_ = THEN_CLAUSE (stmt);
167 else_ = ELSE_CLAUSE (stmt);
170 then_ = build_empty_stmt ();
172 else_ = build_empty_stmt ();
174 if (integer_nonzerop (cond) && !TREE_SIDE_EFFECTS (else_))
176 else if (integer_zerop (cond) && !TREE_SIDE_EFFECTS (then_))
179 stmt = build3 (COND_EXPR, void_type_node, cond, then_, else_);
183 /* Build a generic representation of one of the C loop forms. COND is the
184 loop condition or NULL_TREE. BODY is the (possibly compound) statement
185 controlled by the loop. INCR is the increment expression of a for-loop,
186 or NULL_TREE. COND_IS_FIRST indicates whether the condition is
187 evaluated before the loop body as in while and for loops, or after the
188 loop body as in do-while loops. */
191 /* APPLE LOCAL begin for-fsf-4_4 3274130 5295549 */ \
192 gimplify_cp_loop (tree cond, tree body, tree incr, tree attrs,
193 bool cond_is_first, tree inner_foreach)
194 /* APPLE LOCAL end for-fsf-4_4 3274130 5295549 */ \
196 tree top, entry, exit, cont_block, break_block, stmt_list, t;
197 location_t stmt_locus;
199 stmt_locus = input_location;
200 stmt_list = NULL_TREE;
203 break_block = begin_bc_block (bc_break);
204 cont_block = begin_bc_block (bc_continue);
206 /* If condition is zero don't generate a loop construct. */
207 if (cond && integer_zerop (cond))
213 t = build_bc_goto (bc_break);
214 append_to_statement_list (t, &stmt_list);
219 /* If we use a LOOP_EXPR here, we have to feed the whole thing
220 back through the main gimplifier to lower it. Given that we
221 have to gimplify the loop body NOW so that we can resolve
222 break/continue stmts, seems easier to just expand to gotos. */
223 top = build1 (LABEL_EXPR, void_type_node, NULL_TREE);
225 /* If we have an exit condition, then we build an IF with gotos either
226 out of the loop, or to the top of it. If there's no exit condition,
227 then we just build a jump back to the top. */
228 exit = build_and_jump (&LABEL_EXPR_LABEL (top));
229 /* APPLE LOCAL begin for-fsf-4_4 3274130 5295549 */ \
231 /* Add the attributes to the 'top' label. */
232 decl_attributes (&LABEL_EXPR_LABEL (top), attrs, 0);
234 /* APPLE LOCAL end for-fsf-4_4 3274130 5295549 */ \
235 if (cond && !integer_nonzerop (cond))
237 t = build_bc_goto (bc_break);
238 exit = fold_build3 (COND_EXPR, void_type_node, cond, exit, t);
239 gimplify_stmt (&exit);
245 entry = build1 (LABEL_EXPR, void_type_node, NULL_TREE);
246 t = build_and_jump (&LABEL_EXPR_LABEL (entry));
249 t = build_bc_goto (bc_continue);
250 append_to_statement_list (t, &stmt_list);
255 gimplify_stmt (&body);
256 gimplify_stmt (&incr);
258 body = finish_bc_block (bc_continue, cont_block, body);
260 append_to_statement_list (top, &stmt_list);
261 append_to_statement_list (body, &stmt_list);
262 append_to_statement_list (incr, &stmt_list);
263 append_to_statement_list (entry, &stmt_list);
264 append_to_statement_list (exit, &stmt_list);
266 annotate_all_with_locus (&stmt_list, stmt_locus);
268 return finish_bc_block (bc_break, break_block, stmt_list);
271 /* Gimplify a FOR_STMT node. Move the stuff in the for-init-stmt into the
272 prequeue and hand off to gimplify_cp_loop. */
275 gimplify_for_stmt (tree *stmt_p, tree *pre_p)
279 if (FOR_INIT_STMT (stmt))
280 gimplify_and_add (FOR_INIT_STMT (stmt), pre_p);
282 /* APPLE LOCAL begin for-fsf-4_4 3274130 5295549 */ \
283 *stmt_p = gimplify_cp_loop (FOR_COND (stmt), FOR_BODY (stmt),
284 FOR_EXPR (stmt), FOR_ATTRIBUTES (stmt), 1,
286 /* APPLE LOCAL end for-fsf-4_4 3274130 5295549 */ \
289 /* Gimplify a WHILE_STMT node. */
292 gimplify_while_stmt (tree *stmt_p)
295 /* APPLE LOCAL begin for-fsf-4_4 3274130 5295549 */ \
296 *stmt_p = gimplify_cp_loop (WHILE_COND (stmt), WHILE_BODY (stmt),
297 NULL_TREE, WHILE_ATTRIBUTES (stmt), 1,
299 /* APPLE LOCAL end for-fsf-4_4 3274130 5295549 */ \
302 /* Gimplify a DO_STMT node. */
305 gimplify_do_stmt (tree *stmt_p)
308 /* APPLE LOCAL begin for-fsf-4_4 3274130 5295549 */ \
309 *stmt_p = gimplify_cp_loop (DO_COND (stmt), DO_BODY (stmt),
310 NULL_TREE, DO_ATTRIBUTES (stmt), 0,
312 /* APPLE LOCAL end for-fsf-4_4 3274130 5295549 */ \
315 /* Genericize a SWITCH_STMT by turning it into a SWITCH_EXPR. */
318 gimplify_switch_stmt (tree *stmt_p)
321 tree break_block, body;
322 location_t stmt_locus = input_location;
324 break_block = begin_bc_block (bc_break);
326 body = SWITCH_STMT_BODY (stmt);
328 body = build_empty_stmt ();
330 *stmt_p = build3 (SWITCH_EXPR, SWITCH_STMT_TYPE (stmt),
331 SWITCH_STMT_COND (stmt), body, NULL_TREE);
332 SET_EXPR_LOCATION (*stmt_p, stmt_locus);
333 gimplify_stmt (stmt_p);
335 *stmt_p = finish_bc_block (bc_break, break_block, *stmt_p);
338 /* Hook into the middle of gimplifying an OMP_FOR node. This is required
339 in order to properly gimplify CONTINUE statements. Here we merely
340 manage the continue stack; the rest of the job is performed by the
341 regular gimplifier. */
343 static enum gimplify_status
344 cp_gimplify_omp_for (tree *expr_p)
346 tree for_stmt = *expr_p;
349 /* Protect ourselves from recursion. */
350 if (OMP_FOR_GIMPLIFYING_P (for_stmt))
352 OMP_FOR_GIMPLIFYING_P (for_stmt) = 1;
354 /* Note that while technically the continue label is enabled too soon
355 here, we should have already diagnosed invalid continues nested within
356 statement expressions within the INIT, COND, or INCR expressions. */
357 cont_block = begin_bc_block (bc_continue);
359 gimplify_stmt (expr_p);
361 OMP_FOR_BODY (for_stmt)
362 = finish_bc_block (bc_continue, cont_block, OMP_FOR_BODY (for_stmt));
363 OMP_FOR_GIMPLIFYING_P (for_stmt) = 0;
368 /* Gimplify an EXPR_STMT node. */
371 gimplify_expr_stmt (tree *stmt_p)
373 tree stmt = EXPR_STMT_EXPR (*stmt_p);
375 if (stmt == error_mark_node)
378 /* Gimplification of a statement expression will nullify the
379 statement if all its side effects are moved to *PRE_P and *POST_P.
381 In this case we will not want to emit the gimplified statement.
382 However, we may still want to emit a warning, so we do that before
384 if (stmt && (extra_warnings || warn_unused_value))
386 if (!TREE_SIDE_EFFECTS (stmt))
388 if (!IS_EMPTY_STMT (stmt)
389 && !VOID_TYPE_P (TREE_TYPE (stmt))
390 && !TREE_NO_WARNING (stmt))
391 warning (OPT_Wextra, "statement with no effect");
393 else if (warn_unused_value)
394 warn_if_unused_value (stmt, input_location);
397 if (stmt == NULL_TREE)
398 stmt = alloc_stmt_list ();
403 /* Gimplify initialization from an AGGR_INIT_EXPR. */
406 cp_gimplify_init_expr (tree *expr_p, tree *pre_p, tree *post_p)
408 tree from = TREE_OPERAND (*expr_p, 1);
409 tree to = TREE_OPERAND (*expr_p, 0);
412 /* What about code that pulls out the temp and uses it elsewhere? I
413 think that such code never uses the TARGET_EXPR as an initializer. If
414 I'm wrong, we'll abort because the temp won't have any RTL. In that
415 case, I guess we'll need to replace references somehow. */
416 if (TREE_CODE (from) == TARGET_EXPR)
417 from = TARGET_EXPR_INITIAL (from);
419 /* Look through any COMPOUND_EXPRs, since build_compound_expr pushes them
420 inside the TARGET_EXPR. */
421 sub = expr_last (from);
423 /* If we are initializing from an AGGR_INIT_EXPR, drop the INIT_EXPR and
424 replace the slot operand with our target.
426 Should we add a target parm to gimplify_expr instead? No, as in this
427 case we want to replace the INIT_EXPR. */
428 if (TREE_CODE (sub) == AGGR_INIT_EXPR)
430 gimplify_expr (&to, pre_p, post_p, is_gimple_lvalue, fb_lvalue);
431 TREE_OPERAND (sub, 2) = to;
434 /* The initialization is now a side-effect, so the container can
437 TREE_TYPE (from) = void_type_node;
441 /* Gimplify a MUST_NOT_THROW_EXPR. */
444 gimplify_must_not_throw_expr (tree *expr_p, tree *pre_p)
447 tree temp = voidify_wrapper_expr (stmt, NULL);
448 tree body = TREE_OPERAND (stmt, 0);
450 gimplify_stmt (&body);
452 stmt = gimple_build_eh_filter (body, NULL_TREE,
453 build_call (terminate_node, NULL_TREE));
457 append_to_statement_list (stmt, pre_p);
464 /* Do C++-specific gimplification. Args are as for gimplify_expr. */
467 cp_gimplify_expr (tree *expr_p, tree *pre_p, tree *post_p)
469 int saved_stmts_are_full_exprs_p = 0;
470 enum tree_code code = TREE_CODE (*expr_p);
471 enum gimplify_status ret;
473 if (STATEMENT_CODE_P (code))
475 saved_stmts_are_full_exprs_p = stmts_are_full_exprs_p ();
476 current_stmt_tree ()->stmts_are_full_exprs_p
477 = STMT_IS_FULL_EXPR_P (*expr_p);
483 *expr_p = cplus_expand_constant (*expr_p);
488 simplify_aggr_init_expr (expr_p);
493 /* FIXME communicate throw type to backend, probably by moving
494 THROW_EXPR into ../tree.def. */
495 *expr_p = TREE_OPERAND (*expr_p, 0);
499 case MUST_NOT_THROW_EXPR:
500 gimplify_must_not_throw_expr (expr_p, pre_p);
504 /* We used to do this for MODIFY_EXPR as well, but that's unsafe; the
505 LHS of an assignment might also be involved in the RHS, as in bug
508 cp_gimplify_init_expr (expr_p, pre_p, post_p);
512 case EMPTY_CLASS_EXPR:
513 /* We create an empty CONSTRUCTOR with RECORD_TYPE. */
514 *expr_p = build_constructor (TREE_TYPE (*expr_p), NULL);
519 *expr_p = BASELINK_FUNCTIONS (*expr_p);
524 genericize_try_block (expr_p);
529 genericize_catch_block (expr_p);
534 genericize_eh_spec_block (expr_p);
539 /* Just ignore for now. Eventually we will want to pass this on to
541 *expr_p = build_empty_stmt ();
546 gimplify_if_stmt (expr_p);
551 gimplify_for_stmt (expr_p, pre_p);
556 gimplify_while_stmt (expr_p);
561 gimplify_do_stmt (expr_p);
566 gimplify_switch_stmt (expr_p);
571 ret = cp_gimplify_omp_for (expr_p);
575 *expr_p = build_bc_goto (bc_continue);
580 *expr_p = build_bc_goto (bc_break);
585 gimplify_expr_stmt (expr_p);
589 case UNARY_PLUS_EXPR:
591 tree arg = TREE_OPERAND (*expr_p, 0);
592 tree type = TREE_TYPE (*expr_p);
593 *expr_p = (TREE_TYPE (arg) != type) ? fold_convert (type, arg)
600 ret = c_gimplify_expr (expr_p, pre_p, post_p);
604 /* Restore saved state. */
605 if (STATEMENT_CODE_P (code))
606 current_stmt_tree ()->stmts_are_full_exprs_p
607 = saved_stmts_are_full_exprs_p;
613 is_invisiref_parm (tree t)
615 return ((TREE_CODE (t) == PARM_DECL || TREE_CODE (t) == RESULT_DECL)
616 && DECL_BY_REFERENCE (t));
619 /* Return true if the uid in both int tree maps are equal. */
622 cxx_int_tree_map_eq (const void *va, const void *vb)
624 const struct cxx_int_tree_map *a = (const struct cxx_int_tree_map *) va;
625 const struct cxx_int_tree_map *b = (const struct cxx_int_tree_map *) vb;
626 return (a->uid == b->uid);
629 /* Hash a UID in a cxx_int_tree_map. */
632 cxx_int_tree_map_hash (const void *item)
634 return ((const struct cxx_int_tree_map *)item)->uid;
637 /* Perform any pre-gimplification lowering of C++ front end trees to
641 cp_genericize_r (tree *stmt_p, int *walk_subtrees, void *data)
644 struct pointer_set_t *p_set = (struct pointer_set_t*) data;
646 if (is_invisiref_parm (stmt)
647 /* Don't dereference parms in a thunk, pass the references through. */
648 && !(DECL_THUNK_P (current_function_decl)
649 && TREE_CODE (stmt) == PARM_DECL))
651 *stmt_p = convert_from_reference (stmt);
656 /* Map block scope extern declarations to visible declarations with the
657 same name and type in outer scopes if any. */
658 if (cp_function_chain->extern_decl_map
659 && (TREE_CODE (stmt) == FUNCTION_DECL || TREE_CODE (stmt) == VAR_DECL)
660 && DECL_EXTERNAL (stmt))
662 struct cxx_int_tree_map *h, in;
663 in.uid = DECL_UID (stmt);
664 h = (struct cxx_int_tree_map *)
665 htab_find_with_hash (cp_function_chain->extern_decl_map,
675 /* Other than invisiref parms, don't walk the same tree twice. */
676 if (pointer_set_contains (p_set, stmt))
682 if (TREE_CODE (stmt) == ADDR_EXPR
683 && is_invisiref_parm (TREE_OPERAND (stmt, 0)))
685 *stmt_p = convert (TREE_TYPE (stmt), TREE_OPERAND (stmt, 0));
688 else if (TREE_CODE (stmt) == RETURN_EXPR
689 && TREE_OPERAND (stmt, 0)
690 && is_invisiref_parm (TREE_OPERAND (stmt, 0)))
691 /* Don't dereference an invisiref RESULT_DECL inside a RETURN_EXPR. */
693 else if (TREE_CODE (stmt) == OMP_CLAUSE)
694 switch (OMP_CLAUSE_CODE (stmt))
696 case OMP_CLAUSE_PRIVATE:
697 case OMP_CLAUSE_SHARED:
698 case OMP_CLAUSE_FIRSTPRIVATE:
699 case OMP_CLAUSE_LASTPRIVATE:
700 case OMP_CLAUSE_COPYIN:
701 case OMP_CLAUSE_COPYPRIVATE:
702 /* Don't dereference an invisiref in OpenMP clauses. */
703 if (is_invisiref_parm (OMP_CLAUSE_DECL (stmt)))
706 case OMP_CLAUSE_REDUCTION:
707 gcc_assert (!is_invisiref_parm (OMP_CLAUSE_DECL (stmt)));
712 else if (IS_TYPE_OR_DECL_P (stmt))
715 /* Due to the way voidify_wrapper_expr is written, we don't get a chance
716 to lower this construct before scanning it, so we need to lower these
717 before doing anything else. */
718 else if (TREE_CODE (stmt) == CLEANUP_STMT)
719 *stmt_p = build2 (CLEANUP_EH_ONLY (stmt) ? TRY_CATCH_EXPR
723 CLEANUP_EXPR (stmt));
725 pointer_set_insert (p_set, *stmt_p);
731 cp_genericize (tree fndecl)
734 struct pointer_set_t *p_set;
736 /* Fix up the types of parms passed by invisible reference. */
737 for (t = DECL_ARGUMENTS (fndecl); t; t = TREE_CHAIN (t))
738 if (TREE_ADDRESSABLE (TREE_TYPE (t)))
740 /* If a function's arguments are copied to create a thunk,
741 then DECL_BY_REFERENCE will be set -- but the type of the
742 argument will be a pointer type, so we will never get
744 gcc_assert (!DECL_BY_REFERENCE (t));
745 gcc_assert (DECL_ARG_TYPE (t) != TREE_TYPE (t));
746 TREE_TYPE (t) = DECL_ARG_TYPE (t);
747 DECL_BY_REFERENCE (t) = 1;
748 TREE_ADDRESSABLE (t) = 0;
752 /* Do the same for the return value. */
753 if (TREE_ADDRESSABLE (TREE_TYPE (DECL_RESULT (fndecl))))
755 t = DECL_RESULT (fndecl);
756 TREE_TYPE (t) = build_reference_type (TREE_TYPE (t));
757 DECL_BY_REFERENCE (t) = 1;
758 TREE_ADDRESSABLE (t) = 0;
762 /* If we're a clone, the body is already GIMPLE. */
763 if (DECL_CLONED_FUNCTION_P (fndecl))
766 /* We do want to see every occurrence of the parms, so we can't just use
767 walk_tree's hash functionality. */
768 p_set = pointer_set_create ();
769 walk_tree (&DECL_SAVED_TREE (fndecl), cp_genericize_r, p_set, NULL);
770 pointer_set_destroy (p_set);
772 /* Do everything else. */
773 c_genericize (fndecl);
775 gcc_assert (bc_label[bc_break] == NULL);
776 gcc_assert (bc_label[bc_continue] == NULL);
779 /* Build code to apply FN to each member of ARG1 and ARG2. FN may be
780 NULL if there is in fact nothing to do. ARG2 may be null if FN
781 actually only takes one argument. */
784 cxx_omp_clause_apply_fn (tree fn, tree arg1, tree arg2)
792 defparm = TREE_CHAIN (TYPE_ARG_TYPES (TREE_TYPE (fn)));
794 defparm = TREE_CHAIN (defparm);
796 if (TREE_CODE (TREE_TYPE (arg1)) == ARRAY_TYPE)
798 tree inner_type = TREE_TYPE (arg1);
799 tree start1, end1, p1;
800 tree start2 = NULL, p2 = NULL;
801 tree ret = NULL, lab, t;
807 inner_type = TREE_TYPE (inner_type);
808 start1 = build4 (ARRAY_REF, inner_type, start1,
809 size_zero_node, NULL, NULL);
811 start2 = build4 (ARRAY_REF, inner_type, start2,
812 size_zero_node, NULL, NULL);
814 while (TREE_CODE (inner_type) == ARRAY_TYPE);
815 start1 = build_fold_addr_expr (start1);
817 start2 = build_fold_addr_expr (start2);
819 end1 = TYPE_SIZE_UNIT (TREE_TYPE (arg1));
820 end1 = fold_convert (TREE_TYPE (start1), end1);
821 end1 = build2 (PLUS_EXPR, TREE_TYPE (start1), start1, end1);
823 p1 = create_tmp_var (TREE_TYPE (start1), NULL);
824 t = build2 (MODIFY_EXPR, void_type_node, p1, start1);
825 append_to_statement_list (t, &ret);
829 p2 = create_tmp_var (TREE_TYPE (start2), NULL);
830 t = build2 (MODIFY_EXPR, void_type_node, p2, start2);
831 append_to_statement_list (t, &ret);
834 lab = create_artificial_label ();
835 t = build1 (LABEL_EXPR, void_type_node, lab);
836 append_to_statement_list (t, &ret);
838 t = tree_cons (NULL, p1, NULL);
840 t = tree_cons (NULL, p2, t);
841 /* Handle default arguments. */
842 i = 1 + (arg2 != NULL);
843 for (parm = defparm; parm != void_list_node; parm = TREE_CHAIN (parm))
844 t = tree_cons (NULL, convert_default_arg (TREE_VALUE (parm),
847 t = build_call (fn, nreverse (t));
848 append_to_statement_list (t, &ret);
850 t = fold_convert (TREE_TYPE (p1), TYPE_SIZE_UNIT (inner_type));
851 t = build2 (PLUS_EXPR, TREE_TYPE (p1), p1, t);
852 t = build2 (MODIFY_EXPR, void_type_node, p1, t);
853 append_to_statement_list (t, &ret);
857 t = fold_convert (TREE_TYPE (p2), TYPE_SIZE_UNIT (inner_type));
858 t = build2 (PLUS_EXPR, TREE_TYPE (p2), p2, t);
859 t = build2 (MODIFY_EXPR, void_type_node, p2, t);
860 append_to_statement_list (t, &ret);
863 t = build2 (NE_EXPR, boolean_type_node, p1, end1);
864 t = build3 (COND_EXPR, void_type_node, t, build_and_jump (&lab), NULL);
865 append_to_statement_list (t, &ret);
871 tree t = tree_cons (NULL, build_fold_addr_expr (arg1), NULL);
873 t = tree_cons (NULL, build_fold_addr_expr (arg2), t);
874 /* Handle default arguments. */
875 i = 1 + (arg2 != NULL);
876 for (parm = defparm; parm != void_list_node; parm = TREE_CHAIN (parm))
877 t = tree_cons (NULL, convert_default_arg (TREE_VALUE (parm),
880 return build_call (fn, nreverse (t));
884 /* Return code to initialize DECL with its default constructor, or
885 NULL if there's nothing to do. */
888 cxx_omp_clause_default_ctor (tree clause, tree decl)
890 tree info = CP_OMP_CLAUSE_INFO (clause);
894 ret = cxx_omp_clause_apply_fn (TREE_VEC_ELT (info, 0), decl, NULL);
899 /* Return code to initialize DST with a copy constructor from SRC. */
902 cxx_omp_clause_copy_ctor (tree clause, tree dst, tree src)
904 tree info = CP_OMP_CLAUSE_INFO (clause);
908 ret = cxx_omp_clause_apply_fn (TREE_VEC_ELT (info, 0), dst, src);
910 ret = build2 (MODIFY_EXPR, void_type_node, dst, src);
915 /* Similarly, except use an assignment operator instead. */
918 cxx_omp_clause_assign_op (tree clause, tree dst, tree src)
920 tree info = CP_OMP_CLAUSE_INFO (clause);
924 ret = cxx_omp_clause_apply_fn (TREE_VEC_ELT (info, 2), dst, src);
926 ret = build2 (MODIFY_EXPR, void_type_node, dst, src);
931 /* Return code to destroy DECL. */
934 cxx_omp_clause_dtor (tree clause, tree decl)
936 tree info = CP_OMP_CLAUSE_INFO (clause);
940 ret = cxx_omp_clause_apply_fn (TREE_VEC_ELT (info, 1), decl, NULL);
945 /* True if OpenMP should privatize what this DECL points to rather
946 than the DECL itself. */
949 cxx_omp_privatize_by_reference (tree decl)
951 return is_invisiref_parm (decl);