OSDN Git Service

* config/i386/i386.c (override_options): Define c3-2 as a 686 with SSE.
[pf3gnuchains/gcc-fork.git] / gcc / c-semantics.c
index c0bbc51..e19e73e 100644 (file)
@@ -1,7 +1,7 @@
 /* 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, 2002 Free Software Foundation, Inc.
+   Copyright (C) 2000, 2001, 2002, 2003 Free Software Foundation, Inc.
    Written by Benjamin Chelf (chelf@codesourcery.com).
 
 This file is part of GCC.
@@ -23,6 +23,8 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
 
 #include "config.h"
 #include "system.h"
+#include "coretypes.h"
+#include "tm.h"
 #include "tree.h"
 #include "function.h"
 #include "splay-tree.h"
@@ -36,6 +38,7 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
 #include "expr.h"
 #include "output.h"
 #include "timevar.h"
+#include "predict.h"
 
 /* If non-NULL, the address of a language-specific function for
    expanding statements.  */
@@ -143,6 +146,8 @@ add_scope_stmt (begin_p, partial_p)
     }
   else
     {
+      if (partial_p != SCOPE_PARTIAL_P (TREE_PURPOSE (top)))
+       abort ();
       TREE_VALUE (top) = ss;
       *stack_ptr = TREE_CHAIN (top);
     }
@@ -334,7 +339,7 @@ genrtl_expr_stmt (expr)
    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
+   MAYBE_LAST is nonzero if this EXPR_STMT might be the last statement
    in expression statement.  */
 
 void 
@@ -419,16 +424,20 @@ void
 genrtl_while_stmt (t)
      tree t;
 {
-  tree cond;
+  tree cond = WHILE_COND (t);
+
   emit_nop ();
   emit_line_note (input_filename, lineno);
   expand_start_loop (1); 
   genrtl_do_pushlevel ();
 
-  cond = expand_cond (WHILE_COND (t));
-  emit_line_note (input_filename, lineno);
-  expand_exit_loop_top_cond (0, cond);
-  genrtl_do_pushlevel ();
+  if (cond && !integer_nonzerop (cond))
+    {
+      cond = expand_cond (cond);
+      emit_line_note (input_filename, lineno);
+      expand_exit_loop_top_cond (0, cond);
+      genrtl_do_pushlevel ();
+    }
   
   expand_stmt (WHILE_BODY (t));
 
@@ -446,13 +455,25 @@ genrtl_do_stmt (t)
   /* Recognize the common special-case of do { ... } while (0) and do
      not emit the loop widgetry in this case.  In particular this
      avoids cluttering the rtl with dummy loop notes, which can affect
-     alignment of adjacent labels.  */
-  if (integer_zerop (cond))
+     alignment of adjacent labels.  COND can be NULL due to parse
+     errors.  */
+  if (!cond || integer_zerop (cond))
     {
       expand_start_null_loop ();
       expand_stmt (DO_BODY (t));
       expand_end_null_loop ();
     }
+  else if (integer_nonzerop (cond))
+    {
+      emit_nop ();
+      emit_line_note (input_filename, lineno);
+      expand_start_loop (1);
+
+      expand_stmt (DO_BODY (t));
+
+      emit_line_note (input_filename, lineno);
+      expand_end_loop ();
+    }
   else
     {
       emit_nop ();
@@ -486,7 +507,7 @@ genrtl_return_stmt (stmt)
 {
   tree expr;
 
-  expr = RETURN_EXPR (stmt);
+  expr = RETURN_STMT_EXPR (stmt);
 
   emit_line_note (input_filename, lineno);
   if (!expr)
@@ -505,7 +526,7 @@ void
 genrtl_for_stmt (t)
      tree t;
 {
-  tree cond;
+  tree cond = FOR_COND (t);
   const char *saved_filename;
   int saved_lineno;
 
@@ -517,9 +538,11 @@ genrtl_for_stmt (t)
   /* Expand the initialization.  */
   emit_nop ();
   emit_line_note (input_filename, lineno);
-  expand_start_loop_continue_elsewhere (1); 
+  if (FOR_EXPR (t))
+    expand_start_loop_continue_elsewhere (1); 
+  else
+    expand_start_loop (1);
   genrtl_do_pushlevel ();
-  cond = expand_cond (FOR_COND (t));
 
   /* Save the filename and line number so that we expand the FOR_EXPR
      we can reset them back to the saved values.  */
@@ -527,21 +550,26 @@ genrtl_for_stmt (t)
   saved_lineno = lineno;
 
   /* Expand the condition.  */
-  emit_line_note (input_filename, lineno);
-  if (cond)
-    expand_exit_loop_top_cond (0, cond);
+  if (cond && !integer_nonzerop (cond))
+    {
+      cond = expand_cond (cond);
+      emit_line_note (input_filename, lineno);
+      expand_exit_loop_top_cond (0, cond);
+      genrtl_do_pushlevel ();
+    }
 
   /* Expand the body.  */
-  genrtl_do_pushlevel ();
   expand_stmt (FOR_BODY (t));
 
   /* Expand the increment expression.  */
   input_filename = saved_filename;
   lineno = saved_lineno;
   emit_line_note (input_filename, lineno);
-  expand_loop_continue_here ();
   if (FOR_EXPR (t))
-    genrtl_expr_stmt (FOR_EXPR (t));
+    {
+      expand_loop_continue_here ();
+      genrtl_expr_stmt (FOR_EXPR (t));
+    }
   expand_end_loop ();
 }
 
@@ -615,6 +643,7 @@ genrtl_scope_stmt (t)
        {
          if (TREE_CODE (fn) == FUNCTION_DECL 
              && DECL_CONTEXT (fn) == current_function_decl
+             && DECL_SAVED_INSNS (fn)
              && !TREE_ASM_WRITTEN (fn)
              && TREE_ADDRESSABLE (fn))
            {
@@ -644,7 +673,7 @@ genrtl_switch_stmt (t)
   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.  */
@@ -672,8 +701,7 @@ genrtl_case_label (case_label)
   if (cleanup)
     {
       static int explained = 0;
-      warning_with_decl (TREE_PURPOSE (cleanup), 
-                        "destructor needed for `%#D'");
+      warning ("destructor needed for `%#D'", (TREE_PURPOSE (cleanup)));
       warning ("where case label appears here");
       if (!explained)
        {
@@ -727,7 +755,7 @@ genrtl_asm_stmt (cv_qualifier, string, output_operands,
 
   emit_line_note (input_filename, lineno);
   if (asm_input_p)
-    expand_asm (string);
+    expand_asm (string, cv_qualifier != NULL_TREE);
   else
     c_expand_asm_operands (string, output_operands, input_operands, 
                           clobbers, cv_qualifier != NULL_TREE,
@@ -737,12 +765,12 @@ genrtl_asm_stmt (cv_qualifier, string, output_operands,
 /* Generate the RTL for a DECL_CLEANUP.  */
 
 void 
-genrtl_decl_cleanup (decl, cleanup)
-     tree decl;
-     tree cleanup;
+genrtl_decl_cleanup (t)
+     tree t;
 {
+  tree decl = CLEANUP_DECL (t);
   if (!decl || (DECL_SIZE (decl) && TREE_TYPE (decl) != error_mark_node))
-    expand_decl_cleanup (decl, cleanup);
+    expand_decl_cleanup_eh (decl, CLEANUP_EXPR (t), CLEANUP_EH_ONLY (t));
 }
 
 /* We're about to expand T, a statement.  Set up appropriate context
@@ -834,6 +862,14 @@ expand_stmt (t)
          break;
 
        case GOTO_STMT:
+         /* Emit information for branch prediction.  */
+         if (!GOTO_FAKE_P (t)
+             && TREE_CODE (GOTO_DESTINATION (t)) == LABEL_DECL)
+           {
+             rtx note = emit_note (NULL, NOTE_INSN_PREDICTION);
+
+             NOTE_PREDICTION (note) = NOTE_PREDICT (PRED_GOTO, NOT_TAKEN);
+           }
          genrtl_goto_stmt (GOTO_DESTINATION (t));
          break;
 
@@ -847,6 +883,10 @@ expand_stmt (t)
          genrtl_scope_stmt (t);
          break;
 
+       case CLEANUP_STMT:
+         genrtl_decl_cleanup (t);
+         break;
+
        default:
          if (lang_expand_stmt)
            (*lang_expand_stmt) (t);