summaryrefslogtreecommitdiff
path: root/gcc/cp/pt.c
diff options
context:
space:
mode:
Diffstat (limited to 'gcc/cp/pt.c')
-rw-r--r--gcc/cp/pt.c91
1 files changed, 45 insertions, 46 deletions
diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c
index ff96eaa83c7..c93184aa0c7 100644
--- a/gcc/cp/pt.c
+++ b/gcc/cp/pt.c
@@ -42,6 +42,7 @@ Boston, MA 02111-1307, USA. */
#include "toplev.h"
#include "rtl.h"
#include "timevar.h"
+#include "tree-iterator.h"
/* The type of functions taking a tree, and some additional data, and
returning an int. */
@@ -7615,22 +7616,6 @@ tsubst_copy (tree t, tree args, tsubst_flags_t complain, tree in_decl)
in_decl),
NULL_TREE);
- case STMT_EXPR:
- /* This processing should really occur in tsubst_expr. However,
- tsubst_expr does not recurse into expressions, since it
- assumes that there aren't any statements inside them. So, we
- need to expand the STMT_EXPR here. */
- if (!processing_template_decl)
- {
- tree stmt_expr = begin_stmt_expr ();
-
- tsubst_expr (STMT_EXPR_STMT (t), args,
- complain | tf_stmt_expr_cmpd, in_decl);
- return finish_stmt_expr (stmt_expr, false);
- }
-
- return t;
-
case COND_EXPR:
case MODOP_EXPR:
case PSEUDO_DTOR_EXPR:
@@ -7752,20 +7737,26 @@ tsubst_copy (tree t, tree args, tsubst_flags_t complain, tree in_decl)
static tree
tsubst_expr (tree t, tree args, tsubst_flags_t complain, tree in_decl)
{
+ /* Live only within one (recursive) call to tsubst_expr. We use
+ this to pass the statement expression node from the STMT_EXPR
+ to the EXPR_STMT that is its result. */
+ static tree cur_stmt_expr;
+
tree stmt, tmp;
- tsubst_flags_t stmt_expr
- = complain & (tf_stmt_expr_cmpd | tf_stmt_expr_body);
- complain ^= stmt_expr;
if (t == NULL_TREE || t == error_mark_node)
return t;
- if (!STATEMENT_CODE_P (TREE_CODE (t)))
- return tsubst_copy_and_build (t, args, complain, in_decl,
- /*function_p=*/false);
-
switch (TREE_CODE (t))
{
+ case STATEMENT_LIST:
+ {
+ tree_stmt_iterator i;
+ for (i = tsi_start (t); !tsi_end_p (i); tsi_next (&i))
+ tsubst_expr (tsi_stmt (i), args, complain, in_decl);
+ break;
+ }
+
case CTOR_INITIALIZER:
prep_stmt (t);
finish_mem_initializers (tsubst_initializer_list
@@ -7778,6 +7769,19 @@ tsubst_expr (tree t, tree args, tsubst_flags_t complain, tree in_decl)
args, complain, in_decl));
break;
+ case STMT_EXPR:
+ {
+ tree old_stmt_expr = cur_stmt_expr;
+ tree stmt_expr = begin_stmt_expr ();
+
+ cur_stmt_expr = stmt_expr;
+ tsubst_expr (STMT_EXPR_STMT (t), args, complain, in_decl);
+ stmt_expr = finish_stmt_expr (stmt_expr, false);
+ cur_stmt_expr = old_stmt_expr;
+
+ return stmt_expr;
+ }
+
case EXPR_STMT:
{
tree r;
@@ -7785,8 +7789,8 @@ tsubst_expr (tree t, tree args, tsubst_flags_t complain, tree in_decl)
prep_stmt (t);
r = tsubst_expr (EXPR_STMT_EXPR (t), args, complain, in_decl);
- if (stmt_expr & tf_stmt_expr_body && !TREE_CHAIN (t))
- finish_stmt_expr_expr (r);
+ if (EXPR_STMT_STMT_EXPR_RESULT (t))
+ finish_stmt_expr_expr (r, cur_stmt_expr);
else
finish_expr_stmt (r);
break;
@@ -7861,12 +7865,9 @@ tsubst_expr (tree t, tree args, tsubst_flags_t complain, tree in_decl)
}
/* A DECL_STMT can also be used as an expression, in the condition
- clause of an if/for/while construct. If we aren't followed by
- another statement, return our decl. */
- if (TREE_CHAIN (t) == NULL_TREE)
- return decl;
+ clause of an if/for/while construct. */
+ return decl;
}
- break;
case FOR_STMT:
{
@@ -7916,21 +7917,17 @@ tsubst_expr (tree t, tree args, tsubst_flags_t complain, tree in_decl)
finish_if_stmt_cond (tsubst_expr (IF_COND (t),
args, complain, in_decl),
stmt);
+ tsubst_expr (THEN_CLAUSE (t), args, complain, in_decl);
+ finish_then_clause (stmt);
- if (tmp = THEN_CLAUSE (t), tmp)
- {
- tsubst_expr (tmp, args, complain, in_decl);
- finish_then_clause (stmt);
- }
-
- if (tmp = ELSE_CLAUSE (t), tmp)
+ if (ELSE_CLAUSE (t))
{
- begin_else_clause ();
- tsubst_expr (tmp, args, complain, in_decl);
+ begin_else_clause (stmt);
+ tsubst_expr (ELSE_CLAUSE (t), args, complain, in_decl);
finish_else_clause (stmt);
}
- finish_if_stmt ();
+ finish_if_stmt (stmt);
}
break;
@@ -7940,11 +7937,10 @@ tsubst_expr (tree t, tree args, tsubst_flags_t complain, tree in_decl)
if (COMPOUND_STMT_BODY_BLOCK (t))
stmt = begin_function_body ();
else
- stmt = begin_compound_stmt (COMPOUND_STMT_NO_SCOPE (t));
+ stmt = begin_compound_stmt (COMPOUND_STMT_TRY_BLOCK (t)
+ ? BCS_TRY_BLOCK : 0);
- tsubst_expr (COMPOUND_BODY (t), args,
- complain | ((stmt_expr & tf_stmt_expr_cmpd) << 1),
- in_decl);
+ tsubst_expr (COMPOUND_BODY (t), args, complain, in_decl);
if (COMPOUND_STMT_BODY_BLOCK (t))
finish_function_body (stmt);
@@ -8053,7 +8049,7 @@ tsubst_expr (tree t, tree args, tsubst_flags_t complain, tree in_decl)
stmt = begin_handler ();
if (HANDLER_PARMS (t))
{
- decl = DECL_STMT_DECL (HANDLER_PARMS (t));
+ decl = HANDLER_PARMS (t);
decl = tsubst (decl, args, complain, in_decl);
/* Prevent instantiate_decl from trying to instantiate
this variable. We've already done all that needs to be
@@ -8074,10 +8070,13 @@ tsubst_expr (tree t, tree args, tsubst_flags_t complain, tree in_decl)
break;
default:
+ if (!STATEMENT_CODE_P (TREE_CODE (t)))
+ return tsubst_copy_and_build (t, args, complain, in_decl,
+ /*function_p=*/false);
abort ();
}
- return tsubst_expr (TREE_CHAIN (t), args, complain | stmt_expr, in_decl);
+ return NULL_TREE;
}
/* T is a postfix-expression that is not being used in a function