/* 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"
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);
for (i = 0; i < length; i++)
TREE_OPERAND (t, i) = va_arg (p, tree);
- va_end (p);
+ VA_CLOSE (p);
return t;
}
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);
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 ()
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)
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);
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)
(*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)
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)
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)
}
}
-/* 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)
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)
}
}
-/* 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)
expand_end_loop ();
}
-/* Build a break statement node and return it. */
+/* Build a break statement node and return it. */
tree
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 ()
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 ()
return (build_stmt (CONTINUE_STMT));
}
-/* Generate the RTL for a CONTINUE_STMT. */
+/* Generate the RTL for a CONTINUE_STMT. */
void
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)
}
}
-/* 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)
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_end_case (cond);
}
-/* 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)
}
-/* Generate the RTL for a CASE_LABEL. */
+/* Generate the RTL for a CASE_LABEL. */
void
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 (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,
input_filename, lineno);
}
-/* Generate the RTL for a DECL_CLEANUP. */
+/* Generate the RTL for a DECL_CLEANUP. */
void
genrtl_decl_cleanup (decl, cleanup)
}
/* 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)
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: