aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorMark Mitchell <mark@codesourcery.com>1999-09-09 22:28:15 +0000
committerMark Mitchell <mmitchel@gcc.gnu.org>1999-09-09 22:28:15 +0000
commit527f0080b0407487c0ed478b63989e443b112144 (patch)
tree5eb83d783c84045000af919d00bfe42328a92153 /gcc
parent8a79e5cb72647db7aacbb5d1eae29162ccee8549 (diff)
downloadgcc-527f0080b0407487c0ed478b63989e443b112144.zip
gcc-527f0080b0407487c0ed478b63989e443b112144.tar.gz
gcc-527f0080b0407487c0ed478b63989e443b112144.tar.bz2
cp-tree.h (begin_switch_stmt): Adjust prototype.
* 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. From-SVN: r29246
Diffstat (limited to 'gcc')
-rw-r--r--gcc/cp/ChangeLog12
-rw-r--r--gcc/cp/cp-tree.h4
-rw-r--r--gcc/cp/parse.c4
-rw-r--r--gcc/cp/parse.y4
-rw-r--r--gcc/cp/pt.c4
-rw-r--r--gcc/cp/semantics.c93
-rw-r--r--gcc/testsuite/g++.old-deja/g++.pt/switch1.C15
7 files changed, 99 insertions, 37 deletions
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog
index 399a3d4..49c585d 100644
--- a/gcc/cp/ChangeLog
+++ b/gcc/cp/ChangeLog
@@ -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.
diff --git a/gcc/cp/cp-tree.h b/gcc/cp/cp-tree.h
index 04f26c2..c8fc430 100644
--- a/gcc/cp/cp-tree.h
+++ b/gcc/cp/cp-tree.h
@@ -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));
diff --git a/gcc/cp/parse.c b/gcc/cp/parse.c
index 0283e62..76c762a 100644
--- a/gcc/cp/parse.c
+++ b/gcc/cp/parse.c
@@ -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"
diff --git a/gcc/cp/parse.y b/gcc/cp/parse.y
index 76b8830..1b1c8b5 100644
--- a/gcc/cp/parse.y
+++ b/gcc/cp/parse.y
@@ -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 ':'
diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c
index feb7f76..0795a19 100644
--- a/gcc/cp/pt.c
+++ b/gcc/cp/pt.c
@@ -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);
}
diff --git a/gcc/cp/semantics.c b/gcc/cp/semantics.c
index 38eab3b..4d6a234 100644
--- a/gcc/cp/semantics.c
+++ b/gcc/cp/semantics.c
@@ -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
index 0000000..51d2de1
--- /dev/null
+++ b/gcc/testsuite/g++.old-deja/g++.pt/switch1.C
@@ -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>();
+
+