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 /* APPLE LOCAL begin C* language */
204 /* Order of label addition to stack is important for objc's foreach-stmt. */
205 /* APPLE LOCAL radar 4667060 */
206 if (inner_foreach == integer_zero_node)
208 cont_block = begin_bc_block (bc_continue);
209 break_block = begin_bc_block (bc_break);
213 break_block = begin_bc_block (bc_break);
214 cont_block = begin_bc_block (bc_continue);
216 /* APPLE LOCAL end C* language */
218 /* If condition is zero don't generate a loop construct. */
219 if (cond && integer_zerop (cond))
225 t = build_bc_goto (bc_break);
226 append_to_statement_list (t, &stmt_list);
231 /* If we use a LOOP_EXPR here, we have to feed the whole thing
232 back through the main gimplifier to lower it. Given that we
233 have to gimplify the loop body NOW so that we can resolve
234 break/continue stmts, seems easier to just expand to gotos. */
235 top = build1 (LABEL_EXPR, void_type_node, NULL_TREE);
237 /* If we have an exit condition, then we build an IF with gotos either
238 out of the loop, or to the top of it. If there's no exit condition,
239 then we just build a jump back to the top. */
240 exit = build_and_jump (&LABEL_EXPR_LABEL (top));
241 /* APPLE LOCAL begin for-fsf-4_4 3274130 5295549 */ \
243 /* Add the attributes to the 'top' label. */
244 decl_attributes (&LABEL_EXPR_LABEL (top), attrs, 0);
246 /* APPLE LOCAL end for-fsf-4_4 3274130 5295549 */ \
247 if (cond && !integer_nonzerop (cond))
249 t = build_bc_goto (bc_break);
250 exit = fold_build3 (COND_EXPR, void_type_node, cond, exit, t);
251 gimplify_stmt (&exit);
257 entry = build1 (LABEL_EXPR, void_type_node, NULL_TREE);
258 t = build_and_jump (&LABEL_EXPR_LABEL (entry));
261 t = build_bc_goto (bc_continue);
262 append_to_statement_list (t, &stmt_list);
267 /* APPLE LOCAL begin radar 4547045 */
268 /* Pop foreach's inner loop break label so outer loop's
269 break label becomes target of inner loop body's break statements.
272 gimplify_stmt (&body);
273 gimplify_stmt (&incr);
275 body = finish_bc_block (bc_continue, cont_block, body);
276 /* APPLE LOCAL begin radar 4547045 */
277 /* Push back inner loop's own 'break' label so rest
278 of code works seemlessly. */
279 /* APPLE LOCAL radar 4667060 */
281 append_to_statement_list (top, &stmt_list);
282 append_to_statement_list (body, &stmt_list);
283 append_to_statement_list (incr, &stmt_list);
284 append_to_statement_list (entry, &stmt_list);
285 append_to_statement_list (exit, &stmt_list);
287 annotate_all_with_locus (&stmt_list, stmt_locus);
289 return finish_bc_block (bc_break, break_block, stmt_list);
292 /* Gimplify a FOR_STMT node. Move the stuff in the for-init-stmt into the
293 prequeue and hand off to gimplify_cp_loop. */
296 gimplify_for_stmt (tree *stmt_p, tree *pre_p)
300 if (FOR_INIT_STMT (stmt))
301 gimplify_and_add (FOR_INIT_STMT (stmt), pre_p);
303 /* APPLE LOCAL begin for-fsf-4_4 3274130 5295549 */ \
304 *stmt_p = gimplify_cp_loop (FOR_COND (stmt), FOR_BODY (stmt),
305 FOR_EXPR (stmt), FOR_ATTRIBUTES (stmt), 1,
307 /* APPLE LOCAL end for-fsf-4_4 3274130 5295549 */ \
310 /* Gimplify a WHILE_STMT node. */
313 gimplify_while_stmt (tree *stmt_p)
316 /* APPLE LOCAL begin for-fsf-4_4 3274130 5295549 */ \
317 *stmt_p = gimplify_cp_loop (WHILE_COND (stmt), WHILE_BODY (stmt),
318 NULL_TREE, WHILE_ATTRIBUTES (stmt), 1,
320 /* APPLE LOCAL end for-fsf-4_4 3274130 5295549 */ \
323 /* Gimplify a DO_STMT node. */
326 gimplify_do_stmt (tree *stmt_p)
329 /* APPLE LOCAL begin for-fsf-4_4 3274130 5295549 */ \
330 *stmt_p = gimplify_cp_loop (DO_COND (stmt), DO_BODY (stmt),
331 NULL_TREE, DO_ATTRIBUTES (stmt), 0,
333 /* APPLE LOCAL end for-fsf-4_4 3274130 5295549 */ \
336 /* Genericize a SWITCH_STMT by turning it into a SWITCH_EXPR. */
339 gimplify_switch_stmt (tree *stmt_p)
342 tree break_block, body;
343 location_t stmt_locus = input_location;
345 break_block = begin_bc_block (bc_break);
347 body = SWITCH_STMT_BODY (stmt);
349 body = build_empty_stmt ();
351 *stmt_p = build3 (SWITCH_EXPR, SWITCH_STMT_TYPE (stmt),
352 SWITCH_STMT_COND (stmt), body, NULL_TREE);
353 SET_EXPR_LOCATION (*stmt_p, stmt_locus);
354 gimplify_stmt (stmt_p);
356 *stmt_p = finish_bc_block (bc_break, break_block, *stmt_p);
359 /* Hook into the middle of gimplifying an OMP_FOR node. This is required
360 in order to properly gimplify CONTINUE statements. Here we merely
361 manage the continue stack; the rest of the job is performed by the
362 regular gimplifier. */
364 static enum gimplify_status
365 cp_gimplify_omp_for (tree *expr_p)
367 tree for_stmt = *expr_p;
370 /* Protect ourselves from recursion. */
371 if (OMP_FOR_GIMPLIFYING_P (for_stmt))
373 OMP_FOR_GIMPLIFYING_P (for_stmt) = 1;
375 /* Note that while technically the continue label is enabled too soon
376 here, we should have already diagnosed invalid continues nested within
377 statement expressions within the INIT, COND, or INCR expressions. */
378 cont_block = begin_bc_block (bc_continue);
380 gimplify_stmt (expr_p);
382 OMP_FOR_BODY (for_stmt)
383 = finish_bc_block (bc_continue, cont_block, OMP_FOR_BODY (for_stmt));
384 OMP_FOR_GIMPLIFYING_P (for_stmt) = 0;
389 /* Gimplify an EXPR_STMT node. */
392 gimplify_expr_stmt (tree *stmt_p)
394 tree stmt = EXPR_STMT_EXPR (*stmt_p);
396 if (stmt == error_mark_node)
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
405 if (stmt && (extra_warnings || 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_Wextra, "statement with no effect");
414 else if (warn_unused_value)
415 warn_if_unused_value (stmt, input_location);
418 if (stmt == NULL_TREE)
419 stmt = alloc_stmt_list ();
424 /* Gimplify initialization from an AGGR_INIT_EXPR. */
427 cp_gimplify_init_expr (tree *expr_p, tree *pre_p, tree *post_p)
429 tree from = TREE_OPERAND (*expr_p, 1);
430 tree to = TREE_OPERAND (*expr_p, 0);
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 sub = expr_last (from);
444 /* If we are initializing from an AGGR_INIT_EXPR, drop the INIT_EXPR and
445 replace the slot operand with our target.
447 Should we add a target parm to gimplify_expr instead? No, as in this
448 case we want to replace the INIT_EXPR. */
449 if (TREE_CODE (sub) == AGGR_INIT_EXPR)
451 gimplify_expr (&to, pre_p, post_p, is_gimple_lvalue, fb_lvalue);
452 TREE_OPERAND (sub, 2) = to;
455 /* The initialization is now a side-effect, so the container can
458 TREE_TYPE (from) = void_type_node;
462 /* Gimplify a MUST_NOT_THROW_EXPR. */
465 gimplify_must_not_throw_expr (tree *expr_p, tree *pre_p)
468 tree temp = voidify_wrapper_expr (stmt, NULL);
469 tree body = TREE_OPERAND (stmt, 0);
471 gimplify_stmt (&body);
473 stmt = gimple_build_eh_filter (body, NULL_TREE,
474 build_call (terminate_node, NULL_TREE));
478 append_to_statement_list (stmt, pre_p);
485 /* Do C++-specific gimplification. Args are as for gimplify_expr. */
488 cp_gimplify_expr (tree *expr_p, tree *pre_p, tree *post_p)
490 int saved_stmts_are_full_exprs_p = 0;
491 enum tree_code code = TREE_CODE (*expr_p);
492 enum gimplify_status ret;
494 if (STATEMENT_CODE_P (code))
496 saved_stmts_are_full_exprs_p = stmts_are_full_exprs_p ();
497 current_stmt_tree ()->stmts_are_full_exprs_p
498 = STMT_IS_FULL_EXPR_P (*expr_p);
504 *expr_p = cplus_expand_constant (*expr_p);
509 simplify_aggr_init_expr (expr_p);
514 /* FIXME communicate throw type to backend, probably by moving
515 THROW_EXPR into ../tree.def. */
516 *expr_p = TREE_OPERAND (*expr_p, 0);
520 case MUST_NOT_THROW_EXPR:
521 gimplify_must_not_throw_expr (expr_p, pre_p);
525 /* We used to do this for MODIFY_EXPR as well, but that's unsafe; the
526 LHS of an assignment might also be involved in the RHS, as in bug
529 cp_gimplify_init_expr (expr_p, pre_p, post_p);
533 case EMPTY_CLASS_EXPR:
534 /* We create an empty CONSTRUCTOR with RECORD_TYPE. */
535 *expr_p = build_constructor (TREE_TYPE (*expr_p), NULL);
540 *expr_p = BASELINK_FUNCTIONS (*expr_p);
545 genericize_try_block (expr_p);
550 genericize_catch_block (expr_p);
555 genericize_eh_spec_block (expr_p);
560 /* Just ignore for now. Eventually we will want to pass this on to
562 *expr_p = build_empty_stmt ();
567 gimplify_if_stmt (expr_p);
572 gimplify_for_stmt (expr_p, pre_p);
577 gimplify_while_stmt (expr_p);
582 gimplify_do_stmt (expr_p);
587 gimplify_switch_stmt (expr_p);
592 ret = cp_gimplify_omp_for (expr_p);
596 *expr_p = build_bc_goto (bc_continue);
601 *expr_p = build_bc_goto (bc_break);
606 gimplify_expr_stmt (expr_p);
610 case UNARY_PLUS_EXPR:
612 tree arg = TREE_OPERAND (*expr_p, 0);
613 tree type = TREE_TYPE (*expr_p);
614 *expr_p = (TREE_TYPE (arg) != type) ? fold_convert (type, arg)
621 ret = c_gimplify_expr (expr_p, pre_p, post_p);
625 /* Restore saved state. */
626 if (STATEMENT_CODE_P (code))
627 current_stmt_tree ()->stmts_are_full_exprs_p
628 = saved_stmts_are_full_exprs_p;
634 is_invisiref_parm (tree t)
636 return ((TREE_CODE (t) == PARM_DECL || TREE_CODE (t) == RESULT_DECL)
637 && DECL_BY_REFERENCE (t));
640 /* Return true if the uid in both int tree maps are equal. */
643 cxx_int_tree_map_eq (const void *va, const void *vb)
645 const struct cxx_int_tree_map *a = (const struct cxx_int_tree_map *) va;
646 const struct cxx_int_tree_map *b = (const struct cxx_int_tree_map *) vb;
647 return (a->uid == b->uid);
650 /* Hash a UID in a cxx_int_tree_map. */
653 cxx_int_tree_map_hash (const void *item)
655 return ((const struct cxx_int_tree_map *)item)->uid;
658 /* Perform any pre-gimplification lowering of C++ front end trees to
662 cp_genericize_r (tree *stmt_p, int *walk_subtrees, void *data)
665 struct pointer_set_t *p_set = (struct pointer_set_t*) data;
667 if (is_invisiref_parm (stmt)
668 /* Don't dereference parms in a thunk, pass the references through. */
669 && !(DECL_THUNK_P (current_function_decl)
670 && TREE_CODE (stmt) == PARM_DECL))
672 *stmt_p = convert_from_reference (stmt);
677 /* Map block scope extern declarations to visible declarations with the
678 same name and type in outer scopes if any. */
679 if (cp_function_chain->extern_decl_map
680 && (TREE_CODE (stmt) == FUNCTION_DECL || TREE_CODE (stmt) == VAR_DECL)
681 && DECL_EXTERNAL (stmt))
683 struct cxx_int_tree_map *h, in;
684 in.uid = DECL_UID (stmt);
685 h = (struct cxx_int_tree_map *)
686 htab_find_with_hash (cp_function_chain->extern_decl_map,
696 /* Other than invisiref parms, don't walk the same tree twice. */
697 if (pointer_set_contains (p_set, stmt))
703 if (TREE_CODE (stmt) == ADDR_EXPR
704 && is_invisiref_parm (TREE_OPERAND (stmt, 0)))
706 *stmt_p = convert (TREE_TYPE (stmt), TREE_OPERAND (stmt, 0));
709 else if (TREE_CODE (stmt) == RETURN_EXPR
710 && TREE_OPERAND (stmt, 0)
711 && is_invisiref_parm (TREE_OPERAND (stmt, 0)))
712 /* Don't dereference an invisiref RESULT_DECL inside a RETURN_EXPR. */
714 else if (TREE_CODE (stmt) == OMP_CLAUSE)
715 switch (OMP_CLAUSE_CODE (stmt))
717 case OMP_CLAUSE_PRIVATE:
718 case OMP_CLAUSE_SHARED:
719 case OMP_CLAUSE_FIRSTPRIVATE:
720 case OMP_CLAUSE_LASTPRIVATE:
721 case OMP_CLAUSE_COPYIN:
722 case OMP_CLAUSE_COPYPRIVATE:
723 /* Don't dereference an invisiref in OpenMP clauses. */
724 if (is_invisiref_parm (OMP_CLAUSE_DECL (stmt)))
727 case OMP_CLAUSE_REDUCTION:
728 gcc_assert (!is_invisiref_parm (OMP_CLAUSE_DECL (stmt)));
733 else if (IS_TYPE_OR_DECL_P (stmt))
736 /* Due to the way voidify_wrapper_expr is written, we don't get a chance
737 to lower this construct before scanning it, so we need to lower these
738 before doing anything else. */
739 else if (TREE_CODE (stmt) == CLEANUP_STMT)
740 *stmt_p = build2 (CLEANUP_EH_ONLY (stmt) ? TRY_CATCH_EXPR
744 CLEANUP_EXPR (stmt));
746 pointer_set_insert (p_set, *stmt_p);
752 cp_genericize (tree fndecl)
755 struct pointer_set_t *p_set;
757 /* Fix up the types of parms passed by invisible reference. */
758 for (t = DECL_ARGUMENTS (fndecl); t; t = TREE_CHAIN (t))
759 if (TREE_ADDRESSABLE (TREE_TYPE (t)))
761 /* If a function's arguments are copied to create a thunk,
762 then DECL_BY_REFERENCE will be set -- but the type of the
763 argument will be a pointer type, so we will never get
765 gcc_assert (!DECL_BY_REFERENCE (t));
766 gcc_assert (DECL_ARG_TYPE (t) != TREE_TYPE (t));
767 TREE_TYPE (t) = DECL_ARG_TYPE (t);
768 DECL_BY_REFERENCE (t) = 1;
769 TREE_ADDRESSABLE (t) = 0;
773 /* Do the same for the return value. */
774 if (TREE_ADDRESSABLE (TREE_TYPE (DECL_RESULT (fndecl))))
776 t = DECL_RESULT (fndecl);
777 TREE_TYPE (t) = build_reference_type (TREE_TYPE (t));
778 DECL_BY_REFERENCE (t) = 1;
779 TREE_ADDRESSABLE (t) = 0;
783 /* If we're a clone, the body is already GIMPLE. */
784 if (DECL_CLONED_FUNCTION_P (fndecl))
787 /* We do want to see every occurrence of the parms, so we can't just use
788 walk_tree's hash functionality. */
789 p_set = pointer_set_create ();
790 walk_tree (&DECL_SAVED_TREE (fndecl), cp_genericize_r, p_set, NULL);
791 pointer_set_destroy (p_set);
793 /* Do everything else. */
794 c_genericize (fndecl);
796 gcc_assert (bc_label[bc_break] == NULL);
797 gcc_assert (bc_label[bc_continue] == NULL);
800 /* Build code to apply FN to each member of ARG1 and ARG2. FN may be
801 NULL if there is in fact nothing to do. ARG2 may be null if FN
802 actually only takes one argument. */
805 cxx_omp_clause_apply_fn (tree fn, tree arg1, tree arg2)
813 defparm = TREE_CHAIN (TYPE_ARG_TYPES (TREE_TYPE (fn)));
815 defparm = TREE_CHAIN (defparm);
817 if (TREE_CODE (TREE_TYPE (arg1)) == ARRAY_TYPE)
819 tree inner_type = TREE_TYPE (arg1);
820 tree start1, end1, p1;
821 tree start2 = NULL, p2 = NULL;
822 tree ret = NULL, lab, t;
828 inner_type = TREE_TYPE (inner_type);
829 start1 = build4 (ARRAY_REF, inner_type, start1,
830 size_zero_node, NULL, NULL);
832 start2 = build4 (ARRAY_REF, inner_type, start2,
833 size_zero_node, NULL, NULL);
835 while (TREE_CODE (inner_type) == ARRAY_TYPE);
836 start1 = build_fold_addr_expr (start1);
838 start2 = build_fold_addr_expr (start2);
840 end1 = TYPE_SIZE_UNIT (TREE_TYPE (arg1));
841 end1 = fold_convert (TREE_TYPE (start1), end1);
842 end1 = build2 (PLUS_EXPR, TREE_TYPE (start1), start1, end1);
844 p1 = create_tmp_var (TREE_TYPE (start1), NULL);
845 t = build2 (MODIFY_EXPR, void_type_node, p1, start1);
846 append_to_statement_list (t, &ret);
850 p2 = create_tmp_var (TREE_TYPE (start2), NULL);
851 t = build2 (MODIFY_EXPR, void_type_node, p2, start2);
852 append_to_statement_list (t, &ret);
855 lab = create_artificial_label ();
856 t = build1 (LABEL_EXPR, void_type_node, lab);
857 append_to_statement_list (t, &ret);
859 t = tree_cons (NULL, p1, NULL);
861 t = tree_cons (NULL, p2, t);
862 /* Handle default arguments. */
863 i = 1 + (arg2 != NULL);
864 for (parm = defparm; parm != void_list_node; parm = TREE_CHAIN (parm))
865 t = tree_cons (NULL, convert_default_arg (TREE_VALUE (parm),
868 t = build_call (fn, nreverse (t));
869 append_to_statement_list (t, &ret);
871 t = fold_convert (TREE_TYPE (p1), TYPE_SIZE_UNIT (inner_type));
872 t = build2 (PLUS_EXPR, TREE_TYPE (p1), p1, t);
873 t = build2 (MODIFY_EXPR, void_type_node, p1, t);
874 append_to_statement_list (t, &ret);
878 t = fold_convert (TREE_TYPE (p2), TYPE_SIZE_UNIT (inner_type));
879 t = build2 (PLUS_EXPR, TREE_TYPE (p2), p2, t);
880 t = build2 (MODIFY_EXPR, void_type_node, p2, t);
881 append_to_statement_list (t, &ret);
884 t = build2 (NE_EXPR, boolean_type_node, p1, end1);
885 t = build3 (COND_EXPR, void_type_node, t, build_and_jump (&lab), NULL);
886 append_to_statement_list (t, &ret);
892 tree t = tree_cons (NULL, build_fold_addr_expr (arg1), NULL);
894 t = tree_cons (NULL, build_fold_addr_expr (arg2), t);
895 /* Handle default arguments. */
896 i = 1 + (arg2 != NULL);
897 for (parm = defparm; parm != void_list_node; parm = TREE_CHAIN (parm))
898 t = tree_cons (NULL, convert_default_arg (TREE_VALUE (parm),
901 return build_call (fn, nreverse (t));
905 /* Return code to initialize DECL with its default constructor, or
906 NULL if there's nothing to do. */
909 cxx_omp_clause_default_ctor (tree clause, tree decl)
911 tree info = CP_OMP_CLAUSE_INFO (clause);
915 ret = cxx_omp_clause_apply_fn (TREE_VEC_ELT (info, 0), decl, NULL);
920 /* Return code to initialize DST with a copy constructor from SRC. */
923 cxx_omp_clause_copy_ctor (tree clause, tree dst, tree src)
925 tree info = CP_OMP_CLAUSE_INFO (clause);
929 ret = cxx_omp_clause_apply_fn (TREE_VEC_ELT (info, 0), dst, src);
931 ret = build2 (MODIFY_EXPR, void_type_node, dst, src);
936 /* Similarly, except use an assignment operator instead. */
939 cxx_omp_clause_assign_op (tree clause, tree dst, tree src)
941 tree info = CP_OMP_CLAUSE_INFO (clause);
945 ret = cxx_omp_clause_apply_fn (TREE_VEC_ELT (info, 2), dst, src);
947 ret = build2 (MODIFY_EXPR, void_type_node, dst, src);
952 /* Return code to destroy DECL. */
955 cxx_omp_clause_dtor (tree clause, tree decl)
957 tree info = CP_OMP_CLAUSE_INFO (clause);
961 ret = cxx_omp_clause_apply_fn (TREE_VEC_ELT (info, 1), decl, NULL);
966 /* True if OpenMP should privatize what this DECL points to rather
967 than the DECL itself. */
970 cxx_omp_privatize_by_reference (tree decl)
972 return is_invisiref_parm (decl);