OSDN Git Service

* cp-tree.h (begin_switch_stmt): Adjust prototype.
authormmitchel <mmitchel@138bc75d-0d04-0410-961f-82ee72b054a4>
Thu, 9 Sep 1999 22:28:15 +0000 (22:28 +0000)
committermmitchel <mmitchel@138bc75d-0d04-0410-961f-82ee72b054a4>
Thu, 9 Sep 1999 22:28:15 +0000 (22:28 +0000)
(finish_switch_cond): Likewise.
* parse.y (simple_stmt): Adjust accordingly.
* parse.c: Regenerated.
* pt.c (tsubst_expr): Adjust accordingly.
* semantics.c (expand_cond): New function.
(FINISH_COND): New macro.
(begin_switch_stmt): Build the SWITCH_STMT here.
(finish_switch_stmt_cond): Not here.
(expand_stmt): Adjust calls to begin_switch_stmt and
finish_switch_cond.  Use expand_cond throughout.

git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@29246 138bc75d-0d04-0410-961f-82ee72b054a4

gcc/cp/ChangeLog
gcc/cp/cp-tree.h
gcc/cp/parse.c
gcc/cp/parse.y
gcc/cp/pt.c
gcc/cp/semantics.c
gcc/testsuite/g++.old-deja/g++.pt/switch1.C [new file with mode: 0644]

index 399a3d4..49c585d 100644 (file)
@@ -1,5 +1,17 @@
 1999-09-09  Mark Mitchell  <mark@codesourcery.com>
 
+       * cp-tree.h (begin_switch_stmt): Adjust prototype.
+       (finish_switch_cond): Likewise.
+       * parse.y (simple_stmt): Adjust accordingly.
+       * parse.c: Regenerated.
+       * pt.c (tsubst_expr): Adjust accordingly.
+       * semantics.c (expand_cond): New function.
+       (FINISH_COND): New macro.
+       (begin_switch_stmt): Build the SWITCH_STMT here.
+       (finish_switch_stmt_cond): Not here.
+       (expand_stmt): Adjust calls to begin_switch_stmt and
+       finish_switch_cond.  Use expand_cond throughout.
+
        * dump.c (dequeue_and_dump): Dump types for constants.
        Describe DECL_ARG_TYPE more intuitively.
        Handle ARRAY_REF.
index 04f26c2..c8fc430 100644 (file)
@@ -3572,8 +3572,8 @@ extern void finish_for_expr                     PROTO((tree, tree));
 extern void finish_for_stmt                     PROTO((tree, tree));
 extern void finish_break_stmt                   PROTO((void));
 extern void finish_continue_stmt                PROTO((void));
-extern void begin_switch_stmt                   PROTO((void));
-extern tree finish_switch_cond                  PROTO((tree));
+extern tree begin_switch_stmt                   PROTO((void));
+extern void finish_switch_cond                  PROTO((tree, tree));
 extern void finish_switch_stmt                  PROTO((tree, tree));
 extern void finish_case_label                   PROTO((tree, tree));
 extern void finish_goto_stmt                    PROTO((tree));
index 0283e62..76c762a 100644 (file)
@@ -7623,11 +7623,11 @@ case 738:
     break;}
 case 739:
 #line 3277 "parse.y"
-{ begin_switch_stmt (); ;
+{ yyval.ttype = begin_switch_stmt (); ;
     break;}
 case 740:
 #line 3279 "parse.y"
-{ yyval.ttype = finish_switch_cond (yyvsp[-1].ttype); ;
+{ finish_switch_cond (yyvsp[-1].ttype, yyvsp[-3].ttype); ;
     break;}
 case 741:
 #line 3281 "parse.y"
index 76b8830..1b1c8b5 100644 (file)
@@ -3274,9 +3274,9 @@ simple_stmt:
          already_scoped_stmt
                 { finish_for_stmt ($9, $<ttype>2); }
        | SWITCH 
-                { begin_switch_stmt (); }
+                { $<ttype>$ = begin_switch_stmt (); }
            '(' condition ')'
-                { $<ttype>$ = finish_switch_cond ($4); }
+                { finish_switch_cond ($4, $<ttype>2); }
          implicitly_scoped_stmt
                 { finish_switch_stmt ($4, $<ttype>6); }
        | CASE expr_no_commas ':'
index feb7f76..0795a19 100644 (file)
@@ -7392,9 +7392,9 @@ tsubst_expr (t, args, complain, in_decl)
        tree val;
 
        lineno = STMT_LINENO (t);
-       begin_switch_stmt ();
+       stmt = begin_switch_stmt ();
        val = tsubst_expr (SWITCH_COND (t), args, complain, in_decl);
-       stmt = finish_switch_cond (val);
+       finish_switch_cond (val, stmt);
        tsubst_expr (SWITCH_BODY (t), args, complain, in_decl);
        finish_switch_stmt (val, stmt);
       }
index 38eab3b..4d6a234 100644 (file)
@@ -44,6 +44,7 @@
 static void expand_stmts PROTO((tree));
 static void do_pushlevel PROTO((void));
 static tree do_poplevel PROTO((void));
+static tree expand_cond PROTO((tree));
 
 /* When parsing a template, LAST_TREE contains the last statement
    parsed.  These are chained together through the TREE_CHAIN field,
@@ -64,6 +65,16 @@ static tree do_poplevel PROTO((void));
 #define RECHAIN_STMTS_FROM_CHAIN(stmt, substmt)        \
   RECHAIN_STMTS (stmt, substmt, TREE_CHAIN (stmt))
 
+/* Finish processing the COND, the SUBSTMT condition for STMT.  */
+
+#define FINISH_COND(cond, stmt, substmt)       \
+  do {                                         \
+    if (last_tree != stmt)                     \
+      RECHAIN_STMTS_FROM_LAST (stmt, substmt); \
+    else                                       \
+      substmt = cond;                          \
+  } while (0)
+  
 /* Finish an expression-statement, whose EXPRESSION is as indicated.  */
 
 void 
@@ -492,49 +503,51 @@ finish_continue_stmt ()
     cp_error ("continue statement not within a loop");   
 }
 
-/* Begin a switch-statement.  */
+/* Begin a switch-statement.  Returns a new SWITCH_STMT if
+   appropriate.  */
 
-void
+tree
 begin_switch_stmt ()
 {
+  tree r;
+
+  if (building_stmt_tree ())
+    {
+      r = build_min_nt (SWITCH_STMT, NULL_TREE, NULL_TREE);
+      add_tree (r);
+    }
+  else
+    r = NULL_TREE;
+
   do_pushlevel ();
+
+  return r;
 }
 
-/* Finish the cond of a switch-statement.  Returns a new
-   SWITCH_STMT if appropriate.  */ 
+/* Finish the cond of a switch-statement.  */
 
-tree
-finish_switch_cond (cond)
+void
+finish_switch_cond (cond, switch_stmt)
      tree cond;
+     tree switch_stmt;
 {
-  tree r;
-
   if (building_stmt_tree ())
-    {
-      r = build_min_nt (SWITCH_STMT, cond, NULL_TREE);
-      add_tree (r);
-    }
+    FINISH_COND (cond, switch_stmt, SWITCH_COND (switch_stmt));
   else if (cond != error_mark_node)
     {
       emit_line_note (input_filename, lineno);
       c_expand_start_case (cond);
-      r = NULL_TREE;
     }
   else
-    {
-      /* The code is in error, but we don't want expand_end_case to
-         crash. */
-      c_expand_start_case (boolean_false_node);
-      r = NULL_TREE;
-    }
+    /* The code is in error, but we don't want expand_end_case to
+       crash. */
+    c_expand_start_case (boolean_false_node);
 
   push_switch ();
 
   /* Don't let the tree nodes for COND be discarded by
      clear_momentary during the parsing of the next stmt.  */
   push_momentary ();
-
-  return r;
 }
 
 /* Finish the body of a switch-statement, which may be given by
@@ -1963,6 +1976,24 @@ finish_stmt_tree (fn)
   DECL_SAVED_TREE (fn) = TREE_CHAIN (DECL_SAVED_TREE (fn));
 }
 
+/* Some statements, like for-statements or if-statements, require a
+   condition.  This condition can be a declaration.  If T is such a
+   declaration it is processed, and an expression appropriate to use
+   as the condition is returned.  Otherwise, T itself is returned.  */
+
+static tree
+expand_cond (t)
+     tree t;
+{
+  if (t && TREE_CODE (t) == DECL_STMT)
+    {
+      expand_stmt (t);
+      return convert_from_reference (DECL_STMT_DECL (t));
+    }
+  else 
+    return t;
+}
+
 /* Generate RTL for the chain of statements T.  */
 
 static void 
@@ -2038,7 +2069,7 @@ expand_stmt (t)
        for (tmp = FOR_INIT_STMT (t); tmp; tmp = TREE_CHAIN (tmp))
          expand_stmt (tmp);
        finish_for_init_stmt (NULL_TREE);
-       finish_for_cond (FOR_COND (t), NULL_TREE);
+       finish_for_cond (expand_cond (FOR_COND (t)), NULL_TREE);
        tmp = FOR_EXPR (t);
        finish_for_expr (tmp, NULL_TREE);
        expand_stmt (FOR_BODY (t));
@@ -2050,7 +2081,7 @@ expand_stmt (t)
       {
        lineno = STMT_LINENO (t);
        begin_while_stmt ();
-       finish_while_stmt_cond (WHILE_COND (t), NULL_TREE);
+       finish_while_stmt_cond (expand_cond (WHILE_COND (t)), NULL_TREE);
        expand_stmt (WHILE_BODY (t));
        finish_while_stmt (NULL_TREE);
       }
@@ -2069,7 +2100,7 @@ expand_stmt (t)
     case IF_STMT:
       lineno = STMT_LINENO (t);
       begin_if_stmt ();
-      finish_if_stmt_cond (IF_COND (t), NULL_TREE);
+      finish_if_stmt_cond (expand_cond (IF_COND (t)), NULL_TREE);
       if (THEN_CLAUSE (t))
        {
          expand_stmt (THEN_CLAUSE (t));
@@ -2102,12 +2133,16 @@ expand_stmt (t)
       break;
 
     case SWITCH_STMT:
-      lineno = STMT_LINENO (t);
-      begin_switch_stmt ();
-      finish_switch_cond (SWITCH_COND (t));
-      if (TREE_OPERAND (t, 1))
+      {
+       tree cond;
+
+       lineno = STMT_LINENO (t);
+       begin_switch_stmt ();
+       cond = expand_cond (SWITCH_COND (t));
+       finish_switch_cond (cond, NULL_TREE);
        expand_stmt (SWITCH_BODY (t));
-      finish_switch_stmt (SWITCH_COND (t), NULL_TREE);
+       finish_switch_stmt (cond, NULL_TREE);
+      }
       break;
 
     case CASE_LABEL:
diff --git a/gcc/testsuite/g++.old-deja/g++.pt/switch1.C b/gcc/testsuite/g++.old-deja/g++.pt/switch1.C
new file mode 100644 (file)
index 0000000..51d2de1
--- /dev/null
@@ -0,0 +1,15 @@
+// Build don't link:
+// Origin: Mark Mitchell <mark@codesourcery.com>
+
+template <class T>
+void f ()
+{
+  int i;
+  
+  switch (int i = 3) {
+  }
+}
+
+template void f<int>();
+
+