OSDN Git Service

PR c++/37146
[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
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 ();
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 }
157
158 /* Genericize an IF_STMT by turning it into a COND_EXPR.  */
159
160 static void
161 gimplify_if_stmt (tree *stmt_p)
162 {
163   tree stmt, cond, then_, else_;
164   location_t locus = EXPR_LOCATION (*stmt_p);
165
166   stmt = *stmt_p;
167   cond = IF_COND (stmt);
168   then_ = THEN_CLAUSE (stmt);
169   else_ = ELSE_CLAUSE (stmt);
170
171   if (!then_)
172     then_ = build_empty_stmt ();
173   if (!else_)
174     else_ = build_empty_stmt ();
175
176   if (integer_nonzerop (cond) && !TREE_SIDE_EFFECTS (else_))
177     stmt = then_;
178   else if (integer_zerop (cond) && !TREE_SIDE_EFFECTS (then_))
179     stmt = else_;
180   else
181     stmt = build3 (COND_EXPR, void_type_node, cond, then_, else_);
182   if (CAN_HAVE_LOCATION_P (stmt) && !EXPR_HAS_LOCATION (stmt))
183     SET_EXPR_LOCATION (stmt, locus);
184   *stmt_p = stmt;
185 }
186
187 /* Build a generic representation of one of the C loop forms.  COND is the
188    loop condition or NULL_TREE.  BODY is the (possibly compound) statement
189    controlled by the loop.  INCR is the increment expression of a for-loop,
190    or NULL_TREE.  COND_IS_FIRST indicates whether the condition is
191    evaluated before the loop body as in while and for loops, or after the
192    loop body as in do-while loops.  */
193
194 static gimple_seq
195 gimplify_cp_loop (tree cond, tree body, tree incr, bool cond_is_first)
196 {
197   gimple top, entry, stmt;
198   gimple_seq stmt_list, body_seq, incr_seq, exit_seq;
199   tree cont_block, break_block;
200   location_t stmt_locus;
201
202   stmt_locus = input_location;
203   stmt_list = NULL;
204   body_seq = NULL;
205   incr_seq = NULL;
206   exit_seq = NULL;
207   entry = NULL;
208
209   break_block = begin_bc_block (bc_break);
210   cont_block = begin_bc_block (bc_continue);
211
212   /* If condition is zero don't generate a loop construct.  */
213   if (cond && integer_zerop (cond))
214     {
215       top = NULL;
216       if (cond_is_first)
217         {
218           stmt = gimple_build_goto (get_bc_label (bc_break));
219           gimple_set_location (stmt, stmt_locus);
220           gimple_seq_add_stmt (&stmt_list, stmt);
221         }
222     }
223   else
224     {
225       /* If we use a LOOP_EXPR here, we have to feed the whole thing
226          back through the main gimplifier to lower it.  Given that we
227          have to gimplify the loop body NOW so that we can resolve
228          break/continue stmts, seems easier to just expand to gotos.  */
229       top = gimple_build_label (create_artificial_label ());
230
231       /* If we have an exit condition, then we build an IF with gotos either
232          out of the loop, or to the top of it.  If there's no exit condition,
233          then we just build a jump back to the top.  */
234       if (cond && !integer_nonzerop (cond))
235         {
236           if (cond != error_mark_node)
237             { 
238               gimplify_expr (&cond, &exit_seq, NULL, is_gimple_val, fb_rvalue);
239               stmt = gimple_build_cond (NE_EXPR, cond,
240                                         build_int_cst (TREE_TYPE (cond), 0),
241                                         gimple_label_label (top),
242                                         get_bc_label (bc_break));
243               gimple_seq_add_stmt (&exit_seq, stmt);
244             }
245
246           if (cond_is_first)
247             {
248               if (incr)
249                 {
250                   entry = gimple_build_label (create_artificial_label ());
251                   stmt = gimple_build_goto (gimple_label_label (entry));
252                 }
253               else
254                 stmt = gimple_build_goto (get_bc_label (bc_continue));
255               gimple_set_location (stmt, stmt_locus);
256               gimple_seq_add_stmt (&stmt_list, stmt);
257             }
258         }
259       else
260         {
261           stmt = gimple_build_goto (gimple_label_label (top));
262           gimple_seq_add_stmt (&exit_seq, stmt);
263         }
264     }
265
266   gimplify_stmt (&body, &body_seq);
267   gimplify_stmt (&incr, &incr_seq);
268
269   body_seq = finish_bc_block (bc_continue, cont_block, body_seq);
270
271   gimple_seq_add_stmt (&stmt_list, top);
272   gimple_seq_add_seq (&stmt_list, body_seq);
273   gimple_seq_add_seq (&stmt_list, incr_seq);
274   gimple_seq_add_stmt (&stmt_list, entry);
275   gimple_seq_add_seq (&stmt_list, exit_seq);
276
277   annotate_all_with_location (stmt_list, stmt_locus);
278
279   return finish_bc_block (bc_break, break_block, stmt_list);
280 }
281
282 /* Gimplify a FOR_STMT node.  Move the stuff in the for-init-stmt into the
283    prequeue and hand off to gimplify_cp_loop.  */
284
285 static void
286 gimplify_for_stmt (tree *stmt_p, gimple_seq *pre_p)
287 {
288   tree stmt = *stmt_p;
289
290   if (FOR_INIT_STMT (stmt))
291     gimplify_and_add (FOR_INIT_STMT (stmt), pre_p);
292
293   gimple_seq_add_seq (pre_p,
294                       gimplify_cp_loop (FOR_COND (stmt), FOR_BODY (stmt),
295                                         FOR_EXPR (stmt), 1));
296   *stmt_p = NULL_TREE;
297 }
298
299 /* Gimplify a WHILE_STMT node.  */
300
301 static void
302 gimplify_while_stmt (tree *stmt_p, gimple_seq *pre_p)
303 {
304   tree stmt = *stmt_p;
305   gimple_seq_add_seq (pre_p,
306                       gimplify_cp_loop (WHILE_COND (stmt), WHILE_BODY (stmt),
307                                         NULL_TREE, 1));
308   *stmt_p = NULL_TREE;
309 }
310
311 /* Gimplify a DO_STMT node.  */
312
313 static void
314 gimplify_do_stmt (tree *stmt_p, gimple_seq *pre_p)
315 {
316   tree stmt = *stmt_p;
317   gimple_seq_add_seq (pre_p,
318                       gimplify_cp_loop (DO_COND (stmt), DO_BODY (stmt),
319                                         NULL_TREE, 0));
320   *stmt_p = NULL_TREE;
321 }
322
323 /* Genericize a SWITCH_STMT by turning it into a SWITCH_EXPR.  */
324
325 static void
326 gimplify_switch_stmt (tree *stmt_p, gimple_seq *pre_p)
327 {
328   tree stmt = *stmt_p;
329   tree break_block, body, t;
330   location_t stmt_locus = input_location;
331   gimple_seq seq = NULL;
332
333   break_block = begin_bc_block (bc_break);
334
335   body = SWITCH_STMT_BODY (stmt);
336   if (!body)
337     body = build_empty_stmt ();
338
339   t = build3 (SWITCH_EXPR, SWITCH_STMT_TYPE (stmt),
340               SWITCH_STMT_COND (stmt), body, NULL_TREE);
341   SET_EXPR_LOCATION (t, stmt_locus);
342   gimplify_and_add (t, &seq);
343
344   seq = finish_bc_block (bc_break, break_block, seq);
345   gimple_seq_add_seq (pre_p, seq);
346   *stmt_p = NULL_TREE;
347 }
348
349 /* Hook into the middle of gimplifying an OMP_FOR node.  This is required
350    in order to properly gimplify CONTINUE statements.  Here we merely
351    manage the continue stack; the rest of the job is performed by the
352    regular gimplifier.  */
353
354 static enum gimplify_status
355 cp_gimplify_omp_for (tree *expr_p, gimple_seq *pre_p)
356 {
357   tree for_stmt = *expr_p;
358   tree cont_block;
359   gimple stmt;
360   gimple_seq seq = NULL;
361
362   /* Protect ourselves from recursion.  */
363   if (OMP_FOR_GIMPLIFYING_P (for_stmt))
364     return GS_UNHANDLED;
365   OMP_FOR_GIMPLIFYING_P (for_stmt) = 1;
366
367   /* Note that while technically the continue label is enabled too soon
368      here, we should have already diagnosed invalid continues nested within
369      statement expressions within the INIT, COND, or INCR expressions.  */
370   cont_block = begin_bc_block (bc_continue);
371
372   gimplify_and_add (for_stmt, &seq);
373   stmt = gimple_seq_last_stmt (seq);
374   if (gimple_code (stmt) == GIMPLE_OMP_FOR)
375     gimple_omp_set_body (stmt, finish_bc_block (bc_continue, cont_block,
376                                                 gimple_omp_body (stmt)));
377   else
378     seq = finish_bc_block (bc_continue, cont_block, seq);
379   gimple_seq_add_seq (pre_p, seq);
380
381   OMP_FOR_GIMPLIFYING_P (for_stmt) = 0;
382
383   return GS_ALL_DONE;
384 }
385
386 /*  Gimplify an EXPR_STMT node.  */
387
388 static void
389 gimplify_expr_stmt (tree *stmt_p)
390 {
391   tree stmt = EXPR_STMT_EXPR (*stmt_p);
392
393   if (stmt == error_mark_node)
394     stmt = NULL;
395
396   /* Gimplification of a statement expression will nullify the
397      statement if all its side effects are moved to *PRE_P and *POST_P.
398
399      In this case we will not want to emit the gimplified statement.
400      However, we may still want to emit a warning, so we do that before
401      gimplification.  */
402   if (stmt && warn_unused_value)
403     {
404       if (!TREE_SIDE_EFFECTS (stmt))
405         {
406           if (!IS_EMPTY_STMT (stmt)
407               && !VOID_TYPE_P (TREE_TYPE (stmt))
408               && !TREE_NO_WARNING (stmt))
409             warning (OPT_Wunused_value, "statement with no effect");
410         }
411       else
412         warn_if_unused_value (stmt, input_location);
413     }
414
415   if (stmt == NULL_TREE)
416     stmt = alloc_stmt_list ();
417
418   *stmt_p = stmt;
419 }
420
421 /* Gimplify initialization from an AGGR_INIT_EXPR.  */
422
423 static void
424 cp_gimplify_init_expr (tree *expr_p, gimple_seq *pre_p, gimple_seq *post_p)
425 {
426   tree from = TREE_OPERAND (*expr_p, 1);
427   tree to = TREE_OPERAND (*expr_p, 0);
428   tree t;
429   tree slot = NULL_TREE;
430
431   /* What about code that pulls out the temp and uses it elsewhere?  I
432      think that such code never uses the TARGET_EXPR as an initializer.  If
433      I'm wrong, we'll abort because the temp won't have any RTL.  In that
434      case, I guess we'll need to replace references somehow.  */
435   if (TREE_CODE (from) == TARGET_EXPR)
436     {
437       slot = TARGET_EXPR_SLOT (from);
438       from = TARGET_EXPR_INITIAL (from);
439     }
440
441   /* Look through any COMPOUND_EXPRs, since build_compound_expr pushes them
442      inside the TARGET_EXPR.  */
443   for (t = from; t; )
444     {
445       tree sub = TREE_CODE (t) == COMPOUND_EXPR ? TREE_OPERAND (t, 0) : t;
446
447       /* If we are initializing from an AGGR_INIT_EXPR, drop the INIT_EXPR and
448          replace the slot operand with our target.
449
450          Should we add a target parm to gimplify_expr instead?  No, as in this
451          case we want to replace the INIT_EXPR.  */
452       if (TREE_CODE (sub) == AGGR_INIT_EXPR)
453         {
454           gimplify_expr (&to, pre_p, post_p, is_gimple_lvalue, fb_lvalue);
455           AGGR_INIT_EXPR_SLOT (sub) = to;
456           *expr_p = from;
457
458           /* The initialization is now a side-effect, so the container can
459              become void.  */
460           if (from != sub)
461             TREE_TYPE (from) = void_type_node;
462         }
463       else if (TREE_CODE (sub) == INIT_EXPR
464                && TREE_OPERAND (sub, 0) == slot)
465         {
466           /* An INIT_EXPR under TARGET_EXPR created by build_value_init,
467              will be followed by an AGGR_INIT_EXPR.  */
468           gimplify_expr (&to, pre_p, post_p, is_gimple_lvalue, fb_lvalue);
469           TREE_OPERAND (sub, 0) = to;
470         }
471
472       if (t == sub)
473         break;
474       else
475         t = TREE_OPERAND (t, 1);
476     }
477
478 }
479
480 /* Gimplify a MUST_NOT_THROW_EXPR.  */
481
482 static enum gimplify_status
483 gimplify_must_not_throw_expr (tree *expr_p, gimple_seq *pre_p)
484 {
485   tree stmt = *expr_p;
486   tree temp = voidify_wrapper_expr (stmt, NULL);
487   tree body = TREE_OPERAND (stmt, 0);
488
489   stmt = build_gimple_eh_filter_tree (body, NULL_TREE,
490                                       build_call_n (terminate_node, 0));
491
492   gimplify_and_add (stmt, pre_p);
493   if (temp)
494     {
495       *expr_p = temp;
496       return GS_OK;
497     }
498
499   *expr_p = NULL;
500   return GS_ALL_DONE;
501 }
502
503 /* Do C++-specific gimplification.  Args are as for gimplify_expr.  */
504
505 int
506 cp_gimplify_expr (tree *expr_p, gimple_seq *pre_p, gimple_seq *post_p)
507 {
508   int saved_stmts_are_full_exprs_p = 0;
509   enum tree_code code = TREE_CODE (*expr_p);
510   enum gimplify_status ret;
511   tree block = NULL;
512   VEC(gimple, heap) *bind_expr_stack = NULL;
513
514   if (STATEMENT_CODE_P (code))
515     {
516       saved_stmts_are_full_exprs_p = stmts_are_full_exprs_p ();
517       current_stmt_tree ()->stmts_are_full_exprs_p
518         = STMT_IS_FULL_EXPR_P (*expr_p);
519     }
520
521   switch (code)
522     {
523     case PTRMEM_CST:
524       *expr_p = cplus_expand_constant (*expr_p);
525       ret = GS_OK;
526       break;
527
528     case AGGR_INIT_EXPR:
529       simplify_aggr_init_expr (expr_p);
530       ret = GS_OK;
531       break;
532
533     case THROW_EXPR:
534       /* FIXME communicate throw type to back end, probably by moving
535          THROW_EXPR into ../tree.def.  */
536       *expr_p = TREE_OPERAND (*expr_p, 0);
537       ret = GS_OK;
538       break;
539
540     case MUST_NOT_THROW_EXPR:
541       ret = gimplify_must_not_throw_expr (expr_p, pre_p);
542       break;
543
544       /* We used to do this for MODIFY_EXPR as well, but that's unsafe; the
545          LHS of an assignment might also be involved in the RHS, as in bug
546          25979.  */
547     case INIT_EXPR:
548       cp_gimplify_init_expr (expr_p, pre_p, post_p);
549       ret = GS_OK;
550       break;
551
552     case EMPTY_CLASS_EXPR:
553       /* We create an empty CONSTRUCTOR with RECORD_TYPE.  */
554       *expr_p = build_constructor (TREE_TYPE (*expr_p), NULL);
555       ret = GS_OK;
556       break;
557
558     case BASELINK:
559       *expr_p = BASELINK_FUNCTIONS (*expr_p);
560       ret = GS_OK;
561       break;
562
563     case TRY_BLOCK:
564       genericize_try_block (expr_p);
565       ret = GS_OK;
566       break;
567
568     case HANDLER:
569       genericize_catch_block (expr_p);
570       ret = GS_OK;
571       break;
572
573     case EH_SPEC_BLOCK:
574       genericize_eh_spec_block (expr_p);
575       ret = GS_OK;
576       break;
577
578     case USING_STMT:
579       /* Get the innermost inclosing GIMPLE_BIND that has a non NULL
580          BLOCK, and append an IMPORTED_DECL to its
581          BLOCK_VARS chained list.  */
582
583       bind_expr_stack = gimple_bind_expr_stack ();
584       if (bind_expr_stack)
585         {
586           int i;
587           for (i = VEC_length (gimple, bind_expr_stack) - 1; i >= 0; i--)
588             if ((block = gimple_bind_block (VEC_index (gimple,
589                                                        bind_expr_stack,
590                                                        i))))
591               break;
592         }
593       if (block)
594         {
595           tree using_directive;
596           gcc_assert (TREE_OPERAND (*expr_p,0)
597                       && NAMESPACE_DECL_CHECK (TREE_OPERAND (*expr_p, 0)));
598
599           using_directive = make_node (IMPORTED_DECL);
600           TREE_TYPE (using_directive) = void_type_node;
601
602           IMPORTED_DECL_ASSOCIATED_DECL (using_directive)
603             = TREE_OPERAND (*expr_p, 0);
604           DECL_NAME (using_directive)
605             = DECL_NAME (TREE_OPERAND (*expr_p, 0));
606           TREE_CHAIN (using_directive) = BLOCK_VARS (block);
607           BLOCK_VARS (block) = using_directive;
608         }
609       /* The USING_STMT won't appear in GIMPLE.  */
610       *expr_p = NULL;
611       ret = GS_ALL_DONE;
612       break;
613
614     case IF_STMT:
615       gimplify_if_stmt (expr_p);
616       ret = GS_OK;
617       break;
618
619     case FOR_STMT:
620       gimplify_for_stmt (expr_p, pre_p);
621       ret = GS_OK;
622       break;
623
624     case WHILE_STMT:
625       gimplify_while_stmt (expr_p, pre_p);
626       ret = GS_OK;
627       break;
628
629     case DO_STMT:
630       gimplify_do_stmt (expr_p, pre_p);
631       ret = GS_OK;
632       break;
633
634     case SWITCH_STMT:
635       gimplify_switch_stmt (expr_p, pre_p);
636       ret = GS_OK;
637       break;
638
639     case OMP_FOR:
640       ret = cp_gimplify_omp_for (expr_p, pre_p);
641       break;
642
643     case CONTINUE_STMT:
644       gimple_seq_add_stmt (pre_p, gimple_build_predict (PRED_CONTINUE, NOT_TAKEN));
645       gimple_seq_add_stmt (pre_p, gimple_build_goto (get_bc_label (bc_continue)));
646       *expr_p = NULL_TREE;
647       ret = GS_ALL_DONE;
648       break;
649
650     case BREAK_STMT:
651       gimple_seq_add_stmt (pre_p, gimple_build_goto (get_bc_label (bc_break)));
652       *expr_p = NULL_TREE;
653       ret = GS_ALL_DONE;
654       break;
655
656     case EXPR_STMT:
657       gimplify_expr_stmt (expr_p);
658       ret = GS_OK;
659       break;
660
661     case UNARY_PLUS_EXPR:
662       {
663         tree arg = TREE_OPERAND (*expr_p, 0);
664         tree type = TREE_TYPE (*expr_p);
665         *expr_p = (TREE_TYPE (arg) != type) ? fold_convert (type, arg)
666                                             : arg;
667         ret = GS_OK;
668       }
669       break;
670
671     default:
672       ret = c_gimplify_expr (expr_p, pre_p, post_p);
673       break;
674     }
675
676   /* Restore saved state.  */
677   if (STATEMENT_CODE_P (code))
678     current_stmt_tree ()->stmts_are_full_exprs_p
679       = saved_stmts_are_full_exprs_p;
680
681   return ret;
682 }
683
684 static inline bool
685 is_invisiref_parm (const_tree t)
686 {
687   return ((TREE_CODE (t) == PARM_DECL || TREE_CODE (t) == RESULT_DECL)
688           && DECL_BY_REFERENCE (t));
689 }
690
691 /* Return true if the uid in both int tree maps are equal.  */
692
693 int
694 cxx_int_tree_map_eq (const void *va, const void *vb)
695 {
696   const struct cxx_int_tree_map *a = (const struct cxx_int_tree_map *) va;
697   const struct cxx_int_tree_map *b = (const struct cxx_int_tree_map *) vb;
698   return (a->uid == b->uid);
699 }
700
701 /* Hash a UID in a cxx_int_tree_map.  */
702
703 unsigned int
704 cxx_int_tree_map_hash (const void *item)
705 {
706   return ((const struct cxx_int_tree_map *)item)->uid;
707 }
708
709 /* Perform any pre-gimplification lowering of C++ front end trees to
710    GENERIC.  */
711
712 static tree
713 cp_genericize_r (tree *stmt_p, int *walk_subtrees, void *data)
714 {
715   tree stmt = *stmt_p;
716   struct pointer_set_t *p_set = (struct pointer_set_t*) data;
717
718   if (is_invisiref_parm (stmt)
719       /* Don't dereference parms in a thunk, pass the references through. */
720       && !(DECL_THUNK_P (current_function_decl)
721            && TREE_CODE (stmt) == PARM_DECL))
722     {
723       *stmt_p = convert_from_reference (stmt);
724       *walk_subtrees = 0;
725       return NULL;
726     }
727
728   /* Map block scope extern declarations to visible declarations with the
729      same name and type in outer scopes if any.  */
730   if (cp_function_chain->extern_decl_map
731       && (TREE_CODE (stmt) == FUNCTION_DECL || TREE_CODE (stmt) == VAR_DECL)
732       && DECL_EXTERNAL (stmt))
733     {
734       struct cxx_int_tree_map *h, in;
735       in.uid = DECL_UID (stmt);
736       h = (struct cxx_int_tree_map *)
737           htab_find_with_hash (cp_function_chain->extern_decl_map,
738                                &in, in.uid);
739       if (h)
740         {
741           *stmt_p = h->to;
742           *walk_subtrees = 0;
743           return NULL;
744         }
745     }
746
747   /* Other than invisiref parms, don't walk the same tree twice.  */
748   if (pointer_set_contains (p_set, stmt))
749     {
750       *walk_subtrees = 0;
751       return NULL_TREE;
752     }
753
754   if (TREE_CODE (stmt) == ADDR_EXPR
755       && is_invisiref_parm (TREE_OPERAND (stmt, 0)))
756     {
757       *stmt_p = convert (TREE_TYPE (stmt), TREE_OPERAND (stmt, 0));
758       *walk_subtrees = 0;
759     }
760   else if (TREE_CODE (stmt) == RETURN_EXPR
761            && TREE_OPERAND (stmt, 0)
762            && is_invisiref_parm (TREE_OPERAND (stmt, 0)))
763     /* Don't dereference an invisiref RESULT_DECL inside a RETURN_EXPR.  */
764     *walk_subtrees = 0;
765   else if (TREE_CODE (stmt) == OMP_CLAUSE)
766     switch (OMP_CLAUSE_CODE (stmt))
767       {
768       case OMP_CLAUSE_LASTPRIVATE:
769         /* Don't dereference an invisiref in OpenMP clauses.  */
770         if (is_invisiref_parm (OMP_CLAUSE_DECL (stmt)))
771           {
772             *walk_subtrees = 0;
773             if (OMP_CLAUSE_LASTPRIVATE_STMT (stmt))
774               cp_walk_tree (&OMP_CLAUSE_LASTPRIVATE_STMT (stmt),
775                             cp_genericize_r, p_set, NULL);
776           }
777         break;
778       case OMP_CLAUSE_PRIVATE:
779       case OMP_CLAUSE_SHARED:
780       case OMP_CLAUSE_FIRSTPRIVATE:
781       case OMP_CLAUSE_COPYIN:
782       case OMP_CLAUSE_COPYPRIVATE:
783         /* Don't dereference an invisiref in OpenMP clauses.  */
784         if (is_invisiref_parm (OMP_CLAUSE_DECL (stmt)))
785           *walk_subtrees = 0;
786         break;
787       case OMP_CLAUSE_REDUCTION:
788         gcc_assert (!is_invisiref_parm (OMP_CLAUSE_DECL (stmt)));
789         break;
790       default:
791         break;
792       }
793   else if (IS_TYPE_OR_DECL_P (stmt))
794     *walk_subtrees = 0;
795
796   /* Due to the way voidify_wrapper_expr is written, we don't get a chance
797      to lower this construct before scanning it, so we need to lower these
798      before doing anything else.  */
799   else if (TREE_CODE (stmt) == CLEANUP_STMT)
800     *stmt_p = build2 (CLEANUP_EH_ONLY (stmt) ? TRY_CATCH_EXPR
801                                              : TRY_FINALLY_EXPR,
802                       void_type_node,
803                       CLEANUP_BODY (stmt),
804                       CLEANUP_EXPR (stmt));
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         {
820           TREE_OPERAND (stmt, 1)
821             = fold_convert (type_left, TREE_OPERAND (stmt, 1));
822           gcc_assert (useless_type_conversion_p (TREE_TYPE (stmt),
823                                                  type_left));
824         }
825       if (type_right)
826         {
827           TREE_OPERAND (stmt, 2)
828             = fold_convert (type_right, TREE_OPERAND (stmt, 2));
829           gcc_assert (useless_type_conversion_p (TREE_TYPE (stmt),
830                                                  type_right));
831         }
832     }
833
834   pointer_set_insert (p_set, *stmt_p);
835
836   return NULL;
837 }
838
839 void
840 cp_genericize (tree fndecl)
841 {
842   tree t;
843   struct pointer_set_t *p_set;
844
845   /* Fix up the types of parms passed by invisible reference.  */
846   for (t = DECL_ARGUMENTS (fndecl); t; t = TREE_CHAIN (t))
847     if (TREE_ADDRESSABLE (TREE_TYPE (t)))
848       {
849         /* If a function's arguments are copied to create a thunk,
850            then DECL_BY_REFERENCE will be set -- but the type of the
851            argument will be a pointer type, so we will never get
852            here.  */
853         gcc_assert (!DECL_BY_REFERENCE (t));
854         gcc_assert (DECL_ARG_TYPE (t) != TREE_TYPE (t));
855         TREE_TYPE (t) = DECL_ARG_TYPE (t);
856         DECL_BY_REFERENCE (t) = 1;
857         TREE_ADDRESSABLE (t) = 0;
858         relayout_decl (t);
859       }
860
861   /* Do the same for the return value.  */
862   if (TREE_ADDRESSABLE (TREE_TYPE (DECL_RESULT (fndecl))))
863     {
864       t = DECL_RESULT (fndecl);
865       TREE_TYPE (t) = build_reference_type (TREE_TYPE (t));
866       DECL_BY_REFERENCE (t) = 1;
867       TREE_ADDRESSABLE (t) = 0;
868       relayout_decl (t);
869     }
870
871   /* If we're a clone, the body is already GIMPLE.  */
872   if (DECL_CLONED_FUNCTION_P (fndecl))
873     return;
874
875   /* We do want to see every occurrence of the parms, so we can't just use
876      walk_tree's hash functionality.  */
877   p_set = pointer_set_create ();
878   cp_walk_tree (&DECL_SAVED_TREE (fndecl), cp_genericize_r, p_set, NULL);
879   pointer_set_destroy (p_set);
880
881   /* Do everything else.  */
882   c_genericize (fndecl);
883
884   gcc_assert (bc_label[bc_break] == NULL);
885   gcc_assert (bc_label[bc_continue] == NULL);
886 }
887 \f
888 /* Build code to apply FN to each member of ARG1 and ARG2.  FN may be
889    NULL if there is in fact nothing to do.  ARG2 may be null if FN
890    actually only takes one argument.  */
891
892 static tree
893 cxx_omp_clause_apply_fn (tree fn, tree arg1, tree arg2)
894 {
895   tree defparm, parm, t;
896   int i = 0;
897   int nargs;
898   tree *argarray;
899
900   if (fn == NULL)
901     return NULL;
902
903   nargs = list_length (DECL_ARGUMENTS (fn));
904   argarray = (tree *) alloca (nargs * sizeof (tree));
905
906   defparm = TREE_CHAIN (TYPE_ARG_TYPES (TREE_TYPE (fn)));
907   if (arg2)
908     defparm = TREE_CHAIN (defparm);
909
910   if (TREE_CODE (TREE_TYPE (arg1)) == ARRAY_TYPE)
911     {
912       tree inner_type = TREE_TYPE (arg1);
913       tree start1, end1, p1;
914       tree start2 = NULL, p2 = NULL;
915       tree ret = NULL, lab;
916
917       start1 = arg1;
918       start2 = arg2;
919       do
920         {
921           inner_type = TREE_TYPE (inner_type);
922           start1 = build4 (ARRAY_REF, inner_type, start1,
923                            size_zero_node, NULL, NULL);
924           if (arg2)
925             start2 = build4 (ARRAY_REF, inner_type, start2,
926                              size_zero_node, NULL, NULL);
927         }
928       while (TREE_CODE (inner_type) == ARRAY_TYPE);
929       start1 = build_fold_addr_expr (start1);
930       if (arg2)
931         start2 = build_fold_addr_expr (start2);
932
933       end1 = TYPE_SIZE_UNIT (TREE_TYPE (arg1));
934       end1 = build2 (POINTER_PLUS_EXPR, TREE_TYPE (start1), start1, end1);
935
936       p1 = create_tmp_var (TREE_TYPE (start1), NULL);
937       t = build2 (MODIFY_EXPR, TREE_TYPE (p1), p1, start1);
938       append_to_statement_list (t, &ret);
939
940       if (arg2)
941         {
942           p2 = create_tmp_var (TREE_TYPE (start2), NULL);
943           t = build2 (MODIFY_EXPR, TREE_TYPE (p2), p2, start2);
944           append_to_statement_list (t, &ret);
945         }
946
947       lab = create_artificial_label ();
948       t = build1 (LABEL_EXPR, void_type_node, lab);
949       append_to_statement_list (t, &ret);
950
951       argarray[i++] = p1;
952       if (arg2)
953         argarray[i++] = p2;
954       /* Handle default arguments.  */
955       for (parm = defparm; parm && parm != void_list_node;
956            parm = TREE_CHAIN (parm), i++)
957         argarray[i] = convert_default_arg (TREE_VALUE (parm),
958                                            TREE_PURPOSE (parm), fn, i);
959       t = build_call_a (fn, i, argarray);
960       t = fold_convert (void_type_node, t);
961       t = fold_build_cleanup_point_expr (TREE_TYPE (t), t);
962       append_to_statement_list (t, &ret);
963
964       t = TYPE_SIZE_UNIT (inner_type);
965       t = build2 (POINTER_PLUS_EXPR, TREE_TYPE (p1), p1, t);
966       t = build2 (MODIFY_EXPR, TREE_TYPE (p1), p1, t);
967       append_to_statement_list (t, &ret);
968
969       if (arg2)
970         {
971           t = TYPE_SIZE_UNIT (inner_type);
972           t = build2 (POINTER_PLUS_EXPR, TREE_TYPE (p2), p2, t);
973           t = build2 (MODIFY_EXPR, TREE_TYPE (p2), p2, t);
974           append_to_statement_list (t, &ret);
975         }
976
977       t = build2 (NE_EXPR, boolean_type_node, p1, end1);
978       t = build3 (COND_EXPR, void_type_node, t, build_and_jump (&lab), NULL);
979       append_to_statement_list (t, &ret);
980
981       return ret;
982     }
983   else
984     {
985       argarray[i++] = build_fold_addr_expr (arg1);
986       if (arg2)
987         argarray[i++] = build_fold_addr_expr (arg2);
988       /* Handle default arguments.  */
989       for (parm = defparm; parm && parm != void_list_node;
990            parm = TREE_CHAIN (parm), i++)
991         argarray[i] = convert_default_arg (TREE_VALUE (parm),
992                                            TREE_PURPOSE (parm),
993                                            fn, i);
994       t = build_call_a (fn, i, argarray);
995       t = fold_convert (void_type_node, t);
996       return fold_build_cleanup_point_expr (TREE_TYPE (t), t);
997     }
998 }
999
1000 /* Return code to initialize DECL with its default constructor, or
1001    NULL if there's nothing to do.  */
1002
1003 tree
1004 cxx_omp_clause_default_ctor (tree clause, tree decl,
1005                              tree outer ATTRIBUTE_UNUSED)
1006 {
1007   tree info = CP_OMP_CLAUSE_INFO (clause);
1008   tree ret = NULL;
1009
1010   if (info)
1011     ret = cxx_omp_clause_apply_fn (TREE_VEC_ELT (info, 0), decl, NULL);
1012
1013   return ret;
1014 }
1015
1016 /* Return code to initialize DST with a copy constructor from SRC.  */
1017
1018 tree
1019 cxx_omp_clause_copy_ctor (tree clause, tree dst, tree src)
1020 {
1021   tree info = CP_OMP_CLAUSE_INFO (clause);
1022   tree ret = NULL;
1023
1024   if (info)
1025     ret = cxx_omp_clause_apply_fn (TREE_VEC_ELT (info, 0), dst, src);
1026   if (ret == NULL)
1027     ret = build2 (MODIFY_EXPR, TREE_TYPE (dst), dst, src);
1028
1029   return ret;
1030 }
1031
1032 /* Similarly, except use an assignment operator instead.  */
1033
1034 tree
1035 cxx_omp_clause_assign_op (tree clause, tree dst, tree src)
1036 {
1037   tree info = CP_OMP_CLAUSE_INFO (clause);
1038   tree ret = NULL;
1039
1040   if (info)
1041     ret = cxx_omp_clause_apply_fn (TREE_VEC_ELT (info, 2), dst, src);
1042   if (ret == NULL)
1043     ret = build2 (MODIFY_EXPR, TREE_TYPE (dst), dst, src);
1044
1045   return ret;
1046 }
1047
1048 /* Return code to destroy DECL.  */
1049
1050 tree
1051 cxx_omp_clause_dtor (tree clause, tree decl)
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, 1), decl, NULL);
1058
1059   return ret;
1060 }
1061
1062 /* True if OpenMP should privatize what this DECL points to rather
1063    than the DECL itself.  */
1064
1065 bool
1066 cxx_omp_privatize_by_reference (const_tree decl)
1067 {
1068   return is_invisiref_parm (decl);
1069 }
1070
1071 /* True if OpenMP sharing attribute of DECL is predetermined.  */
1072
1073 enum omp_clause_default_kind
1074 cxx_omp_predetermined_sharing (tree decl)
1075 {
1076   tree type;
1077
1078   /* Static data members are predetermined as shared.  */
1079   if (TREE_STATIC (decl))
1080     {
1081       tree ctx = CP_DECL_CONTEXT (decl);
1082       if (TYPE_P (ctx) && MAYBE_CLASS_TYPE_P (ctx))
1083         return OMP_CLAUSE_DEFAULT_SHARED;
1084     }
1085
1086   type = TREE_TYPE (decl);
1087   if (TREE_CODE (type) == REFERENCE_TYPE)
1088     {
1089       if (!is_invisiref_parm (decl))
1090         return OMP_CLAUSE_DEFAULT_UNSPECIFIED;
1091       type = TREE_TYPE (type);
1092
1093       if (TREE_CODE (decl) == RESULT_DECL && DECL_NAME (decl))
1094         {
1095           /* NVR doesn't preserve const qualification of the
1096              variable's type.  */
1097           tree outer = outer_curly_brace_block (current_function_decl);
1098           tree var;
1099
1100           if (outer)
1101             for (var = BLOCK_VARS (outer); var; var = TREE_CHAIN (var))
1102               if (DECL_NAME (decl) == DECL_NAME (var)
1103                   && (TYPE_MAIN_VARIANT (type)
1104                       == TYPE_MAIN_VARIANT (TREE_TYPE (var))))
1105                 {
1106                   if (TYPE_READONLY (TREE_TYPE (var)))
1107                     type = TREE_TYPE (var);
1108                   break;
1109                 }
1110         }
1111     }
1112
1113   if (type == error_mark_node)
1114     return OMP_CLAUSE_DEFAULT_UNSPECIFIED;
1115
1116   /* Variables with const-qualified type having no mutable member
1117      are predetermined shared.  */
1118   if (TYPE_READONLY (type) && !cp_has_mutable_p (type))
1119     return OMP_CLAUSE_DEFAULT_SHARED;
1120
1121   return OMP_CLAUSE_DEFAULT_UNSPECIFIED;
1122 }
1123
1124 /* Finalize an implicitly determined clause.  */
1125
1126 void
1127 cxx_omp_finish_clause (tree c)
1128 {
1129   tree decl, inner_type;
1130   bool make_shared = false;
1131
1132   if (OMP_CLAUSE_CODE (c) != OMP_CLAUSE_FIRSTPRIVATE)
1133     return;
1134
1135   decl = OMP_CLAUSE_DECL (c);
1136   decl = require_complete_type (decl);
1137   inner_type = TREE_TYPE (decl);
1138   if (decl == error_mark_node)
1139     make_shared = true;
1140   else if (TREE_CODE (TREE_TYPE (decl)) == REFERENCE_TYPE)
1141     {
1142       if (is_invisiref_parm (decl))
1143         inner_type = TREE_TYPE (inner_type);
1144       else
1145         {
1146           error ("%qE implicitly determined as %<firstprivate%> has reference type",
1147                  decl);
1148           make_shared = true;
1149         }
1150     }
1151
1152   /* We're interested in the base element, not arrays.  */
1153   while (TREE_CODE (inner_type) == ARRAY_TYPE)
1154     inner_type = TREE_TYPE (inner_type);
1155
1156   /* Check for special function availability by building a call to one.
1157      Save the results, because later we won't be in the right context
1158      for making these queries.  */
1159   if (!make_shared
1160       && CLASS_TYPE_P (inner_type)
1161       && cxx_omp_create_clause_info (c, inner_type, false, true, false))
1162     make_shared = true;
1163
1164   if (make_shared)
1165     OMP_CLAUSE_CODE (c) = OMP_CLAUSE_SHARED;
1166 }