OSDN Git Service

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