OSDN Git Service

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