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