X-Git-Url: http://git.sourceforge.jp/view?a=blobdiff_plain;f=gcc%2Fc-semantics.c;h=3d8759d8584cdf4237a6d297bae0b3300b9a53ed;hb=42a92fdfbb75052c8de3922957f3fa9a4a089051;hp=13480480a4337e757f9d80a55d56da94eaad18c5;hpb=65b7f83fcb833ccbead60bbb1533884ad0898486;p=pf3gnuchains%2Fgcc-fork.git diff --git a/gcc/c-semantics.c b/gcc/c-semantics.c index 13480480a43..3d8759d8584 100644 --- a/gcc/c-semantics.c +++ b/gcc/c-semantics.c @@ -1,25 +1,25 @@ /* This file contains the definitions and documentation for the common tree codes used in the GNU C and C++ compilers (see c-common.def for the standard codes). - Copyright (C) 2000, 2001 Free Software Foundation, Inc. + Copyright (C) 2000, 2001, 2002 Free Software Foundation, Inc. Written by Benjamin Chelf (chelf@codesourcery.com). -This file is part of GNU CC. +This file is part of GCC. -GNU CC is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 2, or (at your option) -any later version. +GCC is free software; you can redistribute it and/or modify it under +the terms of the GNU General Public License as published by the Free +Software Foundation; either version 2, or (at your option) any later +version. -GNU CC is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. +GCC is distributed in the hope that it will be useful, but WITHOUT ANY +WARRANTY; without even the implied warranty of MERCHANTABILITY or +FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +for more details. You should have received a copy of the GNU General Public License -along with GNU CC; see the file COPYING. If not, write to -the Free Software Foundation, 59 Temple Place - Suite 330, -Boston, MA 02111-1307, USA. */ +along with GCC; see the file COPYING. If not, write to the Free +Software Foundation, 59 Temple Place - Suite 330, Boston, MA +02111-1307, USA. */ #include "config.h" #include "system.h" @@ -60,6 +60,7 @@ begin_stmt_tree (t) *t = build_nt (EXPR_STMT, void_zero_node); last_tree = *t; last_expr_type = NULL_TREE; + last_expr_filename = input_filename; } /* T is a statement. Add it to the statement-tree. */ @@ -68,6 +69,19 @@ tree add_stmt (t) tree t; { + if (input_filename != last_expr_filename) + { + /* If the filename has changed, also add in a FILE_STMT. Do a string + compare first, though, as it might be an equivalent string. */ + int add = (strcmp (input_filename, last_expr_filename) != 0); + last_expr_filename = input_filename; + if (add) + { + tree pos = build_nt (FILE_STMT, get_identifier (input_filename)); + add_stmt (pos); + } + } + /* Add T to the statement-tree. */ TREE_CHAIN (last_tree) = t; last_tree = t; @@ -112,8 +126,9 @@ add_scope_stmt (begin_p, partial_p) int begin_p; int partial_p; { + tree *stack_ptr = current_scope_stmt_stack (); tree ss; - tree top; + tree top = *stack_ptr; /* Build the statement. */ ss = build_stmt (SCOPE_STMT, NULL_TREE); @@ -123,15 +138,13 @@ add_scope_stmt (begin_p, partial_p) /* Keep the scope stack up to date. */ if (begin_p) { - *current_scope_stmt_stack () - = tree_cons (ss, NULL_TREE, *current_scope_stmt_stack ()); - top = *current_scope_stmt_stack (); + top = tree_cons (ss, NULL_TREE, top); + *stack_ptr = top; } else { - top = *current_scope_stmt_stack (); TREE_VALUE (top) = ss; - *current_scope_stmt_stack () = TREE_CHAIN (top); + *stack_ptr = TREE_CHAIN (top); } /* Add the new statement to the statement-tree. */ @@ -171,19 +184,12 @@ finish_stmt_tree (t) tree build_stmt VPARAMS ((enum tree_code code, ...)) { -#ifndef ANSI_PROTOTYPES - enum tree_code code; -#endif - va_list p; - register tree t; - register int length; - register int i; - - VA_START (p, code); + tree t; + int length; + int i; -#ifndef ANSI_PROTOTYPES - code = va_arg (p, enum tree_code); -#endif + VA_OPEN (p, code); + VA_FIXEDARG (p, enum tree_code, code); t = make_node (code); length = TREE_CODE_LENGTH (code); @@ -192,7 +198,7 @@ build_stmt VPARAMS ((enum tree_code code, ...)) for (i = 0; i < length; i++) TREE_OPERAND (t, i) = va_arg (p, tree); - va_end (p); + VA_CLOSE (p); return t; } @@ -244,7 +250,7 @@ make_rtl_for_local_static (decl) already create RTL, which means that the modification to DECL_ASSEMBLER_NAME came only via the explicit extension. */ if (DECL_ASSEMBLER_NAME (decl) != DECL_NAME (decl) - && !DECL_RTL (decl)) + && !DECL_RTL_SET_P (decl)) asmspec = IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (decl)); rest_of_decl_compilation (decl, asmspec, /*top_level=*/0, /*at_end=*/0); @@ -279,7 +285,7 @@ emit_local_var (decl) expand_end_target_temps (); } -/* Helper for generating the RTL at the beginning of a scope. */ +/* Helper for generating the RTL at the beginning of a scope. */ void genrtl_do_pushlevel () @@ -288,7 +294,7 @@ genrtl_do_pushlevel () clear_last_expr (); } -/* Generate the RTL for DESTINATION, which is a GOTO_STMT. */ +/* Generate the RTL for DESTINATION, which is a GOTO_STMT. */ void genrtl_goto_stmt (destination) @@ -313,12 +319,29 @@ genrtl_goto_stmt (destination) expand_computed_goto (destination); } -/* Generate the RTL for EXPR, which is an EXPR_STMT. */ +/* Generate the RTL for EXPR, which is an EXPR_STMT. Provided just + for backward compatibility. genrtl_expr_stmt_value() should be + used for new code. */ -void +void genrtl_expr_stmt (expr) tree expr; { + genrtl_expr_stmt_value (expr, -1, 1); +} + +/* Generate the RTL for EXPR, which is an EXPR_STMT. WANT_VALUE tells + whether to (1) save the value of the expression, (0) discard it or + (-1) use expr_stmts_for_value to tell. The use of -1 is + deprecated, and retained only for backward compatibility. + MAYBE_LAST is non-zero if this EXPR_STMT might be the last statement + in expression statement. */ + +void +genrtl_expr_stmt_value (expr, want_value, maybe_last) + tree expr; + int want_value, maybe_last; +{ if (expr != NULL_TREE) { emit_line_note (input_filename, lineno); @@ -327,14 +350,14 @@ genrtl_expr_stmt (expr) expand_start_target_temps (); if (expr != error_mark_node) - expand_expr_stmt (expr); + expand_expr_stmt_value (expr, want_value, maybe_last); if (stmts_are_full_exprs_p ()) expand_end_target_temps (); } } -/* Generate the RTL for T, which is a DECL_STMT. */ +/* Generate the RTL for T, which is a DECL_STMT. */ void genrtl_decl_stmt (t) @@ -369,7 +392,7 @@ genrtl_decl_stmt (t) (*lang_expand_decl_stmt) (t); } -/* Generate the RTL for T, which is an IF_STMT. */ +/* Generate the RTL for T, which is an IF_STMT. */ void genrtl_if_stmt (t) @@ -390,7 +413,7 @@ genrtl_if_stmt (t) expand_end_cond (); } -/* Generate the RTL for T, which is a WHILE_STMT. */ +/* Generate the RTL for T, which is a WHILE_STMT. */ void genrtl_while_stmt (t) @@ -404,7 +427,7 @@ genrtl_while_stmt (t) cond = expand_cond (WHILE_COND (t)); emit_line_note (input_filename, lineno); - expand_exit_loop_if_false (0, cond); + expand_exit_loop_top_cond (0, cond); genrtl_do_pushlevel (); expand_stmt (WHILE_BODY (t)); @@ -412,7 +435,7 @@ genrtl_while_stmt (t) expand_end_loop (); } -/* Generate the RTL for T, which is a DO_STMT. */ +/* Generate the RTL for T, which is a DO_STMT. */ void genrtl_do_stmt (t) @@ -446,7 +469,7 @@ genrtl_do_stmt (t) } } -/* Build the node for a return statement and return it. */ +/* Build the node for a return statement and return it. */ tree build_return_stmt (expr) @@ -455,13 +478,15 @@ build_return_stmt (expr) return (build_stmt (RETURN_STMT, expr)); } -/* Generate the RTL for STMT, which is a RETURN_STMT. */ +/* Generate the RTL for STMT, which is a RETURN_STMT. */ void genrtl_return_stmt (stmt) tree stmt; { - tree expr = RETURN_EXPR (stmt); + tree expr; + + expr = RETURN_EXPR (stmt); emit_line_note (input_filename, lineno); if (!expr) @@ -474,7 +499,7 @@ genrtl_return_stmt (stmt) } } -/* Generate the RTL for T, which is a FOR_STMT. */ +/* Generate the RTL for T, which is a FOR_STMT. */ void genrtl_for_stmt (t) @@ -504,7 +529,7 @@ genrtl_for_stmt (t) /* Expand the condition. */ emit_line_note (input_filename, lineno); if (cond) - expand_exit_loop_if_false (0, cond); + expand_exit_loop_top_cond (0, cond); /* Expand the body. */ genrtl_do_pushlevel (); @@ -520,7 +545,7 @@ genrtl_for_stmt (t) expand_end_loop (); } -/* Build a break statement node and return it. */ +/* Build a break statement node and return it. */ tree build_break_stmt () @@ -528,7 +553,7 @@ build_break_stmt () return (build_stmt (BREAK_STMT)); } -/* Generate the RTL for a BREAK_STMT. */ +/* Generate the RTL for a BREAK_STMT. */ void genrtl_break_stmt () @@ -538,7 +563,7 @@ genrtl_break_stmt () error ("break statement not within loop or switch"); } -/* Build a continue statement node and return it. */ +/* Build a continue statement node and return it. */ tree build_continue_stmt () @@ -546,7 +571,7 @@ build_continue_stmt () return (build_stmt (CONTINUE_STMT)); } -/* Generate the RTL for a CONTINUE_STMT. */ +/* Generate the RTL for a CONTINUE_STMT. */ void genrtl_continue_stmt () @@ -556,17 +581,18 @@ genrtl_continue_stmt () error ("continue statement not within a loop"); } -/* Generate the RTL for T, which is a SCOPE_STMT. */ +/* Generate the RTL for T, which is a SCOPE_STMT. */ void genrtl_scope_stmt (t) tree t; { + tree block = SCOPE_STMT_BLOCK (t); + if (!SCOPE_NO_CLEANUPS_P (t)) { if (SCOPE_BEGIN_P (t)) - expand_start_bindings_and_block (2 * SCOPE_NULLIFIED_P (t), - SCOPE_STMT_BLOCK (t)); + expand_start_bindings_and_block (2 * SCOPE_NULLIFIED_P (t), block); else if (SCOPE_END_P (t)) expand_end_bindings (NULL_TREE, !SCOPE_NULLIFIED_P (t), 0); } @@ -576,11 +602,31 @@ genrtl_scope_stmt (t) (SCOPE_BEGIN_P (t) ? NOTE_INSN_BLOCK_BEG : NOTE_INSN_BLOCK_END)); - NOTE_BLOCK (note) = SCOPE_STMT_BLOCK (t); + NOTE_BLOCK (note) = block; + } + + /* If we're at the end of a scope that contains inlined nested + functions, we have to decide whether or not to write them out. */ + if (block && SCOPE_END_P (t)) + { + tree fn; + + for (fn = BLOCK_VARS (block); fn; fn = TREE_CHAIN (fn)) + { + if (TREE_CODE (fn) == FUNCTION_DECL + && DECL_CONTEXT (fn) == current_function_decl + && !TREE_ASM_WRITTEN (fn) + && TREE_ADDRESSABLE (fn)) + { + push_function_context (); + output_inline_function (fn); + pop_function_context (); + } + } } } -/* Generate the RTL for T, which is a SWITCH_STMT. */ +/* Generate the RTL for T, which is a SWITCH_STMT. */ void genrtl_switch_stmt (t) @@ -592,16 +638,16 @@ genrtl_switch_stmt (t) cond = expand_cond (SWITCH_COND (t)); if (cond == error_mark_node) /* The code is in error, but we don't want expand_end_case to - crash. */ + crash. */ cond = boolean_false_node; emit_line_note (input_filename, lineno); expand_start_case (1, cond, TREE_TYPE (cond), "switch statement"); expand_stmt (SWITCH_BODY (t)); - expand_end_case (cond); + expand_end_case_type (cond, SWITCH_TYPE (t)); } -/* Create a CASE_LABEL tree node and return it. */ +/* Create a CASE_LABEL tree node and return it. */ tree build_case_label (low_value, high_value, label_decl) @@ -613,7 +659,7 @@ build_case_label (low_value, high_value, label_decl) } -/* Generate the RTL for a CASE_LABEL. */ +/* Generate the RTL for a CASE_LABEL. */ void genrtl_case_label (case_label) @@ -640,16 +686,26 @@ genrtl_case_label (case_label) CASE_LABEL_DECL (case_label), &duplicate); } -/* Generate the RTL for T, which is a COMPOUND_STMT. */ +/* Generate the RTL for T, which is a COMPOUND_STMT. */ void genrtl_compound_stmt (t) tree t; { +#ifdef ENABLE_CHECKING + struct nesting *n = current_nesting_level (); +#endif + expand_stmt (COMPOUND_BODY (t)); + +#ifdef ENABLE_CHECKING + /* Make sure that we've pushed and popped the same number of levels. */ + if (!COMPOUND_STMT_NO_SCOPE (t) && n != current_nesting_level ()) + abort (); +#endif } -/* Generate the RTL for an ASM_STMT. */ +/* Generate the RTL for an ASM_STMT. */ void genrtl_asm_stmt (cv_qualifier, string, output_operands, @@ -678,7 +734,7 @@ genrtl_asm_stmt (cv_qualifier, string, output_operands, input_filename, lineno); } -/* Generate the RTL for a DECL_CLEANUP. */ +/* Generate the RTL for a DECL_CLEANUP. */ void genrtl_decl_cleanup (decl, cleanup) @@ -702,7 +758,7 @@ prep_stmt (t) } /* Generate the RTL for the statement T, its substatements, and any - other statements at its nesting level. */ + other statements at its nesting level. */ void expand_stmt (t) @@ -718,12 +774,19 @@ expand_stmt (t) switch (TREE_CODE (t)) { + case FILE_STMT: + input_filename = FILE_STMT_FILENAME (t); + break; + case RETURN_STMT: genrtl_return_stmt (t); break; case EXPR_STMT: - genrtl_expr_stmt (EXPR_STMT_EXPR (t)); + genrtl_expr_stmt_value (EXPR_STMT_EXPR (t), TREE_ADDRESSABLE (t), + TREE_CHAIN (t) == NULL + || (TREE_CODE (TREE_CHAIN (t)) == SCOPE_STMT + && TREE_CHAIN (TREE_CHAIN (t)) == NULL)); break; case DECL_STMT: @@ -784,6 +847,10 @@ expand_stmt (t) genrtl_scope_stmt (t); break; + case CLEANUP_STMT: + genrtl_decl_cleanup (CLEANUP_DECL (t), CLEANUP_EXPR (t)); + break; + default: if (lang_expand_stmt) (*lang_expand_stmt) (t); @@ -800,4 +867,3 @@ expand_stmt (t) t = TREE_CHAIN (t); } } -