OSDN Git Service

2010-10-12 Richard Guenther <rguenther@suse.de>
[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
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 "toplev.h"
31 #include "tree-iterator.h"
32 #include "gimple.h"
33 #include "hashtab.h"
34 #include "pointer-set.h"
35 #include "flags.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, gimple_seq *pre_p, gimple_seq *post_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           gimplify_expr (&to, pre_p, post_p, is_gimple_lvalue, fb_lvalue);
455           if (TREE_CODE (sub) == AGGR_INIT_EXPR)
456             AGGR_INIT_EXPR_SLOT (sub) = to;
457           else
458             VEC_INIT_EXPR_SLOT (sub) = to;
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         }
466
467       if (t == sub)
468         break;
469       else
470         t = TREE_OPERAND (t, 1);
471     }
472
473 }
474
475 /* Gimplify a MUST_NOT_THROW_EXPR.  */
476
477 static enum gimplify_status
478 gimplify_must_not_throw_expr (tree *expr_p, gimple_seq *pre_p)
479 {
480   tree stmt = *expr_p;
481   tree temp = voidify_wrapper_expr (stmt, NULL);
482   tree body = TREE_OPERAND (stmt, 0);
483   gimple_seq try_ = NULL;
484   gimple_seq catch_ = NULL;
485   gimple mnt;
486
487   gimplify_and_add (body, &try_);
488   mnt = gimple_build_eh_must_not_throw (terminate_node);
489   gimplify_seq_add_stmt (&catch_, mnt);
490   mnt = gimple_build_try (try_, catch_, GIMPLE_TRY_CATCH);
491
492   gimplify_seq_add_stmt (pre_p, mnt);
493   if (temp)
494     {
495       *expr_p = temp;
496       return GS_OK;
497     }
498
499   *expr_p = NULL;
500   return GS_ALL_DONE;
501 }
502
503 /* Do C++-specific gimplification.  Args are as for gimplify_expr.  */
504
505 int
506 cp_gimplify_expr (tree *expr_p, gimple_seq *pre_p, gimple_seq *post_p)
507 {
508   int saved_stmts_are_full_exprs_p = 0;
509   enum tree_code code = TREE_CODE (*expr_p);
510   enum gimplify_status ret;
511
512   if (STATEMENT_CODE_P (code))
513     {
514       saved_stmts_are_full_exprs_p = stmts_are_full_exprs_p ();
515       current_stmt_tree ()->stmts_are_full_exprs_p
516         = STMT_IS_FULL_EXPR_P (*expr_p);
517     }
518
519   switch (code)
520     {
521     case PTRMEM_CST:
522       *expr_p = cplus_expand_constant (*expr_p);
523       ret = GS_OK;
524       break;
525
526     case AGGR_INIT_EXPR:
527       simplify_aggr_init_expr (expr_p);
528       ret = GS_OK;
529       break;
530
531     case VEC_INIT_EXPR:
532       {
533         location_t loc = input_location;
534         gcc_assert (EXPR_HAS_LOCATION (*expr_p));
535         input_location = EXPR_LOCATION (*expr_p);
536         *expr_p = build_vec_init (VEC_INIT_EXPR_SLOT (*expr_p), NULL_TREE,
537                                   VEC_INIT_EXPR_INIT (*expr_p), false, 1,
538                                   tf_warning_or_error);
539         ret = GS_OK;
540         input_location = loc;
541       }
542       break;
543
544     case THROW_EXPR:
545       /* FIXME communicate throw type to back end, probably by moving
546          THROW_EXPR into ../tree.def.  */
547       *expr_p = TREE_OPERAND (*expr_p, 0);
548       ret = GS_OK;
549       break;
550
551     case MUST_NOT_THROW_EXPR:
552       ret = gimplify_must_not_throw_expr (expr_p, pre_p);
553       break;
554
555       /* We used to do this for MODIFY_EXPR as well, but that's unsafe; the
556          LHS of an assignment might also be involved in the RHS, as in bug
557          25979.  */
558     case INIT_EXPR:
559       cp_gimplify_init_expr (expr_p, pre_p, post_p);
560       if (TREE_CODE (*expr_p) != INIT_EXPR)
561         return GS_OK;
562       /* Otherwise fall through.  */
563     case MODIFY_EXPR:
564       {
565         /* If the back end isn't clever enough to know that the lhs and rhs
566            types are the same, add an explicit conversion.  */
567         tree op0 = TREE_OPERAND (*expr_p, 0);
568         tree op1 = TREE_OPERAND (*expr_p, 1);
569
570         if (!error_operand_p (op0)
571             && !error_operand_p (op1)
572             && (TYPE_STRUCTURAL_EQUALITY_P (TREE_TYPE (op0))
573                 || TYPE_STRUCTURAL_EQUALITY_P (TREE_TYPE (op1)))
574             && !useless_type_conversion_p (TREE_TYPE (op1), TREE_TYPE (op0)))
575           TREE_OPERAND (*expr_p, 1) = build1 (VIEW_CONVERT_EXPR,
576                                               TREE_TYPE (op0), op1);
577
578         else if ((is_gimple_lvalue (op1) || INDIRECT_REF_P (op1)
579                   || (TREE_CODE (op1) == CONSTRUCTOR
580                       && CONSTRUCTOR_NELTS (op1) == 0)
581                   || (TREE_CODE (op1) == CALL_EXPR
582                       && !CALL_EXPR_RETURN_SLOT_OPT (op1)))
583                  && is_really_empty_class (TREE_TYPE (op0)))
584           {
585             /* Remove any copies of empty classes.  We check that the RHS
586                has a simple form so that TARGET_EXPRs and non-empty
587                CONSTRUCTORs get reduced properly, and we leave the return
588                slot optimization alone because it isn't a copy (FIXME so it
589                shouldn't be represented as one).
590
591                Also drop volatile variables on the RHS to avoid infinite
592                recursion from gimplify_expr trying to load the value.  */
593             if (!TREE_SIDE_EFFECTS (op1)
594                 || (DECL_P (op1) && TREE_THIS_VOLATILE (op1)))
595               *expr_p = op0;
596             else
597               *expr_p = build2 (COMPOUND_EXPR, TREE_TYPE (*expr_p),
598                                 op0, op1);
599           }
600       }
601       ret = GS_OK;
602       break;
603
604     case EMPTY_CLASS_EXPR:
605       /* We create an empty CONSTRUCTOR with RECORD_TYPE.  */
606       *expr_p = build_constructor (TREE_TYPE (*expr_p), NULL);
607       ret = GS_OK;
608       break;
609
610     case BASELINK:
611       *expr_p = BASELINK_FUNCTIONS (*expr_p);
612       ret = GS_OK;
613       break;
614
615     case TRY_BLOCK:
616       genericize_try_block (expr_p);
617       ret = GS_OK;
618       break;
619
620     case HANDLER:
621       genericize_catch_block (expr_p);
622       ret = GS_OK;
623       break;
624
625     case EH_SPEC_BLOCK:
626       genericize_eh_spec_block (expr_p);
627       ret = GS_OK;
628       break;
629
630     case USING_STMT:
631       gcc_unreachable ();
632
633     case FOR_STMT:
634       gimplify_for_stmt (expr_p, pre_p);
635       ret = GS_OK;
636       break;
637
638     case WHILE_STMT:
639       gimplify_while_stmt (expr_p, pre_p);
640       ret = GS_OK;
641       break;
642
643     case DO_STMT:
644       gimplify_do_stmt (expr_p, pre_p);
645       ret = GS_OK;
646       break;
647
648     case SWITCH_STMT:
649       gimplify_switch_stmt (expr_p, pre_p);
650       ret = GS_OK;
651       break;
652
653     case OMP_FOR:
654       ret = cp_gimplify_omp_for (expr_p, pre_p);
655       break;
656
657     case CONTINUE_STMT:
658       gimple_seq_add_stmt (pre_p, gimple_build_predict (PRED_CONTINUE, NOT_TAKEN));
659       gimple_seq_add_stmt (pre_p, gimple_build_goto (get_bc_label (bc_continue)));
660       *expr_p = NULL_TREE;
661       ret = GS_ALL_DONE;
662       break;
663
664     case BREAK_STMT:
665       gimple_seq_add_stmt (pre_p, gimple_build_goto (get_bc_label (bc_break)));
666       *expr_p = NULL_TREE;
667       ret = GS_ALL_DONE;
668       break;
669
670     case EXPR_STMT:
671       gimplify_expr_stmt (expr_p);
672       ret = GS_OK;
673       break;
674
675     case UNARY_PLUS_EXPR:
676       {
677         tree arg = TREE_OPERAND (*expr_p, 0);
678         tree type = TREE_TYPE (*expr_p);
679         *expr_p = (TREE_TYPE (arg) != type) ? fold_convert (type, arg)
680                                             : arg;
681         ret = GS_OK;
682       }
683       break;
684
685     default:
686       ret = (enum gimplify_status) c_gimplify_expr (expr_p, pre_p, post_p);
687       break;
688     }
689
690   /* Restore saved state.  */
691   if (STATEMENT_CODE_P (code))
692     current_stmt_tree ()->stmts_are_full_exprs_p
693       = saved_stmts_are_full_exprs_p;
694
695   return ret;
696 }
697
698 static inline bool
699 is_invisiref_parm (const_tree t)
700 {
701   return ((TREE_CODE (t) == PARM_DECL || TREE_CODE (t) == RESULT_DECL)
702           && DECL_BY_REFERENCE (t));
703 }
704
705 /* Return true if the uid in both int tree maps are equal.  */
706
707 int
708 cxx_int_tree_map_eq (const void *va, const void *vb)
709 {
710   const struct cxx_int_tree_map *a = (const struct cxx_int_tree_map *) va;
711   const struct cxx_int_tree_map *b = (const struct cxx_int_tree_map *) vb;
712   return (a->uid == b->uid);
713 }
714
715 /* Hash a UID in a cxx_int_tree_map.  */
716
717 unsigned int
718 cxx_int_tree_map_hash (const void *item)
719 {
720   return ((const struct cxx_int_tree_map *)item)->uid;
721 }
722
723 struct cp_genericize_data
724 {
725   struct pointer_set_t *p_set;
726   VEC (tree, heap) *bind_expr_stack;
727 };
728
729 /* Perform any pre-gimplification lowering of C++ front end trees to
730    GENERIC.  */
731
732 static tree
733 cp_genericize_r (tree *stmt_p, int *walk_subtrees, void *data)
734 {
735   tree stmt = *stmt_p;
736   struct cp_genericize_data *wtd = (struct cp_genericize_data *) data;
737   struct pointer_set_t *p_set = wtd->p_set;
738
739   if (is_invisiref_parm (stmt)
740       /* Don't dereference parms in a thunk, pass the references through. */
741       && !(DECL_THUNK_P (current_function_decl)
742            && TREE_CODE (stmt) == PARM_DECL))
743     {
744       *stmt_p = convert_from_reference (stmt);
745       *walk_subtrees = 0;
746       return NULL;
747     }
748
749   /* Map block scope extern declarations to visible declarations with the
750      same name and type in outer scopes if any.  */
751   if (cp_function_chain->extern_decl_map
752       && (TREE_CODE (stmt) == FUNCTION_DECL || TREE_CODE (stmt) == VAR_DECL)
753       && DECL_EXTERNAL (stmt))
754     {
755       struct cxx_int_tree_map *h, in;
756       in.uid = DECL_UID (stmt);
757       h = (struct cxx_int_tree_map *)
758           htab_find_with_hash (cp_function_chain->extern_decl_map,
759                                &in, in.uid);
760       if (h)
761         {
762           *stmt_p = h->to;
763           *walk_subtrees = 0;
764           return NULL;
765         }
766     }
767
768   /* Other than invisiref parms, don't walk the same tree twice.  */
769   if (pointer_set_contains (p_set, stmt))
770     {
771       *walk_subtrees = 0;
772       return NULL_TREE;
773     }
774
775   if (TREE_CODE (stmt) == ADDR_EXPR
776       && is_invisiref_parm (TREE_OPERAND (stmt, 0)))
777     {
778       *stmt_p = convert (TREE_TYPE (stmt), TREE_OPERAND (stmt, 0));
779       *walk_subtrees = 0;
780     }
781   else if (TREE_CODE (stmt) == RETURN_EXPR
782            && TREE_OPERAND (stmt, 0)
783            && is_invisiref_parm (TREE_OPERAND (stmt, 0)))
784     /* Don't dereference an invisiref RESULT_DECL inside a RETURN_EXPR.  */
785     *walk_subtrees = 0;
786   else if (TREE_CODE (stmt) == OMP_CLAUSE)
787     switch (OMP_CLAUSE_CODE (stmt))
788       {
789       case OMP_CLAUSE_LASTPRIVATE:
790         /* Don't dereference an invisiref in OpenMP clauses.  */
791         if (is_invisiref_parm (OMP_CLAUSE_DECL (stmt)))
792           {
793             *walk_subtrees = 0;
794             if (OMP_CLAUSE_LASTPRIVATE_STMT (stmt))
795               cp_walk_tree (&OMP_CLAUSE_LASTPRIVATE_STMT (stmt),
796                             cp_genericize_r, data, NULL);
797           }
798         break;
799       case OMP_CLAUSE_PRIVATE:
800       case OMP_CLAUSE_SHARED:
801       case OMP_CLAUSE_FIRSTPRIVATE:
802       case OMP_CLAUSE_COPYIN:
803       case OMP_CLAUSE_COPYPRIVATE:
804         /* Don't dereference an invisiref in OpenMP clauses.  */
805         if (is_invisiref_parm (OMP_CLAUSE_DECL (stmt)))
806           *walk_subtrees = 0;
807         break;
808       case OMP_CLAUSE_REDUCTION:
809         gcc_assert (!is_invisiref_parm (OMP_CLAUSE_DECL (stmt)));
810         break;
811       default:
812         break;
813       }
814   else if (IS_TYPE_OR_DECL_P (stmt))
815     *walk_subtrees = 0;
816
817   /* Due to the way voidify_wrapper_expr is written, we don't get a chance
818      to lower this construct before scanning it, so we need to lower these
819      before doing anything else.  */
820   else if (TREE_CODE (stmt) == CLEANUP_STMT)
821     *stmt_p = build2 (CLEANUP_EH_ONLY (stmt) ? TRY_CATCH_EXPR
822                                              : TRY_FINALLY_EXPR,
823                       void_type_node,
824                       CLEANUP_BODY (stmt),
825                       CLEANUP_EXPR (stmt));
826
827   else if (TREE_CODE (stmt) == IF_STMT)
828     {
829       genericize_if_stmt (stmt_p);
830       /* *stmt_p has changed, tail recurse to handle it again.  */
831       return cp_genericize_r (stmt_p, walk_subtrees, data);
832     }
833
834   /* COND_EXPR might have incompatible types in branches if one or both
835      arms are bitfields.  Fix it up now.  */
836   else if (TREE_CODE (stmt) == COND_EXPR)
837     {
838       tree type_left
839         = (TREE_OPERAND (stmt, 1)
840            ? is_bitfield_expr_with_lowered_type (TREE_OPERAND (stmt, 1))
841            : NULL_TREE);
842       tree type_right
843         = (TREE_OPERAND (stmt, 2)
844            ? is_bitfield_expr_with_lowered_type (TREE_OPERAND (stmt, 2))
845            : NULL_TREE);
846       if (type_left
847           && !useless_type_conversion_p (TREE_TYPE (stmt),
848                                          TREE_TYPE (TREE_OPERAND (stmt, 1))))
849         {
850           TREE_OPERAND (stmt, 1)
851             = fold_convert (type_left, TREE_OPERAND (stmt, 1));
852           gcc_assert (useless_type_conversion_p (TREE_TYPE (stmt),
853                                                  type_left));
854         }
855       if (type_right
856           && !useless_type_conversion_p (TREE_TYPE (stmt),
857                                          TREE_TYPE (TREE_OPERAND (stmt, 2))))
858         {
859           TREE_OPERAND (stmt, 2)
860             = fold_convert (type_right, TREE_OPERAND (stmt, 2));
861           gcc_assert (useless_type_conversion_p (TREE_TYPE (stmt),
862                                                  type_right));
863         }
864     }
865
866   else if (TREE_CODE (stmt) == BIND_EXPR)
867     {
868       VEC_safe_push (tree, heap, wtd->bind_expr_stack, stmt);
869       cp_walk_tree (&BIND_EXPR_BODY (stmt),
870                     cp_genericize_r, data, NULL);
871       VEC_pop (tree, wtd->bind_expr_stack);
872     }
873
874   else if (TREE_CODE (stmt) == USING_STMT)
875     {
876       tree block = NULL_TREE;
877
878       /* Get the innermost inclosing GIMPLE_BIND that has a non NULL
879          BLOCK, and append an IMPORTED_DECL to its
880          BLOCK_VARS chained list.  */
881       if (wtd->bind_expr_stack)
882         {
883           int i;
884           for (i = VEC_length (tree, wtd->bind_expr_stack) - 1; i >= 0; i--)
885             if ((block = BIND_EXPR_BLOCK (VEC_index (tree,
886                                                      wtd->bind_expr_stack, i))))
887               break;
888         }
889       if (block)
890         {
891           tree using_directive;
892           gcc_assert (TREE_OPERAND (stmt, 0));
893
894           using_directive = make_node (IMPORTED_DECL);
895           TREE_TYPE (using_directive) = void_type_node;
896
897           IMPORTED_DECL_ASSOCIATED_DECL (using_directive)
898             = TREE_OPERAND (stmt, 0);
899           DECL_CHAIN (using_directive) = BLOCK_VARS (block);
900           BLOCK_VARS (block) = using_directive;
901         }
902       /* The USING_STMT won't appear in GENERIC.  */
903       *stmt_p = build1 (NOP_EXPR, void_type_node, integer_zero_node);
904       *walk_subtrees = 0;
905     }
906
907   else if (TREE_CODE (stmt) == DECL_EXPR
908            && TREE_CODE (DECL_EXPR_DECL (stmt)) == USING_DECL)
909     {
910       /* Using decls inside DECL_EXPRs are just dropped on the floor.  */
911       *stmt_p = build1 (NOP_EXPR, void_type_node, integer_zero_node);
912       *walk_subtrees = 0;
913     }
914
915   pointer_set_insert (p_set, *stmt_p);
916
917   return NULL;
918 }
919
920 void
921 cp_genericize (tree fndecl)
922 {
923   tree t;
924   struct cp_genericize_data wtd;
925
926   /* Fix up the types of parms passed by invisible reference.  */
927   for (t = DECL_ARGUMENTS (fndecl); t; t = DECL_CHAIN (t))
928     if (TREE_ADDRESSABLE (TREE_TYPE (t)))
929       {
930         /* If a function's arguments are copied to create a thunk,
931            then DECL_BY_REFERENCE will be set -- but the type of the
932            argument will be a pointer type, so we will never get
933            here.  */
934         gcc_assert (!DECL_BY_REFERENCE (t));
935         gcc_assert (DECL_ARG_TYPE (t) != TREE_TYPE (t));
936         TREE_TYPE (t) = DECL_ARG_TYPE (t);
937         DECL_BY_REFERENCE (t) = 1;
938         TREE_ADDRESSABLE (t) = 0;
939         relayout_decl (t);
940       }
941
942   /* Do the same for the return value.  */
943   if (TREE_ADDRESSABLE (TREE_TYPE (DECL_RESULT (fndecl))))
944     {
945       t = DECL_RESULT (fndecl);
946       TREE_TYPE (t) = build_reference_type (TREE_TYPE (t));
947       DECL_BY_REFERENCE (t) = 1;
948       TREE_ADDRESSABLE (t) = 0;
949       relayout_decl (t);
950     }
951
952   /* If we're a clone, the body is already GIMPLE.  */
953   if (DECL_CLONED_FUNCTION_P (fndecl))
954     return;
955
956   /* We do want to see every occurrence of the parms, so we can't just use
957      walk_tree's hash functionality.  */
958   wtd.p_set = pointer_set_create ();
959   wtd.bind_expr_stack = NULL;
960   cp_walk_tree (&DECL_SAVED_TREE (fndecl), cp_genericize_r, &wtd, NULL);
961   pointer_set_destroy (wtd.p_set);
962   VEC_free (tree, heap, wtd.bind_expr_stack);
963
964   /* Do everything else.  */
965   c_genericize (fndecl);
966
967   gcc_assert (bc_label[bc_break] == NULL);
968   gcc_assert (bc_label[bc_continue] == NULL);
969 }
970 \f
971 /* Build code to apply FN to each member of ARG1 and ARG2.  FN may be
972    NULL if there is in fact nothing to do.  ARG2 may be null if FN
973    actually only takes one argument.  */
974
975 static tree
976 cxx_omp_clause_apply_fn (tree fn, tree arg1, tree arg2)
977 {
978   tree defparm, parm, t;
979   int i = 0;
980   int nargs;
981   tree *argarray;
982
983   if (fn == NULL)
984     return NULL;
985
986   nargs = list_length (DECL_ARGUMENTS (fn));
987   argarray = XALLOCAVEC (tree, nargs);
988
989   defparm = TREE_CHAIN (TYPE_ARG_TYPES (TREE_TYPE (fn)));
990   if (arg2)
991     defparm = TREE_CHAIN (defparm);
992
993   if (TREE_CODE (TREE_TYPE (arg1)) == ARRAY_TYPE)
994     {
995       tree inner_type = TREE_TYPE (arg1);
996       tree start1, end1, p1;
997       tree start2 = NULL, p2 = NULL;
998       tree ret = NULL, lab;
999
1000       start1 = arg1;
1001       start2 = arg2;
1002       do
1003         {
1004           inner_type = TREE_TYPE (inner_type);
1005           start1 = build4 (ARRAY_REF, inner_type, start1,
1006                            size_zero_node, NULL, NULL);
1007           if (arg2)
1008             start2 = build4 (ARRAY_REF, inner_type, start2,
1009                              size_zero_node, NULL, NULL);
1010         }
1011       while (TREE_CODE (inner_type) == ARRAY_TYPE);
1012       start1 = build_fold_addr_expr_loc (input_location, start1);
1013       if (arg2)
1014         start2 = build_fold_addr_expr_loc (input_location, start2);
1015
1016       end1 = TYPE_SIZE_UNIT (TREE_TYPE (arg1));
1017       end1 = build2 (POINTER_PLUS_EXPR, TREE_TYPE (start1), start1, end1);
1018
1019       p1 = create_tmp_var (TREE_TYPE (start1), NULL);
1020       t = build2 (MODIFY_EXPR, TREE_TYPE (p1), p1, start1);
1021       append_to_statement_list (t, &ret);
1022
1023       if (arg2)
1024         {
1025           p2 = create_tmp_var (TREE_TYPE (start2), NULL);
1026           t = build2 (MODIFY_EXPR, TREE_TYPE (p2), p2, start2);
1027           append_to_statement_list (t, &ret);
1028         }
1029
1030       lab = create_artificial_label (input_location);
1031       t = build1 (LABEL_EXPR, void_type_node, lab);
1032       append_to_statement_list (t, &ret);
1033
1034       argarray[i++] = p1;
1035       if (arg2)
1036         argarray[i++] = p2;
1037       /* Handle default arguments.  */
1038       for (parm = defparm; parm && parm != void_list_node;
1039            parm = TREE_CHAIN (parm), i++)
1040         argarray[i] = convert_default_arg (TREE_VALUE (parm),
1041                                            TREE_PURPOSE (parm), fn, i);
1042       t = build_call_a (fn, i, argarray);
1043       t = fold_convert (void_type_node, t);
1044       t = fold_build_cleanup_point_expr (TREE_TYPE (t), t);
1045       append_to_statement_list (t, &ret);
1046
1047       t = TYPE_SIZE_UNIT (inner_type);
1048       t = build2 (POINTER_PLUS_EXPR, TREE_TYPE (p1), p1, t);
1049       t = build2 (MODIFY_EXPR, TREE_TYPE (p1), p1, t);
1050       append_to_statement_list (t, &ret);
1051
1052       if (arg2)
1053         {
1054           t = TYPE_SIZE_UNIT (inner_type);
1055           t = build2 (POINTER_PLUS_EXPR, TREE_TYPE (p2), p2, t);
1056           t = build2 (MODIFY_EXPR, TREE_TYPE (p2), p2, t);
1057           append_to_statement_list (t, &ret);
1058         }
1059
1060       t = build2 (NE_EXPR, boolean_type_node, p1, end1);
1061       t = build3 (COND_EXPR, void_type_node, t, build_and_jump (&lab), NULL);
1062       append_to_statement_list (t, &ret);
1063
1064       return ret;
1065     }
1066   else
1067     {
1068       argarray[i++] = build_fold_addr_expr_loc (input_location, arg1);
1069       if (arg2)
1070         argarray[i++] = build_fold_addr_expr_loc (input_location, arg2);
1071       /* Handle default arguments.  */
1072       for (parm = defparm; parm && parm != void_list_node;
1073            parm = TREE_CHAIN (parm), i++)
1074         argarray[i] = convert_default_arg (TREE_VALUE (parm),
1075                                            TREE_PURPOSE (parm),
1076                                            fn, i);
1077       t = build_call_a (fn, i, argarray);
1078       t = fold_convert (void_type_node, t);
1079       return fold_build_cleanup_point_expr (TREE_TYPE (t), t);
1080     }
1081 }
1082
1083 /* Return code to initialize DECL with its default constructor, or
1084    NULL if there's nothing to do.  */
1085
1086 tree
1087 cxx_omp_clause_default_ctor (tree clause, tree decl,
1088                              tree outer ATTRIBUTE_UNUSED)
1089 {
1090   tree info = CP_OMP_CLAUSE_INFO (clause);
1091   tree ret = NULL;
1092
1093   if (info)
1094     ret = cxx_omp_clause_apply_fn (TREE_VEC_ELT (info, 0), decl, NULL);
1095
1096   return ret;
1097 }
1098
1099 /* Return code to initialize DST with a copy constructor from SRC.  */
1100
1101 tree
1102 cxx_omp_clause_copy_ctor (tree clause, tree dst, tree src)
1103 {
1104   tree info = CP_OMP_CLAUSE_INFO (clause);
1105   tree ret = NULL;
1106
1107   if (info)
1108     ret = cxx_omp_clause_apply_fn (TREE_VEC_ELT (info, 0), dst, src);
1109   if (ret == NULL)
1110     ret = build2 (MODIFY_EXPR, TREE_TYPE (dst), dst, src);
1111
1112   return ret;
1113 }
1114
1115 /* Similarly, except use an assignment operator instead.  */
1116
1117 tree
1118 cxx_omp_clause_assign_op (tree clause, tree dst, tree src)
1119 {
1120   tree info = CP_OMP_CLAUSE_INFO (clause);
1121   tree ret = NULL;
1122
1123   if (info)
1124     ret = cxx_omp_clause_apply_fn (TREE_VEC_ELT (info, 2), dst, src);
1125   if (ret == NULL)
1126     ret = build2 (MODIFY_EXPR, TREE_TYPE (dst), dst, src);
1127
1128   return ret;
1129 }
1130
1131 /* Return code to destroy DECL.  */
1132
1133 tree
1134 cxx_omp_clause_dtor (tree clause, tree decl)
1135 {
1136   tree info = CP_OMP_CLAUSE_INFO (clause);
1137   tree ret = NULL;
1138
1139   if (info)
1140     ret = cxx_omp_clause_apply_fn (TREE_VEC_ELT (info, 1), decl, NULL);
1141
1142   return ret;
1143 }
1144
1145 /* True if OpenMP should privatize what this DECL points to rather
1146    than the DECL itself.  */
1147
1148 bool
1149 cxx_omp_privatize_by_reference (const_tree decl)
1150 {
1151   return is_invisiref_parm (decl);
1152 }
1153
1154 /* True if OpenMP sharing attribute of DECL is predetermined.  */
1155
1156 enum omp_clause_default_kind
1157 cxx_omp_predetermined_sharing (tree decl)
1158 {
1159   tree type;
1160
1161   /* Static data members are predetermined as shared.  */
1162   if (TREE_STATIC (decl))
1163     {
1164       tree ctx = CP_DECL_CONTEXT (decl);
1165       if (TYPE_P (ctx) && MAYBE_CLASS_TYPE_P (ctx))
1166         return OMP_CLAUSE_DEFAULT_SHARED;
1167     }
1168
1169   type = TREE_TYPE (decl);
1170   if (TREE_CODE (type) == REFERENCE_TYPE)
1171     {
1172       if (!is_invisiref_parm (decl))
1173         return OMP_CLAUSE_DEFAULT_UNSPECIFIED;
1174       type = TREE_TYPE (type);
1175
1176       if (TREE_CODE (decl) == RESULT_DECL && DECL_NAME (decl))
1177         {
1178           /* NVR doesn't preserve const qualification of the
1179              variable's type.  */
1180           tree outer = outer_curly_brace_block (current_function_decl);
1181           tree var;
1182
1183           if (outer)
1184             for (var = BLOCK_VARS (outer); var; var = DECL_CHAIN (var))
1185               if (DECL_NAME (decl) == DECL_NAME (var)
1186                   && (TYPE_MAIN_VARIANT (type)
1187                       == TYPE_MAIN_VARIANT (TREE_TYPE (var))))
1188                 {
1189                   if (TYPE_READONLY (TREE_TYPE (var)))
1190                     type = TREE_TYPE (var);
1191                   break;
1192                 }
1193         }
1194     }
1195
1196   if (type == error_mark_node)
1197     return OMP_CLAUSE_DEFAULT_UNSPECIFIED;
1198
1199   /* Variables with const-qualified type having no mutable member
1200      are predetermined shared.  */
1201   if (TYPE_READONLY (type) && !cp_has_mutable_p (type))
1202     return OMP_CLAUSE_DEFAULT_SHARED;
1203
1204   return OMP_CLAUSE_DEFAULT_UNSPECIFIED;
1205 }
1206
1207 /* Finalize an implicitly determined clause.  */
1208
1209 void
1210 cxx_omp_finish_clause (tree c)
1211 {
1212   tree decl, inner_type;
1213   bool make_shared = false;
1214
1215   if (OMP_CLAUSE_CODE (c) != OMP_CLAUSE_FIRSTPRIVATE)
1216     return;
1217
1218   decl = OMP_CLAUSE_DECL (c);
1219   decl = require_complete_type (decl);
1220   inner_type = TREE_TYPE (decl);
1221   if (decl == error_mark_node)
1222     make_shared = true;
1223   else if (TREE_CODE (TREE_TYPE (decl)) == REFERENCE_TYPE)
1224     {
1225       if (is_invisiref_parm (decl))
1226         inner_type = TREE_TYPE (inner_type);
1227       else
1228         {
1229           error ("%qE implicitly determined as %<firstprivate%> has reference type",
1230                  decl);
1231           make_shared = true;
1232         }
1233     }
1234
1235   /* We're interested in the base element, not arrays.  */
1236   while (TREE_CODE (inner_type) == ARRAY_TYPE)
1237     inner_type = TREE_TYPE (inner_type);
1238
1239   /* Check for special function availability by building a call to one.
1240      Save the results, because later we won't be in the right context
1241      for making these queries.  */
1242   if (!make_shared
1243       && CLASS_TYPE_P (inner_type)
1244       && cxx_omp_create_clause_info (c, inner_type, false, true, false))
1245     make_shared = true;
1246
1247   if (make_shared)
1248     OMP_CLAUSE_CODE (c) = OMP_CLAUSE_SHARED;
1249 }