OSDN Git Service

eea9f9209e50dbd6af61d9a6a8712077d69418f5
[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 Free Software Foundation, Inc.  Written by
5    Benjamin Chelf (chelf@codesourcery.com).
6
7 This file is part of GNU CC.
8
9 GNU CC is free software; you can redistribute it and/or modify
10 it under the terms of the GNU General Public License as published by
11 the Free Software Foundation; either version 2, or (at your option)
12 any later version.
13
14 GNU CC is distributed in the hope that it will be useful,
15 but WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17 GNU General Public License for more details.
18
19 You should have received a copy of the GNU General Public License
20 along with GNU CC; see the file COPYING.  If not, write to
21 the Free Software Foundation, 59 Temple Place - Suite 330,
22 Boston, MA 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 "output.h"
37 #include "timevar.h"
38
39 static tree prune_unused_decls PARAMS ((tree *, int *, void *));
40
41 /* Create an empty statement tree rooted at T.  */
42
43 void
44 begin_stmt_tree (t)
45      tree *t;
46 {
47   /* We create a trivial EXPR_STMT so that last_tree is never NULL in
48      what follows.  We remove the extraneous statement in
49      finish_stmt_tree.  */
50   *t = build_nt (EXPR_STMT, void_zero_node);
51   last_tree = *t;
52   last_expr_type = NULL_TREE;
53 }
54
55 /* T is a statement.  Add it to the statement-tree.  */
56
57 void
58 add_stmt (t)
59      tree t;
60 {
61   /* Add T to the statement-tree.  */
62   TREE_CHAIN (last_tree) = t;
63   last_tree = t;
64   /* When we expand a statement-tree, we must know whether or not the
65      statements are full-expresions.  We record that fact here.  */
66   STMT_IS_FULL_EXPR_P (last_tree) = stmts_are_full_exprs_p ();
67 }
68
69 /* Remove declarations of internal variables that are not used from a
70    stmt tree.  To qualify, the variable must have a name and must have
71    a zero DECL_SOURCE_LINE.  We tried to remove all variables for
72    which TREE_USED was false, but it turns out that there's tons of
73    variables for which TREE_USED is false but that are still in fact
74    used.  */
75
76 static tree
77 prune_unused_decls (tp, walk_subtrees, data)
78      tree *tp;
79      int *walk_subtrees ATTRIBUTE_UNUSED;
80      void *data ATTRIBUTE_UNUSED;
81 {
82   tree t = *tp;
83
84   if (t == NULL_TREE)
85     {
86       *walk_subtrees = 0;
87       return NULL_TREE;
88     }
89
90   if (TREE_CODE (t) == DECL_STMT)
91     {
92       tree d = DECL_STMT_DECL (t);
93       if (!TREE_USED (d) && DECL_NAME (d) && DECL_SOURCE_LINE (d) == 0)
94         {
95           *tp = TREE_CHAIN (t);
96           /* Recurse on the new value of tp, otherwise we will skip
97              the next statement.  */
98           return prune_unused_decls (tp, walk_subtrees, data);
99         }
100     }
101   else if (TREE_CODE (t) == SCOPE_STMT)
102     {
103       /* Remove all unused decls from the BLOCK of this SCOPE_STMT.  */
104       tree block = SCOPE_STMT_BLOCK (t);
105
106       if (block)
107         {
108           tree *vp;
109
110           for (vp = &BLOCK_VARS (block); *vp; )
111             {
112               tree v = *vp;
113               if (! TREE_USED (v) && DECL_NAME (v) && DECL_SOURCE_LINE (v) == 0)
114                 *vp = TREE_CHAIN (v);  /* drop */
115               else
116                 vp = &TREE_CHAIN (v);  /* advance */
117             }
118           /* If there are now no variables, the entire BLOCK can be dropped.
119              (This causes SCOPE_NULLIFIED_P (t) to be true.)  */
120           if (BLOCK_VARS (block) == NULL_TREE)
121             SCOPE_STMT_BLOCK (t) = NULL_TREE;
122         }
123     }
124   return NULL_TREE;
125 }
126
127 /* Finish the statement tree rooted at T.  */
128
129 void
130 finish_stmt_tree (t)
131      tree *t;
132 {
133   tree stmt;
134   
135   /* Remove the fake extra statement added in begin_stmt_tree.  */
136   stmt = TREE_CHAIN (*t);
137   *t = stmt;
138   last_tree = NULL_TREE;
139
140   /* Remove unused decls from the stmt tree.  */
141   walk_stmt_tree (t, prune_unused_decls, NULL);
142
143   if (cfun)
144     {
145       /* The line-number recorded in the outermost statement in a function
146          is the line number of the end of the function.  */
147       STMT_LINENO (stmt) = lineno;
148       STMT_LINENO_FOR_FN_P (stmt) = 1;
149     }
150 }
151
152 /* Build a generic statement based on the given type of node and
153    arguments. Similar to `build_nt', except that we set
154    TREE_COMPLEXITY to be the current line number.  */
155
156 tree
157 build_stmt VPARAMS ((enum tree_code code, ...))
158 {
159 #ifndef ANSI_PROTOTYPES
160   enum tree_code code;
161 #endif
162   va_list p;
163   register tree t;
164   register int length;
165   register int i;
166
167   VA_START (p, code);
168
169 #ifndef ANSI_PROTOTYPES
170   code = va_arg (p, enum tree_code);
171 #endif
172
173   t = make_node (code);
174   length = TREE_CODE_LENGTH (code);
175   TREE_COMPLEXITY (t) = lineno;
176
177   for (i = 0; i < length; i++)
178     TREE_OPERAND (t, i) = va_arg (p, tree);
179
180   va_end (p);
181   return t;
182 }
183
184 /* Some statements, like for-statements or if-statements, require a
185    condition.  This condition can be a declaration.  If T is such a
186    declaration it is processed, and an expression appropriate to use
187    as the condition is returned.  Otherwise, T itself is returned.  */
188
189 tree
190 expand_cond (t)
191      tree t;
192 {
193   if (t && TREE_CODE (t) == TREE_LIST)
194     {
195       expand_stmt (TREE_PURPOSE (t));
196       return TREE_VALUE (t);
197     }
198   else 
199     return t;
200 }
201
202 /* Create RTL for the local static variable DECL.  */
203
204 void
205 make_rtl_for_local_static (decl)
206      tree decl;
207 {
208   const char *asmspec = NULL;
209
210   /* If we inlined this variable, we could see it's declaration
211      again.  */
212   if (TREE_ASM_WRITTEN (decl))
213     return;
214
215   if (DECL_ASSEMBLER_NAME (decl) != DECL_NAME (decl))
216     {
217       /* The only way this situaton can occur is if the
218          user specified a name for this DECL using the
219          `attribute' syntax.  */
220       asmspec = IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (decl));
221       DECL_ASSEMBLER_NAME (decl) = DECL_NAME (decl);
222     }
223
224   rest_of_decl_compilation (decl, asmspec, /*top_level=*/0, /*at_end=*/0);
225 }
226
227 /* Let the back-end know about DECL.  */
228
229 void
230 emit_local_var (decl)
231      tree decl;
232 {
233   /* Create RTL for this variable.  */
234   if (!DECL_RTL (decl))
235     {
236       if (DECL_ASSEMBLER_NAME (decl) != DECL_NAME (decl))
237         /* The user must have specified an assembler name for this
238            variable.  Set that up now.  */
239         rest_of_decl_compilation
240           (decl, IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (decl)),
241            /*top_level=*/0, /*at_end=*/0);
242       else
243         expand_decl (decl);
244     }
245
246   /* Actually do the initialization.  */
247   if (stmts_are_full_exprs_p ())
248     expand_start_target_temps ();
249
250   expand_decl_init (decl);
251
252   if (stmts_are_full_exprs_p ())
253     expand_end_target_temps ();
254 }
255
256 /* Helper for generating the RTL at the beginning of a scope. */
257
258 void
259 genrtl_do_pushlevel ()
260 {
261   emit_line_note (input_filename, lineno);
262   clear_last_expr ();
263 }
264
265 /* Helper for generating the RTL. */
266
267 void
268 genrtl_clear_out_block ()
269 {
270   /* If COND wasn't a declaration, clear out the
271      block we made for it and start a new one here so the
272      optimization in expand_end_loop will work.  */
273   if (getdecls () == NULL_TREE)
274     genrtl_do_pushlevel ();
275 }
276
277 /* Generate the RTL for DESTINATION, which is a GOTO_STMT. */
278
279 void
280 genrtl_goto_stmt (destination)
281      tree destination;
282 {
283   if (TREE_CODE (destination) == IDENTIFIER_NODE)
284     abort ();
285   
286   /* We warn about unused labels with -Wunused.  That means we have to
287      mark the used labels as used.  */
288   if (TREE_CODE (destination) == LABEL_DECL)
289     TREE_USED (destination) = 1;
290   
291   emit_line_note (input_filename, lineno);
292   
293   if (TREE_CODE (destination) == LABEL_DECL)
294     {
295       label_rtx (destination);
296       expand_goto (destination); 
297     }
298   else
299     expand_computed_goto (destination);
300 }
301
302 /* Generate the RTL for EXPR, which is an EXPR_STMT. */
303
304 void 
305 genrtl_expr_stmt (expr)
306      tree expr;
307 {
308   if (expr != NULL_TREE)
309     {
310       emit_line_note (input_filename, lineno);
311       
312       if (stmts_are_full_exprs_p ())
313         expand_start_target_temps ();
314       
315       lang_expand_expr_stmt (expr);
316       
317       if (stmts_are_full_exprs_p ())
318         expand_end_target_temps ();
319     }
320 }
321
322 /* Generate the RTL for T, which is a DECL_STMT. */
323
324 void
325 genrtl_decl_stmt (t)
326      tree t;
327 {
328   tree decl;
329   emit_line_note (input_filename, lineno);
330   decl = DECL_STMT_DECL (t);
331   /* If this is a declaration for an automatic local
332      variable, initialize it.  Note that we might also see a
333      declaration for a namespace-scope object (declared with
334      `extern').  We don't have to handle the initialization
335      of those objects here; they can only be declarations,
336      rather than definitions.  */
337   if (TREE_CODE (decl) == VAR_DECL 
338       && !TREE_STATIC (decl)
339       && !DECL_EXTERNAL (decl))
340     {
341       /* Let the back-end know about this variable.  */
342       if (!anon_aggr_type_p (TREE_TYPE (decl)))
343         emit_local_var (decl);
344       else
345         expand_anon_union_decl (decl, NULL_TREE, 
346                                 DECL_ANON_UNION_ELEMS (decl));
347     }
348   else if (TREE_CODE (decl) == VAR_DECL && TREE_STATIC (decl))
349     {
350       if (DECL_ARTIFICIAL (decl) && ! TREE_USED (decl))
351         /* Do not emit unused decls. This is not just an
352            optimization. We really do not want to emit
353            __PRETTY_FUNCTION__ etc, if they're never used.  */
354         DECL_IGNORED_P (decl) = 1;
355       else
356         make_rtl_for_local_static (decl);
357     }
358 }
359
360 /* Generate the RTL for T, which is an IF_STMT. */
361
362 void
363 genrtl_if_stmt (t)
364      tree t;
365 {
366   tree cond;
367   genrtl_do_pushlevel ();
368   cond = expand_cond (IF_COND (t));
369   emit_line_note (input_filename, lineno);
370   expand_start_cond (cond, 0);
371   if (THEN_CLAUSE (t))
372     expand_stmt (THEN_CLAUSE (t));
373   if (ELSE_CLAUSE (t))
374     {
375       expand_start_else ();
376       expand_stmt (ELSE_CLAUSE (t));
377     }
378   expand_end_cond ();
379 }
380
381 /* Generate the RTL for T, which is a WHILE_STMT. */
382
383 void
384 genrtl_while_stmt (t)
385      tree t;
386 {
387   tree cond;
388   emit_nop ();
389   emit_line_note (input_filename, lineno);
390   expand_start_loop (1); 
391   genrtl_do_pushlevel ();
392
393   cond = expand_cond (WHILE_COND (t));
394   emit_line_note (input_filename, lineno);
395   expand_exit_loop_if_false (0, cond);
396   genrtl_clear_out_block ();
397   
398   expand_stmt (WHILE_BODY (t));
399
400   expand_end_loop ();
401 }
402
403 /* Generate the RTL for T, which is a DO_STMT. */
404
405 void
406 genrtl_do_stmt (t)
407      tree t;
408 {
409   tree cond;
410   emit_nop ();
411   emit_line_note (input_filename, lineno);
412   expand_start_loop_continue_elsewhere (1);
413
414   expand_stmt (DO_BODY (t));
415
416   expand_loop_continue_here ();
417
418   cond = expand_cond (DO_COND (t));
419   emit_line_note (input_filename, lineno);
420   expand_exit_loop_if_false (0, cond);
421   expand_end_loop ();
422 }
423
424 /* Build the node for a return statement and return it. */
425
426 tree
427 build_return_stmt (expr)
428      tree expr;
429 {
430   return (build_stmt (RETURN_STMT, expr));
431 }
432
433 /* Generate the RTL for EXPR, which is a RETURN_STMT. */
434
435 void
436 genrtl_return_stmt (expr)
437      tree expr;
438 {
439   emit_line_note (input_filename, lineno);
440   c_expand_return (expr);
441 }
442
443 /* Generate the RTL for T, which is a FOR_STMT. */
444
445 void
446 genrtl_for_stmt (t)
447      tree t;
448 {
449   tree tmp;
450   tree cond;
451   if (NEW_FOR_SCOPE_P (t))
452     genrtl_do_pushlevel ();
453
454   expand_stmt (FOR_INIT_STMT (t));
455
456   emit_nop ();
457   emit_line_note (input_filename, lineno);
458   expand_start_loop_continue_elsewhere (1); 
459   genrtl_do_pushlevel ();
460   cond = expand_cond (FOR_COND (t));
461   emit_line_note (input_filename, lineno);
462   if (cond)
463     expand_exit_loop_if_false (0, cond);
464   genrtl_clear_out_block ();
465   tmp = FOR_EXPR (t);
466
467   expand_stmt (FOR_BODY (t));
468
469   emit_line_note (input_filename, lineno);
470   expand_loop_continue_here ();
471   if (tmp) 
472     genrtl_expr_stmt (tmp);
473   expand_end_loop ();
474 }
475
476 /* Build a break statement node and return it. */
477
478 tree
479 build_break_stmt ()
480 {
481   return (build_stmt (BREAK_STMT));
482 }
483
484 /* Generate the RTL for a BREAK_STMT. */
485
486 void
487 genrtl_break_stmt ()
488 {
489   emit_line_note (input_filename, lineno);
490   if ( ! expand_exit_something ())
491     error ("break statement not within loop or switch");
492 }
493
494 /* Build a continue statement node and return it. */
495
496 tree
497 build_continue_stmt ()
498 {
499   return (build_stmt (CONTINUE_STMT));
500 }
501
502 /* Generate the RTL for a CONTINUE_STMT. */
503
504 void
505 genrtl_continue_stmt ()
506 {
507   emit_line_note (input_filename, lineno);
508   if (! expand_continue_loop (0))
509     error ("continue statement not within a loop");   
510 }
511
512 /* Generate the RTL for T, which is a SCOPE_STMT. */
513
514 void
515 genrtl_scope_stmt (t)
516      tree t;
517 {
518   if (!SCOPE_NO_CLEANUPS_P (t))
519     {
520       if (SCOPE_BEGIN_P (t))
521         expand_start_bindings_and_block (2 * SCOPE_NULLIFIED_P (t),
522                                          SCOPE_STMT_BLOCK (t));
523       else if (SCOPE_END_P (t))
524         expand_end_bindings (NULL_TREE, !SCOPE_NULLIFIED_P (t), 0);
525     }
526   else if (!SCOPE_NULLIFIED_P (t))
527     {
528       rtx note = emit_note (NULL,
529                             (SCOPE_BEGIN_P (t) 
530                              ? NOTE_INSN_BLOCK_BEG
531                              : NOTE_INSN_BLOCK_END));
532       NOTE_BLOCK (note) = SCOPE_STMT_BLOCK (t);
533     }
534 }
535
536 /* Generate the RTL for T, which is a SWITCH_STMT. */
537
538 void
539 genrtl_switch_stmt (t)
540      tree t;
541 {
542   tree cond;
543   genrtl_do_pushlevel ();
544  
545   cond = expand_cond (SWITCH_COND (t));
546   if (cond != error_mark_node)
547     {
548       emit_line_note (input_filename, lineno);
549       c_expand_start_case (cond);
550     }
551   else
552     /* The code is in error, but we don't want expand_end_case to
553        crash. */
554     c_expand_start_case (boolean_false_node);
555
556   expand_stmt (SWITCH_BODY (t));
557
558   expand_end_case (cond);
559 }
560
561 /* Create a CASE_LABEL tree node and return it. */
562
563 tree
564 build_case_label (low_value, high_value)
565      tree low_value;
566      tree high_value;
567 {
568   return build_stmt (CASE_LABEL, low_value, high_value);
569 }
570
571
572 /* Generate the RTL for a CASE_LABEL. */
573
574 void 
575 genrtl_case_label (low_value, high_value)
576      tree low_value;
577      tree high_value;
578 {
579   do_case (low_value, high_value);
580 }
581
582 /* Generate the RTL for T, which is a COMPOUND_STMT. */
583
584 void
585 genrtl_compound_stmt (t)
586     tree t;
587 {
588   /* If this is the outermost block of the function, declare the
589      variables __FUNCTION__, __PRETTY_FUNCTION__, and so forth.  */
590   if (cfun
591       && !current_function_name_declared () 
592       && !COMPOUND_STMT_NO_SCOPE (t))
593     {
594       set_current_function_name_declared (1);
595       declare_function_name ();
596     } 
597
598   expand_stmt (COMPOUND_BODY (t));
599 }
600
601 /* Generate the RTL for an ASM_STMT. */
602
603 void
604 genrtl_asm_stmt (cv_qualifier, string, output_operands,
605                  input_operands, clobbers)
606      tree cv_qualifier;
607      tree string;
608      tree output_operands;
609      tree input_operands;
610      tree clobbers;
611 {
612   if (TREE_CHAIN (string))
613     string = combine_strings (string);
614
615   if (cv_qualifier != NULL_TREE
616       && cv_qualifier != ridpointers[(int) RID_VOLATILE])
617     {
618       warning ("%s qualifier ignored on asm",
619                IDENTIFIER_POINTER (cv_qualifier));
620       cv_qualifier = NULL_TREE;
621     }
622
623   emit_line_note (input_filename, lineno);
624   if (output_operands != NULL_TREE || input_operands != NULL_TREE
625       || clobbers != NULL_TREE)
626       c_expand_asm_operands (string, output_operands,
627                              input_operands, 
628                              clobbers,
629                              cv_qualifier != NULL_TREE,
630                              input_filename, lineno);
631   else
632     expand_asm (string);
633 }
634
635 /* Generate the RTL for a DECL_CLEANUP. */
636
637 void 
638 genrtl_decl_cleanup (decl, cleanup)
639      tree decl;
640      tree cleanup;
641 {
642   if (!decl || (DECL_SIZE (decl) && TREE_TYPE (decl) != error_mark_node))
643     expand_decl_cleanup (decl, cleanup);
644 }
645
646 /* Generate the RTL for the statement T, its substatements, and any
647    other statements at its nesting level. */
648
649 tree
650 expand_stmt (t)
651      tree t;
652 {
653   tree rval;
654   rval = lang_expand_stmt (t);
655   return rval;
656 }
657