OSDN Git Service

PR c++/49066
[pf3gnuchains/gcc-fork.git] / gcc / cp / cp-gimplify.c
1 /* C++-specific tree lowering bits; see also c-gimplify.c and tree-gimple.c.
2
3    Copyright (C) 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011
4    Free Software Foundation, Inc.
5    Contributed by Jason Merrill <jason@redhat.com>
6
7 This file is part of GCC.
8
9 GCC is free software; you can redistribute it and/or modify it under
10 the terms of the GNU General Public License as published by the Free
11 Software Foundation; either version 3, or (at your option) any later
12 version.
13
14 GCC is distributed in the hope that it will be useful, but WITHOUT ANY
15 WARRANTY; without even the implied warranty of MERCHANTABILITY or
16 FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
17 for more details.
18
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/>.  */
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-family/c-common.h"
30 #include "tree-iterator.h"
31 #include "gimple.h"
32 #include "hashtab.h"
33 #include "pointer-set.h"
34 #include "flags.h"
35 #include "splay-tree.h"
36
37 /* Local declarations.  */
38
39 enum bc_t { bc_break = 0, bc_continue = 1 };
40
41 /* Stack of labels which are targets for "break" or "continue",
42    linked through TREE_CHAIN.  */
43 static tree bc_label[2];
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
50 static tree
51 begin_bc_block (enum bc_t bc)
52 {
53   tree label = create_artificial_label (input_location);
54   DECL_CHAIN (label) = bc_label[bc];
55   bc_label[bc] = label;
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
66 static gimple_seq
67 finish_bc_block (enum bc_t bc, tree label, gimple_seq body)
68 {
69   gcc_assert (label == bc_label[bc]);
70
71   if (TREE_USED (label))
72     {
73       gimple_seq_add_stmt (&body, gimple_build_label (label));
74     }
75
76   bc_label[bc] = DECL_CHAIN (label);
77   DECL_CHAIN (label) = NULL_TREE;
78   return body;
79 }
80
81 /* Get the LABEL_EXPR to represent a break or continue statement
82    in the current block scope.  BC indicates which.  */
83
84 static tree
85 get_bc_label (enum bc_t bc)
86 {
87   tree label = bc_label[bc];
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;
101   return label;
102 }
103
104 /* Genericize a TRY_BLOCK.  */
105
106 static void
107 genericize_try_block (tree *stmt_p)
108 {
109   tree body = TRY_STMTS (*stmt_p);
110   tree cleanup = TRY_HANDLERS (*stmt_p);
111
112   *stmt_p = build2 (TRY_CATCH_EXPR, void_type_node, body, cleanup);
113 }
114
115 /* Genericize a HANDLER by converting to a CATCH_EXPR.  */
116
117 static void
118 genericize_catch_block (tree *stmt_p)
119 {
120   tree type = HANDLER_TYPE (*stmt_p);
121   tree body = HANDLER_BODY (*stmt_p);
122
123   /* FIXME should the caught type go in TREE_TYPE?  */
124   *stmt_p = build2 (CATCH_EXPR, void_type_node, type, body);
125 }
126
127 /* A terser interface for building a representation of an exception
128    specification.  */
129
130 static tree
131 build_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
145 /* Genericize an EH_SPEC_BLOCK by converting it to a
146    TRY_CATCH_EXPR/EH_FILTER_EXPR pair.  */
147
148 static void
149 genericize_eh_spec_block (tree *stmt_p)
150 {
151   tree body = EH_SPEC_STMTS (*stmt_p);
152   tree allowed = EH_SPEC_RAISES (*stmt_p);
153   tree failure = build_call_n (call_unexpected_node, 1, build_exc_ptr ());
154
155   *stmt_p = build_gimple_eh_filter_tree (body, allowed, failure);
156   TREE_NO_WARNING (*stmt_p) = true;
157   TREE_NO_WARNING (TREE_OPERAND (*stmt_p, 1)) = true;
158 }
159
160 /* Genericize an IF_STMT by turning it into a COND_EXPR.  */
161
162 static void
163 genericize_if_stmt (tree *stmt_p)
164 {
165   tree stmt, cond, then_, else_;
166   location_t locus = EXPR_LOCATION (*stmt_p);
167
168   stmt = *stmt_p;
169   cond = IF_COND (stmt);
170   then_ = THEN_CLAUSE (stmt);
171   else_ = ELSE_CLAUSE (stmt);
172
173   if (!then_)
174     then_ = build_empty_stmt (locus);
175   if (!else_)
176     else_ = build_empty_stmt (locus);
177
178   if (integer_nonzerop (cond) && !TREE_SIDE_EFFECTS (else_))
179     stmt = then_;
180   else if (integer_zerop (cond) && !TREE_SIDE_EFFECTS (then_))
181     stmt = else_;
182   else
183     stmt = build3 (COND_EXPR, void_type_node, cond, then_, else_);
184   if (CAN_HAVE_LOCATION_P (stmt) && !EXPR_HAS_LOCATION (stmt))
185     SET_EXPR_LOCATION (stmt, locus);
186   *stmt_p = stmt;
187 }
188
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
196 static gimple_seq
197 gimplify_cp_loop (tree cond, tree body, tree incr, bool cond_is_first)
198 {
199   gimple top, entry, stmt;
200   gimple_seq stmt_list, body_seq, incr_seq, exit_seq;
201   tree cont_block, break_block;
202   location_t stmt_locus;
203
204   stmt_locus = input_location;
205   stmt_list = NULL;
206   body_seq = NULL;
207   incr_seq = NULL;
208   exit_seq = NULL;
209   entry = NULL;
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     {
217       top = NULL;
218       if (cond_is_first)
219         {
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);
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.  */
231       top = gimple_build_label (create_artificial_label (stmt_locus));
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.  */
236       if (cond && !integer_nonzerop (cond))
237         {
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             }
247
248           if (cond_is_first)
249             {
250               if (incr)
251                 {
252                   entry = gimple_build_label 
253                     (create_artificial_label (stmt_locus));
254                   stmt = gimple_build_goto (gimple_label_label (entry));
255                 }
256               else
257                 stmt = gimple_build_goto (get_bc_label (bc_continue));
258               gimple_set_location (stmt, stmt_locus);
259               gimple_seq_add_stmt (&stmt_list, stmt);
260             }
261         }
262       else
263         {
264           stmt = gimple_build_goto (gimple_label_label (top));
265           gimple_seq_add_stmt (&exit_seq, stmt);
266         }
267     }
268
269   gimplify_stmt (&body, &body_seq);
270   gimplify_stmt (&incr, &incr_seq);
271
272   body_seq = finish_bc_block (bc_continue, cont_block, body_seq);
273
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);
279
280   annotate_all_with_location (stmt_list, stmt_locus);
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
288 static void
289 gimplify_for_stmt (tree *stmt_p, gimple_seq *pre_p)
290 {
291   tree stmt = *stmt_p;
292
293   if (FOR_INIT_STMT (stmt))
294     gimplify_and_add (FOR_INIT_STMT (stmt), pre_p);
295
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;
300 }
301
302 /* Gimplify a WHILE_STMT node.  */
303
304 static void
305 gimplify_while_stmt (tree *stmt_p, gimple_seq *pre_p)
306 {
307   tree stmt = *stmt_p;
308   gimple_seq_add_seq (pre_p,
309                       gimplify_cp_loop (WHILE_COND (stmt), WHILE_BODY (stmt),
310                                         NULL_TREE, 1));
311   *stmt_p = NULL_TREE;
312 }
313
314 /* Gimplify a DO_STMT node.  */
315
316 static void
317 gimplify_do_stmt (tree *stmt_p, gimple_seq *pre_p)
318 {
319   tree stmt = *stmt_p;
320   gimple_seq_add_seq (pre_p,
321                       gimplify_cp_loop (DO_COND (stmt), DO_BODY (stmt),
322                                         NULL_TREE, 0));
323   *stmt_p = NULL_TREE;
324 }
325
326 /* Genericize a SWITCH_STMT by turning it into a SWITCH_EXPR.  */
327
328 static void
329 gimplify_switch_stmt (tree *stmt_p, gimple_seq *pre_p)
330 {
331   tree stmt = *stmt_p;
332   tree break_block, body, t;
333   location_t stmt_locus = input_location;
334   gimple_seq seq = NULL;
335
336   break_block = begin_bc_block (bc_break);
337
338   body = SWITCH_STMT_BODY (stmt);
339   if (!body)
340     body = build_empty_stmt (stmt_locus);
341
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);
346
347   seq = finish_bc_block (bc_break, break_block, seq);
348   gimple_seq_add_seq (pre_p, seq);
349   *stmt_p = NULL_TREE;
350 }
351
352 /* Hook into the middle of gimplifying an OMP_FOR node.  This is required
353    in order to properly gimplify CONTINUE statements.  Here we merely
354    manage the continue stack; the rest of the job is performed by the
355    regular gimplifier.  */
356
357 static enum gimplify_status
358 cp_gimplify_omp_for (tree *expr_p, gimple_seq *pre_p)
359 {
360   tree for_stmt = *expr_p;
361   tree cont_block;
362   gimple stmt;
363   gimple_seq seq = NULL;
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
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);
383
384   OMP_FOR_GIMPLIFYING_P (for_stmt) = 0;
385
386   return GS_ALL_DONE;
387 }
388
389 /*  Gimplify an EXPR_STMT node.  */
390
391 static void
392 gimplify_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.  */
405   if (stmt && warn_unused_value)
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))
412             warning (OPT_Wunused_value, "statement with no effect");
413         }
414       else
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
424 /* Gimplify initialization from an AGGR_INIT_EXPR.  */
425
426 static void
427 cp_gimplify_init_expr (tree *expr_p)
428 {
429   tree from = TREE_OPERAND (*expr_p, 1);
430   tree to = TREE_OPERAND (*expr_p, 0);
431   tree t;
432
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);
439
440   /* Look through any COMPOUND_EXPRs, since build_compound_expr pushes them
441      inside the TARGET_EXPR.  */
442   for (t = from; t; )
443     {
444       tree sub = TREE_CODE (t) == COMPOUND_EXPR ? TREE_OPERAND (t, 0) : t;
445
446       /* If we are initializing from an AGGR_INIT_EXPR, drop the INIT_EXPR and
447          replace the slot operand with our target.
448
449          Should we add a target parm to gimplify_expr instead?  No, as in this
450          case we want to replace the INIT_EXPR.  */
451       if (TREE_CODE (sub) == AGGR_INIT_EXPR
452           || TREE_CODE (sub) == VEC_INIT_EXPR)
453         {
454           if (TREE_CODE (sub) == AGGR_INIT_EXPR)
455             AGGR_INIT_EXPR_SLOT (sub) = to;
456           else
457             VEC_INIT_EXPR_SLOT (sub) = to;
458           *expr_p = from;
459
460           /* The initialization is now a side-effect, so the container can
461              become void.  */
462           if (from != sub)
463             TREE_TYPE (from) = void_type_node;
464         }
465
466       if (t == sub)
467         break;
468       else
469         t = TREE_OPERAND (t, 1);
470     }
471
472 }
473
474 /* Gimplify a MUST_NOT_THROW_EXPR.  */
475
476 static enum gimplify_status
477 gimplify_must_not_throw_expr (tree *expr_p, gimple_seq *pre_p)
478 {
479   tree stmt = *expr_p;
480   tree temp = voidify_wrapper_expr (stmt, NULL);
481   tree body = TREE_OPERAND (stmt, 0);
482   gimple_seq try_ = NULL;
483   gimple_seq catch_ = NULL;
484   gimple mnt;
485
486   gimplify_and_add (body, &try_);
487   mnt = gimple_build_eh_must_not_throw (terminate_node);
488   gimplify_seq_add_stmt (&catch_, mnt);
489   mnt = gimple_build_try (try_, catch_, GIMPLE_TRY_CATCH);
490
491   gimplify_seq_add_stmt (pre_p, mnt);
492   if (temp)
493     {
494       *expr_p = temp;
495       return GS_OK;
496     }
497
498   *expr_p = NULL;
499   return GS_ALL_DONE;
500 }
501
502 /* Do C++-specific gimplification.  Args are as for gimplify_expr.  */
503
504 int
505 cp_gimplify_expr (tree *expr_p, gimple_seq *pre_p, gimple_seq *post_p)
506 {
507   int saved_stmts_are_full_exprs_p = 0;
508   enum tree_code code = TREE_CODE (*expr_p);
509   enum gimplify_status ret;
510
511   if (STATEMENT_CODE_P (code))
512     {
513       saved_stmts_are_full_exprs_p = stmts_are_full_exprs_p ();
514       current_stmt_tree ()->stmts_are_full_exprs_p
515         = STMT_IS_FULL_EXPR_P (*expr_p);
516     }
517
518   switch (code)
519     {
520     case PTRMEM_CST:
521       *expr_p = cplus_expand_constant (*expr_p);
522       ret = GS_OK;
523       break;
524
525     case AGGR_INIT_EXPR:
526       simplify_aggr_init_expr (expr_p);
527       ret = GS_OK;
528       break;
529
530     case VEC_INIT_EXPR:
531       {
532         location_t loc = input_location;
533         tree init = VEC_INIT_EXPR_INIT (*expr_p);
534         int from_array = (init && TREE_CODE (TREE_TYPE (init)) == ARRAY_TYPE);
535         gcc_assert (EXPR_HAS_LOCATION (*expr_p));
536         input_location = EXPR_LOCATION (*expr_p);
537         *expr_p = build_vec_init (VEC_INIT_EXPR_SLOT (*expr_p), NULL_TREE,
538                                   init, VEC_INIT_EXPR_VALUE_INIT (*expr_p),
539                                   from_array,
540                                   tf_warning_or_error);
541         ret = GS_OK;
542         input_location = loc;
543       }
544       break;
545
546     case THROW_EXPR:
547       /* FIXME communicate throw type to back end, probably by moving
548          THROW_EXPR into ../tree.def.  */
549       *expr_p = TREE_OPERAND (*expr_p, 0);
550       ret = GS_OK;
551       break;
552
553     case MUST_NOT_THROW_EXPR:
554       ret = gimplify_must_not_throw_expr (expr_p, pre_p);
555       break;
556
557       /* We used to do this for MODIFY_EXPR as well, but that's unsafe; the
558          LHS of an assignment might also be involved in the RHS, as in bug
559          25979.  */
560     case INIT_EXPR:
561       cp_gimplify_init_expr (expr_p);
562       if (TREE_CODE (*expr_p) != INIT_EXPR)
563         return GS_OK;
564       /* Otherwise fall through.  */
565     case MODIFY_EXPR:
566       {
567         /* If the back end isn't clever enough to know that the lhs and rhs
568            types are the same, add an explicit conversion.  */
569         tree op0 = TREE_OPERAND (*expr_p, 0);
570         tree op1 = TREE_OPERAND (*expr_p, 1);
571
572         if (!error_operand_p (op0)
573             && !error_operand_p (op1)
574             && (TYPE_STRUCTURAL_EQUALITY_P (TREE_TYPE (op0))
575                 || TYPE_STRUCTURAL_EQUALITY_P (TREE_TYPE (op1)))
576             && !useless_type_conversion_p (TREE_TYPE (op1), TREE_TYPE (op0)))
577           TREE_OPERAND (*expr_p, 1) = build1 (VIEW_CONVERT_EXPR,
578                                               TREE_TYPE (op0), op1);
579
580         else if ((is_gimple_lvalue (op1) || INDIRECT_REF_P (op1)
581                   || (TREE_CODE (op1) == CONSTRUCTOR
582                       && CONSTRUCTOR_NELTS (op1) == 0)
583                   || (TREE_CODE (op1) == CALL_EXPR
584                       && !CALL_EXPR_RETURN_SLOT_OPT (op1)))
585                  && is_really_empty_class (TREE_TYPE (op0)))
586           {
587             /* Remove any copies of empty classes.  We check that the RHS
588                has a simple form so that TARGET_EXPRs and non-empty
589                CONSTRUCTORs get reduced properly, and we leave the return
590                slot optimization alone because it isn't a copy (FIXME so it
591                shouldn't be represented as one).
592
593                Also drop volatile variables on the RHS to avoid infinite
594                recursion from gimplify_expr trying to load the value.  */
595             if (!TREE_SIDE_EFFECTS (op1)
596                 || (DECL_P (op1) && TREE_THIS_VOLATILE (op1)))
597               *expr_p = op0;
598             else if (TREE_CODE (op1) == MEM_REF
599                      && TREE_THIS_VOLATILE (op1))
600               {
601                 /* Similarly for volatile MEM_REFs on the RHS.  */
602                 if (!TREE_SIDE_EFFECTS (TREE_OPERAND (op1, 0)))
603                   *expr_p = op0;
604                 else
605                   *expr_p = build2 (COMPOUND_EXPR, TREE_TYPE (*expr_p),
606                                     TREE_OPERAND (op1, 0), op0);
607               }
608             else
609               *expr_p = build2 (COMPOUND_EXPR, TREE_TYPE (*expr_p),
610                                 op0, op1);
611           }
612       }
613       ret = GS_OK;
614       break;
615
616     case EMPTY_CLASS_EXPR:
617       /* We create an empty CONSTRUCTOR with RECORD_TYPE.  */
618       *expr_p = build_constructor (TREE_TYPE (*expr_p), NULL);
619       ret = GS_OK;
620       break;
621
622     case BASELINK:
623       *expr_p = BASELINK_FUNCTIONS (*expr_p);
624       ret = GS_OK;
625       break;
626
627     case TRY_BLOCK:
628       genericize_try_block (expr_p);
629       ret = GS_OK;
630       break;
631
632     case HANDLER:
633       genericize_catch_block (expr_p);
634       ret = GS_OK;
635       break;
636
637     case EH_SPEC_BLOCK:
638       genericize_eh_spec_block (expr_p);
639       ret = GS_OK;
640       break;
641
642     case USING_STMT:
643       gcc_unreachable ();
644
645     case FOR_STMT:
646       gimplify_for_stmt (expr_p, pre_p);
647       ret = GS_OK;
648       break;
649
650     case WHILE_STMT:
651       gimplify_while_stmt (expr_p, pre_p);
652       ret = GS_OK;
653       break;
654
655     case DO_STMT:
656       gimplify_do_stmt (expr_p, pre_p);
657       ret = GS_OK;
658       break;
659
660     case SWITCH_STMT:
661       gimplify_switch_stmt (expr_p, pre_p);
662       ret = GS_OK;
663       break;
664
665     case OMP_FOR:
666       ret = cp_gimplify_omp_for (expr_p, pre_p);
667       break;
668
669     case CONTINUE_STMT:
670       gimple_seq_add_stmt (pre_p, gimple_build_predict (PRED_CONTINUE, NOT_TAKEN));
671       gimple_seq_add_stmt (pre_p, gimple_build_goto (get_bc_label (bc_continue)));
672       *expr_p = NULL_TREE;
673       ret = GS_ALL_DONE;
674       break;
675
676     case BREAK_STMT:
677       gimple_seq_add_stmt (pre_p, gimple_build_goto (get_bc_label (bc_break)));
678       *expr_p = NULL_TREE;
679       ret = GS_ALL_DONE;
680       break;
681
682     case EXPR_STMT:
683       gimplify_expr_stmt (expr_p);
684       ret = GS_OK;
685       break;
686
687     case UNARY_PLUS_EXPR:
688       {
689         tree arg = TREE_OPERAND (*expr_p, 0);
690         tree type = TREE_TYPE (*expr_p);
691         *expr_p = (TREE_TYPE (arg) != type) ? fold_convert (type, arg)
692                                             : arg;
693         ret = GS_OK;
694       }
695       break;
696
697     default:
698       ret = (enum gimplify_status) c_gimplify_expr (expr_p, pre_p, post_p);
699       break;
700     }
701
702   /* Restore saved state.  */
703   if (STATEMENT_CODE_P (code))
704     current_stmt_tree ()->stmts_are_full_exprs_p
705       = saved_stmts_are_full_exprs_p;
706
707   return ret;
708 }
709
710 static inline bool
711 is_invisiref_parm (const_tree t)
712 {
713   return ((TREE_CODE (t) == PARM_DECL || TREE_CODE (t) == RESULT_DECL)
714           && DECL_BY_REFERENCE (t));
715 }
716
717 /* Return true if the uid in both int tree maps are equal.  */
718
719 int
720 cxx_int_tree_map_eq (const void *va, const void *vb)
721 {
722   const struct cxx_int_tree_map *a = (const struct cxx_int_tree_map *) va;
723   const struct cxx_int_tree_map *b = (const struct cxx_int_tree_map *) vb;
724   return (a->uid == b->uid);
725 }
726
727 /* Hash a UID in a cxx_int_tree_map.  */
728
729 unsigned int
730 cxx_int_tree_map_hash (const void *item)
731 {
732   return ((const struct cxx_int_tree_map *)item)->uid;
733 }
734
735 /* A stable comparison routine for use with splay trees and DECLs.  */
736
737 static int
738 splay_tree_compare_decl_uid (splay_tree_key xa, splay_tree_key xb)
739 {
740   tree a = (tree) xa;
741   tree b = (tree) xb;
742
743   return DECL_UID (a) - DECL_UID (b);
744 }
745
746 /* OpenMP context during genericization.  */
747
748 struct cp_genericize_omp_taskreg
749 {
750   bool is_parallel;
751   bool default_shared;
752   struct cp_genericize_omp_taskreg *outer;
753   splay_tree variables;
754 };
755
756 /* Return true if genericization should try to determine if
757    DECL is firstprivate or shared within task regions.  */
758
759 static bool
760 omp_var_to_track (tree decl)
761 {
762   tree type = TREE_TYPE (decl);
763   if (is_invisiref_parm (decl))
764     type = TREE_TYPE (type);
765   while (TREE_CODE (type) == ARRAY_TYPE)
766     type = TREE_TYPE (type);
767   if (type == error_mark_node || !CLASS_TYPE_P (type))
768     return false;
769   if (TREE_CODE (decl) == VAR_DECL && DECL_THREAD_LOCAL_P (decl))
770     return false;
771   if (cxx_omp_predetermined_sharing (decl) != OMP_CLAUSE_DEFAULT_UNSPECIFIED)
772     return false;
773   return true;
774 }
775
776 /* Note DECL use in OpenMP region OMP_CTX during genericization.  */
777
778 static void
779 omp_cxx_notice_variable (struct cp_genericize_omp_taskreg *omp_ctx, tree decl)
780 {
781   splay_tree_node n = splay_tree_lookup (omp_ctx->variables,
782                                          (splay_tree_key) decl);
783   if (n == NULL)
784     {
785       int flags = OMP_CLAUSE_DEFAULT_SHARED;
786       if (omp_ctx->outer)
787         omp_cxx_notice_variable (omp_ctx->outer, decl);
788       if (!omp_ctx->default_shared)
789         {
790           struct cp_genericize_omp_taskreg *octx;
791
792           for (octx = omp_ctx->outer; octx; octx = octx->outer)
793             {
794               n = splay_tree_lookup (octx->variables, (splay_tree_key) decl);
795               if (n && n->value != OMP_CLAUSE_DEFAULT_SHARED)
796                 {
797                   flags = OMP_CLAUSE_DEFAULT_FIRSTPRIVATE;
798                   break;
799                 }
800               if (octx->is_parallel)
801                 break;
802             }
803           if (octx == NULL
804               && (TREE_CODE (decl) == PARM_DECL
805                   || (!(TREE_STATIC (decl) || DECL_EXTERNAL (decl))
806                       && DECL_CONTEXT (decl) == current_function_decl)))
807             flags = OMP_CLAUSE_DEFAULT_FIRSTPRIVATE;
808           if (flags == OMP_CLAUSE_DEFAULT_FIRSTPRIVATE)
809             {
810               /* DECL is implicitly determined firstprivate in
811                  the current task construct.  Ensure copy ctor and
812                  dtor are instantiated, because during gimplification
813                  it will be already too late.  */
814               tree type = TREE_TYPE (decl);
815               if (is_invisiref_parm (decl))
816                 type = TREE_TYPE (type);
817               while (TREE_CODE (type) == ARRAY_TYPE)
818                 type = TREE_TYPE (type);
819               get_copy_ctor (type, tf_none);
820               get_dtor (type, tf_none);
821             }
822         }
823       splay_tree_insert (omp_ctx->variables, (splay_tree_key) decl, flags);
824     }
825 }
826
827 /* Genericization context.  */
828
829 struct cp_genericize_data
830 {
831   struct pointer_set_t *p_set;
832   VEC (tree, heap) *bind_expr_stack;
833   struct cp_genericize_omp_taskreg *omp_ctx;
834 };
835
836 /* Perform any pre-gimplification lowering of C++ front end trees to
837    GENERIC.  */
838
839 static tree
840 cp_genericize_r (tree *stmt_p, int *walk_subtrees, void *data)
841 {
842   tree stmt = *stmt_p;
843   struct cp_genericize_data *wtd = (struct cp_genericize_data *) data;
844   struct pointer_set_t *p_set = wtd->p_set;
845
846   /* If in an OpenMP context, note var uses.  */
847   if (__builtin_expect (wtd->omp_ctx != NULL, 0)
848       && (TREE_CODE (stmt) == VAR_DECL
849           || TREE_CODE (stmt) == PARM_DECL
850           || TREE_CODE (stmt) == RESULT_DECL)
851       && omp_var_to_track (stmt))
852     omp_cxx_notice_variable (wtd->omp_ctx, stmt);
853
854   if (is_invisiref_parm (stmt)
855       /* Don't dereference parms in a thunk, pass the references through. */
856       && !(DECL_THUNK_P (current_function_decl)
857            && TREE_CODE (stmt) == PARM_DECL))
858     {
859       *stmt_p = convert_from_reference (stmt);
860       *walk_subtrees = 0;
861       return NULL;
862     }
863
864   /* Map block scope extern declarations to visible declarations with the
865      same name and type in outer scopes if any.  */
866   if (cp_function_chain->extern_decl_map
867       && (TREE_CODE (stmt) == FUNCTION_DECL || TREE_CODE (stmt) == VAR_DECL)
868       && DECL_EXTERNAL (stmt))
869     {
870       struct cxx_int_tree_map *h, in;
871       in.uid = DECL_UID (stmt);
872       h = (struct cxx_int_tree_map *)
873           htab_find_with_hash (cp_function_chain->extern_decl_map,
874                                &in, in.uid);
875       if (h)
876         {
877           *stmt_p = h->to;
878           *walk_subtrees = 0;
879           return NULL;
880         }
881     }
882
883   /* Other than invisiref parms, don't walk the same tree twice.  */
884   if (pointer_set_contains (p_set, stmt))
885     {
886       *walk_subtrees = 0;
887       return NULL_TREE;
888     }
889
890   if (TREE_CODE (stmt) == ADDR_EXPR
891       && is_invisiref_parm (TREE_OPERAND (stmt, 0)))
892     {
893       /* If in an OpenMP context, note var uses.  */
894       if (__builtin_expect (wtd->omp_ctx != NULL, 0)
895           && omp_var_to_track (TREE_OPERAND (stmt, 0)))
896         omp_cxx_notice_variable (wtd->omp_ctx, TREE_OPERAND (stmt, 0));
897       *stmt_p = convert (TREE_TYPE (stmt), TREE_OPERAND (stmt, 0));
898       *walk_subtrees = 0;
899     }
900   else if (TREE_CODE (stmt) == RETURN_EXPR
901            && TREE_OPERAND (stmt, 0)
902            && is_invisiref_parm (TREE_OPERAND (stmt, 0)))
903     /* Don't dereference an invisiref RESULT_DECL inside a RETURN_EXPR.  */
904     *walk_subtrees = 0;
905   else if (TREE_CODE (stmt) == OMP_CLAUSE)
906     switch (OMP_CLAUSE_CODE (stmt))
907       {
908       case OMP_CLAUSE_LASTPRIVATE:
909         /* Don't dereference an invisiref in OpenMP clauses.  */
910         if (is_invisiref_parm (OMP_CLAUSE_DECL (stmt)))
911           {
912             *walk_subtrees = 0;
913             if (OMP_CLAUSE_LASTPRIVATE_STMT (stmt))
914               cp_walk_tree (&OMP_CLAUSE_LASTPRIVATE_STMT (stmt),
915                             cp_genericize_r, data, NULL);
916           }
917         break;
918       case OMP_CLAUSE_PRIVATE:
919         /* Don't dereference an invisiref in OpenMP clauses.  */
920         if (is_invisiref_parm (OMP_CLAUSE_DECL (stmt)))
921           *walk_subtrees = 0;
922         else if (wtd->omp_ctx != NULL)
923           {
924             /* Private clause doesn't cause any references to the
925                var in outer contexts, avoid calling
926                omp_cxx_notice_variable for it.  */
927             struct cp_genericize_omp_taskreg *old = wtd->omp_ctx;
928             wtd->omp_ctx = NULL;
929             cp_walk_tree (&OMP_CLAUSE_DECL (stmt), cp_genericize_r,
930                           data, NULL);
931             wtd->omp_ctx = old;
932             *walk_subtrees = 0;
933           }
934         break;
935       case OMP_CLAUSE_SHARED:
936       case OMP_CLAUSE_FIRSTPRIVATE:
937       case OMP_CLAUSE_COPYIN:
938       case OMP_CLAUSE_COPYPRIVATE:
939         /* Don't dereference an invisiref in OpenMP clauses.  */
940         if (is_invisiref_parm (OMP_CLAUSE_DECL (stmt)))
941           *walk_subtrees = 0;
942         break;
943       case OMP_CLAUSE_REDUCTION:
944         gcc_assert (!is_invisiref_parm (OMP_CLAUSE_DECL (stmt)));
945         break;
946       default:
947         break;
948       }
949   else if (IS_TYPE_OR_DECL_P (stmt))
950     *walk_subtrees = 0;
951
952   /* Due to the way voidify_wrapper_expr is written, we don't get a chance
953      to lower this construct before scanning it, so we need to lower these
954      before doing anything else.  */
955   else if (TREE_CODE (stmt) == CLEANUP_STMT)
956     *stmt_p = build2 (CLEANUP_EH_ONLY (stmt) ? TRY_CATCH_EXPR
957                                              : TRY_FINALLY_EXPR,
958                       void_type_node,
959                       CLEANUP_BODY (stmt),
960                       CLEANUP_EXPR (stmt));
961
962   else if (TREE_CODE (stmt) == IF_STMT)
963     {
964       genericize_if_stmt (stmt_p);
965       /* *stmt_p has changed, tail recurse to handle it again.  */
966       return cp_genericize_r (stmt_p, walk_subtrees, data);
967     }
968
969   /* COND_EXPR might have incompatible types in branches if one or both
970      arms are bitfields.  Fix it up now.  */
971   else if (TREE_CODE (stmt) == COND_EXPR)
972     {
973       tree type_left
974         = (TREE_OPERAND (stmt, 1)
975            ? is_bitfield_expr_with_lowered_type (TREE_OPERAND (stmt, 1))
976            : NULL_TREE);
977       tree type_right
978         = (TREE_OPERAND (stmt, 2)
979            ? is_bitfield_expr_with_lowered_type (TREE_OPERAND (stmt, 2))
980            : NULL_TREE);
981       if (type_left
982           && !useless_type_conversion_p (TREE_TYPE (stmt),
983                                          TREE_TYPE (TREE_OPERAND (stmt, 1))))
984         {
985           TREE_OPERAND (stmt, 1)
986             = fold_convert (type_left, TREE_OPERAND (stmt, 1));
987           gcc_assert (useless_type_conversion_p (TREE_TYPE (stmt),
988                                                  type_left));
989         }
990       if (type_right
991           && !useless_type_conversion_p (TREE_TYPE (stmt),
992                                          TREE_TYPE (TREE_OPERAND (stmt, 2))))
993         {
994           TREE_OPERAND (stmt, 2)
995             = fold_convert (type_right, TREE_OPERAND (stmt, 2));
996           gcc_assert (useless_type_conversion_p (TREE_TYPE (stmt),
997                                                  type_right));
998         }
999     }
1000
1001   else if (TREE_CODE (stmt) == BIND_EXPR)
1002     {
1003       if (__builtin_expect (wtd->omp_ctx != NULL, 0))
1004         {
1005           tree decl;
1006           for (decl = BIND_EXPR_VARS (stmt); decl; decl = DECL_CHAIN (decl))
1007             if (TREE_CODE (decl) == VAR_DECL
1008                 && !DECL_EXTERNAL (decl)
1009                 && omp_var_to_track (decl))
1010               {
1011                 splay_tree_node n
1012                   = splay_tree_lookup (wtd->omp_ctx->variables,
1013                                        (splay_tree_key) decl);
1014                 if (n == NULL)
1015                   splay_tree_insert (wtd->omp_ctx->variables,
1016                                      (splay_tree_key) decl,
1017                                      TREE_STATIC (decl)
1018                                      ? OMP_CLAUSE_DEFAULT_SHARED
1019                                      : OMP_CLAUSE_DEFAULT_PRIVATE);
1020               }
1021         }
1022       VEC_safe_push (tree, heap, wtd->bind_expr_stack, stmt);
1023       cp_walk_tree (&BIND_EXPR_BODY (stmt),
1024                     cp_genericize_r, data, NULL);
1025       VEC_pop (tree, wtd->bind_expr_stack);
1026     }
1027
1028   else if (TREE_CODE (stmt) == USING_STMT)
1029     {
1030       tree block = NULL_TREE;
1031
1032       /* Get the innermost inclosing GIMPLE_BIND that has a non NULL
1033          BLOCK, and append an IMPORTED_DECL to its
1034          BLOCK_VARS chained list.  */
1035       if (wtd->bind_expr_stack)
1036         {
1037           int i;
1038           for (i = VEC_length (tree, wtd->bind_expr_stack) - 1; i >= 0; i--)
1039             if ((block = BIND_EXPR_BLOCK (VEC_index (tree,
1040                                                      wtd->bind_expr_stack, i))))
1041               break;
1042         }
1043       if (block)
1044         {
1045           tree using_directive;
1046           gcc_assert (TREE_OPERAND (stmt, 0));
1047
1048           using_directive = make_node (IMPORTED_DECL);
1049           TREE_TYPE (using_directive) = void_type_node;
1050
1051           IMPORTED_DECL_ASSOCIATED_DECL (using_directive)
1052             = TREE_OPERAND (stmt, 0);
1053           DECL_CHAIN (using_directive) = BLOCK_VARS (block);
1054           BLOCK_VARS (block) = using_directive;
1055         }
1056       /* The USING_STMT won't appear in GENERIC.  */
1057       *stmt_p = build1 (NOP_EXPR, void_type_node, integer_zero_node);
1058       *walk_subtrees = 0;
1059     }
1060
1061   else if (TREE_CODE (stmt) == DECL_EXPR
1062            && TREE_CODE (DECL_EXPR_DECL (stmt)) == USING_DECL)
1063     {
1064       /* Using decls inside DECL_EXPRs are just dropped on the floor.  */
1065       *stmt_p = build1 (NOP_EXPR, void_type_node, integer_zero_node);
1066       *walk_subtrees = 0;
1067     }
1068   else if (TREE_CODE (stmt) == OMP_PARALLEL || TREE_CODE (stmt) == OMP_TASK)
1069     {
1070       struct cp_genericize_omp_taskreg omp_ctx;
1071       tree c, decl;
1072       splay_tree_node n;
1073
1074       *walk_subtrees = 0;
1075       cp_walk_tree (&OMP_CLAUSES (stmt), cp_genericize_r, data, NULL);
1076       omp_ctx.is_parallel = TREE_CODE (stmt) == OMP_PARALLEL;
1077       omp_ctx.default_shared = omp_ctx.is_parallel;
1078       omp_ctx.outer = wtd->omp_ctx;
1079       omp_ctx.variables = splay_tree_new (splay_tree_compare_decl_uid, 0, 0);
1080       wtd->omp_ctx = &omp_ctx;
1081       for (c = OMP_CLAUSES (stmt); c; c = OMP_CLAUSE_CHAIN (c))
1082         switch (OMP_CLAUSE_CODE (c))
1083           {
1084           case OMP_CLAUSE_SHARED:
1085           case OMP_CLAUSE_PRIVATE:
1086           case OMP_CLAUSE_FIRSTPRIVATE:
1087           case OMP_CLAUSE_LASTPRIVATE:
1088             decl = OMP_CLAUSE_DECL (c);
1089             if (decl == error_mark_node || !omp_var_to_track (decl))
1090               break;
1091             n = splay_tree_lookup (omp_ctx.variables, (splay_tree_key) decl);
1092             if (n != NULL)
1093               break;
1094             splay_tree_insert (omp_ctx.variables, (splay_tree_key) decl,
1095                                OMP_CLAUSE_CODE (c) == OMP_CLAUSE_SHARED
1096                                ? OMP_CLAUSE_DEFAULT_SHARED
1097                                : OMP_CLAUSE_DEFAULT_PRIVATE);
1098             if (OMP_CLAUSE_CODE (c) != OMP_CLAUSE_PRIVATE
1099                 && omp_ctx.outer)
1100               omp_cxx_notice_variable (omp_ctx.outer, decl);
1101             break;
1102           case OMP_CLAUSE_DEFAULT:
1103             if (OMP_CLAUSE_DEFAULT_KIND (c) == OMP_CLAUSE_DEFAULT_SHARED)
1104               omp_ctx.default_shared = true;
1105           default:
1106             break;
1107           }
1108       cp_walk_tree (&OMP_BODY (stmt), cp_genericize_r, data, NULL);
1109       wtd->omp_ctx = omp_ctx.outer;
1110       splay_tree_delete (omp_ctx.variables);
1111     }
1112
1113   pointer_set_insert (p_set, *stmt_p);
1114
1115   return NULL;
1116 }
1117
1118 void
1119 cp_genericize (tree fndecl)
1120 {
1121   tree t;
1122   struct cp_genericize_data wtd;
1123
1124   /* Fix up the types of parms passed by invisible reference.  */
1125   for (t = DECL_ARGUMENTS (fndecl); t; t = DECL_CHAIN (t))
1126     if (TREE_ADDRESSABLE (TREE_TYPE (t)))
1127       {
1128         /* If a function's arguments are copied to create a thunk,
1129            then DECL_BY_REFERENCE will be set -- but the type of the
1130            argument will be a pointer type, so we will never get
1131            here.  */
1132         gcc_assert (!DECL_BY_REFERENCE (t));
1133         gcc_assert (DECL_ARG_TYPE (t) != TREE_TYPE (t));
1134         TREE_TYPE (t) = DECL_ARG_TYPE (t);
1135         DECL_BY_REFERENCE (t) = 1;
1136         TREE_ADDRESSABLE (t) = 0;
1137         relayout_decl (t);
1138       }
1139
1140   /* Do the same for the return value.  */
1141   if (TREE_ADDRESSABLE (TREE_TYPE (DECL_RESULT (fndecl))))
1142     {
1143       t = DECL_RESULT (fndecl);
1144       TREE_TYPE (t) = build_reference_type (TREE_TYPE (t));
1145       DECL_BY_REFERENCE (t) = 1;
1146       TREE_ADDRESSABLE (t) = 0;
1147       relayout_decl (t);
1148       if (DECL_NAME (t))
1149         {
1150           /* Adjust DECL_VALUE_EXPR of the original var.  */
1151           tree outer = outer_curly_brace_block (current_function_decl);
1152           tree var;
1153
1154           if (outer)
1155             for (var = BLOCK_VARS (outer); var; var = DECL_CHAIN (var))
1156               if (DECL_NAME (t) == DECL_NAME (var)
1157                   && DECL_HAS_VALUE_EXPR_P (var)
1158                   && DECL_VALUE_EXPR (var) == t)
1159                 {
1160                   tree val = convert_from_reference (t);
1161                   SET_DECL_VALUE_EXPR (var, val);
1162                   break;
1163                 }
1164         }
1165     }
1166
1167   /* If we're a clone, the body is already GIMPLE.  */
1168   if (DECL_CLONED_FUNCTION_P (fndecl))
1169     return;
1170
1171   /* We do want to see every occurrence of the parms, so we can't just use
1172      walk_tree's hash functionality.  */
1173   wtd.p_set = pointer_set_create ();
1174   wtd.bind_expr_stack = NULL;
1175   wtd.omp_ctx = NULL;
1176   cp_walk_tree (&DECL_SAVED_TREE (fndecl), cp_genericize_r, &wtd, NULL);
1177   pointer_set_destroy (wtd.p_set);
1178   VEC_free (tree, heap, wtd.bind_expr_stack);
1179
1180   /* Do everything else.  */
1181   c_genericize (fndecl);
1182
1183   gcc_assert (bc_label[bc_break] == NULL);
1184   gcc_assert (bc_label[bc_continue] == NULL);
1185 }
1186 \f
1187 /* Build code to apply FN to each member of ARG1 and ARG2.  FN may be
1188    NULL if there is in fact nothing to do.  ARG2 may be null if FN
1189    actually only takes one argument.  */
1190
1191 static tree
1192 cxx_omp_clause_apply_fn (tree fn, tree arg1, tree arg2)
1193 {
1194   tree defparm, parm, t;
1195   int i = 0;
1196   int nargs;
1197   tree *argarray;
1198
1199   if (fn == NULL)
1200     return NULL;
1201
1202   nargs = list_length (DECL_ARGUMENTS (fn));
1203   argarray = XALLOCAVEC (tree, nargs);
1204
1205   defparm = TREE_CHAIN (TYPE_ARG_TYPES (TREE_TYPE (fn)));
1206   if (arg2)
1207     defparm = TREE_CHAIN (defparm);
1208
1209   if (TREE_CODE (TREE_TYPE (arg1)) == ARRAY_TYPE)
1210     {
1211       tree inner_type = TREE_TYPE (arg1);
1212       tree start1, end1, p1;
1213       tree start2 = NULL, p2 = NULL;
1214       tree ret = NULL, lab;
1215
1216       start1 = arg1;
1217       start2 = arg2;
1218       do
1219         {
1220           inner_type = TREE_TYPE (inner_type);
1221           start1 = build4 (ARRAY_REF, inner_type, start1,
1222                            size_zero_node, NULL, NULL);
1223           if (arg2)
1224             start2 = build4 (ARRAY_REF, inner_type, start2,
1225                              size_zero_node, NULL, NULL);
1226         }
1227       while (TREE_CODE (inner_type) == ARRAY_TYPE);
1228       start1 = build_fold_addr_expr_loc (input_location, start1);
1229       if (arg2)
1230         start2 = build_fold_addr_expr_loc (input_location, start2);
1231
1232       end1 = TYPE_SIZE_UNIT (TREE_TYPE (arg1));
1233       end1 = build2 (POINTER_PLUS_EXPR, TREE_TYPE (start1), start1, end1);
1234
1235       p1 = create_tmp_var (TREE_TYPE (start1), NULL);
1236       t = build2 (MODIFY_EXPR, TREE_TYPE (p1), p1, start1);
1237       append_to_statement_list (t, &ret);
1238
1239       if (arg2)
1240         {
1241           p2 = create_tmp_var (TREE_TYPE (start2), NULL);
1242           t = build2 (MODIFY_EXPR, TREE_TYPE (p2), p2, start2);
1243           append_to_statement_list (t, &ret);
1244         }
1245
1246       lab = create_artificial_label (input_location);
1247       t = build1 (LABEL_EXPR, void_type_node, lab);
1248       append_to_statement_list (t, &ret);
1249
1250       argarray[i++] = p1;
1251       if (arg2)
1252         argarray[i++] = p2;
1253       /* Handle default arguments.  */
1254       for (parm = defparm; parm && parm != void_list_node;
1255            parm = TREE_CHAIN (parm), i++)
1256         argarray[i] = convert_default_arg (TREE_VALUE (parm),
1257                                            TREE_PURPOSE (parm), fn, i);
1258       t = build_call_a (fn, i, argarray);
1259       t = fold_convert (void_type_node, t);
1260       t = fold_build_cleanup_point_expr (TREE_TYPE (t), t);
1261       append_to_statement_list (t, &ret);
1262
1263       t = TYPE_SIZE_UNIT (inner_type);
1264       t = build2 (POINTER_PLUS_EXPR, TREE_TYPE (p1), p1, t);
1265       t = build2 (MODIFY_EXPR, TREE_TYPE (p1), p1, t);
1266       append_to_statement_list (t, &ret);
1267
1268       if (arg2)
1269         {
1270           t = TYPE_SIZE_UNIT (inner_type);
1271           t = build2 (POINTER_PLUS_EXPR, TREE_TYPE (p2), p2, t);
1272           t = build2 (MODIFY_EXPR, TREE_TYPE (p2), p2, t);
1273           append_to_statement_list (t, &ret);
1274         }
1275
1276       t = build2 (NE_EXPR, boolean_type_node, p1, end1);
1277       t = build3 (COND_EXPR, void_type_node, t, build_and_jump (&lab), NULL);
1278       append_to_statement_list (t, &ret);
1279
1280       return ret;
1281     }
1282   else
1283     {
1284       argarray[i++] = build_fold_addr_expr_loc (input_location, arg1);
1285       if (arg2)
1286         argarray[i++] = build_fold_addr_expr_loc (input_location, arg2);
1287       /* Handle default arguments.  */
1288       for (parm = defparm; parm && parm != void_list_node;
1289            parm = TREE_CHAIN (parm), i++)
1290         argarray[i] = convert_default_arg (TREE_VALUE (parm),
1291                                            TREE_PURPOSE (parm),
1292                                            fn, i);
1293       t = build_call_a (fn, i, argarray);
1294       t = fold_convert (void_type_node, t);
1295       return fold_build_cleanup_point_expr (TREE_TYPE (t), t);
1296     }
1297 }
1298
1299 /* Return code to initialize DECL with its default constructor, or
1300    NULL if there's nothing to do.  */
1301
1302 tree
1303 cxx_omp_clause_default_ctor (tree clause, tree decl,
1304                              tree outer ATTRIBUTE_UNUSED)
1305 {
1306   tree info = CP_OMP_CLAUSE_INFO (clause);
1307   tree ret = NULL;
1308
1309   if (info)
1310     ret = cxx_omp_clause_apply_fn (TREE_VEC_ELT (info, 0), decl, NULL);
1311
1312   return ret;
1313 }
1314
1315 /* Return code to initialize DST with a copy constructor from SRC.  */
1316
1317 tree
1318 cxx_omp_clause_copy_ctor (tree clause, tree dst, tree src)
1319 {
1320   tree info = CP_OMP_CLAUSE_INFO (clause);
1321   tree ret = NULL;
1322
1323   if (info)
1324     ret = cxx_omp_clause_apply_fn (TREE_VEC_ELT (info, 0), dst, src);
1325   if (ret == NULL)
1326     ret = build2 (MODIFY_EXPR, TREE_TYPE (dst), dst, src);
1327
1328   return ret;
1329 }
1330
1331 /* Similarly, except use an assignment operator instead.  */
1332
1333 tree
1334 cxx_omp_clause_assign_op (tree clause, tree dst, tree src)
1335 {
1336   tree info = CP_OMP_CLAUSE_INFO (clause);
1337   tree ret = NULL;
1338
1339   if (info)
1340     ret = cxx_omp_clause_apply_fn (TREE_VEC_ELT (info, 2), dst, src);
1341   if (ret == NULL)
1342     ret = build2 (MODIFY_EXPR, TREE_TYPE (dst), dst, src);
1343
1344   return ret;
1345 }
1346
1347 /* Return code to destroy DECL.  */
1348
1349 tree
1350 cxx_omp_clause_dtor (tree clause, tree decl)
1351 {
1352   tree info = CP_OMP_CLAUSE_INFO (clause);
1353   tree ret = NULL;
1354
1355   if (info)
1356     ret = cxx_omp_clause_apply_fn (TREE_VEC_ELT (info, 1), decl, NULL);
1357
1358   return ret;
1359 }
1360
1361 /* True if OpenMP should privatize what this DECL points to rather
1362    than the DECL itself.  */
1363
1364 bool
1365 cxx_omp_privatize_by_reference (const_tree decl)
1366 {
1367   return is_invisiref_parm (decl);
1368 }
1369
1370 /* True if OpenMP sharing attribute of DECL is predetermined.  */
1371
1372 enum omp_clause_default_kind
1373 cxx_omp_predetermined_sharing (tree decl)
1374 {
1375   tree type;
1376
1377   /* Static data members are predetermined as shared.  */
1378   if (TREE_STATIC (decl))
1379     {
1380       tree ctx = CP_DECL_CONTEXT (decl);
1381       if (TYPE_P (ctx) && MAYBE_CLASS_TYPE_P (ctx))
1382         return OMP_CLAUSE_DEFAULT_SHARED;
1383     }
1384
1385   type = TREE_TYPE (decl);
1386   if (TREE_CODE (type) == REFERENCE_TYPE)
1387     {
1388       if (!is_invisiref_parm (decl))
1389         return OMP_CLAUSE_DEFAULT_UNSPECIFIED;
1390       type = TREE_TYPE (type);
1391
1392       if (TREE_CODE (decl) == RESULT_DECL && DECL_NAME (decl))
1393         {
1394           /* NVR doesn't preserve const qualification of the
1395              variable's type.  */
1396           tree outer = outer_curly_brace_block (current_function_decl);
1397           tree var;
1398
1399           if (outer)
1400             for (var = BLOCK_VARS (outer); var; var = DECL_CHAIN (var))
1401               if (DECL_NAME (decl) == DECL_NAME (var)
1402                   && (TYPE_MAIN_VARIANT (type)
1403                       == TYPE_MAIN_VARIANT (TREE_TYPE (var))))
1404                 {
1405                   if (TYPE_READONLY (TREE_TYPE (var)))
1406                     type = TREE_TYPE (var);
1407                   break;
1408                 }
1409         }
1410     }
1411
1412   if (type == error_mark_node)
1413     return OMP_CLAUSE_DEFAULT_UNSPECIFIED;
1414
1415   /* Variables with const-qualified type having no mutable member
1416      are predetermined shared.  */
1417   if (TYPE_READONLY (type) && !cp_has_mutable_p (type))
1418     return OMP_CLAUSE_DEFAULT_SHARED;
1419
1420   return OMP_CLAUSE_DEFAULT_UNSPECIFIED;
1421 }
1422
1423 /* Finalize an implicitly determined clause.  */
1424
1425 void
1426 cxx_omp_finish_clause (tree c)
1427 {
1428   tree decl, inner_type;
1429   bool make_shared = false;
1430
1431   if (OMP_CLAUSE_CODE (c) != OMP_CLAUSE_FIRSTPRIVATE)
1432     return;
1433
1434   decl = OMP_CLAUSE_DECL (c);
1435   decl = require_complete_type (decl);
1436   inner_type = TREE_TYPE (decl);
1437   if (decl == error_mark_node)
1438     make_shared = true;
1439   else if (TREE_CODE (TREE_TYPE (decl)) == REFERENCE_TYPE)
1440     {
1441       if (is_invisiref_parm (decl))
1442         inner_type = TREE_TYPE (inner_type);
1443       else
1444         {
1445           error ("%qE implicitly determined as %<firstprivate%> has reference type",
1446                  decl);
1447           make_shared = true;
1448         }
1449     }
1450
1451   /* We're interested in the base element, not arrays.  */
1452   while (TREE_CODE (inner_type) == ARRAY_TYPE)
1453     inner_type = TREE_TYPE (inner_type);
1454
1455   /* Check for special function availability by building a call to one.
1456      Save the results, because later we won't be in the right context
1457      for making these queries.  */
1458   if (!make_shared
1459       && CLASS_TYPE_P (inner_type)
1460       && cxx_omp_create_clause_info (c, inner_type, false, true, false))
1461     make_shared = true;
1462
1463   if (make_shared)
1464     OMP_CLAUSE_CODE (c) = OMP_CLAUSE_SHARED;
1465 }