]> gcc.gnu.org Git - gcc.git/blame - gcc/cp/cp-gimplify.c
re PR c++/43787 (memory copy of empty class (sizeof is one))
[gcc.git] / gcc / cp / cp-gimplify.c
CommitLineData
eadf906f 1/* C++-specific tree lowering bits; see also c-gimplify.c and tree-gimple.c.
6de9cd9a 2
f74d9c8f 3 Copyright (C) 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009
e77f031d 4 Free Software Foundation, Inc.
6de9cd9a
DN
5 Contributed by Jason Merrill <jason@redhat.com>
6
7This file is part of GCC.
8
9GCC is free software; you can redistribute it and/or modify it under
10the terms of the GNU General Public License as published by the Free
e77f031d 11Software Foundation; either version 3, or (at your option) any later
6de9cd9a
DN
12version.
13
14GCC is distributed in the hope that it will be useful, but WITHOUT ANY
15WARRANTY; without even the implied warranty of MERCHANTABILITY or
16FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
17for more details.
18
19You should have received a copy of the GNU General Public License
e77f031d
NC
20along with GCC; see the file COPYING3. If not see
21<http://www.gnu.org/licenses/>. */
6de9cd9a
DN
22
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-common.h"
30#include "toplev.h"
726a989a
RB
31#include "tree-iterator.h"
32#include "gimple.h"
d8472c75 33#include "hashtab.h"
e09a5d62 34#include "pointer-set.h"
934790cc 35#include "flags.h"
6de9cd9a 36
fbc315db
ILT
37/* Local declarations. */
38
39enum bc_t { bc_break = 0, bc_continue = 1 };
40
1799e5d5
RH
41/* Stack of labels which are targets for "break" or "continue",
42 linked through TREE_CHAIN. */
43static tree bc_label[2];
fbc315db
ILT
44
45/* Begin a scope which can be exited by a break or continue statement. BC
46 indicates which.
47
48 Just creates a label and pushes it into the current context. */
49
50static tree
51begin_bc_block (enum bc_t bc)
52{
c2255bc4 53 tree label = create_artificial_label (input_location);
1799e5d5
RH
54 TREE_CHAIN (label) = bc_label[bc];
55 bc_label[bc] = label;
fbc315db
ILT
56 return label;
57}
58
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.
62
63 If we saw a break (or continue) in the scope, append a LABEL_EXPR to
64 body. Otherwise, just forget the label. */
65
726a989a
RB
66static gimple_seq
67finish_bc_block (enum bc_t bc, tree label, gimple_seq body)
fbc315db 68{
1799e5d5 69 gcc_assert (label == bc_label[bc]);
fbc315db
ILT
70
71 if (TREE_USED (label))
72 {
726a989a 73 gimple_seq_add_stmt (&body, gimple_build_label (label));
fbc315db
ILT
74 }
75
1799e5d5 76 bc_label[bc] = TREE_CHAIN (label);
fbc315db
ILT
77 TREE_CHAIN (label) = NULL_TREE;
78 return body;
79}
80
726a989a
RB
81/* Get the LABEL_EXPR to represent a break or continue statement
82 in the current block scope. BC indicates which. */
fbc315db
ILT
83
84static tree
726a989a 85get_bc_label (enum bc_t bc)
fbc315db 86{
1799e5d5 87 tree label = bc_label[bc];
fbc315db
ILT
88
89 if (label == NULL_TREE)
90 {
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");
95
96 return NULL_TREE;
97 }
98
99 /* Mark the label used for finish_bc_block. */
100 TREE_USED (label) = 1;
726a989a 101 return label;
fbc315db
ILT
102}
103
6de9cd9a
DN
104/* Genericize a TRY_BLOCK. */
105
106static void
107genericize_try_block (tree *stmt_p)
108{
109 tree body = TRY_STMTS (*stmt_p);
110 tree cleanup = TRY_HANDLERS (*stmt_p);
111
f293ce4b 112 *stmt_p = build2 (TRY_CATCH_EXPR, void_type_node, body, cleanup);
6de9cd9a
DN
113}
114
115/* Genericize a HANDLER by converting to a CATCH_EXPR. */
116
117static void
118genericize_catch_block (tree *stmt_p)
119{
120 tree type = HANDLER_TYPE (*stmt_p);
121 tree body = HANDLER_BODY (*stmt_p);
122
6de9cd9a 123 /* FIXME should the caught type go in TREE_TYPE? */
f293ce4b 124 *stmt_p = build2 (CATCH_EXPR, void_type_node, type, body);
6de9cd9a
DN
125}
126
726a989a
RB
127/* A terser interface for building a representation of an exception
128 specification. */
129
130static tree
131build_gimple_eh_filter_tree (tree body, tree allowed, tree failure)
132{
133 tree t;
134
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));
138
139 t = build2 (TRY_CATCH_EXPR, void_type_node, NULL_TREE, t);
140 append_to_statement_list (body, &TREE_OPERAND (t, 0));
141
142 return t;
143}
144
6de9cd9a
DN
145/* Genericize an EH_SPEC_BLOCK by converting it to a
146 TRY_CATCH_EXPR/EH_FILTER_EXPR pair. */
147
148static void
149genericize_eh_spec_block (tree *stmt_p)
150{
151 tree body = EH_SPEC_STMTS (*stmt_p);
152 tree allowed = EH_SPEC_RAISES (*stmt_p);
94a0dd7b 153 tree failure = build_call_n (call_unexpected_node, 1, build_exc_ptr ());
6de9cd9a 154
726a989a 155 *stmt_p = build_gimple_eh_filter_tree (body, allowed, failure);
d665b6e5
MLI
156 TREE_NO_WARNING (*stmt_p) = true;
157 TREE_NO_WARNING (TREE_OPERAND (*stmt_p, 1)) = true;
6de9cd9a
DN
158}
159
5a508662
RH
160/* Genericize an IF_STMT by turning it into a COND_EXPR. */
161
162static void
f74d9c8f 163genericize_if_stmt (tree *stmt_p)
5a508662 164{
eeae0768 165 tree stmt, cond, then_, else_;
726a989a 166 location_t locus = EXPR_LOCATION (*stmt_p);
5a508662
RH
167
168 stmt = *stmt_p;
eeae0768 169 cond = IF_COND (stmt);
5a508662
RH
170 then_ = THEN_CLAUSE (stmt);
171 else_ = ELSE_CLAUSE (stmt);
172
173 if (!then_)
c2255bc4 174 then_ = build_empty_stmt (locus);
5a508662 175 if (!else_)
c2255bc4 176 else_ = build_empty_stmt (locus);
5a508662 177
eeae0768
RS
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_);
726a989a
RB
184 if (CAN_HAVE_LOCATION_P (stmt) && !EXPR_HAS_LOCATION (stmt))
185 SET_EXPR_LOCATION (stmt, locus);
5a508662
RH
186 *stmt_p = stmt;
187}
188
fbc315db
ILT
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. */
195
726a989a 196static gimple_seq
fbc315db
ILT
197gimplify_cp_loop (tree cond, tree body, tree incr, bool cond_is_first)
198{
726a989a
RB
199 gimple top, entry, stmt;
200 gimple_seq stmt_list, body_seq, incr_seq, exit_seq;
201 tree cont_block, break_block;
fbc315db
ILT
202 location_t stmt_locus;
203
204 stmt_locus = input_location;
726a989a
RB
205 stmt_list = NULL;
206 body_seq = NULL;
207 incr_seq = NULL;
208 exit_seq = NULL;
209 entry = NULL;
fbc315db
ILT
210
211 break_block = begin_bc_block (bc_break);
212 cont_block = begin_bc_block (bc_continue);
213
214 /* If condition is zero don't generate a loop construct. */
215 if (cond && integer_zerop (cond))
216 {
726a989a 217 top = NULL;
fbc315db
ILT
218 if (cond_is_first)
219 {
726a989a
RB
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);
fbc315db
ILT
223 }
224 }
225 else
226 {
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. */
c2255bc4 231 top = gimple_build_label (create_artificial_label (stmt_locus));
fbc315db
ILT
232
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. */
fbc315db
ILT
236 if (cond && !integer_nonzerop (cond))
237 {
726a989a
RB
238 if (cond != error_mark_node)
239 {
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);
246 }
fbc315db
ILT
247
248 if (cond_is_first)
249 {
250 if (incr)
251 {
c2255bc4
AH
252 entry = gimple_build_label
253 (create_artificial_label (stmt_locus));
726a989a 254 stmt = gimple_build_goto (gimple_label_label (entry));
fbc315db
ILT
255 }
256 else
726a989a
RB
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);
fbc315db
ILT
260 }
261 }
726a989a
RB
262 else
263 {
264 stmt = gimple_build_goto (gimple_label_label (top));
265 gimple_seq_add_stmt (&exit_seq, stmt);
266 }
fbc315db
ILT
267 }
268
726a989a
RB
269 gimplify_stmt (&body, &body_seq);
270 gimplify_stmt (&incr, &incr_seq);
fbc315db 271
726a989a 272 body_seq = finish_bc_block (bc_continue, cont_block, body_seq);
fbc315db 273
726a989a
RB
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);
fbc315db 279
726a989a 280 annotate_all_with_location (stmt_list, stmt_locus);
fbc315db
ILT
281
282 return finish_bc_block (bc_break, break_block, stmt_list);
283}
284
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. */
287
288static void
726a989a 289gimplify_for_stmt (tree *stmt_p, gimple_seq *pre_p)
fbc315db
ILT
290{
291 tree stmt = *stmt_p;
292
293 if (FOR_INIT_STMT (stmt))
294 gimplify_and_add (FOR_INIT_STMT (stmt), pre_p);
295
726a989a
RB
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;
fbc315db
ILT
300}
301
302/* Gimplify a WHILE_STMT node. */
303
304static void
726a989a 305gimplify_while_stmt (tree *stmt_p, gimple_seq *pre_p)
fbc315db
ILT
306{
307 tree stmt = *stmt_p;
726a989a
RB
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;
fbc315db
ILT
312}
313
314/* Gimplify a DO_STMT node. */
315
316static void
726a989a 317gimplify_do_stmt (tree *stmt_p, gimple_seq *pre_p)
fbc315db
ILT
318{
319 tree stmt = *stmt_p;
726a989a
RB
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;
fbc315db
ILT
324}
325
326/* Genericize a SWITCH_STMT by turning it into a SWITCH_EXPR. */
327
328static void
726a989a 329gimplify_switch_stmt (tree *stmt_p, gimple_seq *pre_p)
fbc315db
ILT
330{
331 tree stmt = *stmt_p;
726a989a 332 tree break_block, body, t;
fbc315db 333 location_t stmt_locus = input_location;
726a989a 334 gimple_seq seq = NULL;
fbc315db
ILT
335
336 break_block = begin_bc_block (bc_break);
337
338 body = SWITCH_STMT_BODY (stmt);
339 if (!body)
c2255bc4 340 body = build_empty_stmt (stmt_locus);
fbc315db 341
726a989a
RB
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);
fbc315db 346
726a989a
RB
347 seq = finish_bc_block (bc_break, break_block, seq);
348 gimple_seq_add_seq (pre_p, seq);
349 *stmt_p = NULL_TREE;
fbc315db
ILT
350}
351
1799e5d5
RH
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
3db45ab5 355 regular gimplifier. */
1799e5d5
RH
356
357static enum gimplify_status
726a989a 358cp_gimplify_omp_for (tree *expr_p, gimple_seq *pre_p)
1799e5d5
RH
359{
360 tree for_stmt = *expr_p;
361 tree cont_block;
726a989a
RB
362 gimple stmt;
363 gimple_seq seq = NULL;
1799e5d5
RH
364
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;
369
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);
374
726a989a
RB
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);
1799e5d5 383
1799e5d5
RH
384 OMP_FOR_GIMPLIFYING_P (for_stmt) = 0;
385
386 return GS_ALL_DONE;
387}
388
934790cc
ILT
389/* Gimplify an EXPR_STMT node. */
390
391static void
392gimplify_expr_stmt (tree *stmt_p)
393{
394 tree stmt = EXPR_STMT_EXPR (*stmt_p);
395
396 if (stmt == error_mark_node)
397 stmt = NULL;
398
399 /* Gimplification of a statement expression will nullify the
400 statement if all its side effects are moved to *PRE_P and *POST_P.
401
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. */
27f33b15 405 if (stmt && warn_unused_value)
934790cc
ILT
406 {
407 if (!TREE_SIDE_EFFECTS (stmt))
408 {
409 if (!IS_EMPTY_STMT (stmt)
410 && !VOID_TYPE_P (TREE_TYPE (stmt))
411 && !TREE_NO_WARNING (stmt))
27f33b15 412 warning (OPT_Wunused_value, "statement with no effect");
934790cc 413 }
27f33b15 414 else
934790cc
ILT
415 warn_if_unused_value (stmt, input_location);
416 }
417
418 if (stmt == NULL_TREE)
419 stmt = alloc_stmt_list ();
420
421 *stmt_p = stmt;
422}
423
6de9cd9a
DN
424/* Gimplify initialization from an AGGR_INIT_EXPR. */
425
426static void
726a989a 427cp_gimplify_init_expr (tree *expr_p, gimple_seq *pre_p, gimple_seq *post_p)
6de9cd9a
DN
428{
429 tree from = TREE_OPERAND (*expr_p, 1);
430 tree to = TREE_OPERAND (*expr_p, 0);
0fcedd9c 431 tree t;
6de9cd9a 432
6de9cd9a
DN
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)
db80e34e 438 from = TARGET_EXPR_INITIAL (from);
6de9cd9a 439
c6c7698d
JM
440 /* Look through any COMPOUND_EXPRs, since build_compound_expr pushes them
441 inside the TARGET_EXPR. */
0fcedd9c
JM
442 for (t = from; t; )
443 {
444 tree sub = TREE_CODE (t) == COMPOUND_EXPR ? TREE_OPERAND (t, 0) : t;
6de9cd9a 445
0fcedd9c
JM
446 /* If we are initializing from an AGGR_INIT_EXPR, drop the INIT_EXPR and
447 replace the slot operand with our target.
6de9cd9a 448
0fcedd9c
JM
449 Should we add a target parm to gimplify_expr instead? No, as in this
450 case we want to replace the INIT_EXPR. */
d5f4eddd
JM
451 if (TREE_CODE (sub) == AGGR_INIT_EXPR
452 || TREE_CODE (sub) == VEC_INIT_EXPR)
0fcedd9c
JM
453 {
454 gimplify_expr (&to, pre_p, post_p, is_gimple_lvalue, fb_lvalue);
d5f4eddd
JM
455 if (TREE_CODE (sub) == AGGR_INIT_EXPR)
456 AGGR_INIT_EXPR_SLOT (sub) = to;
457 else
458 VEC_INIT_EXPR_SLOT (sub) = to;
0fcedd9c
JM
459 *expr_p = from;
460
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;
465 }
0fcedd9c
JM
466
467 if (t == sub)
468 break;
469 else
470 t = TREE_OPERAND (t, 1);
6de9cd9a 471 }
0fcedd9c 472
6de9cd9a
DN
473}
474
475/* Gimplify a MUST_NOT_THROW_EXPR. */
476
726a989a
RB
477static enum gimplify_status
478gimplify_must_not_throw_expr (tree *expr_p, gimple_seq *pre_p)
6de9cd9a
DN
479{
480 tree stmt = *expr_p;
325c3691 481 tree temp = voidify_wrapper_expr (stmt, NULL);
6de9cd9a
DN
482 tree body = TREE_OPERAND (stmt, 0);
483
726a989a
RB
484 stmt = build_gimple_eh_filter_tree (body, NULL_TREE,
485 build_call_n (terminate_node, 0));
6de9cd9a 486
726a989a 487 gimplify_and_add (stmt, pre_p);
6de9cd9a
DN
488 if (temp)
489 {
6de9cd9a 490 *expr_p = temp;
726a989a 491 return GS_OK;
6de9cd9a 492 }
726a989a
RB
493
494 *expr_p = NULL;
495 return GS_ALL_DONE;
6de9cd9a 496}
7c34ced1
RH
497
498/* Do C++-specific gimplification. Args are as for gimplify_expr. */
499
500int
726a989a 501cp_gimplify_expr (tree *expr_p, gimple_seq *pre_p, gimple_seq *post_p)
7c34ced1
RH
502{
503 int saved_stmts_are_full_exprs_p = 0;
504 enum tree_code code = TREE_CODE (*expr_p);
505 enum gimplify_status ret;
506
507 if (STATEMENT_CODE_P (code))
508 {
509 saved_stmts_are_full_exprs_p = stmts_are_full_exprs_p ();
510 current_stmt_tree ()->stmts_are_full_exprs_p
511 = STMT_IS_FULL_EXPR_P (*expr_p);
512 }
513
514 switch (code)
515 {
516 case PTRMEM_CST:
517 *expr_p = cplus_expand_constant (*expr_p);
518 ret = GS_OK;
519 break;
520
521 case AGGR_INIT_EXPR:
522 simplify_aggr_init_expr (expr_p);
523 ret = GS_OK;
524 break;
525
d5f4eddd
JM
526 case VEC_INIT_EXPR:
527 {
528 location_t loc = input_location;
529 gcc_assert (EXPR_HAS_LOCATION (*expr_p));
530 input_location = EXPR_LOCATION (*expr_p);
531 *expr_p = build_vec_init (VEC_INIT_EXPR_SLOT (*expr_p), NULL_TREE,
532 VEC_INIT_EXPR_INIT (*expr_p), false, 1,
533 tf_warning_or_error);
534 ret = GS_OK;
535 input_location = loc;
536 }
537 break;
538
7c34ced1 539 case THROW_EXPR:
3b426391 540 /* FIXME communicate throw type to back end, probably by moving
7c34ced1
RH
541 THROW_EXPR into ../tree.def. */
542 *expr_p = TREE_OPERAND (*expr_p, 0);
543 ret = GS_OK;
544 break;
545
546 case MUST_NOT_THROW_EXPR:
726a989a 547 ret = gimplify_must_not_throw_expr (expr_p, pre_p);
7c34ced1
RH
548 break;
549
726a989a 550 /* We used to do this for MODIFY_EXPR as well, but that's unsafe; the
dae7ec87
JM
551 LHS of an assignment might also be involved in the RHS, as in bug
552 25979. */
7c34ced1 553 case INIT_EXPR:
7c34ced1 554 cp_gimplify_init_expr (expr_p, pre_p, post_p);
85a52ea5
JM
555 if (TREE_CODE (*expr_p) != INIT_EXPR)
556 return GS_OK;
557 /* Otherwise fall through. */
1e2ddf80
JM
558 case MODIFY_EXPR:
559 {
560 /* If the back end isn't clever enough to know that the lhs and rhs
561 types are the same, add an explicit conversion. */
562 tree op0 = TREE_OPERAND (*expr_p, 0);
563 tree op1 = TREE_OPERAND (*expr_p, 1);
564
0d08582e
JM
565 if (!error_operand_p (op0)
566 && !error_operand_p (op1)
567 && (TYPE_STRUCTURAL_EQUALITY_P (TREE_TYPE (op0))
568 || TYPE_STRUCTURAL_EQUALITY_P (TREE_TYPE (op1)))
1e2ddf80
JM
569 && !useless_type_conversion_p (TREE_TYPE (op1), TREE_TYPE (op0)))
570 TREE_OPERAND (*expr_p, 1) = build1 (VIEW_CONVERT_EXPR,
571 TREE_TYPE (op0), op1);
6d729f28
JM
572
573 else if ((rhs_predicate_for (op0)) (op1)
574 && !(TREE_CODE (op1) == CALL_EXPR
575 && CALL_EXPR_RETURN_SLOT_OPT (op1))
576 && is_really_empty_class (TREE_TYPE (op0)))
577 {
578 /* Remove any copies of empty classes. We check that the RHS
579 has a simple form so that TARGET_EXPRs and CONSTRUCTORs get
580 reduced properly, and we leave the return slot optimization
581 alone because it isn't a copy.
582
583 Also drop volatile variables on the RHS to avoid infinite
584 recursion from gimplify_expr trying to load the value. */
585 if (!TREE_SIDE_EFFECTS (op1)
586 || (DECL_P (op1) && TREE_THIS_VOLATILE (op1)))
587 *expr_p = op0;
588 else
589 *expr_p = build2 (COMPOUND_EXPR, TREE_TYPE (*expr_p),
590 op0, op1);
591 }
1e2ddf80 592 }
7c34ced1
RH
593 ret = GS_OK;
594 break;
595
596 case EMPTY_CLASS_EXPR:
f7683d37
RG
597 /* We create an empty CONSTRUCTOR with RECORD_TYPE. */
598 *expr_p = build_constructor (TREE_TYPE (*expr_p), NULL);
7c34ced1
RH
599 ret = GS_OK;
600 break;
601
602 case BASELINK:
603 *expr_p = BASELINK_FUNCTIONS (*expr_p);
604 ret = GS_OK;
605 break;
606
607 case TRY_BLOCK:
608 genericize_try_block (expr_p);
609 ret = GS_OK;
610 break;
611
612 case HANDLER:
613 genericize_catch_block (expr_p);
614 ret = GS_OK;
615 break;
616
617 case EH_SPEC_BLOCK:
618 genericize_eh_spec_block (expr_p);
619 ret = GS_OK;
620 break;
621
622 case USING_STMT:
ac3cbee5 623 gcc_unreachable ();
7c34ced1 624
fbc315db
ILT
625 case FOR_STMT:
626 gimplify_for_stmt (expr_p, pre_p);
726a989a 627 ret = GS_OK;
fbc315db
ILT
628 break;
629
630 case WHILE_STMT:
726a989a
RB
631 gimplify_while_stmt (expr_p, pre_p);
632 ret = GS_OK;
fbc315db
ILT
633 break;
634
635 case DO_STMT:
726a989a
RB
636 gimplify_do_stmt (expr_p, pre_p);
637 ret = GS_OK;
fbc315db
ILT
638 break;
639
640 case SWITCH_STMT:
726a989a
RB
641 gimplify_switch_stmt (expr_p, pre_p);
642 ret = GS_OK;
fbc315db
ILT
643 break;
644
1799e5d5 645 case OMP_FOR:
726a989a 646 ret = cp_gimplify_omp_for (expr_p, pre_p);
1799e5d5
RH
647 break;
648
fbc315db 649 case CONTINUE_STMT:
7299cb99 650 gimple_seq_add_stmt (pre_p, gimple_build_predict (PRED_CONTINUE, NOT_TAKEN));
726a989a
RB
651 gimple_seq_add_stmt (pre_p, gimple_build_goto (get_bc_label (bc_continue)));
652 *expr_p = NULL_TREE;
fbc315db
ILT
653 ret = GS_ALL_DONE;
654 break;
655
656 case BREAK_STMT:
726a989a
RB
657 gimple_seq_add_stmt (pre_p, gimple_build_goto (get_bc_label (bc_break)));
658 *expr_p = NULL_TREE;
fbc315db
ILT
659 ret = GS_ALL_DONE;
660 break;
661
934790cc
ILT
662 case EXPR_STMT:
663 gimplify_expr_stmt (expr_p);
664 ret = GS_OK;
665 break;
666
392e3d51
RS
667 case UNARY_PLUS_EXPR:
668 {
669 tree arg = TREE_OPERAND (*expr_p, 0);
670 tree type = TREE_TYPE (*expr_p);
671 *expr_p = (TREE_TYPE (arg) != type) ? fold_convert (type, arg)
672 : arg;
673 ret = GS_OK;
674 }
675 break;
676
7c34ced1 677 default:
32e8bb8e 678 ret = (enum gimplify_status) c_gimplify_expr (expr_p, pre_p, post_p);
7c34ced1
RH
679 break;
680 }
681
682 /* Restore saved state. */
683 if (STATEMENT_CODE_P (code))
684 current_stmt_tree ()->stmts_are_full_exprs_p
685 = saved_stmts_are_full_exprs_p;
686
687 return ret;
688}
5a508662 689
d8472c75 690static inline bool
58f9752a 691is_invisiref_parm (const_tree t)
d8472c75 692{
cc77ae10 693 return ((TREE_CODE (t) == PARM_DECL || TREE_CODE (t) == RESULT_DECL)
d8472c75
JM
694 && DECL_BY_REFERENCE (t));
695}
696
10827cd8
JJ
697/* Return true if the uid in both int tree maps are equal. */
698
699int
700cxx_int_tree_map_eq (const void *va, const void *vb)
701{
702 const struct cxx_int_tree_map *a = (const struct cxx_int_tree_map *) va;
703 const struct cxx_int_tree_map *b = (const struct cxx_int_tree_map *) vb;
704 return (a->uid == b->uid);
705}
706
707/* Hash a UID in a cxx_int_tree_map. */
708
709unsigned int
710cxx_int_tree_map_hash (const void *item)
711{
712 return ((const struct cxx_int_tree_map *)item)->uid;
713}
714
ac3cbee5
RG
715struct cp_genericize_data
716{
717 struct pointer_set_t *p_set;
718 VEC (tree, heap) *bind_expr_stack;
719};
720
d8472c75
JM
721/* Perform any pre-gimplification lowering of C++ front end trees to
722 GENERIC. */
5a508662
RH
723
724static tree
d8472c75 725cp_genericize_r (tree *stmt_p, int *walk_subtrees, void *data)
5a508662
RH
726{
727 tree stmt = *stmt_p;
ac3cbee5
RG
728 struct cp_genericize_data *wtd = (struct cp_genericize_data *) data;
729 struct pointer_set_t *p_set = wtd->p_set;
5a508662 730
5b009a96
JM
731 if (is_invisiref_parm (stmt)
732 /* Don't dereference parms in a thunk, pass the references through. */
733 && !(DECL_THUNK_P (current_function_decl)
3db45ab5 734 && TREE_CODE (stmt) == PARM_DECL))
d8472c75 735 {
cc77ae10 736 *stmt_p = convert_from_reference (stmt);
d8472c75
JM
737 *walk_subtrees = 0;
738 return NULL;
739 }
740
10827cd8
JJ
741 /* Map block scope extern declarations to visible declarations with the
742 same name and type in outer scopes if any. */
743 if (cp_function_chain->extern_decl_map
744 && (TREE_CODE (stmt) == FUNCTION_DECL || TREE_CODE (stmt) == VAR_DECL)
745 && DECL_EXTERNAL (stmt))
746 {
747 struct cxx_int_tree_map *h, in;
748 in.uid = DECL_UID (stmt);
749 h = (struct cxx_int_tree_map *)
750 htab_find_with_hash (cp_function_chain->extern_decl_map,
751 &in, in.uid);
752 if (h)
753 {
754 *stmt_p = h->to;
755 *walk_subtrees = 0;
756 return NULL;
757 }
758 }
759
d8472c75 760 /* Other than invisiref parms, don't walk the same tree twice. */
af76441f 761 if (pointer_set_contains (p_set, stmt))
d8472c75
JM
762 {
763 *walk_subtrees = 0;
764 return NULL_TREE;
765 }
766
767 if (TREE_CODE (stmt) == ADDR_EXPR
768 && is_invisiref_parm (TREE_OPERAND (stmt, 0)))
769 {
770 *stmt_p = convert (TREE_TYPE (stmt), TREE_OPERAND (stmt, 0));
771 *walk_subtrees = 0;
772 }
cc77ae10
JM
773 else if (TREE_CODE (stmt) == RETURN_EXPR
774 && TREE_OPERAND (stmt, 0)
775 && is_invisiref_parm (TREE_OPERAND (stmt, 0)))
776 /* Don't dereference an invisiref RESULT_DECL inside a RETURN_EXPR. */
777 *walk_subtrees = 0;
e02a048f
JJ
778 else if (TREE_CODE (stmt) == OMP_CLAUSE)
779 switch (OMP_CLAUSE_CODE (stmt))
780 {
a68ab351
JJ
781 case OMP_CLAUSE_LASTPRIVATE:
782 /* Don't dereference an invisiref in OpenMP clauses. */
783 if (is_invisiref_parm (OMP_CLAUSE_DECL (stmt)))
784 {
785 *walk_subtrees = 0;
786 if (OMP_CLAUSE_LASTPRIVATE_STMT (stmt))
787 cp_walk_tree (&OMP_CLAUSE_LASTPRIVATE_STMT (stmt),
ac3cbee5 788 cp_genericize_r, data, NULL);
a68ab351
JJ
789 }
790 break;
e02a048f
JJ
791 case OMP_CLAUSE_PRIVATE:
792 case OMP_CLAUSE_SHARED:
793 case OMP_CLAUSE_FIRSTPRIVATE:
e02a048f
JJ
794 case OMP_CLAUSE_COPYIN:
795 case OMP_CLAUSE_COPYPRIVATE:
796 /* Don't dereference an invisiref in OpenMP clauses. */
797 if (is_invisiref_parm (OMP_CLAUSE_DECL (stmt)))
798 *walk_subtrees = 0;
799 break;
800 case OMP_CLAUSE_REDUCTION:
801 gcc_assert (!is_invisiref_parm (OMP_CLAUSE_DECL (stmt)));
802 break;
803 default:
804 break;
805 }
6615c446 806 else if (IS_TYPE_OR_DECL_P (stmt))
5a508662 807 *walk_subtrees = 0;
d8472c75
JM
808
809 /* Due to the way voidify_wrapper_expr is written, we don't get a chance
810 to lower this construct before scanning it, so we need to lower these
811 before doing anything else. */
5a508662 812 else if (TREE_CODE (stmt) == CLEANUP_STMT)
af76441f
AP
813 *stmt_p = build2 (CLEANUP_EH_ONLY (stmt) ? TRY_CATCH_EXPR
814 : TRY_FINALLY_EXPR,
815 void_type_node,
816 CLEANUP_BODY (stmt),
817 CLEANUP_EXPR (stmt));
818
f74d9c8f
JJ
819 else if (TREE_CODE (stmt) == IF_STMT)
820 {
821 genericize_if_stmt (stmt_p);
822 /* *stmt_p has changed, tail recurse to handle it again. */
823 return cp_genericize_r (stmt_p, walk_subtrees, data);
824 }
825
bbdf5682
JJ
826 /* COND_EXPR might have incompatible types in branches if one or both
827 arms are bitfields. Fix it up now. */
828 else if (TREE_CODE (stmt) == COND_EXPR)
829 {
830 tree type_left
831 = (TREE_OPERAND (stmt, 1)
832 ? is_bitfield_expr_with_lowered_type (TREE_OPERAND (stmt, 1))
833 : NULL_TREE);
834 tree type_right
835 = (TREE_OPERAND (stmt, 2)
836 ? is_bitfield_expr_with_lowered_type (TREE_OPERAND (stmt, 2))
837 : NULL_TREE);
d767aebf
JJ
838 if (type_left
839 && !useless_type_conversion_p (TREE_TYPE (stmt),
840 TREE_TYPE (TREE_OPERAND (stmt, 1))))
bbdf5682
JJ
841 {
842 TREE_OPERAND (stmt, 1)
843 = fold_convert (type_left, TREE_OPERAND (stmt, 1));
844 gcc_assert (useless_type_conversion_p (TREE_TYPE (stmt),
845 type_left));
846 }
d767aebf
JJ
847 if (type_right
848 && !useless_type_conversion_p (TREE_TYPE (stmt),
849 TREE_TYPE (TREE_OPERAND (stmt, 2))))
bbdf5682
JJ
850 {
851 TREE_OPERAND (stmt, 2)
852 = fold_convert (type_right, TREE_OPERAND (stmt, 2));
853 gcc_assert (useless_type_conversion_p (TREE_TYPE (stmt),
854 type_right));
855 }
856 }
857
ac3cbee5
RG
858 else if (TREE_CODE (stmt) == BIND_EXPR)
859 {
860 VEC_safe_push (tree, heap, wtd->bind_expr_stack, stmt);
861 cp_walk_tree (&BIND_EXPR_BODY (stmt),
862 cp_genericize_r, data, NULL);
863 VEC_pop (tree, wtd->bind_expr_stack);
ac3cbee5
RG
864 }
865
866 else if (TREE_CODE (stmt) == USING_STMT)
867 {
868 tree block = NULL_TREE;
869
870 /* Get the innermost inclosing GIMPLE_BIND that has a non NULL
871 BLOCK, and append an IMPORTED_DECL to its
872 BLOCK_VARS chained list. */
873 if (wtd->bind_expr_stack)
874 {
875 int i;
876 for (i = VEC_length (tree, wtd->bind_expr_stack) - 1; i >= 0; i--)
877 if ((block = BIND_EXPR_BLOCK (VEC_index (tree,
878 wtd->bind_expr_stack, i))))
879 break;
880 }
881 if (block)
882 {
883 tree using_directive;
884 gcc_assert (TREE_OPERAND (stmt, 0));
885
886 using_directive = make_node (IMPORTED_DECL);
887 TREE_TYPE (using_directive) = void_type_node;
888
889 IMPORTED_DECL_ASSOCIATED_DECL (using_directive)
890 = TREE_OPERAND (stmt, 0);
891 TREE_CHAIN (using_directive) = BLOCK_VARS (block);
892 BLOCK_VARS (block) = using_directive;
893 }
894 /* The USING_STMT won't appear in GENERIC. */
895 *stmt_p = build1 (NOP_EXPR, void_type_node, integer_zero_node);
896 *walk_subtrees = 0;
897 }
898
899 else if (TREE_CODE (stmt) == DECL_EXPR
900 && TREE_CODE (DECL_EXPR_DECL (stmt)) == USING_DECL)
901 {
902 /* Using decls inside DECL_EXPRs are just dropped on the floor. */
903 *stmt_p = build1 (NOP_EXPR, void_type_node, integer_zero_node);
904 *walk_subtrees = 0;
905 }
906
af76441f 907 pointer_set_insert (p_set, *stmt_p);
c8094d83 908
5a508662
RH
909 return NULL;
910}
911
912void
913cp_genericize (tree fndecl)
914{
d8472c75 915 tree t;
ac3cbee5 916 struct cp_genericize_data wtd;
d8472c75
JM
917
918 /* Fix up the types of parms passed by invisible reference. */
919 for (t = DECL_ARGUMENTS (fndecl); t; t = TREE_CHAIN (t))
dfb5c523
MM
920 if (TREE_ADDRESSABLE (TREE_TYPE (t)))
921 {
922 /* If a function's arguments are copied to create a thunk,
923 then DECL_BY_REFERENCE will be set -- but the type of the
924 argument will be a pointer type, so we will never get
925 here. */
926 gcc_assert (!DECL_BY_REFERENCE (t));
927 gcc_assert (DECL_ARG_TYPE (t) != TREE_TYPE (t));
928 TREE_TYPE (t) = DECL_ARG_TYPE (t);
929 DECL_BY_REFERENCE (t) = 1;
930 TREE_ADDRESSABLE (t) = 0;
931 relayout_decl (t);
932 }
d8472c75 933
cc77ae10
JM
934 /* Do the same for the return value. */
935 if (TREE_ADDRESSABLE (TREE_TYPE (DECL_RESULT (fndecl))))
936 {
937 t = DECL_RESULT (fndecl);
938 TREE_TYPE (t) = build_reference_type (TREE_TYPE (t));
939 DECL_BY_REFERENCE (t) = 1;
940 TREE_ADDRESSABLE (t) = 0;
941 relayout_decl (t);
942 }
943
d8472c75
JM
944 /* If we're a clone, the body is already GIMPLE. */
945 if (DECL_CLONED_FUNCTION_P (fndecl))
946 return;
947
948 /* We do want to see every occurrence of the parms, so we can't just use
949 walk_tree's hash functionality. */
ac3cbee5
RG
950 wtd.p_set = pointer_set_create ();
951 wtd.bind_expr_stack = NULL;
952 cp_walk_tree (&DECL_SAVED_TREE (fndecl), cp_genericize_r, &wtd, NULL);
953 pointer_set_destroy (wtd.p_set);
954 VEC_free (tree, heap, wtd.bind_expr_stack);
5a508662
RH
955
956 /* Do everything else. */
957 c_genericize (fndecl);
1799e5d5
RH
958
959 gcc_assert (bc_label[bc_break] == NULL);
960 gcc_assert (bc_label[bc_continue] == NULL);
961}
962\f
963/* Build code to apply FN to each member of ARG1 and ARG2. FN may be
964 NULL if there is in fact nothing to do. ARG2 may be null if FN
965 actually only takes one argument. */
966
967static tree
968cxx_omp_clause_apply_fn (tree fn, tree arg1, tree arg2)
969{
c2898ec9 970 tree defparm, parm, t;
94a0dd7b
SL
971 int i = 0;
972 int nargs;
973 tree *argarray;
fae2b46b 974
1799e5d5
RH
975 if (fn == NULL)
976 return NULL;
977
94a0dd7b
SL
978 nargs = list_length (DECL_ARGUMENTS (fn));
979 argarray = (tree *) alloca (nargs * sizeof (tree));
980
fae2b46b
JJ
981 defparm = TREE_CHAIN (TYPE_ARG_TYPES (TREE_TYPE (fn)));
982 if (arg2)
983 defparm = TREE_CHAIN (defparm);
984
1799e5d5
RH
985 if (TREE_CODE (TREE_TYPE (arg1)) == ARRAY_TYPE)
986 {
987 tree inner_type = TREE_TYPE (arg1);
988 tree start1, end1, p1;
989 tree start2 = NULL, p2 = NULL;
c2898ec9 990 tree ret = NULL, lab;
1799e5d5
RH
991
992 start1 = arg1;
993 start2 = arg2;
994 do
995 {
996 inner_type = TREE_TYPE (inner_type);
997 start1 = build4 (ARRAY_REF, inner_type, start1,
998 size_zero_node, NULL, NULL);
999 if (arg2)
1000 start2 = build4 (ARRAY_REF, inner_type, start2,
1001 size_zero_node, NULL, NULL);
1002 }
1003 while (TREE_CODE (inner_type) == ARRAY_TYPE);
db3927fb 1004 start1 = build_fold_addr_expr_loc (input_location, start1);
1799e5d5 1005 if (arg2)
db3927fb 1006 start2 = build_fold_addr_expr_loc (input_location, start2);
1799e5d5
RH
1007
1008 end1 = TYPE_SIZE_UNIT (TREE_TYPE (arg1));
5be014d5 1009 end1 = build2 (POINTER_PLUS_EXPR, TREE_TYPE (start1), start1, end1);
1799e5d5
RH
1010
1011 p1 = create_tmp_var (TREE_TYPE (start1), NULL);
726a989a 1012 t = build2 (MODIFY_EXPR, TREE_TYPE (p1), p1, start1);
1799e5d5
RH
1013 append_to_statement_list (t, &ret);
1014
1015 if (arg2)
1016 {
1017 p2 = create_tmp_var (TREE_TYPE (start2), NULL);
726a989a 1018 t = build2 (MODIFY_EXPR, TREE_TYPE (p2), p2, start2);
1799e5d5
RH
1019 append_to_statement_list (t, &ret);
1020 }
1021
c2255bc4 1022 lab = create_artificial_label (input_location);
1799e5d5
RH
1023 t = build1 (LABEL_EXPR, void_type_node, lab);
1024 append_to_statement_list (t, &ret);
1025
94a0dd7b 1026 argarray[i++] = p1;
1799e5d5 1027 if (arg2)
94a0dd7b 1028 argarray[i++] = p2;
fae2b46b 1029 /* Handle default arguments. */
d2ee546f
JJ
1030 for (parm = defparm; parm && parm != void_list_node;
1031 parm = TREE_CHAIN (parm), i++)
94a0dd7b
SL
1032 argarray[i] = convert_default_arg (TREE_VALUE (parm),
1033 TREE_PURPOSE (parm), fn, i);
1034 t = build_call_a (fn, i, argarray);
c2898ec9
JJ
1035 t = fold_convert (void_type_node, t);
1036 t = fold_build_cleanup_point_expr (TREE_TYPE (t), t);
1799e5d5
RH
1037 append_to_statement_list (t, &ret);
1038
5be014d5
AP
1039 t = TYPE_SIZE_UNIT (inner_type);
1040 t = build2 (POINTER_PLUS_EXPR, TREE_TYPE (p1), p1, t);
726a989a 1041 t = build2 (MODIFY_EXPR, TREE_TYPE (p1), p1, t);
1799e5d5
RH
1042 append_to_statement_list (t, &ret);
1043
1044 if (arg2)
1045 {
5be014d5
AP
1046 t = TYPE_SIZE_UNIT (inner_type);
1047 t = build2 (POINTER_PLUS_EXPR, TREE_TYPE (p2), p2, t);
726a989a 1048 t = build2 (MODIFY_EXPR, TREE_TYPE (p2), p2, t);
1799e5d5
RH
1049 append_to_statement_list (t, &ret);
1050 }
1051
1052 t = build2 (NE_EXPR, boolean_type_node, p1, end1);
1053 t = build3 (COND_EXPR, void_type_node, t, build_and_jump (&lab), NULL);
1054 append_to_statement_list (t, &ret);
1055
1056 return ret;
1057 }
1058 else
1059 {
db3927fb 1060 argarray[i++] = build_fold_addr_expr_loc (input_location, arg1);
1799e5d5 1061 if (arg2)
db3927fb 1062 argarray[i++] = build_fold_addr_expr_loc (input_location, arg2);
fae2b46b 1063 /* Handle default arguments. */
d2ee546f 1064 for (parm = defparm; parm && parm != void_list_node;
94a0dd7b
SL
1065 parm = TREE_CHAIN (parm), i++)
1066 argarray[i] = convert_default_arg (TREE_VALUE (parm),
1067 TREE_PURPOSE (parm),
1068 fn, i);
c2898ec9
JJ
1069 t = build_call_a (fn, i, argarray);
1070 t = fold_convert (void_type_node, t);
1071 return fold_build_cleanup_point_expr (TREE_TYPE (t), t);
1799e5d5
RH
1072 }
1073}
1074
1075/* Return code to initialize DECL with its default constructor, or
1076 NULL if there's nothing to do. */
1077
1078tree
a68ab351
JJ
1079cxx_omp_clause_default_ctor (tree clause, tree decl,
1080 tree outer ATTRIBUTE_UNUSED)
1799e5d5
RH
1081{
1082 tree info = CP_OMP_CLAUSE_INFO (clause);
1083 tree ret = NULL;
1084
1085 if (info)
1086 ret = cxx_omp_clause_apply_fn (TREE_VEC_ELT (info, 0), decl, NULL);
1087
1088 return ret;
1089}
1090
1091/* Return code to initialize DST with a copy constructor from SRC. */
1092
1093tree
1094cxx_omp_clause_copy_ctor (tree clause, tree dst, tree src)
1095{
1096 tree info = CP_OMP_CLAUSE_INFO (clause);
1097 tree ret = NULL;
1098
1099 if (info)
1100 ret = cxx_omp_clause_apply_fn (TREE_VEC_ELT (info, 0), dst, src);
1101 if (ret == NULL)
726a989a 1102 ret = build2 (MODIFY_EXPR, TREE_TYPE (dst), dst, src);
1799e5d5
RH
1103
1104 return ret;
1105}
1106
1107/* Similarly, except use an assignment operator instead. */
1108
1109tree
1110cxx_omp_clause_assign_op (tree clause, tree dst, tree src)
1111{
1112 tree info = CP_OMP_CLAUSE_INFO (clause);
1113 tree ret = NULL;
1114
1115 if (info)
1116 ret = cxx_omp_clause_apply_fn (TREE_VEC_ELT (info, 2), dst, src);
1117 if (ret == NULL)
726a989a 1118 ret = build2 (MODIFY_EXPR, TREE_TYPE (dst), dst, src);
1799e5d5
RH
1119
1120 return ret;
1121}
1122
1123/* Return code to destroy DECL. */
1124
1125tree
1126cxx_omp_clause_dtor (tree clause, tree decl)
1127{
1128 tree info = CP_OMP_CLAUSE_INFO (clause);
1129 tree ret = NULL;
1130
1131 if (info)
1132 ret = cxx_omp_clause_apply_fn (TREE_VEC_ELT (info, 1), decl, NULL);
1133
1134 return ret;
5a508662 1135}
077b0dfb
JJ
1136
1137/* True if OpenMP should privatize what this DECL points to rather
1138 than the DECL itself. */
1139
1140bool
58f9752a 1141cxx_omp_privatize_by_reference (const_tree decl)
077b0dfb 1142{
e02a048f 1143 return is_invisiref_parm (decl);
077b0dfb 1144}
a68ab351
JJ
1145
1146/* True if OpenMP sharing attribute of DECL is predetermined. */
1147
1148enum omp_clause_default_kind
1149cxx_omp_predetermined_sharing (tree decl)
1150{
1151 tree type;
1152
1153 /* Static data members are predetermined as shared. */
1154 if (TREE_STATIC (decl))
1155 {
1156 tree ctx = CP_DECL_CONTEXT (decl);
1157 if (TYPE_P (ctx) && MAYBE_CLASS_TYPE_P (ctx))
1158 return OMP_CLAUSE_DEFAULT_SHARED;
1159 }
1160
1161 type = TREE_TYPE (decl);
1162 if (TREE_CODE (type) == REFERENCE_TYPE)
1163 {
1164 if (!is_invisiref_parm (decl))
1165 return OMP_CLAUSE_DEFAULT_UNSPECIFIED;
1166 type = TREE_TYPE (type);
1167
1168 if (TREE_CODE (decl) == RESULT_DECL && DECL_NAME (decl))
1169 {
1170 /* NVR doesn't preserve const qualification of the
1171 variable's type. */
1172 tree outer = outer_curly_brace_block (current_function_decl);
1173 tree var;
1174
1175 if (outer)
1176 for (var = BLOCK_VARS (outer); var; var = TREE_CHAIN (var))
1177 if (DECL_NAME (decl) == DECL_NAME (var)
1178 && (TYPE_MAIN_VARIANT (type)
1179 == TYPE_MAIN_VARIANT (TREE_TYPE (var))))
1180 {
1181 if (TYPE_READONLY (TREE_TYPE (var)))
1182 type = TREE_TYPE (var);
1183 break;
1184 }
1185 }
1186 }
1187
1188 if (type == error_mark_node)
1189 return OMP_CLAUSE_DEFAULT_UNSPECIFIED;
1190
1191 /* Variables with const-qualified type having no mutable member
1192 are predetermined shared. */
1193 if (TYPE_READONLY (type) && !cp_has_mutable_p (type))
1194 return OMP_CLAUSE_DEFAULT_SHARED;
1195
1196 return OMP_CLAUSE_DEFAULT_UNSPECIFIED;
1197}
1198
1199/* Finalize an implicitly determined clause. */
1200
1201void
1202cxx_omp_finish_clause (tree c)
1203{
1204 tree decl, inner_type;
1205 bool make_shared = false;
1206
1207 if (OMP_CLAUSE_CODE (c) != OMP_CLAUSE_FIRSTPRIVATE)
1208 return;
1209
1210 decl = OMP_CLAUSE_DECL (c);
1211 decl = require_complete_type (decl);
1212 inner_type = TREE_TYPE (decl);
1213 if (decl == error_mark_node)
1214 make_shared = true;
1215 else if (TREE_CODE (TREE_TYPE (decl)) == REFERENCE_TYPE)
1216 {
1217 if (is_invisiref_parm (decl))
1218 inner_type = TREE_TYPE (inner_type);
1219 else
1220 {
1221 error ("%qE implicitly determined as %<firstprivate%> has reference type",
1222 decl);
1223 make_shared = true;
1224 }
1225 }
1226
1227 /* We're interested in the base element, not arrays. */
1228 while (TREE_CODE (inner_type) == ARRAY_TYPE)
1229 inner_type = TREE_TYPE (inner_type);
1230
1231 /* Check for special function availability by building a call to one.
1232 Save the results, because later we won't be in the right context
1233 for making these queries. */
1234 if (!make_shared
1235 && CLASS_TYPE_P (inner_type)
1236 && cxx_omp_create_clause_info (c, inner_type, false, true, false))
1237 make_shared = true;
1238
1239 if (make_shared)
1240 OMP_CLAUSE_CODE (c) = OMP_CLAUSE_SHARED;
1241}
This page took 1.467336 seconds and 5 git commands to generate.