OSDN Git Service

4e27bec22b27f01d267def14e49e57f4e45f09ad
[pf3gnuchains/gcc-fork.git] / gcc / c-semantics.c
1 /* This file contains the definitions and documentation for the common
2    tree codes used in the GNU C and C++ compilers (see c-common.def
3    for the standard codes).
4    Copyright (C) 2000, 2001, 2002, 2003 Free Software Foundation, Inc.
5    Written by Benjamin Chelf (chelf@codesourcery.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 2, 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 COPYING.  If not, write to the Free
21 Software Foundation, 59 Temple Place - Suite 330, Boston, MA
22 02111-1307, USA.  */
23
24 #include "config.h"
25 #include "system.h"
26 #include "coretypes.h"
27 #include "tm.h"
28 #include "tree.h"
29 #include "function.h"
30 #include "splay-tree.h"
31 #include "varray.h"
32 #include "c-common.h"
33 #include "except.h"
34 /* In order for the format checking to accept the C frontend
35    diagnostic framework extensions, you must define this token before
36    including toplev.h.  */
37 #define GCC_DIAG_STYLE __gcc_cdiag__
38 #include "toplev.h"
39 #include "flags.h"
40 #include "ggc.h"
41 #include "rtl.h"
42 #include "expr.h"
43 #include "output.h"
44 #include "timevar.h"
45 #include "predict.h"
46 #include "tree-inline.h"
47
48 /* If non-NULL, the address of a language-specific function for
49    expanding statements.  */
50 void (*lang_expand_stmt) (tree);
51
52 /* If non-NULL, the address of a language-specific function for
53    expanding a DECL_STMT.  After the language-independent cases are
54    handled, this function will be called.  If this function is not
55    defined, it is assumed that declarations other than those for
56    variables and labels do not require any RTL generation.  */
57 void (*lang_expand_decl_stmt) (tree);
58
59 static tree find_reachable_label_1 (tree *, int *, void *);
60 static tree find_reachable_label (tree);
61 static bool expand_unreachable_if_stmt (tree);
62 static tree expand_unreachable_stmt (tree, int);
63 static void genrtl_do_stmt_1 (tree, tree);
64
65 /* Create an empty statement tree rooted at T.  */
66
67 void
68 begin_stmt_tree (tree *t)
69 {
70   /* We create a trivial EXPR_STMT so that last_tree is never NULL in
71      what follows.  We remove the extraneous statement in
72      finish_stmt_tree.  */
73   *t = build_nt (EXPR_STMT, void_zero_node);
74   last_tree = *t;
75   last_expr_type = NULL_TREE;
76   last_expr_filename = input_filename;
77 }
78
79 /* T is a statement.  Add it to the statement-tree.  */
80
81 tree
82 add_stmt (tree t)
83 {
84   if (input_filename != last_expr_filename)
85     {
86       /* If the filename has changed, also add in a FILE_STMT.  Do a string
87          compare first, though, as it might be an equivalent string.  */
88       int add = (strcmp (input_filename, last_expr_filename) != 0);
89       last_expr_filename = input_filename;
90       if (add)
91         {
92           tree pos = build_nt (FILE_STMT, get_identifier (input_filename));
93           add_stmt (pos);
94         }
95     }
96
97   /* Add T to the statement-tree.  */
98   TREE_CHAIN (last_tree) = t;
99   last_tree = t;
100
101   /* When we expand a statement-tree, we must know whether or not the
102      statements are full-expressions.  We record that fact here.  */
103   STMT_IS_FULL_EXPR_P (last_tree) = stmts_are_full_exprs_p ();
104
105   /* Keep track of the number of statements in this function.  */
106   if (current_function_decl)
107     ++DECL_NUM_STMTS (current_function_decl);
108
109   return t;
110 }
111
112 /* Create a declaration statement for the declaration given by the
113    DECL.  */
114
115 void
116 add_decl_stmt (tree decl)
117 {
118   tree decl_stmt;
119
120   /* We need the type to last until instantiation time.  */
121   decl_stmt = build_stmt (DECL_STMT, decl);
122   add_stmt (decl_stmt);
123 }
124
125 /* Add a scope-statement to the statement-tree.  BEGIN_P indicates
126    whether this statements opens or closes a scope.  PARTIAL_P is true
127    for a partial scope, i.e, the scope that begins after a label when
128    an object that needs a cleanup is created.  If BEGIN_P is nonzero,
129    returns a new TREE_LIST representing the top of the SCOPE_STMT
130    stack.  The TREE_PURPOSE is the new SCOPE_STMT.  If BEGIN_P is
131    zero, returns a TREE_LIST whose TREE_VALUE is the new SCOPE_STMT,
132    and whose TREE_PURPOSE is the matching SCOPE_STMT with
133    SCOPE_BEGIN_P set.  */
134
135 tree
136 add_scope_stmt (int begin_p, int partial_p)
137 {
138   tree *stack_ptr = current_scope_stmt_stack ();
139   tree ss;
140   tree top = *stack_ptr;
141
142   /* Build the statement.  */
143   ss = build_stmt (SCOPE_STMT, NULL_TREE);
144   SCOPE_BEGIN_P (ss) = begin_p;
145   SCOPE_PARTIAL_P (ss) = partial_p;
146
147   /* Keep the scope stack up to date.  */
148   if (begin_p)
149     {
150       top = tree_cons (ss, NULL_TREE, top);
151       *stack_ptr = top;
152     }
153   else
154     {
155       if (partial_p != SCOPE_PARTIAL_P (TREE_PURPOSE (top)))
156         abort ();
157       TREE_VALUE (top) = ss;
158       *stack_ptr = TREE_CHAIN (top);
159     }
160
161   /* Add the new statement to the statement-tree.  */
162   add_stmt (ss);
163
164   return top;
165 }
166
167 /* Finish the statement tree rooted at T.  */
168
169 void
170 finish_stmt_tree (tree *t)
171 {
172   tree stmt;
173
174   /* Remove the fake extra statement added in begin_stmt_tree.  */
175   stmt = TREE_CHAIN (*t);
176   *t = stmt;
177   last_tree = NULL_TREE;
178
179   if (cfun && stmt)
180     {
181       /* The line-number recorded in the outermost statement in a function
182          is the line number of the end of the function.  */
183       STMT_LINENO (stmt) = input_line;
184       STMT_LINENO_FOR_FN_P (stmt) = 1;
185     }
186 }
187
188 /* Build a generic statement based on the given type of node and
189    arguments. Similar to `build_nt', except that we set
190    STMT_LINENO to be the current line number.  */
191 /* ??? This should be obsolete with the lineno_stmt productions
192    in the grammar.  */
193
194 tree
195 build_stmt (enum tree_code code, ...)
196 {
197   tree t;
198   int length;
199   int i;
200   va_list p;
201
202   va_start (p, code);
203
204   t = make_node (code);
205   length = TREE_CODE_LENGTH (code);
206   STMT_LINENO (t) = input_line;
207
208   for (i = 0; i < length; i++)
209     TREE_OPERAND (t, i) = va_arg (p, tree);
210
211   va_end (p);
212   return t;
213 }
214
215 /* Some statements, like for-statements or if-statements, require a
216    condition.  This condition can be a declaration.  If T is such a
217    declaration it is processed, and an expression appropriate to use
218    as the condition is returned.  Otherwise, T itself is returned.  */
219
220 tree
221 expand_cond (tree t)
222 {
223   if (t && TREE_CODE (t) == TREE_LIST)
224     {
225       expand_stmt (TREE_PURPOSE (t));
226       return TREE_VALUE (t);
227     }
228   else
229     return t;
230 }
231
232 /* Create RTL for the local static variable DECL.  */
233
234 void
235 make_rtl_for_local_static (tree decl)
236 {
237   const char *asmspec = NULL;
238
239   /* If we inlined this variable, we could see it's declaration
240      again.  */
241   if (TREE_ASM_WRITTEN (decl))
242     return;
243
244   /* If the DECL_ASSEMBLER_NAME is not the same as the DECL_NAME, then
245      either we already created RTL for this DECL (and since it was a
246      local variable, its DECL_ASSEMBLER_NAME got hacked up to prevent
247      clashes with other local statics with the same name by a previous
248      call to make_decl_rtl), or the user explicitly requested a
249      particular assembly name for this variable, using the GNU
250      extension for this purpose:
251
252        int i asm ("j");
253
254      There's no way to know which case we're in, here.  But, it turns
255      out we're safe.  If there's already RTL, then
256      rest_of_decl_compilation ignores the ASMSPEC parameter, so we
257      may as well not pass it in.  If there isn't RTL, then we didn't
258      already create RTL, which means that the modification to
259      DECL_ASSEMBLER_NAME came only via the explicit extension.  */
260   if (DECL_ASSEMBLER_NAME (decl) != DECL_NAME (decl)
261       && !DECL_RTL_SET_P (decl))
262     asmspec = IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (decl));
263
264   rest_of_decl_compilation (decl, asmspec, /*top_level=*/0, /*at_end=*/0);
265 }
266
267 /* Let the back-end know about DECL.  */
268
269 void
270 emit_local_var (tree decl)
271 {
272   /* Create RTL for this variable.  */
273   if (!DECL_RTL_SET_P (decl))
274     {
275       if (DECL_C_HARD_REGISTER (decl))
276         /* The user specified an assembler name for this variable.
277            Set that up now.  */
278         rest_of_decl_compilation
279           (decl, IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (decl)),
280            /*top_level=*/0, /*at_end=*/0);
281       else
282         expand_decl (decl);
283     }
284
285   if (DECL_INITIAL (decl))
286     {
287       /* Actually do the initialization.  */
288       if (stmts_are_full_exprs_p ())
289         expand_start_target_temps ();
290
291       expand_decl_init (decl);
292
293       if (stmts_are_full_exprs_p ())
294         expand_end_target_temps ();
295     }
296 }
297
298 /* Helper for generating the RTL at the beginning of a scope.  */
299
300 void
301 genrtl_do_pushlevel (void)
302 {
303   emit_line_note (input_filename, input_line);
304   clear_last_expr ();
305 }
306
307 /* Generate the RTL for DESTINATION, which is a GOTO_STMT.  */
308
309 void
310 genrtl_goto_stmt (tree destination)
311 {
312   if (TREE_CODE (destination) == IDENTIFIER_NODE)
313     abort ();
314
315   /* We warn about unused labels with -Wunused.  That means we have to
316      mark the used labels as used.  */
317   if (TREE_CODE (destination) == LABEL_DECL)
318     TREE_USED (destination) = 1;
319
320   emit_line_note (input_filename, input_line);
321
322   if (TREE_CODE (destination) == LABEL_DECL)
323     {
324       label_rtx (destination);
325       expand_goto (destination);
326     }
327   else
328     expand_computed_goto (destination);
329 }
330
331 /* Generate the RTL for EXPR, which is an EXPR_STMT.  Provided just
332    for backward compatibility.  genrtl_expr_stmt_value() should be
333    used for new code.  */
334
335 void
336 genrtl_expr_stmt (tree expr)
337 {
338   genrtl_expr_stmt_value (expr, -1, 1);
339 }
340
341 /* Generate the RTL for EXPR, which is an EXPR_STMT.  WANT_VALUE tells
342    whether to (1) save the value of the expression, (0) discard it or
343    (-1) use expr_stmts_for_value to tell.  The use of -1 is
344    deprecated, and retained only for backward compatibility.
345    MAYBE_LAST is nonzero if this EXPR_STMT might be the last statement
346    in expression statement.  */
347
348 void
349 genrtl_expr_stmt_value (tree expr, int want_value, int maybe_last)
350 {
351   if (expr != NULL_TREE)
352     {
353       emit_line_note (input_filename, input_line);
354
355       if (stmts_are_full_exprs_p ())
356         expand_start_target_temps ();
357
358       if (expr != error_mark_node)
359         expand_expr_stmt_value (expr, want_value, maybe_last);
360
361       if (stmts_are_full_exprs_p ())
362         expand_end_target_temps ();
363     }
364 }
365
366 /* Generate the RTL for T, which is a DECL_STMT.  */
367
368 void
369 genrtl_decl_stmt (tree t)
370 {
371   tree decl;
372   emit_line_note (input_filename, input_line);
373   decl = DECL_STMT_DECL (t);
374   /* If this is a declaration for an automatic local
375      variable, initialize it.  Note that we might also see a
376      declaration for a namespace-scope object (declared with
377      `extern').  We don't have to handle the initialization
378      of those objects here; they can only be declarations,
379      rather than definitions.  */
380   if (TREE_CODE (decl) == VAR_DECL
381       && !TREE_STATIC (decl)
382       && !DECL_EXTERNAL (decl))
383     {
384       /* Let the back-end know about this variable.  */
385       if (!anon_aggr_type_p (TREE_TYPE (decl)))
386         emit_local_var (decl);
387       else
388         expand_anon_union_decl (decl, NULL_TREE,
389                                 DECL_ANON_UNION_ELEMS (decl));
390     }
391   else if (TREE_CODE (decl) == VAR_DECL && TREE_STATIC (decl))
392     make_rtl_for_local_static (decl);
393   else if (TREE_CODE (decl) == LABEL_DECL
394            && C_DECLARED_LABEL_FLAG (decl))
395     declare_nonlocal_label (decl);
396   else if (lang_expand_decl_stmt)
397     (*lang_expand_decl_stmt) (t);
398 }
399
400 /* Generate the RTL for T, which is an IF_STMT.  */
401
402 void
403 genrtl_if_stmt (tree t)
404 {
405   tree cond;
406   genrtl_do_pushlevel ();
407   cond = expand_cond (IF_COND (t));
408   emit_line_note (input_filename, input_line);
409   expand_start_cond (cond, 0);
410   if (THEN_CLAUSE (t))
411     {
412       tree nextt = THEN_CLAUSE (t);
413
414       if (cond && integer_zerop (cond))
415         nextt = expand_unreachable_stmt (nextt, warn_notreached);
416       expand_stmt (nextt);
417     }
418
419   if (ELSE_CLAUSE (t))
420     {
421       tree nextt = ELSE_CLAUSE (t);
422       expand_start_else ();
423       if (cond && integer_nonzerop (cond))
424         nextt = expand_unreachable_stmt (nextt, warn_notreached);
425       expand_stmt (nextt);
426     }
427   expand_end_cond ();
428 }
429
430 /* Generate the RTL for T, which is a WHILE_STMT.  */
431
432 void
433 genrtl_while_stmt (tree t)
434 {
435   tree cond = WHILE_COND (t);
436
437   emit_nop ();
438   emit_line_note (input_filename, input_line);
439   expand_start_loop (1);
440   genrtl_do_pushlevel ();
441
442   if (cond && !integer_nonzerop (cond))
443     {
444       cond = expand_cond (cond);
445       emit_line_note (input_filename, input_line);
446       expand_exit_loop_top_cond (0, cond);
447       genrtl_do_pushlevel ();
448     }
449
450   expand_stmt (WHILE_BODY (t));
451
452   expand_end_loop ();
453 }
454
455 /* Generate the RTL for a DO_STMT with condition COND and loop BODY
456    body.  This is reused for expanding unreachable WHILE_STMTS.  */
457
458 static void
459 genrtl_do_stmt_1 (tree cond, tree body)
460 {
461   /* Recognize the common special-case of do { ... } while (0) and do
462      not emit the loop widgetry in this case.  In particular this
463      avoids cluttering the rtl with dummy loop notes, which can affect
464      alignment of adjacent labels.  COND can be NULL due to parse
465      errors.  */
466   if (!cond || integer_zerop (cond))
467     {
468       expand_start_null_loop ();
469       expand_stmt (body);
470       expand_end_null_loop ();
471     }
472   else if (integer_nonzerop (cond))
473     {
474       emit_nop ();
475       emit_line_note (input_filename, input_line);
476       expand_start_loop (1);
477
478       expand_stmt (body);
479
480       emit_line_note (input_filename, input_line);
481       expand_end_loop ();
482     }
483   else
484     {
485       emit_nop ();
486       emit_line_note (input_filename, input_line);
487       expand_start_loop_continue_elsewhere (1);
488
489       expand_stmt (body);
490
491       expand_loop_continue_here ();
492       cond = expand_cond (cond);
493       emit_line_note (input_filename, input_line);
494       expand_exit_loop_if_false (0, cond);
495       expand_end_loop ();
496     }
497 }
498
499 /* Generate the RTL for T, which is a DO_STMT.  */
500
501 void
502 genrtl_do_stmt (tree t)
503 {
504   genrtl_do_stmt_1 (DO_COND (t), DO_BODY (t));
505 }
506
507 /* Build the node for a return statement and return it.  */
508
509 tree
510 build_return_stmt (tree expr)
511 {
512   return (build_stmt (RETURN_STMT, expr));
513 }
514
515 /* Generate the RTL for STMT, which is a RETURN_STMT.  */
516
517 void
518 genrtl_return_stmt (tree stmt)
519 {
520   tree expr;
521
522   expr = RETURN_STMT_EXPR (stmt);
523
524   emit_line_note (input_filename, input_line);
525   if (!expr)
526     expand_null_return ();
527   else
528     {
529       expand_start_target_temps ();
530       expand_return (expr);
531       expand_end_target_temps ();
532     }
533 }
534
535 /* Generate the RTL for T, which is a FOR_STMT.  */
536
537 void
538 genrtl_for_stmt (tree t)
539 {
540   tree cond = FOR_COND (t);
541   location_t saved_loc;
542
543   if (NEW_FOR_SCOPE_P (t))
544     genrtl_do_pushlevel ();
545
546   expand_stmt (FOR_INIT_STMT (t));
547
548   /* Expand the initialization.  */
549   emit_nop ();
550   emit_line_note (input_filename, input_line);
551   if (FOR_EXPR (t))
552     expand_start_loop_continue_elsewhere (1);
553   else
554     expand_start_loop (1);
555   genrtl_do_pushlevel ();
556
557   /* Save the filename and line number so that we expand the FOR_EXPR
558      we can reset them back to the saved values.  */
559   saved_loc = input_location;
560
561   /* Expand the condition.  */
562   if (cond && !integer_nonzerop (cond))
563     {
564       cond = expand_cond (cond);
565       emit_line_note (input_filename, input_line);
566       expand_exit_loop_top_cond (0, cond);
567       genrtl_do_pushlevel ();
568     }
569
570   /* Expand the body.  */
571   expand_stmt (FOR_BODY (t));
572
573   /* Expand the increment expression.  */
574   input_location = saved_loc;
575   emit_line_note (input_filename, input_line);
576   if (FOR_EXPR (t))
577     {
578       expand_loop_continue_here ();
579       genrtl_expr_stmt (FOR_EXPR (t));
580     }
581   expand_end_loop ();
582 }
583
584 /* Build a break statement node and return it.  */
585
586 tree
587 build_break_stmt (void)
588 {
589   return (build_stmt (BREAK_STMT));
590 }
591
592 /* Generate the RTL for a BREAK_STMT.  */
593
594 void
595 genrtl_break_stmt (void)
596 {
597   emit_line_note (input_filename, input_line);
598   if ( ! expand_exit_something ())
599     error ("break statement not within loop or switch");
600 }
601
602 /* Build a continue statement node and return it.  */
603
604 tree
605 build_continue_stmt (void)
606 {
607   return (build_stmt (CONTINUE_STMT));
608 }
609
610 /* Generate the RTL for a CONTINUE_STMT.  */
611
612 void
613 genrtl_continue_stmt (void)
614 {
615   emit_line_note (input_filename, input_line);
616   if (! expand_continue_loop (0))
617     error ("continue statement not within a loop");
618 }
619
620 /* Generate the RTL for T, which is a SCOPE_STMT.  */
621
622 void
623 genrtl_scope_stmt (tree t)
624 {
625   tree block = SCOPE_STMT_BLOCK (t);
626
627   if (!SCOPE_NO_CLEANUPS_P (t))
628     {
629       if (SCOPE_BEGIN_P (t))
630         expand_start_bindings_and_block (2 * SCOPE_NULLIFIED_P (t), block);
631       else if (SCOPE_END_P (t))
632         expand_end_bindings (NULL_TREE, !SCOPE_NULLIFIED_P (t), 0);
633     }
634   else if (!SCOPE_NULLIFIED_P (t))
635     {
636       rtx note = emit_note (SCOPE_BEGIN_P (t)
637                             ? NOTE_INSN_BLOCK_BEG : NOTE_INSN_BLOCK_END);
638       NOTE_BLOCK (note) = block;
639     }
640
641   /* If we're at the end of a scope that contains inlined nested
642      functions, we have to decide whether or not to write them out.  */
643   if (block && SCOPE_END_P (t))
644     {
645       tree fn;
646
647       for (fn = BLOCK_VARS (block); fn; fn = TREE_CHAIN (fn))
648         {
649           if (TREE_CODE (fn) == FUNCTION_DECL
650               && DECL_CONTEXT (fn) == current_function_decl
651               && DECL_SAVED_INSNS (fn)
652               && !TREE_ASM_WRITTEN (fn)
653               && TREE_ADDRESSABLE (fn))
654             {
655               push_function_context ();
656               output_inline_function (fn);
657               pop_function_context ();
658             }
659         }
660     }
661 }
662
663 /* Generate the RTL for T, which is a SWITCH_STMT.  */
664
665 void
666 genrtl_switch_stmt (tree t)
667 {
668   tree cond;
669   genrtl_do_pushlevel ();
670
671   cond = expand_cond (SWITCH_COND (t));
672   if (cond == error_mark_node)
673     /* The code is in error, but we don't want expand_end_case to
674        crash.  */
675     cond = boolean_false_node;
676
677   emit_line_note (input_filename, input_line);
678   expand_start_case (1, cond, TREE_TYPE (cond), "switch statement");
679   expand_stmt (expand_unreachable_stmt (SWITCH_BODY (t), warn_notreached));
680   expand_end_case_type (cond, SWITCH_TYPE (t));
681 }
682
683 /* Create a CASE_LABEL tree node and return it.  */
684
685 tree
686 build_case_label (tree low_value, tree high_value, tree label_decl)
687 {
688   return build_stmt (CASE_LABEL, low_value, high_value, label_decl);
689 }
690
691
692 /* Generate the RTL for a CASE_LABEL.  */
693
694 void
695 genrtl_case_label (tree case_label)
696 {
697   tree duplicate;
698   tree cleanup;
699
700   cleanup = last_cleanup_this_contour ();
701   if (cleanup)
702     {
703       static int explained = 0;
704       warning ("destructor needed for `%D'", (TREE_PURPOSE (cleanup)));
705       warning ("where case label appears here");
706       if (!explained)
707         {
708           warning ("(enclose actions of previous case statements requiring destructors in their own scope.)");
709           explained = 1;
710         }
711     }
712
713   add_case_node (CASE_LOW (case_label), CASE_HIGH (case_label),
714                  CASE_LABEL_DECL (case_label), &duplicate);
715 }
716
717 /* Generate the RTL for T, which is a COMPOUND_STMT.  */
718
719 void
720 genrtl_compound_stmt (tree t)
721 {
722 #ifdef ENABLE_CHECKING
723   struct nesting *n = current_nesting_level ();
724 #endif
725
726   expand_stmt (COMPOUND_BODY (t));
727
728 #ifdef ENABLE_CHECKING
729   /* Make sure that we've pushed and popped the same number of levels.  */
730   if (!COMPOUND_STMT_NO_SCOPE (t) && n != current_nesting_level ())
731     abort ();
732 #endif
733 }
734
735 /* Generate the RTL for an ASM_STMT.  */
736
737 void
738 genrtl_asm_stmt (tree cv_qualifier, tree string, tree output_operands,
739                  tree input_operands, tree clobbers, int asm_input_p)
740 {
741   if (cv_qualifier != NULL_TREE
742       && cv_qualifier != ridpointers[(int) RID_VOLATILE])
743     {
744       warning ("%s qualifier ignored on asm",
745                IDENTIFIER_POINTER (cv_qualifier));
746       cv_qualifier = NULL_TREE;
747     }
748
749   emit_line_note (input_filename, input_line);
750   if (asm_input_p)
751     expand_asm (string, cv_qualifier != NULL_TREE);
752   else
753     c_expand_asm_operands (string, output_operands, input_operands,
754                            clobbers, cv_qualifier != NULL_TREE,
755                            input_filename, input_line);
756 }
757
758 /* Generate the RTL for a CLEANUP_STMT.  */
759
760 void
761 genrtl_cleanup_stmt (tree t)
762 {
763   tree decl = CLEANUP_DECL (t);
764   if (!decl || (DECL_SIZE (decl) && TREE_TYPE (decl) != error_mark_node))
765     expand_decl_cleanup_eh (decl, CLEANUP_EXPR (t), CLEANUP_EH_ONLY (t));
766 }
767
768 /* We're about to expand T, a statement.  Set up appropriate context
769    for the substitution.  */
770
771 void
772 prep_stmt (tree t)
773 {
774   if (!STMT_LINENO_FOR_FN_P (t))
775     input_line = STMT_LINENO (t);
776   current_stmt_tree ()->stmts_are_full_exprs_p = STMT_IS_FULL_EXPR_P (t);
777 }
778
779 /* Generate the RTL for the statement T, its substatements, and any
780    other statements at its nesting level.  */
781
782 void
783 expand_stmt (tree t)
784 {
785   while (t && t != error_mark_node)
786     {
787       int saved_stmts_are_full_exprs_p;
788
789       /* Set up context appropriately for handling this statement.  */
790       saved_stmts_are_full_exprs_p = stmts_are_full_exprs_p ();
791       prep_stmt (t);
792
793       switch (TREE_CODE (t))
794         {
795         case FILE_STMT:
796           input_filename = FILE_STMT_FILENAME (t);
797           break;
798
799         case RETURN_STMT:
800           genrtl_return_stmt (t);
801           t = expand_unreachable_stmt (TREE_CHAIN (t), warn_notreached);
802           goto process_t;
803
804         case EXPR_STMT:
805           genrtl_expr_stmt_value (EXPR_STMT_EXPR (t), TREE_ADDRESSABLE (t),
806                                   TREE_CHAIN (t) == NULL
807                                   || (TREE_CODE (TREE_CHAIN (t)) == SCOPE_STMT
808                                       && TREE_CHAIN (TREE_CHAIN (t)) == NULL));
809           break;
810
811         case DECL_STMT:
812           genrtl_decl_stmt (t);
813           break;
814
815         case FOR_STMT:
816           genrtl_for_stmt (t);
817           break;
818
819         case WHILE_STMT:
820           genrtl_while_stmt (t);
821           break;
822
823         case DO_STMT:
824           genrtl_do_stmt (t);
825           break;
826
827         case IF_STMT:
828           genrtl_if_stmt (t);
829           break;
830
831         case COMPOUND_STMT:
832           genrtl_compound_stmt (t);
833           break;
834
835         case BREAK_STMT:
836           genrtl_break_stmt ();
837           t = expand_unreachable_stmt (TREE_CHAIN (t), warn_notreached);
838           goto process_t;
839
840         case CONTINUE_STMT:
841           genrtl_continue_stmt ();
842           t = expand_unreachable_stmt (TREE_CHAIN (t), warn_notreached);
843           goto process_t;
844
845         case SWITCH_STMT:
846           genrtl_switch_stmt (t);
847           break;
848
849         case CASE_LABEL:
850           genrtl_case_label (t);
851           break;
852
853         case LABEL_STMT:
854           expand_label (LABEL_STMT_LABEL (t));
855           break;
856
857         case GOTO_STMT:
858           /* Emit information for branch prediction.  */
859           if (!GOTO_FAKE_P (t)
860               && TREE_CODE (GOTO_DESTINATION (t)) == LABEL_DECL
861               && flag_guess_branch_prob)
862             {
863               rtx note = emit_note (NOTE_INSN_PREDICTION);
864
865               NOTE_PREDICTION (note) = NOTE_PREDICT (PRED_GOTO, NOT_TAKEN);
866             }
867           genrtl_goto_stmt (GOTO_DESTINATION (t));
868           t = expand_unreachable_stmt (TREE_CHAIN (t), warn_notreached);
869           goto process_t;
870
871         case ASM_STMT:
872           genrtl_asm_stmt (ASM_CV_QUAL (t), ASM_STRING (t),
873                            ASM_OUTPUTS (t), ASM_INPUTS (t),
874                            ASM_CLOBBERS (t), ASM_INPUT_P (t));
875           break;
876
877         case SCOPE_STMT:
878           genrtl_scope_stmt (t);
879           break;
880
881         case CLEANUP_STMT:
882           genrtl_cleanup_stmt (t);
883           break;
884
885         default:
886           if (lang_expand_stmt)
887             (*lang_expand_stmt) (t);
888           else
889             abort ();
890           break;
891         }
892
893       /* Go on to the next statement in this scope.  */
894       t = TREE_CHAIN (t);
895
896     process_t:
897       /* Restore saved state.  */
898       current_stmt_tree ()->stmts_are_full_exprs_p
899         = saved_stmts_are_full_exprs_p;
900     }
901 }
902 \f
903 /* If *TP is a potentially reachable label, return nonzero.  */
904
905 static tree
906 find_reachable_label_1 (tree *tp, int *walk_subtrees ATTRIBUTE_UNUSED,
907                         void *data ATTRIBUTE_UNUSED)
908 {
909   switch (TREE_CODE (*tp))
910     {
911     case LABEL_STMT:
912     case CASE_LABEL:
913       return *tp;
914
915     default:
916       break;
917     }
918   return NULL_TREE;
919 }
920
921 /* Determine whether expression EXP contains a potentially
922    reachable label.  */
923 static tree
924 find_reachable_label (tree exp)
925 {
926   location_t saved_loc = input_location;
927   tree ret = walk_tree (&exp, find_reachable_label_1, NULL, NULL);
928   input_location = saved_loc;
929   return ret;
930 }
931
932 /* Expand an unreachable if statement, T.  This function returns
933    true if the IF_STMT contains a potentially reachable code_label.  */
934 static bool
935 expand_unreachable_if_stmt (tree t)
936 {
937   tree n;
938
939   if (find_reachable_label (IF_COND (t)) != NULL_TREE)
940     {
941       genrtl_if_stmt (t);
942       return true;
943     }
944
945   if (THEN_CLAUSE (t) && ELSE_CLAUSE (t))
946     {
947       n = expand_unreachable_stmt (THEN_CLAUSE (t), 0);
948
949       if (n != NULL_TREE)
950         {
951           rtx label;
952           expand_stmt (n);
953           label = gen_label_rtx ();
954           emit_jump (label);
955           expand_stmt (expand_unreachable_stmt (ELSE_CLAUSE (t), 0));
956           emit_label (label);
957           return true;
958         }
959       else
960         n = expand_unreachable_stmt (ELSE_CLAUSE (t), 0);
961     }
962   else if (THEN_CLAUSE (t))
963     n = expand_unreachable_stmt (THEN_CLAUSE (t), 0);
964   else if (ELSE_CLAUSE (t))
965     n = expand_unreachable_stmt (ELSE_CLAUSE (t), 0);
966   else
967     n = NULL_TREE;
968
969   expand_stmt (n);
970
971   return n != NULL_TREE;
972 }
973
974 /* Expand an unreachable statement list.  This function skips all
975    statements preceding the first potentially reachable label and
976    then returns the label (or, in same cases, the statement after
977    one containing the label).  */
978 static tree
979 expand_unreachable_stmt (tree t, int warn)
980 {
981   int saved;
982
983   while (t && t != error_mark_node)
984     {
985       if (warn)
986         switch (TREE_CODE (t))
987           {
988           case BREAK_STMT:
989           case CONTINUE_STMT:
990           case EXPR_STMT:
991           case GOTO_STMT:
992           case IF_STMT:
993           case RETURN_STMT:
994             if (!STMT_LINENO_FOR_FN_P (t))
995               input_line = STMT_LINENO (t);
996             warning("will never be executed");
997             warn = false;
998             break;
999
1000           default:
1001             break;
1002           }
1003
1004       switch (TREE_CODE (t))
1005         {
1006         case GOTO_STMT:
1007         case CONTINUE_STMT:
1008         case BREAK_STMT:
1009           break;
1010
1011         case FILE_STMT:
1012           input_filename = FILE_STMT_FILENAME (t);
1013           break;
1014
1015         case RETURN_STMT:
1016           if (find_reachable_label (RETURN_STMT_EXPR (t)) != NULL_TREE)
1017             return t;
1018           break;
1019
1020         case EXPR_STMT:
1021           if (find_reachable_label (EXPR_STMT_EXPR (t)) != NULL_TREE)
1022             return t;
1023           break;
1024
1025         case IF_STMT:
1026           if (expand_unreachable_if_stmt (t))
1027             return TREE_CHAIN (t);
1028           break;
1029
1030         case WHILE_STMT:
1031           /* If the start of a while statement is unreachable, there is
1032              no need to rotate the loop, instead the WHILE_STMT can be
1033              expanded like a DO_STMT.  */
1034           genrtl_do_stmt_1 (WHILE_COND (t), WHILE_BODY (t));
1035           return TREE_CHAIN (t);
1036
1037         case COMPOUND_STMT:
1038           {
1039             tree n;
1040             n = expand_unreachable_stmt (COMPOUND_BODY (t), warn);
1041             if (n != NULL_TREE)
1042               {
1043                 expand_stmt (n);
1044                 return TREE_CHAIN (t);
1045               }
1046             warn = false;
1047             break;
1048           }
1049
1050         case SCOPE_STMT:
1051           saved = stmts_are_full_exprs_p ();
1052           prep_stmt (t);
1053           genrtl_scope_stmt (t);
1054           current_stmt_tree ()->stmts_are_full_exprs_p = saved;
1055           break;
1056
1057         default:
1058           return t;
1059         }
1060       t = TREE_CHAIN (t);
1061     }
1062   return NULL_TREE;
1063 }