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
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
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
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/>. */
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_n (call_unexpected_node
, 1, build_exc_ptr ());
150 gimplify_stmt (&body
);
152 *stmt_p
= gimple_build_eh_filter (body
, allowed
, failure
);
155 /* Genericize an IF_STMT by turning it into a COND_EXPR. */
158 gimplify_if_stmt (tree
*stmt_p
)
160 tree stmt
, cond
, then_
, else_
;
163 cond
= IF_COND (stmt
);
164 then_
= THEN_CLAUSE (stmt
);
165 else_
= ELSE_CLAUSE (stmt
);
168 then_
= build_empty_stmt ();
170 else_
= build_empty_stmt ();
172 if (integer_nonzerop (cond
) && !TREE_SIDE_EFFECTS (else_
))
174 else if (integer_zerop (cond
) && !TREE_SIDE_EFFECTS (then_
))
177 stmt
= build3 (COND_EXPR
, void_type_node
, cond
, then_
, else_
);
181 /* Build a generic representation of one of the C loop forms. COND is the
182 loop condition or NULL_TREE. BODY is the (possibly compound) statement
183 controlled by the loop. INCR is the increment expression of a for-loop,
184 or NULL_TREE. COND_IS_FIRST indicates whether the condition is
185 evaluated before the loop body as in while and for loops, or after the
186 loop body as in do-while loops. */
189 gimplify_cp_loop (tree cond
, tree body
, tree incr
, bool cond_is_first
)
191 tree top
, entry
, exit
, cont_block
, break_block
, stmt_list
, t
;
192 location_t stmt_locus
;
194 stmt_locus
= input_location
;
195 stmt_list
= NULL_TREE
;
198 break_block
= begin_bc_block (bc_break
);
199 cont_block
= begin_bc_block (bc_continue
);
201 /* If condition is zero don't generate a loop construct. */
202 if (cond
&& integer_zerop (cond
))
208 t
= build_bc_goto (bc_break
);
209 append_to_statement_list (t
, &stmt_list
);
214 /* If we use a LOOP_EXPR here, we have to feed the whole thing
215 back through the main gimplifier to lower it. Given that we
216 have to gimplify the loop body NOW so that we can resolve
217 break/continue stmts, seems easier to just expand to gotos. */
218 top
= build1 (LABEL_EXPR
, void_type_node
, NULL_TREE
);
220 /* If we have an exit condition, then we build an IF with gotos either
221 out of the loop, or to the top of it. If there's no exit condition,
222 then we just build a jump back to the top. */
223 exit
= build_and_jump (&LABEL_EXPR_LABEL (top
));
224 if (cond
&& !integer_nonzerop (cond
))
226 t
= build_bc_goto (bc_break
);
227 exit
= fold_build3 (COND_EXPR
, void_type_node
, cond
, exit
, t
);
228 gimplify_stmt (&exit
);
234 entry
= build1 (LABEL_EXPR
, void_type_node
, NULL_TREE
);
235 t
= build_and_jump (&LABEL_EXPR_LABEL (entry
));
238 t
= build_bc_goto (bc_continue
);
239 append_to_statement_list (t
, &stmt_list
);
244 gimplify_stmt (&body
);
245 gimplify_stmt (&incr
);
247 body
= finish_bc_block (bc_continue
, cont_block
, body
);
249 append_to_statement_list (top
, &stmt_list
);
250 append_to_statement_list (body
, &stmt_list
);
251 append_to_statement_list (incr
, &stmt_list
);
252 append_to_statement_list (entry
, &stmt_list
);
253 append_to_statement_list (exit
, &stmt_list
);
255 annotate_all_with_locus (&stmt_list
, stmt_locus
);
257 return finish_bc_block (bc_break
, break_block
, stmt_list
);
260 /* Gimplify a FOR_STMT node. Move the stuff in the for-init-stmt into the
261 prequeue and hand off to gimplify_cp_loop. */
264 gimplify_for_stmt (tree
*stmt_p
, tree
*pre_p
)
268 if (FOR_INIT_STMT (stmt
))
269 gimplify_and_add (FOR_INIT_STMT (stmt
), pre_p
);
271 *stmt_p
= gimplify_cp_loop (FOR_COND (stmt
), FOR_BODY (stmt
),
275 /* Gimplify a WHILE_STMT node. */
278 gimplify_while_stmt (tree
*stmt_p
)
281 *stmt_p
= gimplify_cp_loop (WHILE_COND (stmt
), WHILE_BODY (stmt
),
285 /* Gimplify a DO_STMT node. */
288 gimplify_do_stmt (tree
*stmt_p
)
291 *stmt_p
= gimplify_cp_loop (DO_COND (stmt
), DO_BODY (stmt
),
295 /* Genericize a SWITCH_STMT by turning it into a SWITCH_EXPR. */
298 gimplify_switch_stmt (tree
*stmt_p
)
301 tree break_block
, body
;
302 location_t stmt_locus
= input_location
;
304 break_block
= begin_bc_block (bc_break
);
306 body
= SWITCH_STMT_BODY (stmt
);
308 body
= build_empty_stmt ();
310 *stmt_p
= build3 (SWITCH_EXPR
, SWITCH_STMT_TYPE (stmt
),
311 SWITCH_STMT_COND (stmt
), body
, NULL_TREE
);
312 SET_EXPR_LOCATION (*stmt_p
, stmt_locus
);
313 gimplify_stmt (stmt_p
);
315 *stmt_p
= finish_bc_block (bc_break
, break_block
, *stmt_p
);
318 /* Hook into the middle of gimplifying an OMP_FOR node. This is required
319 in order to properly gimplify CONTINUE statements. Here we merely
320 manage the continue stack; the rest of the job is performed by the
321 regular gimplifier. */
323 static enum gimplify_status
324 cp_gimplify_omp_for (tree
*expr_p
)
326 tree for_stmt
= *expr_p
;
329 /* Protect ourselves from recursion. */
330 if (OMP_FOR_GIMPLIFYING_P (for_stmt
))
332 OMP_FOR_GIMPLIFYING_P (for_stmt
) = 1;
334 /* Note that while technically the continue label is enabled too soon
335 here, we should have already diagnosed invalid continues nested within
336 statement expressions within the INIT, COND, or INCR expressions. */
337 cont_block
= begin_bc_block (bc_continue
);
339 gimplify_stmt (expr_p
);
341 OMP_FOR_BODY (for_stmt
)
342 = finish_bc_block (bc_continue
, cont_block
, OMP_FOR_BODY (for_stmt
));
343 OMP_FOR_GIMPLIFYING_P (for_stmt
) = 0;
348 /* Gimplify an EXPR_STMT node. */
351 gimplify_expr_stmt (tree
*stmt_p
)
353 tree stmt
= EXPR_STMT_EXPR (*stmt_p
);
355 if (stmt
== error_mark_node
)
358 /* Gimplification of a statement expression will nullify the
359 statement if all its side effects are moved to *PRE_P and *POST_P.
361 In this case we will not want to emit the gimplified statement.
362 However, we may still want to emit a warning, so we do that before
364 if (stmt
&& warn_unused_value
)
366 if (!TREE_SIDE_EFFECTS (stmt
))
368 if (!IS_EMPTY_STMT (stmt
)
369 && !VOID_TYPE_P (TREE_TYPE (stmt
))
370 && !TREE_NO_WARNING (stmt
))
371 warning (OPT_Wunused_value
, "statement with no effect");
374 warn_if_unused_value (stmt
, input_location
);
377 if (stmt
== NULL_TREE
)
378 stmt
= alloc_stmt_list ();
383 /* Gimplify initialization from an AGGR_INIT_EXPR. */
386 cp_gimplify_init_expr (tree
*expr_p
, tree
*pre_p
, tree
*post_p
)
388 tree from
= TREE_OPERAND (*expr_p
, 1);
389 tree to
= TREE_OPERAND (*expr_p
, 0);
391 tree slot
= NULL_TREE
;
393 /* What about code that pulls out the temp and uses it elsewhere? I
394 think that such code never uses the TARGET_EXPR as an initializer. If
395 I'm wrong, we'll abort because the temp won't have any RTL. In that
396 case, I guess we'll need to replace references somehow. */
397 if (TREE_CODE (from
) == TARGET_EXPR
)
399 slot
= TARGET_EXPR_SLOT (from
);
400 from
= TARGET_EXPR_INITIAL (from
);
403 /* Look through any COMPOUND_EXPRs, since build_compound_expr pushes them
404 inside the TARGET_EXPR. */
407 tree sub
= TREE_CODE (t
) == COMPOUND_EXPR
? TREE_OPERAND (t
, 0) : t
;
409 /* If we are initializing from an AGGR_INIT_EXPR, drop the INIT_EXPR and
410 replace the slot operand with our target.
412 Should we add a target parm to gimplify_expr instead? No, as in this
413 case we want to replace the INIT_EXPR. */
414 if (TREE_CODE (sub
) == AGGR_INIT_EXPR
)
416 gimplify_expr (&to
, pre_p
, post_p
, is_gimple_lvalue
, fb_lvalue
);
417 AGGR_INIT_EXPR_SLOT (sub
) = to
;
420 /* The initialization is now a side-effect, so the container can
423 TREE_TYPE (from
) = void_type_node
;
425 else if (TREE_CODE (sub
) == INIT_EXPR
426 && TREE_OPERAND (sub
, 0) == slot
)
428 /* An INIT_EXPR under TARGET_EXPR created by build_value_init,
429 will be followed by an AGGR_INIT_EXPR. */
430 gimplify_expr (&to
, pre_p
, post_p
, is_gimple_lvalue
, fb_lvalue
);
431 TREE_OPERAND (sub
, 0) = to
;
437 t
= TREE_OPERAND (t
, 1);
442 /* Gimplify a MUST_NOT_THROW_EXPR. */
445 gimplify_must_not_throw_expr (tree
*expr_p
, tree
*pre_p
)
448 tree temp
= voidify_wrapper_expr (stmt
, NULL
);
449 tree body
= TREE_OPERAND (stmt
, 0);
451 gimplify_stmt (&body
);
453 stmt
= gimple_build_eh_filter (body
, NULL_TREE
,
454 build_call_n (terminate_node
, 0));
458 append_to_statement_list (stmt
, pre_p
);
465 /* Do C++-specific gimplification. Args are as for gimplify_expr. */
468 cp_gimplify_expr (tree
*expr_p
, tree
*pre_p
, tree
*post_p
)
470 int saved_stmts_are_full_exprs_p
= 0;
471 enum tree_code code
= TREE_CODE (*expr_p
);
472 enum gimplify_status ret
;
474 if (STATEMENT_CODE_P (code
))
476 saved_stmts_are_full_exprs_p
= stmts_are_full_exprs_p ();
477 current_stmt_tree ()->stmts_are_full_exprs_p
478 = STMT_IS_FULL_EXPR_P (*expr_p
);
484 *expr_p
= cplus_expand_constant (*expr_p
);
489 simplify_aggr_init_expr (expr_p
);
494 /* FIXME communicate throw type to back end, probably by moving
495 THROW_EXPR into ../tree.def. */
496 *expr_p
= TREE_OPERAND (*expr_p
, 0);
500 case MUST_NOT_THROW_EXPR
:
501 gimplify_must_not_throw_expr (expr_p
, pre_p
);
505 /* We used to do this for GIMPLE_MODIFY_STMT as well, but that's unsafe; the
506 LHS of an assignment might also be involved in the RHS, as in bug
509 cp_gimplify_init_expr (expr_p
, pre_p
, post_p
);
513 case EMPTY_CLASS_EXPR
:
514 /* We create an empty CONSTRUCTOR with RECORD_TYPE. */
515 *expr_p
= build_constructor (TREE_TYPE (*expr_p
), NULL
);
520 *expr_p
= BASELINK_FUNCTIONS (*expr_p
);
525 genericize_try_block (expr_p
);
530 genericize_catch_block (expr_p
);
535 genericize_eh_spec_block (expr_p
);
540 /* Just ignore for now. Eventually we will want to pass this on to
542 *expr_p
= build_empty_stmt ();
547 gimplify_if_stmt (expr_p
);
552 gimplify_for_stmt (expr_p
, pre_p
);
557 gimplify_while_stmt (expr_p
);
562 gimplify_do_stmt (expr_p
);
567 gimplify_switch_stmt (expr_p
);
572 ret
= cp_gimplify_omp_for (expr_p
);
576 *expr_p
= build_bc_goto (bc_continue
);
581 *expr_p
= build_bc_goto (bc_break
);
586 gimplify_expr_stmt (expr_p
);
590 case UNARY_PLUS_EXPR
:
592 tree arg
= TREE_OPERAND (*expr_p
, 0);
593 tree type
= TREE_TYPE (*expr_p
);
594 *expr_p
= (TREE_TYPE (arg
) != type
) ? fold_convert (type
, arg
)
601 ret
= c_gimplify_expr (expr_p
, pre_p
, post_p
);
605 /* Restore saved state. */
606 if (STATEMENT_CODE_P (code
))
607 current_stmt_tree ()->stmts_are_full_exprs_p
608 = saved_stmts_are_full_exprs_p
;
614 is_invisiref_parm (const_tree t
)
616 return ((TREE_CODE (t
) == PARM_DECL
|| TREE_CODE (t
) == RESULT_DECL
)
617 && DECL_BY_REFERENCE (t
));
620 /* Return true if the uid in both int tree maps are equal. */
623 cxx_int_tree_map_eq (const void *va
, const void *vb
)
625 const struct cxx_int_tree_map
*a
= (const struct cxx_int_tree_map
*) va
;
626 const struct cxx_int_tree_map
*b
= (const struct cxx_int_tree_map
*) vb
;
627 return (a
->uid
== b
->uid
);
630 /* Hash a UID in a cxx_int_tree_map. */
633 cxx_int_tree_map_hash (const void *item
)
635 return ((const struct cxx_int_tree_map
*)item
)->uid
;
638 /* Perform any pre-gimplification lowering of C++ front end trees to
642 cp_genericize_r (tree
*stmt_p
, int *walk_subtrees
, void *data
)
645 struct pointer_set_t
*p_set
= (struct pointer_set_t
*) data
;
647 if (is_invisiref_parm (stmt
)
648 /* Don't dereference parms in a thunk, pass the references through. */
649 && !(DECL_THUNK_P (current_function_decl
)
650 && TREE_CODE (stmt
) == PARM_DECL
))
652 *stmt_p
= convert_from_reference (stmt
);
657 /* Map block scope extern declarations to visible declarations with the
658 same name and type in outer scopes if any. */
659 if (cp_function_chain
->extern_decl_map
660 && (TREE_CODE (stmt
) == FUNCTION_DECL
|| TREE_CODE (stmt
) == VAR_DECL
)
661 && DECL_EXTERNAL (stmt
))
663 struct cxx_int_tree_map
*h
, in
;
664 in
.uid
= DECL_UID (stmt
);
665 h
= (struct cxx_int_tree_map
*)
666 htab_find_with_hash (cp_function_chain
->extern_decl_map
,
676 /* Other than invisiref parms, don't walk the same tree twice. */
677 if (pointer_set_contains (p_set
, stmt
))
683 if (TREE_CODE (stmt
) == ADDR_EXPR
684 && is_invisiref_parm (TREE_OPERAND (stmt
, 0)))
686 *stmt_p
= convert (TREE_TYPE (stmt
), TREE_OPERAND (stmt
, 0));
689 else if (TREE_CODE (stmt
) == RETURN_EXPR
690 && TREE_OPERAND (stmt
, 0)
691 && is_invisiref_parm (TREE_OPERAND (stmt
, 0)))
692 /* Don't dereference an invisiref RESULT_DECL inside a RETURN_EXPR. */
694 else if (TREE_CODE (stmt
) == OMP_CLAUSE
)
695 switch (OMP_CLAUSE_CODE (stmt
))
697 case OMP_CLAUSE_LASTPRIVATE
:
698 /* Don't dereference an invisiref in OpenMP clauses. */
699 if (is_invisiref_parm (OMP_CLAUSE_DECL (stmt
)))
702 if (OMP_CLAUSE_LASTPRIVATE_STMT (stmt
))
703 cp_walk_tree (&OMP_CLAUSE_LASTPRIVATE_STMT (stmt
),
704 cp_genericize_r
, p_set
, NULL
);
707 case OMP_CLAUSE_PRIVATE
:
708 case OMP_CLAUSE_SHARED
:
709 case OMP_CLAUSE_FIRSTPRIVATE
:
710 case OMP_CLAUSE_COPYIN
:
711 case OMP_CLAUSE_COPYPRIVATE
:
712 /* Don't dereference an invisiref in OpenMP clauses. */
713 if (is_invisiref_parm (OMP_CLAUSE_DECL (stmt
)))
716 case OMP_CLAUSE_REDUCTION
:
717 gcc_assert (!is_invisiref_parm (OMP_CLAUSE_DECL (stmt
)));
722 else if (IS_TYPE_OR_DECL_P (stmt
))
725 /* Due to the way voidify_wrapper_expr is written, we don't get a chance
726 to lower this construct before scanning it, so we need to lower these
727 before doing anything else. */
728 else if (TREE_CODE (stmt
) == CLEANUP_STMT
)
729 *stmt_p
= build2 (CLEANUP_EH_ONLY (stmt
) ? TRY_CATCH_EXPR
733 CLEANUP_EXPR (stmt
));
735 pointer_set_insert (p_set
, *stmt_p
);
741 cp_genericize (tree fndecl
)
744 struct pointer_set_t
*p_set
;
746 /* Fix up the types of parms passed by invisible reference. */
747 for (t
= DECL_ARGUMENTS (fndecl
); t
; t
= TREE_CHAIN (t
))
748 if (TREE_ADDRESSABLE (TREE_TYPE (t
)))
750 /* If a function's arguments are copied to create a thunk,
751 then DECL_BY_REFERENCE will be set -- but the type of the
752 argument will be a pointer type, so we will never get
754 gcc_assert (!DECL_BY_REFERENCE (t
));
755 gcc_assert (DECL_ARG_TYPE (t
) != TREE_TYPE (t
));
756 TREE_TYPE (t
) = DECL_ARG_TYPE (t
);
757 DECL_BY_REFERENCE (t
) = 1;
758 TREE_ADDRESSABLE (t
) = 0;
762 /* Do the same for the return value. */
763 if (TREE_ADDRESSABLE (TREE_TYPE (DECL_RESULT (fndecl
))))
765 t
= DECL_RESULT (fndecl
);
766 TREE_TYPE (t
) = build_reference_type (TREE_TYPE (t
));
767 DECL_BY_REFERENCE (t
) = 1;
768 TREE_ADDRESSABLE (t
) = 0;
772 /* If we're a clone, the body is already GIMPLE. */
773 if (DECL_CLONED_FUNCTION_P (fndecl
))
776 /* We do want to see every occurrence of the parms, so we can't just use
777 walk_tree's hash functionality. */
778 p_set
= pointer_set_create ();
779 cp_walk_tree (&DECL_SAVED_TREE (fndecl
), cp_genericize_r
, p_set
, NULL
);
780 pointer_set_destroy (p_set
);
782 /* Do everything else. */
783 c_genericize (fndecl
);
785 gcc_assert (bc_label
[bc_break
] == NULL
);
786 gcc_assert (bc_label
[bc_continue
] == NULL
);
789 /* Build code to apply FN to each member of ARG1 and ARG2. FN may be
790 NULL if there is in fact nothing to do. ARG2 may be null if FN
791 actually only takes one argument. */
794 cxx_omp_clause_apply_fn (tree fn
, tree arg1
, tree arg2
)
796 tree defparm
, parm
, t
;
804 nargs
= list_length (DECL_ARGUMENTS (fn
));
805 argarray
= (tree
*) alloca (nargs
* sizeof (tree
));
807 defparm
= TREE_CHAIN (TYPE_ARG_TYPES (TREE_TYPE (fn
)));
809 defparm
= TREE_CHAIN (defparm
);
811 if (TREE_CODE (TREE_TYPE (arg1
)) == ARRAY_TYPE
)
813 tree inner_type
= TREE_TYPE (arg1
);
814 tree start1
, end1
, p1
;
815 tree start2
= NULL
, p2
= NULL
;
816 tree ret
= NULL
, lab
;
822 inner_type
= TREE_TYPE (inner_type
);
823 start1
= build4 (ARRAY_REF
, inner_type
, start1
,
824 size_zero_node
, NULL
, NULL
);
826 start2
= build4 (ARRAY_REF
, inner_type
, start2
,
827 size_zero_node
, NULL
, NULL
);
829 while (TREE_CODE (inner_type
) == ARRAY_TYPE
);
830 start1
= build_fold_addr_expr (start1
);
832 start2
= build_fold_addr_expr (start2
);
834 end1
= TYPE_SIZE_UNIT (TREE_TYPE (arg1
));
835 end1
= build2 (POINTER_PLUS_EXPR
, TREE_TYPE (start1
), start1
, end1
);
837 p1
= create_tmp_var (TREE_TYPE (start1
), NULL
);
838 t
= build2 (GIMPLE_MODIFY_STMT
, void_type_node
, p1
, start1
);
839 append_to_statement_list (t
, &ret
);
843 p2
= create_tmp_var (TREE_TYPE (start2
), NULL
);
844 t
= build2 (GIMPLE_MODIFY_STMT
, void_type_node
, p2
, start2
);
845 append_to_statement_list (t
, &ret
);
848 lab
= create_artificial_label ();
849 t
= build1 (LABEL_EXPR
, void_type_node
, lab
);
850 append_to_statement_list (t
, &ret
);
855 /* Handle default arguments. */
856 for (parm
= defparm
; parm
&& parm
!= void_list_node
;
857 parm
= TREE_CHAIN (parm
), i
++)
858 argarray
[i
] = convert_default_arg (TREE_VALUE (parm
),
859 TREE_PURPOSE (parm
), fn
, i
);
860 t
= build_call_a (fn
, i
, argarray
);
861 t
= fold_convert (void_type_node
, t
);
862 t
= fold_build_cleanup_point_expr (TREE_TYPE (t
), t
);
863 append_to_statement_list (t
, &ret
);
865 t
= TYPE_SIZE_UNIT (inner_type
);
866 t
= build2 (POINTER_PLUS_EXPR
, TREE_TYPE (p1
), p1
, t
);
867 t
= build2 (GIMPLE_MODIFY_STMT
, void_type_node
, p1
, t
);
868 append_to_statement_list (t
, &ret
);
872 t
= TYPE_SIZE_UNIT (inner_type
);
873 t
= build2 (POINTER_PLUS_EXPR
, TREE_TYPE (p2
), p2
, t
);
874 t
= build2 (GIMPLE_MODIFY_STMT
, void_type_node
, p2
, t
);
875 append_to_statement_list (t
, &ret
);
878 t
= build2 (NE_EXPR
, boolean_type_node
, p1
, end1
);
879 t
= build3 (COND_EXPR
, void_type_node
, t
, build_and_jump (&lab
), NULL
);
880 append_to_statement_list (t
, &ret
);
886 argarray
[i
++] = build_fold_addr_expr (arg1
);
888 argarray
[i
++] = build_fold_addr_expr (arg2
);
889 /* Handle default arguments. */
890 for (parm
= defparm
; parm
&& parm
!= void_list_node
;
891 parm
= TREE_CHAIN (parm
), i
++)
892 argarray
[i
] = convert_default_arg (TREE_VALUE (parm
),
895 t
= build_call_a (fn
, i
, argarray
);
896 t
= fold_convert (void_type_node
, t
);
897 return fold_build_cleanup_point_expr (TREE_TYPE (t
), t
);
901 /* Return code to initialize DECL with its default constructor, or
902 NULL if there's nothing to do. */
905 cxx_omp_clause_default_ctor (tree clause
, tree decl
,
906 tree outer ATTRIBUTE_UNUSED
)
908 tree info
= CP_OMP_CLAUSE_INFO (clause
);
912 ret
= cxx_omp_clause_apply_fn (TREE_VEC_ELT (info
, 0), decl
, NULL
);
917 /* Return code to initialize DST with a copy constructor from SRC. */
920 cxx_omp_clause_copy_ctor (tree clause
, tree dst
, tree src
)
922 tree info
= CP_OMP_CLAUSE_INFO (clause
);
926 ret
= cxx_omp_clause_apply_fn (TREE_VEC_ELT (info
, 0), dst
, src
);
928 ret
= build2 (GIMPLE_MODIFY_STMT
, void_type_node
, dst
, src
);
933 /* Similarly, except use an assignment operator instead. */
936 cxx_omp_clause_assign_op (tree clause
, tree dst
, tree src
)
938 tree info
= CP_OMP_CLAUSE_INFO (clause
);
942 ret
= cxx_omp_clause_apply_fn (TREE_VEC_ELT (info
, 2), dst
, src
);
944 ret
= build2 (GIMPLE_MODIFY_STMT
, void_type_node
, dst
, src
);
949 /* Return code to destroy DECL. */
952 cxx_omp_clause_dtor (tree clause
, tree decl
)
954 tree info
= CP_OMP_CLAUSE_INFO (clause
);
958 ret
= cxx_omp_clause_apply_fn (TREE_VEC_ELT (info
, 1), decl
, NULL
);
963 /* True if OpenMP should privatize what this DECL points to rather
964 than the DECL itself. */
967 cxx_omp_privatize_by_reference (const_tree decl
)
969 return is_invisiref_parm (decl
);
972 /* True if OpenMP sharing attribute of DECL is predetermined. */
974 enum omp_clause_default_kind
975 cxx_omp_predetermined_sharing (tree decl
)
979 /* Static data members are predetermined as shared. */
980 if (TREE_STATIC (decl
))
982 tree ctx
= CP_DECL_CONTEXT (decl
);
983 if (TYPE_P (ctx
) && MAYBE_CLASS_TYPE_P (ctx
))
984 return OMP_CLAUSE_DEFAULT_SHARED
;
987 type
= TREE_TYPE (decl
);
988 if (TREE_CODE (type
) == REFERENCE_TYPE
)
990 if (!is_invisiref_parm (decl
))
991 return OMP_CLAUSE_DEFAULT_UNSPECIFIED
;
992 type
= TREE_TYPE (type
);
994 if (TREE_CODE (decl
) == RESULT_DECL
&& DECL_NAME (decl
))
996 /* NVR doesn't preserve const qualification of the
998 tree outer
= outer_curly_brace_block (current_function_decl
);
1002 for (var
= BLOCK_VARS (outer
); var
; var
= TREE_CHAIN (var
))
1003 if (DECL_NAME (decl
) == DECL_NAME (var
)
1004 && (TYPE_MAIN_VARIANT (type
)
1005 == TYPE_MAIN_VARIANT (TREE_TYPE (var
))))
1007 if (TYPE_READONLY (TREE_TYPE (var
)))
1008 type
= TREE_TYPE (var
);
1014 if (type
== error_mark_node
)
1015 return OMP_CLAUSE_DEFAULT_UNSPECIFIED
;
1017 /* Variables with const-qualified type having no mutable member
1018 are predetermined shared. */
1019 if (TYPE_READONLY (type
) && !cp_has_mutable_p (type
))
1020 return OMP_CLAUSE_DEFAULT_SHARED
;
1022 return OMP_CLAUSE_DEFAULT_UNSPECIFIED
;
1025 /* Finalize an implicitly determined clause. */
1028 cxx_omp_finish_clause (tree c
)
1030 tree decl
, inner_type
;
1031 bool make_shared
= false;
1033 if (OMP_CLAUSE_CODE (c
) != OMP_CLAUSE_FIRSTPRIVATE
)
1036 decl
= OMP_CLAUSE_DECL (c
);
1037 decl
= require_complete_type (decl
);
1038 inner_type
= TREE_TYPE (decl
);
1039 if (decl
== error_mark_node
)
1041 else if (TREE_CODE (TREE_TYPE (decl
)) == REFERENCE_TYPE
)
1043 if (is_invisiref_parm (decl
))
1044 inner_type
= TREE_TYPE (inner_type
);
1047 error ("%qE implicitly determined as %<firstprivate%> has reference type",
1053 /* We're interested in the base element, not arrays. */
1054 while (TREE_CODE (inner_type
) == ARRAY_TYPE
)
1055 inner_type
= TREE_TYPE (inner_type
);
1057 /* Check for special function availability by building a call to one.
1058 Save the results, because later we won't be in the right context
1059 for making these queries. */
1061 && CLASS_TYPE_P (inner_type
)
1062 && cxx_omp_create_clause_info (c
, inner_type
, false, true, false))
1066 OMP_CLAUSE_CODE (c
) = OMP_CLAUSE_SHARED
;