OSDN Git Service

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