OSDN Git Service

2003-06-10 Andrew Haley <aph@redhat.com>
[pf3gnuchains/gcc-fork.git] / gcc / c-semantics.c
index 19ea48e..374e9f1 100644 (file)
@@ -56,6 +56,7 @@ static tree find_reachable_label_1    PARAMS ((tree *, int *, void *));
 static tree find_reachable_label       PARAMS ((tree));
 static bool expand_unreachable_if_stmt PARAMS ((tree));
 static tree expand_unreachable_stmt    PARAMS ((tree, int));
+static void genrtl_do_stmt_1           PARAMS ((tree, tree));
 
 /* Create an empty statement tree rooted at T.  */
 
@@ -193,14 +194,14 @@ finish_stmt_tree (t)
    in the grammar.  */
 
 tree
-build_stmt VPARAMS ((enum tree_code code, ...))
+build_stmt (enum tree_code code, ...)
 {
   tree t;
   int length;
   int i;
-
-  VA_OPEN (p, code);
-  VA_FIXEDARG (p, enum tree_code, code);
+  va_list p;
+  
+  va_start (p, code);
 
   t = make_node (code);
   length = TREE_CODE_LENGTH (code);
@@ -209,7 +210,7 @@ build_stmt VPARAMS ((enum tree_code code, ...))
   for (i = 0; i < length; i++)
     TREE_OPERAND (t, i) = va_arg (p, tree);
 
-  VA_CLOSE (p);
+  va_end (p);
   return t;
 }
 
@@ -286,14 +287,17 @@ emit_local_var (decl)
        expand_decl (decl);
     }
 
-  /* Actually do the initialization.  */
-  if (stmts_are_full_exprs_p ())
-    expand_start_target_temps ();
+  if (DECL_INITIAL (decl))
+    {
+      /* Actually do the initialization.  */
+      if (stmts_are_full_exprs_p ())
+       expand_start_target_temps ();
 
-  expand_decl_init (decl);
+      expand_decl_init (decl);
 
-  if (stmts_are_full_exprs_p ())
-    expand_end_target_temps ();
+      if (stmts_are_full_exprs_p ())
+       expand_end_target_temps ();
+    }
 }
 
 /* Helper for generating the RTL at the beginning of a scope.  */
@@ -416,19 +420,20 @@ genrtl_if_stmt (t)
   expand_start_cond (cond, 0);
   if (THEN_CLAUSE (t))
     {
+      tree nextt = THEN_CLAUSE (t);
+      
       if (cond && integer_zerop (cond))
-       expand_unreachable_stmt (THEN_CLAUSE (t), warn_notreached);
-      else
-       expand_stmt (THEN_CLAUSE (t));
+       nextt = expand_unreachable_stmt (nextt, warn_notreached);
+      expand_stmt (nextt);
     }
 
   if (ELSE_CLAUSE (t))
     {
+      tree nextt = ELSE_CLAUSE (t);
       expand_start_else ();
       if (cond && integer_nonzerop (cond))
-       expand_unreachable_stmt (ELSE_CLAUSE (t), warn_notreached);
-      else
-       expand_stmt (ELSE_CLAUSE (t));
+       nextt = expand_unreachable_stmt (nextt, warn_notreached);
+      expand_stmt (nextt);
     }
   expand_end_cond ();
 }
@@ -459,14 +464,13 @@ genrtl_while_stmt (t)
   expand_end_loop ();
 }
 
-/* Generate the RTL for T, which is a DO_STMT.  */
+/* Generate the RTL for a DO_STMT with condition COND and loop BODY
+   body.  This is reused for expanding unreachable WHILE_STMTS.  */
 
-void
-genrtl_do_stmt (t)
-     tree t;
+static void
+genrtl_do_stmt_1 (cond, body)
+     tree cond, body;
 {
-  tree cond = DO_COND (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
@@ -475,7 +479,7 @@ genrtl_do_stmt (t)
   if (!cond || integer_zerop (cond))
     {
       expand_start_null_loop ();
-      expand_stmt (DO_BODY (t));
+      expand_stmt (body);
       expand_end_null_loop ();
     }
   else if (integer_nonzerop (cond))
@@ -484,7 +488,7 @@ genrtl_do_stmt (t)
       emit_line_note (input_filename, input_line);
       expand_start_loop (1);
 
-      expand_stmt (DO_BODY (t));
+      expand_stmt (body);
 
       emit_line_note (input_filename, input_line);
       expand_end_loop ();
@@ -495,7 +499,7 @@ genrtl_do_stmt (t)
       emit_line_note (input_filename, input_line);
       expand_start_loop_continue_elsewhere (1);
 
-      expand_stmt (DO_BODY (t));
+      expand_stmt (body);
 
       expand_loop_continue_here ();
       cond = expand_cond (cond);
@@ -505,6 +509,15 @@ genrtl_do_stmt (t)
     }
 }
 
+/* Generate the RTL for T, which is a DO_STMT.  */
+
+void
+genrtl_do_stmt (t)
+     tree t;
+{
+  genrtl_do_stmt_1 (DO_COND (t), DO_BODY (t));
+}
+
 /* Build the node for a return statement and return it.  */
 
 tree
@@ -542,8 +555,7 @@ genrtl_for_stmt (t)
      tree t;
 {
   tree cond = FOR_COND (t);
-  const char *saved_filename;
-  int saved_lineno;
+  location_t saved_loc;
 
   if (NEW_FOR_SCOPE_P (t))
     genrtl_do_pushlevel ();
@@ -561,8 +573,7 @@ genrtl_for_stmt (t)
 
   /* Save the filename and line number so that we expand the FOR_EXPR
      we can reset them back to the saved values.  */
-  saved_filename = input_filename;
-  saved_lineno = input_line;
+  saved_loc = input_location;
 
   /* Expand the condition.  */
   if (cond && !integer_nonzerop (cond))
@@ -577,8 +588,7 @@ genrtl_for_stmt (t)
   expand_stmt (FOR_BODY (t));
 
   /* Expand the increment expression.  */
-  input_filename = saved_filename;
-  input_line = saved_lineno;
+  input_location = saved_loc;
   emit_line_note (input_filename, input_line);
   if (FOR_EXPR (t))
     {
@@ -687,7 +697,7 @@ genrtl_switch_stmt (t)
 
   emit_line_note (input_filename, input_line);
   expand_start_case (1, cond, TREE_TYPE (cond), "switch statement");
-  expand_unreachable_stmt (SWITCH_BODY (t), warn_notreached);
+  expand_stmt (expand_unreachable_stmt (SWITCH_BODY (t), warn_notreached));
   expand_end_case_type (cond, SWITCH_TYPE (t));
 }
 
@@ -951,11 +961,9 @@ static tree
 find_reachable_label (exp)
      tree exp;
 {
-  int line = input_line;
-  const char *file = input_filename;
+  location_t saved_loc = input_location;
   tree ret = walk_tree (&exp, find_reachable_label_1, NULL, NULL);
-  input_filename = file;
-  input_line = line;
+  input_location = saved_loc;
   return ret;
 }
 
@@ -1060,6 +1068,13 @@ expand_unreachable_stmt (t, warn)
            return TREE_CHAIN (t);
          break;
 
+       case WHILE_STMT:
+         /* If the start of a while statement is unreachable, there is
+            no need to rotate the loop, instead the WHILE_STMT can be
+            expanded like a DO_STMT.  */
+         genrtl_do_stmt_1 (WHILE_COND (t), WHILE_BODY (t));
+         return TREE_CHAIN (t);
+
        case COMPOUND_STMT:
          {
            tree n;