OSDN Git Service

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