OSDN Git Service

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