From 581d68632972ebc470ed2b3d635cf2b7f486616e Mon Sep 17 00:00:00 2001 From: mmitchel Date: Thu, 9 Sep 1999 22:28:15 +0000 Subject: [PATCH] * 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. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@29246 138bc75d-0d04-0410-961f-82ee72b054a4 --- gcc/cp/ChangeLog | 12 ++++ gcc/cp/cp-tree.h | 4 +- gcc/cp/parse.c | 4 +- gcc/cp/parse.y | 4 +- gcc/cp/pt.c | 4 +- gcc/cp/semantics.c | 93 ++++++++++++++++++++--------- gcc/testsuite/g++.old-deja/g++.pt/switch1.C | 15 +++++ 7 files changed, 99 insertions(+), 37 deletions(-) create mode 100644 gcc/testsuite/g++.old-deja/g++.pt/switch1.C diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index 399a3d4f71c..49c585ddac9 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,5 +1,17 @@ 1999-09-09 Mark Mitchell + * 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 04f26c243f2..c8fc430a714 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 0283e62a9e1..76c762a2421 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 76b883002b5..1b1c8b557e2 100644 --- a/gcc/cp/parse.y +++ b/gcc/cp/parse.y @@ -3274,9 +3274,9 @@ simple_stmt: already_scoped_stmt { finish_for_stmt ($9, $2); } | SWITCH - { begin_switch_stmt (); } + { $$ = begin_switch_stmt (); } '(' condition ')' - { $$ = finish_switch_cond ($4); } + { finish_switch_cond ($4, $2); } implicitly_scoped_stmt { finish_switch_stmt ($4, $6); } | CASE expr_no_commas ':' diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c index feb7f768072..0795a191f1e 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 38eab3b3197..4d6a234f238 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 00000000000..51d2de14bdd --- /dev/null +++ b/gcc/testsuite/g++.old-deja/g++.pt/switch1.C @@ -0,0 +1,15 @@ +// Build don't link: +// Origin: Mark Mitchell + +template +void f () +{ + int i; + + switch (int i = 3) { + } +} + +template void f(); + + -- 2.11.4.GIT