* emit-rtl.c (subreg_hard_regno): Check that register is representable.
[official-gcc.git] / gcc / c-semantics.c
blob2d88144f2d81a2cd06fe73381e9a3e2994fde9ca
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).
7 This file is part of GCC.
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.
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.
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. */
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"
44 /* If non-NULL, the address of a language-specific function for
45 expanding statements. */
46 void (*lang_expand_stmt) PARAMS ((tree));
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));
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 bool expand_unreachable_stmt PARAMS ((tree, int));
60 /* Create an empty statement tree rooted at T. */
62 void
63 begin_stmt_tree (t)
64 tree *t;
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;
75 /* T is a statement. Add it to the statement-tree. */
77 tree
78 add_stmt (t)
79 tree t;
81 if (input_filename != last_expr_filename)
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)
89 tree pos = build_nt (FILE_STMT, get_identifier (input_filename));
90 add_stmt (pos);
94 /* Add T to the statement-tree. */
95 TREE_CHAIN (last_tree) = t;
96 last_tree = t;
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 ();
102 /* Keep track of the number of statements in this function. */
103 if (current_function_decl)
104 ++DECL_NUM_STMTS (current_function_decl);
106 return t;
109 /* Create a declaration statement for the declaration given by the
110 DECL. */
112 void
113 add_decl_stmt (decl)
114 tree decl;
116 tree decl_stmt;
118 /* We need the type to last until instantiation time. */
119 decl_stmt = build_stmt (DECL_STMT, decl);
120 add_stmt (decl_stmt);
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. */
133 tree
134 add_scope_stmt (begin_p, partial_p)
135 int begin_p;
136 int partial_p;
138 tree *stack_ptr = current_scope_stmt_stack ();
139 tree ss;
140 tree top = *stack_ptr;
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;
147 /* Keep the scope stack up to date. */
148 if (begin_p)
150 top = tree_cons (ss, NULL_TREE, top);
151 *stack_ptr = top;
153 else
155 if (partial_p != SCOPE_PARTIAL_P (TREE_PURPOSE (top)))
156 abort ();
157 TREE_VALUE (top) = ss;
158 *stack_ptr = TREE_CHAIN (top);
161 /* Add the new statement to the statement-tree. */
162 add_stmt (ss);
164 return top;
167 /* Finish the statement tree rooted at T. */
169 void
170 finish_stmt_tree (t)
171 tree *t;
173 tree stmt;
175 /* Remove the fake extra statement added in begin_stmt_tree. */
176 stmt = TREE_CHAIN (*t);
177 *t = stmt;
178 last_tree = NULL_TREE;
180 if (cfun && stmt)
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) = lineno;
185 STMT_LINENO_FOR_FN_P (stmt) = 1;
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. */
195 tree
196 build_stmt VPARAMS ((enum tree_code code, ...))
198 tree t;
199 int length;
200 int i;
202 VA_OPEN (p, code);
203 VA_FIXEDARG (p, enum tree_code, code);
205 t = make_node (code);
206 length = TREE_CODE_LENGTH (code);
207 STMT_LINENO (t) = lineno;
209 for (i = 0; i < length; i++)
210 TREE_OPERAND (t, i) = va_arg (p, tree);
212 VA_CLOSE (p);
213 return t;
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. */
221 tree
222 expand_cond (t)
223 tree t;
225 if (t && TREE_CODE (t) == TREE_LIST)
227 expand_stmt (TREE_PURPOSE (t));
228 return TREE_VALUE (t);
230 else
231 return t;
234 /* Create RTL for the local static variable DECL. */
236 void
237 make_rtl_for_local_static (decl)
238 tree decl;
240 const char *asmspec = NULL;
242 /* If we inlined this variable, we could see it's declaration
243 again. */
244 if (TREE_ASM_WRITTEN (decl))
245 return;
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:
255 int i asm ("j");
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));
267 rest_of_decl_compilation (decl, asmspec, /*top_level=*/0, /*at_end=*/0);
270 /* Let the back-end know about DECL. */
272 void
273 emit_local_var (decl)
274 tree decl;
276 /* Create RTL for this variable. */
277 if (!DECL_RTL_SET_P (decl))
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);
289 /* Actually do the initialization. */
290 if (stmts_are_full_exprs_p ())
291 expand_start_target_temps ();
293 expand_decl_init (decl);
295 if (stmts_are_full_exprs_p ())
296 expand_end_target_temps ();
299 /* Helper for generating the RTL at the beginning of a scope. */
301 void
302 genrtl_do_pushlevel ()
304 emit_line_note (input_filename, lineno);
305 clear_last_expr ();
308 /* Generate the RTL for DESTINATION, which is a GOTO_STMT. */
310 void
311 genrtl_goto_stmt (destination)
312 tree destination;
314 if (TREE_CODE (destination) == IDENTIFIER_NODE)
315 abort ();
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;
322 emit_line_note (input_filename, lineno);
324 if (TREE_CODE (destination) == LABEL_DECL)
326 label_rtx (destination);
327 expand_goto (destination);
329 else
330 expand_computed_goto (destination);
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. */
337 void
338 genrtl_expr_stmt (expr)
339 tree expr;
341 genrtl_expr_stmt_value (expr, -1, 1);
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. */
351 void
352 genrtl_expr_stmt_value (expr, want_value, maybe_last)
353 tree expr;
354 int want_value, maybe_last;
356 if (expr != NULL_TREE)
358 emit_line_note (input_filename, lineno);
360 if (stmts_are_full_exprs_p ())
361 expand_start_target_temps ();
363 if (expr != error_mark_node)
364 expand_expr_stmt_value (expr, want_value, maybe_last);
366 if (stmts_are_full_exprs_p ())
367 expand_end_target_temps ();
371 /* Generate the RTL for T, which is a DECL_STMT. */
373 void
374 genrtl_decl_stmt (t)
375 tree t;
377 tree decl;
378 emit_line_note (input_filename, lineno);
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))
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));
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);
406 /* Generate the RTL for T, which is an IF_STMT. */
408 void
409 genrtl_if_stmt (t)
410 tree t;
412 tree cond;
413 genrtl_do_pushlevel ();
414 cond = expand_cond (IF_COND (t));
415 emit_line_note (input_filename, lineno);
416 expand_start_cond (cond, 0);
417 if (THEN_CLAUSE (t))
419 if (cond && integer_zerop (cond))
420 expand_unreachable_stmt (THEN_CLAUSE (t), warn_notreached);
421 else
422 expand_stmt (THEN_CLAUSE (t));
425 if (ELSE_CLAUSE (t))
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));
433 expand_end_cond ();
436 /* Generate the RTL for T, which is a WHILE_STMT. */
438 void
439 genrtl_while_stmt (t)
440 tree t;
442 tree cond = WHILE_COND (t);
444 emit_nop ();
445 emit_line_note (input_filename, lineno);
446 expand_start_loop (1);
447 genrtl_do_pushlevel ();
449 if (cond && !integer_nonzerop (cond))
451 cond = expand_cond (cond);
452 emit_line_note (input_filename, lineno);
453 expand_exit_loop_top_cond (0, cond);
454 genrtl_do_pushlevel ();
457 expand_stmt (WHILE_BODY (t));
459 expand_end_loop ();
462 /* Generate the RTL for T, which is a DO_STMT. */
464 void
465 genrtl_do_stmt (t)
466 tree t;
468 tree cond = DO_COND (t);
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))
477 expand_start_null_loop ();
478 expand_stmt (DO_BODY (t));
479 expand_end_null_loop ();
481 else if (integer_nonzerop (cond))
483 emit_nop ();
484 emit_line_note (input_filename, lineno);
485 expand_start_loop (1);
487 expand_stmt (DO_BODY (t));
489 emit_line_note (input_filename, lineno);
490 expand_end_loop ();
492 else
494 emit_nop ();
495 emit_line_note (input_filename, lineno);
496 expand_start_loop_continue_elsewhere (1);
498 expand_stmt (DO_BODY (t));
500 expand_loop_continue_here ();
501 cond = expand_cond (cond);
502 emit_line_note (input_filename, lineno);
503 expand_exit_loop_if_false (0, cond);
504 expand_end_loop ();
508 /* Build the node for a return statement and return it. */
510 tree
511 build_return_stmt (expr)
512 tree expr;
514 return (build_stmt (RETURN_STMT, expr));
517 /* Generate the RTL for STMT, which is a RETURN_STMT. */
519 void
520 genrtl_return_stmt (stmt)
521 tree stmt;
523 tree expr;
525 expr = RETURN_STMT_EXPR (stmt);
527 emit_line_note (input_filename, lineno);
528 if (!expr)
529 expand_null_return ();
530 else
532 expand_start_target_temps ();
533 expand_return (expr);
534 expand_end_target_temps ();
538 /* Generate the RTL for T, which is a FOR_STMT. */
540 void
541 genrtl_for_stmt (t)
542 tree t;
544 tree cond = FOR_COND (t);
545 const char *saved_filename;
546 int saved_lineno;
548 if (NEW_FOR_SCOPE_P (t))
549 genrtl_do_pushlevel ();
551 expand_stmt (FOR_INIT_STMT (t));
553 /* Expand the initialization. */
554 emit_nop ();
555 emit_line_note (input_filename, lineno);
556 if (FOR_EXPR (t))
557 expand_start_loop_continue_elsewhere (1);
558 else
559 expand_start_loop (1);
560 genrtl_do_pushlevel ();
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 = lineno;
567 /* Expand the condition. */
568 if (cond && !integer_nonzerop (cond))
570 cond = expand_cond (cond);
571 emit_line_note (input_filename, lineno);
572 expand_exit_loop_top_cond (0, cond);
573 genrtl_do_pushlevel ();
576 /* Expand the body. */
577 expand_stmt (FOR_BODY (t));
579 /* Expand the increment expression. */
580 input_filename = saved_filename;
581 lineno = saved_lineno;
582 emit_line_note (input_filename, lineno);
583 if (FOR_EXPR (t))
585 expand_loop_continue_here ();
586 genrtl_expr_stmt (FOR_EXPR (t));
588 expand_end_loop ();
591 /* Build a break statement node and return it. */
593 tree
594 build_break_stmt ()
596 return (build_stmt (BREAK_STMT));
599 /* Generate the RTL for a BREAK_STMT. */
601 void
602 genrtl_break_stmt ()
604 emit_line_note (input_filename, lineno);
605 if ( ! expand_exit_something ())
606 error ("break statement not within loop or switch");
609 /* Build a continue statement node and return it. */
611 tree
612 build_continue_stmt ()
614 return (build_stmt (CONTINUE_STMT));
617 /* Generate the RTL for a CONTINUE_STMT. */
619 void
620 genrtl_continue_stmt ()
622 emit_line_note (input_filename, lineno);
623 if (! expand_continue_loop (0))
624 error ("continue statement not within a loop");
627 /* Generate the RTL for T, which is a SCOPE_STMT. */
629 void
630 genrtl_scope_stmt (t)
631 tree t;
633 tree block = SCOPE_STMT_BLOCK (t);
635 if (!SCOPE_NO_CLEANUPS_P (t))
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);
642 else if (!SCOPE_NULLIFIED_P (t))
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;
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))
655 tree fn;
657 for (fn = BLOCK_VARS (block); fn; fn = TREE_CHAIN (fn))
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))
665 push_function_context ();
666 output_inline_function (fn);
667 pop_function_context ();
673 /* Generate the RTL for T, which is a SWITCH_STMT. */
675 void
676 genrtl_switch_stmt (t)
677 tree t;
679 tree cond;
680 genrtl_do_pushlevel ();
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;
688 emit_line_note (input_filename, lineno);
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));
694 /* Create a CASE_LABEL tree node and return it. */
696 tree
697 build_case_label (low_value, high_value, label_decl)
698 tree low_value;
699 tree high_value;
700 tree label_decl;
702 return build_stmt (CASE_LABEL, low_value, high_value, label_decl);
706 /* Generate the RTL for a CASE_LABEL. */
708 void
709 genrtl_case_label (case_label)
710 tree case_label;
712 tree duplicate;
713 tree cleanup;
715 cleanup = last_cleanup_this_contour ();
716 if (cleanup)
718 static int explained = 0;
719 warning ("destructor needed for `%#D'", (TREE_PURPOSE (cleanup)));
720 warning ("where case label appears here");
721 if (!explained)
723 warning ("(enclose actions of previous case statements requiring destructors in their own scope.)");
724 explained = 1;
728 add_case_node (CASE_LOW (case_label), CASE_HIGH (case_label),
729 CASE_LABEL_DECL (case_label), &duplicate);
732 /* Generate the RTL for T, which is a COMPOUND_STMT. */
734 void
735 genrtl_compound_stmt (t)
736 tree t;
738 #ifdef ENABLE_CHECKING
739 struct nesting *n = current_nesting_level ();
740 #endif
742 expand_stmt (COMPOUND_BODY (t));
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
751 /* Generate the RTL for an ASM_STMT. */
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;
763 if (cv_qualifier != NULL_TREE
764 && cv_qualifier != ridpointers[(int) RID_VOLATILE])
766 warning ("%s qualifier ignored on asm",
767 IDENTIFIER_POINTER (cv_qualifier));
768 cv_qualifier = NULL_TREE;
771 emit_line_note (input_filename, lineno);
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, lineno);
780 /* Generate the RTL for a DECL_CLEANUP. */
782 void
783 genrtl_decl_cleanup (t)
784 tree t;
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));
791 /* We're about to expand T, a statement. Set up appropriate context
792 for the substitution. */
794 void
795 prep_stmt (t)
796 tree t;
798 if (!STMT_LINENO_FOR_FN_P (t))
799 lineno = STMT_LINENO (t);
800 current_stmt_tree ()->stmts_are_full_exprs_p = STMT_IS_FULL_EXPR_P (t);
803 /* Generate the RTL for the statement T, its substatements, and any
804 other statements at its nesting level. */
806 void
807 expand_stmt (t)
808 tree t;
810 while (t && t != error_mark_node)
812 int saved_stmts_are_full_exprs_p;
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);
818 switch (TREE_CODE (t))
820 case FILE_STMT:
821 input_filename = FILE_STMT_FILENAME (t);
822 break;
824 case RETURN_STMT:
825 genrtl_return_stmt (t);
826 expand_unreachable_stmt (TREE_CHAIN (t), warn_notreached);
827 return;
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;
836 case DECL_STMT:
837 genrtl_decl_stmt (t);
838 break;
840 case FOR_STMT:
841 genrtl_for_stmt (t);
842 break;
844 case WHILE_STMT:
845 genrtl_while_stmt (t);
846 break;
848 case DO_STMT:
849 genrtl_do_stmt (t);
850 break;
852 case IF_STMT:
853 genrtl_if_stmt (t);
854 break;
856 case COMPOUND_STMT:
857 genrtl_compound_stmt (t);
858 break;
860 case BREAK_STMT:
861 genrtl_break_stmt ();
862 expand_unreachable_stmt (TREE_CHAIN (t), warn_notreached);
863 return;
865 case CONTINUE_STMT:
866 genrtl_continue_stmt ();
867 expand_unreachable_stmt (TREE_CHAIN (t), warn_notreached);
868 return;
870 case SWITCH_STMT:
871 genrtl_switch_stmt (t);
872 break;
874 case CASE_LABEL:
875 genrtl_case_label (t);
876 break;
878 case LABEL_STMT:
879 expand_label (LABEL_STMT_LABEL (t));
880 break;
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)
888 rtx note = emit_note (NULL, NOTE_INSN_PREDICTION);
890 NOTE_PREDICTION (note) = NOTE_PREDICT (PRED_GOTO, NOT_TAKEN);
892 genrtl_goto_stmt (GOTO_DESTINATION (t));
893 expand_unreachable_stmt (TREE_CHAIN (t), warn_notreached);
894 return;
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;
902 case SCOPE_STMT:
903 genrtl_scope_stmt (t);
904 break;
906 case CLEANUP_STMT:
907 genrtl_decl_cleanup (t);
908 break;
910 default:
911 if (lang_expand_stmt)
912 (*lang_expand_stmt) (t);
913 else
914 abort ();
915 break;
918 /* Restore saved state. */
919 current_stmt_tree ()->stmts_are_full_exprs_p
920 = saved_stmts_are_full_exprs_p;
922 /* Go on to the next statement in this scope. */
923 t = TREE_CHAIN (t);
927 /* If *TP is a potentially reachable label, return nonzero. */
929 static tree
930 find_reachable_label_1 (tp, walk_subtrees, data)
931 tree *tp;
932 int *walk_subtrees ATTRIBUTE_UNUSED;
933 void *data ATTRIBUTE_UNUSED;
935 switch (TREE_CODE (*tp))
937 case LABEL_STMT:
938 case CASE_LABEL:
939 return *tp;
941 default:
942 break;
944 return NULL_TREE;
947 /* Determine whether expression EXP contains a potentially
948 reachable label. */
949 static tree
950 find_reachable_label (exp)
951 tree exp;
953 int line = lineno;
954 const char *file = input_filename;
955 tree ret = walk_tree (&exp, find_reachable_label_1, NULL, NULL);
956 input_filename = file;
957 lineno = line;
958 return ret;
961 /* Expand an unreachable if statement, T. This function returns
962 true if the IF_STMT contains a potentially reachable code_label. */
963 static bool
964 expand_unreachable_if_stmt (t)
965 tree t;
967 if (find_reachable_label (IF_COND (t)) != NULL_TREE)
969 genrtl_if_stmt (t);
970 return true;
973 if (THEN_CLAUSE (t) && ELSE_CLAUSE (t))
975 if (expand_unreachable_stmt (THEN_CLAUSE (t), 0))
977 rtx label;
978 label = gen_label_rtx ();
979 emit_jump (label);
980 expand_unreachable_stmt (ELSE_CLAUSE (t), 0);
981 emit_label (label);
982 return true;
984 else
985 return expand_unreachable_stmt (ELSE_CLAUSE (t), 0);
987 else if (THEN_CLAUSE (t))
988 return expand_unreachable_stmt (THEN_CLAUSE (t), 0);
989 else if (ELSE_CLAUSE (t))
990 return expand_unreachable_stmt (ELSE_CLAUSE (t), 0);
992 return false;
995 /* Expand an unreachable statement list. This function skips all
996 statements preceding the first potentially reachable label and
997 then expands the statements normally with expand_stmt. This
998 function returns true if such a reachable label was found. */
999 static bool
1000 expand_unreachable_stmt (t, warn)
1001 tree t;
1002 int warn;
1004 int saved;
1006 while (t && t != error_mark_node)
1008 if (warn)
1009 switch (TREE_CODE (t))
1011 case BREAK_STMT:
1012 case CONTINUE_STMT:
1013 case EXPR_STMT:
1014 case GOTO_STMT:
1015 case IF_STMT:
1016 case RETURN_STMT:
1017 if (!STMT_LINENO_FOR_FN_P (t))
1018 lineno = STMT_LINENO (t);
1019 warning("will never be executed");
1020 warn = false;
1021 break;
1023 default:
1024 break;
1027 switch (TREE_CODE (t))
1029 case GOTO_STMT:
1030 case CONTINUE_STMT:
1031 case BREAK_STMT:
1032 break;
1034 case FILE_STMT:
1035 input_filename = FILE_STMT_FILENAME (t);
1036 break;
1038 case RETURN_STMT:
1039 if (find_reachable_label (RETURN_STMT_EXPR (t)) != NULL_TREE)
1041 expand_stmt (t);
1042 return true;
1044 break;
1046 case EXPR_STMT:
1047 if (find_reachable_label (EXPR_STMT_EXPR (t)) != NULL_TREE)
1049 expand_stmt (t);
1050 return true;
1052 break;
1054 case IF_STMT:
1055 if (expand_unreachable_if_stmt (t))
1057 expand_stmt (TREE_CHAIN (t));
1058 return true;
1060 break;
1062 case COMPOUND_STMT:
1063 if (expand_unreachable_stmt (COMPOUND_BODY (t), warn))
1065 expand_stmt (TREE_CHAIN (t));
1066 return true;
1068 warn = false;
1069 break;
1071 case SCOPE_STMT:
1072 saved = stmts_are_full_exprs_p ();
1073 prep_stmt (t);
1074 genrtl_scope_stmt (t);
1075 current_stmt_tree ()->stmts_are_full_exprs_p = saved;
1076 break;
1078 default:
1079 expand_stmt (t);
1080 return true;
1082 t = TREE_CHAIN (t);
1084 return false;