OSDN Git Service

PR c++/46526
[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)
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 struct cp_genericize_data
736 {
737   struct pointer_set_t *p_set;
738   VEC (tree, heap) *bind_expr_stack;
739 };
740
741 /* Perform any pre-gimplification lowering of C++ front end trees to
742    GENERIC.  */
743
744 static tree
745 cp_genericize_r (tree *stmt_p, int *walk_subtrees, void *data)
746 {
747   tree stmt = *stmt_p;
748   struct cp_genericize_data *wtd = (struct cp_genericize_data *) data;
749   struct pointer_set_t *p_set = wtd->p_set;
750
751   if (is_invisiref_parm (stmt)
752       /* Don't dereference parms in a thunk, pass the references through. */
753       && !(DECL_THUNK_P (current_function_decl)
754            && TREE_CODE (stmt) == PARM_DECL))
755     {
756       *stmt_p = convert_from_reference (stmt);
757       *walk_subtrees = 0;
758       return NULL;
759     }
760
761   /* Map block scope extern declarations to visible declarations with the
762      same name and type in outer scopes if any.  */
763   if (cp_function_chain->extern_decl_map
764       && (TREE_CODE (stmt) == FUNCTION_DECL || TREE_CODE (stmt) == VAR_DECL)
765       && DECL_EXTERNAL (stmt))
766     {
767       struct cxx_int_tree_map *h, in;
768       in.uid = DECL_UID (stmt);
769       h = (struct cxx_int_tree_map *)
770           htab_find_with_hash (cp_function_chain->extern_decl_map,
771                                &in, in.uid);
772       if (h)
773         {
774           *stmt_p = h->to;
775           *walk_subtrees = 0;
776           return NULL;
777         }
778     }
779
780   /* Other than invisiref parms, don't walk the same tree twice.  */
781   if (pointer_set_contains (p_set, stmt))
782     {
783       *walk_subtrees = 0;
784       return NULL_TREE;
785     }
786
787   if (TREE_CODE (stmt) == ADDR_EXPR
788       && is_invisiref_parm (TREE_OPERAND (stmt, 0)))
789     {
790       *stmt_p = convert (TREE_TYPE (stmt), TREE_OPERAND (stmt, 0));
791       *walk_subtrees = 0;
792     }
793   else if (TREE_CODE (stmt) == RETURN_EXPR
794            && TREE_OPERAND (stmt, 0)
795            && is_invisiref_parm (TREE_OPERAND (stmt, 0)))
796     /* Don't dereference an invisiref RESULT_DECL inside a RETURN_EXPR.  */
797     *walk_subtrees = 0;
798   else if (TREE_CODE (stmt) == OMP_CLAUSE)
799     switch (OMP_CLAUSE_CODE (stmt))
800       {
801       case OMP_CLAUSE_LASTPRIVATE:
802         /* Don't dereference an invisiref in OpenMP clauses.  */
803         if (is_invisiref_parm (OMP_CLAUSE_DECL (stmt)))
804           {
805             *walk_subtrees = 0;
806             if (OMP_CLAUSE_LASTPRIVATE_STMT (stmt))
807               cp_walk_tree (&OMP_CLAUSE_LASTPRIVATE_STMT (stmt),
808                             cp_genericize_r, data, NULL);
809           }
810         break;
811       case OMP_CLAUSE_PRIVATE:
812       case OMP_CLAUSE_SHARED:
813       case OMP_CLAUSE_FIRSTPRIVATE:
814       case OMP_CLAUSE_COPYIN:
815       case OMP_CLAUSE_COPYPRIVATE:
816         /* Don't dereference an invisiref in OpenMP clauses.  */
817         if (is_invisiref_parm (OMP_CLAUSE_DECL (stmt)))
818           *walk_subtrees = 0;
819         break;
820       case OMP_CLAUSE_REDUCTION:
821         gcc_assert (!is_invisiref_parm (OMP_CLAUSE_DECL (stmt)));
822         break;
823       default:
824         break;
825       }
826   else if (IS_TYPE_OR_DECL_P (stmt))
827     *walk_subtrees = 0;
828
829   /* Due to the way voidify_wrapper_expr is written, we don't get a chance
830      to lower this construct before scanning it, so we need to lower these
831      before doing anything else.  */
832   else if (TREE_CODE (stmt) == CLEANUP_STMT)
833     *stmt_p = build2 (CLEANUP_EH_ONLY (stmt) ? TRY_CATCH_EXPR
834                                              : TRY_FINALLY_EXPR,
835                       void_type_node,
836                       CLEANUP_BODY (stmt),
837                       CLEANUP_EXPR (stmt));
838
839   else if (TREE_CODE (stmt) == IF_STMT)
840     {
841       genericize_if_stmt (stmt_p);
842       /* *stmt_p has changed, tail recurse to handle it again.  */
843       return cp_genericize_r (stmt_p, walk_subtrees, data);
844     }
845
846   /* COND_EXPR might have incompatible types in branches if one or both
847      arms are bitfields.  Fix it up now.  */
848   else if (TREE_CODE (stmt) == COND_EXPR)
849     {
850       tree type_left
851         = (TREE_OPERAND (stmt, 1)
852            ? is_bitfield_expr_with_lowered_type (TREE_OPERAND (stmt, 1))
853            : NULL_TREE);
854       tree type_right
855         = (TREE_OPERAND (stmt, 2)
856            ? is_bitfield_expr_with_lowered_type (TREE_OPERAND (stmt, 2))
857            : NULL_TREE);
858       if (type_left
859           && !useless_type_conversion_p (TREE_TYPE (stmt),
860                                          TREE_TYPE (TREE_OPERAND (stmt, 1))))
861         {
862           TREE_OPERAND (stmt, 1)
863             = fold_convert (type_left, TREE_OPERAND (stmt, 1));
864           gcc_assert (useless_type_conversion_p (TREE_TYPE (stmt),
865                                                  type_left));
866         }
867       if (type_right
868           && !useless_type_conversion_p (TREE_TYPE (stmt),
869                                          TREE_TYPE (TREE_OPERAND (stmt, 2))))
870         {
871           TREE_OPERAND (stmt, 2)
872             = fold_convert (type_right, TREE_OPERAND (stmt, 2));
873           gcc_assert (useless_type_conversion_p (TREE_TYPE (stmt),
874                                                  type_right));
875         }
876     }
877
878   else if (TREE_CODE (stmt) == BIND_EXPR)
879     {
880       VEC_safe_push (tree, heap, wtd->bind_expr_stack, stmt);
881       cp_walk_tree (&BIND_EXPR_BODY (stmt),
882                     cp_genericize_r, data, NULL);
883       VEC_pop (tree, wtd->bind_expr_stack);
884     }
885
886   else if (TREE_CODE (stmt) == USING_STMT)
887     {
888       tree block = NULL_TREE;
889
890       /* Get the innermost inclosing GIMPLE_BIND that has a non NULL
891          BLOCK, and append an IMPORTED_DECL to its
892          BLOCK_VARS chained list.  */
893       if (wtd->bind_expr_stack)
894         {
895           int i;
896           for (i = VEC_length (tree, wtd->bind_expr_stack) - 1; i >= 0; i--)
897             if ((block = BIND_EXPR_BLOCK (VEC_index (tree,
898                                                      wtd->bind_expr_stack, i))))
899               break;
900         }
901       if (block)
902         {
903           tree using_directive;
904           gcc_assert (TREE_OPERAND (stmt, 0));
905
906           using_directive = make_node (IMPORTED_DECL);
907           TREE_TYPE (using_directive) = void_type_node;
908
909           IMPORTED_DECL_ASSOCIATED_DECL (using_directive)
910             = TREE_OPERAND (stmt, 0);
911           DECL_CHAIN (using_directive) = BLOCK_VARS (block);
912           BLOCK_VARS (block) = using_directive;
913         }
914       /* The USING_STMT won't appear in GENERIC.  */
915       *stmt_p = build1 (NOP_EXPR, void_type_node, integer_zero_node);
916       *walk_subtrees = 0;
917     }
918
919   else if (TREE_CODE (stmt) == DECL_EXPR
920            && TREE_CODE (DECL_EXPR_DECL (stmt)) == USING_DECL)
921     {
922       /* Using decls inside DECL_EXPRs are just dropped on the floor.  */
923       *stmt_p = build1 (NOP_EXPR, void_type_node, integer_zero_node);
924       *walk_subtrees = 0;
925     }
926
927   pointer_set_insert (p_set, *stmt_p);
928
929   return NULL;
930 }
931
932 void
933 cp_genericize (tree fndecl)
934 {
935   tree t;
936   struct cp_genericize_data wtd;
937
938   /* Fix up the types of parms passed by invisible reference.  */
939   for (t = DECL_ARGUMENTS (fndecl); t; t = DECL_CHAIN (t))
940     if (TREE_ADDRESSABLE (TREE_TYPE (t)))
941       {
942         /* If a function's arguments are copied to create a thunk,
943            then DECL_BY_REFERENCE will be set -- but the type of the
944            argument will be a pointer type, so we will never get
945            here.  */
946         gcc_assert (!DECL_BY_REFERENCE (t));
947         gcc_assert (DECL_ARG_TYPE (t) != TREE_TYPE (t));
948         TREE_TYPE (t) = DECL_ARG_TYPE (t);
949         DECL_BY_REFERENCE (t) = 1;
950         TREE_ADDRESSABLE (t) = 0;
951         relayout_decl (t);
952       }
953
954   /* Do the same for the return value.  */
955   if (TREE_ADDRESSABLE (TREE_TYPE (DECL_RESULT (fndecl))))
956     {
957       t = DECL_RESULT (fndecl);
958       TREE_TYPE (t) = build_reference_type (TREE_TYPE (t));
959       DECL_BY_REFERENCE (t) = 1;
960       TREE_ADDRESSABLE (t) = 0;
961       relayout_decl (t);
962     }
963
964   /* If we're a clone, the body is already GIMPLE.  */
965   if (DECL_CLONED_FUNCTION_P (fndecl))
966     return;
967
968   /* We do want to see every occurrence of the parms, so we can't just use
969      walk_tree's hash functionality.  */
970   wtd.p_set = pointer_set_create ();
971   wtd.bind_expr_stack = NULL;
972   cp_walk_tree (&DECL_SAVED_TREE (fndecl), cp_genericize_r, &wtd, NULL);
973   pointer_set_destroy (wtd.p_set);
974   VEC_free (tree, heap, wtd.bind_expr_stack);
975
976   /* Do everything else.  */
977   c_genericize (fndecl);
978
979   gcc_assert (bc_label[bc_break] == NULL);
980   gcc_assert (bc_label[bc_continue] == NULL);
981 }
982 \f
983 /* Build code to apply FN to each member of ARG1 and ARG2.  FN may be
984    NULL if there is in fact nothing to do.  ARG2 may be null if FN
985    actually only takes one argument.  */
986
987 static tree
988 cxx_omp_clause_apply_fn (tree fn, tree arg1, tree arg2)
989 {
990   tree defparm, parm, t;
991   int i = 0;
992   int nargs;
993   tree *argarray;
994
995   if (fn == NULL)
996     return NULL;
997
998   nargs = list_length (DECL_ARGUMENTS (fn));
999   argarray = XALLOCAVEC (tree, nargs);
1000
1001   defparm = TREE_CHAIN (TYPE_ARG_TYPES (TREE_TYPE (fn)));
1002   if (arg2)
1003     defparm = TREE_CHAIN (defparm);
1004
1005   if (TREE_CODE (TREE_TYPE (arg1)) == ARRAY_TYPE)
1006     {
1007       tree inner_type = TREE_TYPE (arg1);
1008       tree start1, end1, p1;
1009       tree start2 = NULL, p2 = NULL;
1010       tree ret = NULL, lab;
1011
1012       start1 = arg1;
1013       start2 = arg2;
1014       do
1015         {
1016           inner_type = TREE_TYPE (inner_type);
1017           start1 = build4 (ARRAY_REF, inner_type, start1,
1018                            size_zero_node, NULL, NULL);
1019           if (arg2)
1020             start2 = build4 (ARRAY_REF, inner_type, start2,
1021                              size_zero_node, NULL, NULL);
1022         }
1023       while (TREE_CODE (inner_type) == ARRAY_TYPE);
1024       start1 = build_fold_addr_expr_loc (input_location, start1);
1025       if (arg2)
1026         start2 = build_fold_addr_expr_loc (input_location, start2);
1027
1028       end1 = TYPE_SIZE_UNIT (TREE_TYPE (arg1));
1029       end1 = build2 (POINTER_PLUS_EXPR, TREE_TYPE (start1), start1, end1);
1030
1031       p1 = create_tmp_var (TREE_TYPE (start1), NULL);
1032       t = build2 (MODIFY_EXPR, TREE_TYPE (p1), p1, start1);
1033       append_to_statement_list (t, &ret);
1034
1035       if (arg2)
1036         {
1037           p2 = create_tmp_var (TREE_TYPE (start2), NULL);
1038           t = build2 (MODIFY_EXPR, TREE_TYPE (p2), p2, start2);
1039           append_to_statement_list (t, &ret);
1040         }
1041
1042       lab = create_artificial_label (input_location);
1043       t = build1 (LABEL_EXPR, void_type_node, lab);
1044       append_to_statement_list (t, &ret);
1045
1046       argarray[i++] = p1;
1047       if (arg2)
1048         argarray[i++] = p2;
1049       /* Handle default arguments.  */
1050       for (parm = defparm; parm && parm != void_list_node;
1051            parm = TREE_CHAIN (parm), i++)
1052         argarray[i] = convert_default_arg (TREE_VALUE (parm),
1053                                            TREE_PURPOSE (parm), fn, i);
1054       t = build_call_a (fn, i, argarray);
1055       t = fold_convert (void_type_node, t);
1056       t = fold_build_cleanup_point_expr (TREE_TYPE (t), t);
1057       append_to_statement_list (t, &ret);
1058
1059       t = TYPE_SIZE_UNIT (inner_type);
1060       t = build2 (POINTER_PLUS_EXPR, TREE_TYPE (p1), p1, t);
1061       t = build2 (MODIFY_EXPR, TREE_TYPE (p1), p1, t);
1062       append_to_statement_list (t, &ret);
1063
1064       if (arg2)
1065         {
1066           t = TYPE_SIZE_UNIT (inner_type);
1067           t = build2 (POINTER_PLUS_EXPR, TREE_TYPE (p2), p2, t);
1068           t = build2 (MODIFY_EXPR, TREE_TYPE (p2), p2, t);
1069           append_to_statement_list (t, &ret);
1070         }
1071
1072       t = build2 (NE_EXPR, boolean_type_node, p1, end1);
1073       t = build3 (COND_EXPR, void_type_node, t, build_and_jump (&lab), NULL);
1074       append_to_statement_list (t, &ret);
1075
1076       return ret;
1077     }
1078   else
1079     {
1080       argarray[i++] = build_fold_addr_expr_loc (input_location, arg1);
1081       if (arg2)
1082         argarray[i++] = build_fold_addr_expr_loc (input_location, arg2);
1083       /* Handle default arguments.  */
1084       for (parm = defparm; parm && parm != void_list_node;
1085            parm = TREE_CHAIN (parm), i++)
1086         argarray[i] = convert_default_arg (TREE_VALUE (parm),
1087                                            TREE_PURPOSE (parm),
1088                                            fn, i);
1089       t = build_call_a (fn, i, argarray);
1090       t = fold_convert (void_type_node, t);
1091       return fold_build_cleanup_point_expr (TREE_TYPE (t), t);
1092     }
1093 }
1094
1095 /* Return code to initialize DECL with its default constructor, or
1096    NULL if there's nothing to do.  */
1097
1098 tree
1099 cxx_omp_clause_default_ctor (tree clause, tree decl,
1100                              tree outer ATTRIBUTE_UNUSED)
1101 {
1102   tree info = CP_OMP_CLAUSE_INFO (clause);
1103   tree ret = NULL;
1104
1105   if (info)
1106     ret = cxx_omp_clause_apply_fn (TREE_VEC_ELT (info, 0), decl, NULL);
1107
1108   return ret;
1109 }
1110
1111 /* Return code to initialize DST with a copy constructor from SRC.  */
1112
1113 tree
1114 cxx_omp_clause_copy_ctor (tree clause, tree dst, tree src)
1115 {
1116   tree info = CP_OMP_CLAUSE_INFO (clause);
1117   tree ret = NULL;
1118
1119   if (info)
1120     ret = cxx_omp_clause_apply_fn (TREE_VEC_ELT (info, 0), dst, src);
1121   if (ret == NULL)
1122     ret = build2 (MODIFY_EXPR, TREE_TYPE (dst), dst, src);
1123
1124   return ret;
1125 }
1126
1127 /* Similarly, except use an assignment operator instead.  */
1128
1129 tree
1130 cxx_omp_clause_assign_op (tree clause, tree dst, tree src)
1131 {
1132   tree info = CP_OMP_CLAUSE_INFO (clause);
1133   tree ret = NULL;
1134
1135   if (info)
1136     ret = cxx_omp_clause_apply_fn (TREE_VEC_ELT (info, 2), dst, src);
1137   if (ret == NULL)
1138     ret = build2 (MODIFY_EXPR, TREE_TYPE (dst), dst, src);
1139
1140   return ret;
1141 }
1142
1143 /* Return code to destroy DECL.  */
1144
1145 tree
1146 cxx_omp_clause_dtor (tree clause, tree decl)
1147 {
1148   tree info = CP_OMP_CLAUSE_INFO (clause);
1149   tree ret = NULL;
1150
1151   if (info)
1152     ret = cxx_omp_clause_apply_fn (TREE_VEC_ELT (info, 1), decl, NULL);
1153
1154   return ret;
1155 }
1156
1157 /* True if OpenMP should privatize what this DECL points to rather
1158    than the DECL itself.  */
1159
1160 bool
1161 cxx_omp_privatize_by_reference (const_tree decl)
1162 {
1163   return is_invisiref_parm (decl);
1164 }
1165
1166 /* True if OpenMP sharing attribute of DECL is predetermined.  */
1167
1168 enum omp_clause_default_kind
1169 cxx_omp_predetermined_sharing (tree decl)
1170 {
1171   tree type;
1172
1173   /* Static data members are predetermined as shared.  */
1174   if (TREE_STATIC (decl))
1175     {
1176       tree ctx = CP_DECL_CONTEXT (decl);
1177       if (TYPE_P (ctx) && MAYBE_CLASS_TYPE_P (ctx))
1178         return OMP_CLAUSE_DEFAULT_SHARED;
1179     }
1180
1181   type = TREE_TYPE (decl);
1182   if (TREE_CODE (type) == REFERENCE_TYPE)
1183     {
1184       if (!is_invisiref_parm (decl))
1185         return OMP_CLAUSE_DEFAULT_UNSPECIFIED;
1186       type = TREE_TYPE (type);
1187
1188       if (TREE_CODE (decl) == RESULT_DECL && DECL_NAME (decl))
1189         {
1190           /* NVR doesn't preserve const qualification of the
1191              variable's type.  */
1192           tree outer = outer_curly_brace_block (current_function_decl);
1193           tree var;
1194
1195           if (outer)
1196             for (var = BLOCK_VARS (outer); var; var = DECL_CHAIN (var))
1197               if (DECL_NAME (decl) == DECL_NAME (var)
1198                   && (TYPE_MAIN_VARIANT (type)
1199                       == TYPE_MAIN_VARIANT (TREE_TYPE (var))))
1200                 {
1201                   if (TYPE_READONLY (TREE_TYPE (var)))
1202                     type = TREE_TYPE (var);
1203                   break;
1204                 }
1205         }
1206     }
1207
1208   if (type == error_mark_node)
1209     return OMP_CLAUSE_DEFAULT_UNSPECIFIED;
1210
1211   /* Variables with const-qualified type having no mutable member
1212      are predetermined shared.  */
1213   if (TYPE_READONLY (type) && !cp_has_mutable_p (type))
1214     return OMP_CLAUSE_DEFAULT_SHARED;
1215
1216   return OMP_CLAUSE_DEFAULT_UNSPECIFIED;
1217 }
1218
1219 /* Finalize an implicitly determined clause.  */
1220
1221 void
1222 cxx_omp_finish_clause (tree c)
1223 {
1224   tree decl, inner_type;
1225   bool make_shared = false;
1226
1227   if (OMP_CLAUSE_CODE (c) != OMP_CLAUSE_FIRSTPRIVATE)
1228     return;
1229
1230   decl = OMP_CLAUSE_DECL (c);
1231   decl = require_complete_type (decl);
1232   inner_type = TREE_TYPE (decl);
1233   if (decl == error_mark_node)
1234     make_shared = true;
1235   else if (TREE_CODE (TREE_TYPE (decl)) == REFERENCE_TYPE)
1236     {
1237       if (is_invisiref_parm (decl))
1238         inner_type = TREE_TYPE (inner_type);
1239       else
1240         {
1241           error ("%qE implicitly determined as %<firstprivate%> has reference type",
1242                  decl);
1243           make_shared = true;
1244         }
1245     }
1246
1247   /* We're interested in the base element, not arrays.  */
1248   while (TREE_CODE (inner_type) == ARRAY_TYPE)
1249     inner_type = TREE_TYPE (inner_type);
1250
1251   /* Check for special function availability by building a call to one.
1252      Save the results, because later we won't be in the right context
1253      for making these queries.  */
1254   if (!make_shared
1255       && CLASS_TYPE_P (inner_type)
1256       && cxx_omp_create_clause_info (c, inner_type, false, true, false))
1257     make_shared = true;
1258
1259   if (make_shared)
1260     OMP_CLAUSE_CODE (c) = OMP_CLAUSE_SHARED;
1261 }