From 6f80451c66dcc194baf195462734046e0b06934e Mon Sep 17 00:00:00 2001 From: Mark Mitchell Date: Sun, 3 Oct 1999 18:57:37 +0000 Subject: [PATCH] cp-tree.def (VEC_INIT_EXPR): Remove. * cp-tree.def (VEC_INIT_EXPR): Remove. * cp-tree.h (struct stmt_tree): New type. (struct saved_scope): Remove firstobj. Add x_saved_tree, x_stmt_tree. (class_cache_firstobj): Remove. (struct language_function): Remove stmts_are_full_exprs_p, x_last_tree, and x_last_expr_type. Add x_stmt_tree. (current_stmt_tree): New macro. (last_tree): Adjust. (last_expr_type): Likewise. (doing_semantic_analysis_p): Simplify. (stmts_are_full_exprs_p): Adjust. (begin_tree): Remove prototype. (end_tree): Likewise. (begin_stmt_tree): Change prototype. (finish_stmt_tree): Likewise. (building_stmt_tree): Simplify. * decl.c (mark_stmt_tree): New function. (mark_saved_scope): Use it. (start_function): Rearrange slightly to call begin_stmt_tree earlier. (save_function_data): Tweak. (finish_function): Adjust call to finish_stmt_tree. (mark_lang_function): Use mark_stmt_tree. * expr.c (cplus_expand_expr): Don't handle VEC_INIT_EXPR. * init.c (build_new_1): Remove creation of VEC_INIT_EXPR. (build_vec_init): Remove creation of stand-in intializer. * pt.c (begin_tree): Remove. (end_tree): Likewise. * semantics.c (SET_LAST_STMT): New macro. Use it throughout. (begin_compound_stmt): Handle a compound-statement outside of a function. (begin_stmt_expr): Handle a statement-expression outsidef of a function. (finish_stmt_expr): Likewise. (begin_class_definition): Don't call begin_tree. (finish_inline_definitions): Don't call end_tree. (begin_stmt_tree): Take a pointer to tree, not a function as input. (finish_stmt_tree): Likewise. * tree.c (search_tree): Don't handle VEC_INIT_EXPR. (mapcar): Likewise. * parse.y (simple_stmt): Don't call finish_stmt unnecessarily. * parse.c: Regenerated. * dump.c (dqueue_and_dump): Dump bitfieldness. From-SVN: r29786 --- gcc/cp/ChangeLog | 47 ++++ gcc/cp/cp-tree.def | 5 - gcc/cp/cp-tree.h | 48 ++-- gcc/cp/decl.c | 30 ++- gcc/cp/dump.c | 6 +- gcc/cp/expr.c | 8 - gcc/cp/init.c | 14 +- gcc/cp/parse.c | 241 +++++++++--------- gcc/cp/parse.y | 4 +- gcc/cp/pt.c | 23 -- gcc/cp/semantics.c | 70 +++-- gcc/cp/tree.c | 2 - .../g++.old-deja/g++.ext/stmtexpr1.C | 8 + 13 files changed, 272 insertions(+), 234 deletions(-) create mode 100644 gcc/testsuite/g++.old-deja/g++.ext/stmtexpr1.C diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index ffe4cd265dc..982c00d5e4b 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,5 +1,52 @@ 1999-10-03 Mark Mitchell + * cp-tree.def (VEC_INIT_EXPR): Remove. + * cp-tree.h (struct stmt_tree): New type. + (struct saved_scope): Remove firstobj. Add x_saved_tree, + x_stmt_tree. + (class_cache_firstobj): Remove. + (struct language_function): Remove stmts_are_full_exprs_p, + x_last_tree, and x_last_expr_type. Add x_stmt_tree. + (current_stmt_tree): New macro. + (last_tree): Adjust. + (last_expr_type): Likewise. + (doing_semantic_analysis_p): Simplify. + (stmts_are_full_exprs_p): Adjust. + (begin_tree): Remove prototype. + (end_tree): Likewise. + (begin_stmt_tree): Change prototype. + (finish_stmt_tree): Likewise. + (building_stmt_tree): Simplify. + * decl.c (mark_stmt_tree): New function. + (mark_saved_scope): Use it. + (start_function): Rearrange slightly to call begin_stmt_tree + earlier. + (save_function_data): Tweak. + (finish_function): Adjust call to finish_stmt_tree. + (mark_lang_function): Use mark_stmt_tree. + * expr.c (cplus_expand_expr): Don't handle VEC_INIT_EXPR. + * init.c (build_new_1): Remove creation of VEC_INIT_EXPR. + (build_vec_init): Remove creation of stand-in intializer. + * pt.c (begin_tree): Remove. + (end_tree): Likewise. + * semantics.c (SET_LAST_STMT): New macro. Use it throughout. + (begin_compound_stmt): Handle a compound-statement outside of a + function. + (begin_stmt_expr): Handle a statement-expression outsidef of a + function. + (finish_stmt_expr): Likewise. + (begin_class_definition): Don't call begin_tree. + (finish_inline_definitions): Don't call end_tree. + (begin_stmt_tree): Take a pointer to tree, not a function as input. + (finish_stmt_tree): Likewise. + * tree.c (search_tree): Don't handle VEC_INIT_EXPR. + (mapcar): Likewise. + + * parse.y (simple_stmt): Don't call finish_stmt unnecessarily. + * parse.c: Regenerated. + + * dump.c (dqueue_and_dump): Dump bitfieldness. + * tree.c (lvalue_p_1): Use DECL_C_BIT_FIELD to check for bitfields, rather than DECL_BIT_FIELD. * ir.texi: Document how to tell whether or not a field is a diff --git a/gcc/cp/cp-tree.def b/gcc/cp/cp-tree.def index c96ee36283a..372ad77593d 100644 --- a/gcc/cp/cp-tree.def +++ b/gcc/cp/cp-tree.def @@ -70,11 +70,6 @@ DEFTREECODE (AGGR_INIT_EXPR, "aggr_init_expr", 'e', 3) else it is NULL_TREE. */ DEFTREECODE (THROW_EXPR, "throw_expr", 'e', 1) -/* Initialization of a vector, used in build_new. Operand 0 is the target - of the initialization, operand 1 is the initializer, and operand 2 is - the number of elements. */ -DEFTREECODE (VEC_INIT_EXPR, "vec_init_expr", 'e', 3) - /* Template definition. The following fields have the specified uses, although there are other macros in cp-tree.h that should be used for accessing this data. diff --git a/gcc/cp/cp-tree.h b/gcc/cp/cp-tree.h index c5886fc30b4..f1134afff63 100644 --- a/gcc/cp/cp-tree.h +++ b/gcc/cp/cp-tree.h @@ -566,6 +566,12 @@ extern tree cp_global_trees[CPTI_MAX]; /* Global state. */ +struct stmt_tree { + tree x_last_stmt; + tree x_last_expr_type; + int stmts_are_full_exprs_p; +}; + struct saved_scope { tree old_bindings; tree old_namespace; @@ -580,13 +586,14 @@ struct saved_scope { tree template_parms; tree x_previous_class_type; tree x_previous_class_values; + tree x_saved_tree; HOST_WIDE_INT x_processing_template_decl; int x_processing_specialization; int x_processing_explicit_instantiation; int need_pop_function_context; - char *firstobj; + struct stmt_tree x_stmt_tree; struct binding_level *class_bindings; struct binding_level *bindings; @@ -640,10 +647,6 @@ struct saved_scope { #define previous_class_values scope_chain->x_previous_class_values -/* The low-water mark on the class-cache obstack. */ - -#define class_cache_firstobj scope_chain->firstobj - extern struct saved_scope *scope_chain; /* Global state pertinent to the current function. */ @@ -657,8 +660,6 @@ struct language_function tree x_member_init_list; tree x_current_class_ptr; tree x_current_class_ref; - tree x_last_tree; - tree x_last_expr_type; tree x_eh_spec_try_block; tree x_scope_stmt_stack; tree x_in_charge_parm; @@ -676,10 +677,11 @@ struct language_function int static_labelno; int in_function_try_handler; int x_expanding_p; - int stmts_are_full_exprs_p; int name_declared; int vtbls_set_up_p; + struct stmt_tree x_stmt_tree; + struct named_label_list *x_named_label_uses; struct binding_level *bindings; @@ -722,16 +724,23 @@ struct language_function #define current_class_ref \ (current_function ? cp_function_chain->x_current_class_ref : NULL_TREE) -/* When building a statement-tree, this is the last node added to the - tree. */ +/* Information about the current statement tree. */ -#define last_tree cp_function_chain->x_last_tree +#define current_stmt_tree \ + (current_function \ + ? &cp_function_chain->x_stmt_tree \ + : &scope_chain->x_stmt_tree) + +/* When building a statement-tree, this is the last statement added to + the tree. */ + +#define last_tree current_stmt_tree->x_last_stmt /* The type of the last expression-statement we have seen. This is required because the type of a statement-expression is the type of the last expression statement. */ -#define last_expr_type cp_function_chain->x_last_expr_type +#define last_expr_type current_stmt_tree->x_last_expr_type /* The TRY_BLOCK for the exception-specifiers for the current function, if any. */ @@ -796,8 +805,7 @@ struct language_function /* Non-zero if we are in the semantic analysis phase for the current function. */ -#define doing_semantic_analysis_p() \ - (!expanding_p || !current_function->x_whole_function_mode_p) +#define doing_semantic_analysis_p() (!expanding_p) /* Non-zero if we should treat statements as full expressions. In particular, this variable is no-zero if at the end of a statement @@ -811,7 +819,8 @@ struct language_function within the statement expression should not result in cleanups being run until the entire enclosing statement is complete. */ -#define stmts_are_full_exprs_p cp_function_chain->stmts_are_full_exprs_p +#define stmts_are_full_exprs_p \ + current_stmt_tree->stmts_are_full_exprs_p #define in_function_try_handler cp_function_chain->in_function_try_handler @@ -3719,8 +3728,6 @@ extern void do_type_instantiation PROTO((tree, tree)); extern tree instantiate_decl PROTO((tree)); extern tree get_bindings PROTO((tree, tree, tree)); extern void add_tree PROTO((tree)); -extern void begin_tree PROTO((void)); -extern void end_tree PROTO((void)); extern void add_maybe_template PROTO((tree, tree)); extern void pop_tinst_level PROTO((void)); extern int more_specialized_class PROTO((tree, tree)); @@ -3879,15 +3886,14 @@ extern void finish_decl_cleanup PROTO((tree, tree)); extern void finish_named_return_value PROTO((tree, tree)); extern tree expand_stmt PROTO((tree)); extern void expand_body PROTO((tree)); -extern void begin_stmt_tree PROTO((tree)); -extern void finish_stmt_tree PROTO((tree)); +extern void begin_stmt_tree PROTO((tree *)); +extern void finish_stmt_tree PROTO((tree *)); extern void prep_stmt PROTO((tree)); extern void do_pushlevel PROTO((void)); extern tree do_poplevel PROTO((void)); /* Non-zero if we are presently building a statement tree, rather than expanding each statement as we encounter it. */ -#define building_stmt_tree() \ - (current_function && (processing_template_decl || !expanding_p)) +#define building_stmt_tree() (last_tree != NULL_TREE) /* in spew.c */ extern void init_spew PROTO((void)); diff --git a/gcc/cp/decl.c b/gcc/cp/decl.c index 00043d67b91..9c51069c4d0 100644 --- a/gcc/cp/decl.c +++ b/gcc/cp/decl.c @@ -168,6 +168,7 @@ static void mark_binding_level PROTO((void *)); static void mark_cp_function_context PROTO((struct function *)); static void mark_saved_scope PROTO((void *)); static void mark_lang_function PROTO((struct language_function *)); +static void mark_stmt_tree PROTO((struct stmt_tree *)); static void save_function_data PROTO((tree)); static void check_function_type PROTO((tree)); static void destroy_local_static PROTO((tree)); @@ -2271,6 +2272,16 @@ pop_nested_namespace (ns) scope isn't enough, because more binding levels may be pushed. */ struct saved_scope *scope_chain; +/* Mark ST for GC. */ + +static void +mark_stmt_tree (st) + struct stmt_tree *st; +{ + ggc_mark_tree (st->x_last_stmt); + ggc_mark_tree (st->x_last_expr_type); +} + /* Mark ARG (which is really a struct saved_scope **) for GC. */ static void @@ -2294,6 +2305,9 @@ mark_saved_scope (arg) ggc_mark_tree (t->template_parms); ggc_mark_tree (t->x_previous_class_type); ggc_mark_tree (t->x_previous_class_values); + ggc_mark_tree (t->x_saved_tree); + + mark_stmt_tree (&t->x_stmt_tree); mark_binding_level (&t->bindings); t = t->prev; } @@ -12890,6 +12904,10 @@ start_function (declspecs, declarator, attrs, flags) immediate_size_expand = 0; current_function->x_dont_save_pending_sizes_p = 1; + /* If we're building a statement-tree, start the tree now. */ + if (processing_template_decl || !expanding_p) + begin_stmt_tree (&DECL_SAVED_TREE (decl1)); + /* Let the user know we're compiling this function. */ if (processing_template_decl || !building_stmt_tree ()) announce_function (decl1); @@ -13071,9 +13089,6 @@ start_function (declspecs, declarator, attrs, flags) function body. */ push_momentary (); - if (building_stmt_tree ()) - begin_stmt_tree (decl1); - ++function_depth; if (DESTRUCTOR_NAME_P (DECL_ASSEMBLER_NAME (decl1)) @@ -13289,8 +13304,8 @@ save_function_data (decl) /* Clear out the bits we don't need. */ f->x_base_init_list = NULL_TREE; f->x_member_init_list = NULL_TREE; - f->x_last_tree = NULL_TREE; - f->x_last_expr_type = NULL_TREE; + f->x_stmt_tree.x_last_stmt = NULL_TREE; + f->x_stmt_tree.x_last_expr_type = NULL_TREE; f->x_last_dtor_insn = NULL_RTX; f->x_last_parm_cleanup_insn = NULL_RTX; f->x_result_rtx = NULL_RTX; @@ -13630,7 +13645,7 @@ finish_function (lineno, flags) /* If we're saving up tree structure, tie off the function now. */ if (!expand_p) - finish_stmt_tree (fndecl); + finish_stmt_tree (&DECL_SAVED_TREE (fndecl)); /* This must come after expand_function_end because cleanups might have declarations (from inline functions) that need to go into @@ -14229,8 +14244,6 @@ mark_lang_function (p) ggc_mark_tree (p->x_member_init_list); ggc_mark_tree (p->x_current_class_ptr); ggc_mark_tree (p->x_current_class_ref); - ggc_mark_tree (p->x_last_tree); - ggc_mark_tree (p->x_last_expr_type); ggc_mark_tree (p->x_eh_spec_try_block); ggc_mark_tree (p->x_scope_stmt_stack); @@ -14238,6 +14251,7 @@ mark_lang_function (p) ggc_mark_rtx (p->x_last_parm_cleanup_insn); ggc_mark_rtx (p->x_result_rtx); + mark_stmt_tree (&p->x_stmt_tree); mark_binding_level (&p->bindings); } diff --git a/gcc/cp/dump.c b/gcc/cp/dump.c index 7420c972ae0..00d9e18f558 100644 --- a/gcc/cp/dump.c +++ b/gcc/cp/dump.c @@ -596,7 +596,11 @@ dequeue_and_dump (di) dump_int (di, "algn", DECL_ALIGN (t)); if (TREE_CODE (t) == FIELD_DECL && dump_children_p) - dump_child ("bpos", DECL_FIELD_BITPOS (t)); + { + if (DECL_C_BIT_FIELD (t)) + dump_string (di, "bitfield"); + dump_child ("bpos", DECL_FIELD_BITPOS (t)); + } break; case FUNCTION_DECL: diff --git a/gcc/cp/expr.c b/gcc/cp/expr.c index 5b5352ef4d5..9556caced88 100644 --- a/gcc/cp/expr.c +++ b/gcc/cp/expr.c @@ -233,14 +233,6 @@ cplus_expand_expr (exp, target, tmode, modifier) expand_internal_throw (); return NULL; - case VEC_INIT_EXPR: - return expand_expr - (build_vec_init - (NULL_TREE, TREE_OPERAND (exp, 0), - build_binary_op (MINUS_EXPR, TREE_OPERAND (exp, 2), - integer_one_node), - TREE_OPERAND (exp, 1), 0), target, tmode, modifier); - case STMT_EXPR: { tree rtl_expr = begin_stmt_expr (); diff --git a/gcc/cp/init.c b/gcc/cp/init.c index d420ff5dbd9..40fd8c9cb81 100644 --- a/gcc/cp/init.c +++ b/gcc/cp/init.c @@ -2363,16 +2363,13 @@ build_new_1 (exp) rval = newrval; TREE_HAS_CONSTRUCTOR (rval) = 1; } - else if (current_function_decl) + else rval = (build_vec_init (NULL_TREE, save_expr (rval), build_binary_op (MINUS_EXPR, nelts, integer_one_node), init, /*from_array=*/0)); - else - rval = build (VEC_INIT_EXPR, TREE_TYPE (rval), - save_expr (rval), init, nelts); /* If any part of the object initialization terminates by throwing an exception and a suitable deallocation function can be found, the @@ -2698,15 +2695,6 @@ build_vec_init (decl, base, maxindex, init, from_array) if (maxindex == error_mark_node) return error_mark_node; - if (current_function_decl == NULL_TREE) - { - rval = make_tree_vec (3); - TREE_VEC_ELT (rval, 0) = base; - TREE_VEC_ELT (rval, 1) = maxindex; - TREE_VEC_ELT (rval, 2) = init; - return rval; - } - type = TREE_TYPE (TREE_TYPE (base)); ptype = build_pointer_type (type); size = size_in_bytes (type); diff --git a/gcc/cp/parse.c b/gcc/cp/parse.c index a7b552628de..e7d774d1129 100644 --- a/gcc/cp/parse.c +++ b/gcc/cp/parse.c @@ -735,19 +735,19 @@ static const short yyrline[] = { 0, 3216, 3219, 3222, 3225, 3228, 3230, 3233, 3237, 3239, 3245, 3247, 3248, 3250, 3255, 3257, 3259, 3261, 3263, 3266, 3267, 3269, 3272, 3273, 3276, 3276, 3279, 3279, 3282, 3282, 3284, - 3286, 3288, 3290, 3296, 3302, 3305, 3308, 3314, 3316, 3318, - 3322, 3324, 3325, 3326, 3328, 3331, 3334, 3337, 3343, 3347, - 3349, 3352, 3354, 3357, 3361, 3363, 3366, 3368, 3371, 3388, - 3396, 3399, 3401, 3403, 3407, 3410, 3411, 3419, 3423, 3427, - 3430, 3431, 3437, 3440, 3443, 3445, 3449, 3454, 3457, 3467, - 3472, 3473, 3480, 3483, 3486, 3488, 3491, 3493, 3503, 3517, - 3521, 3524, 3526, 3530, 3534, 3537, 3540, 3542, 3546, 3548, - 3555, 3562, 3565, 3569, 3573, 3577, 3583, 3587, 3592, 3594, - 3597, 3602, 3608, 3619, 3622, 3624, 3628, 3636, 3639, 3643, - 3646, 3648, 3650, 3656, 3661, 3664, 3666, 3668, 3670, 3672, - 3674, 3676, 3678, 3680, 3682, 3684, 3686, 3688, 3690, 3692, - 3694, 3696, 3698, 3700, 3702, 3704, 3706, 3708, 3710, 3712, - 3714, 3716, 3718, 3720, 3722, 3724, 3726, 3729, 3731 + 3286, 3288, 3290, 3296, 3302, 3305, 3308, 3314, 3316, 3317, + 3320, 3322, 3323, 3324, 3326, 3329, 3332, 3335, 3341, 3345, + 3347, 3350, 3352, 3355, 3359, 3361, 3364, 3366, 3369, 3386, + 3394, 3397, 3399, 3401, 3405, 3408, 3409, 3417, 3421, 3425, + 3428, 3429, 3435, 3438, 3441, 3443, 3447, 3452, 3455, 3465, + 3470, 3471, 3478, 3481, 3484, 3486, 3489, 3491, 3501, 3515, + 3519, 3522, 3524, 3528, 3532, 3535, 3538, 3540, 3544, 3546, + 3553, 3560, 3563, 3567, 3571, 3575, 3581, 3585, 3590, 3592, + 3595, 3600, 3606, 3617, 3620, 3622, 3626, 3634, 3637, 3641, + 3644, 3646, 3648, 3654, 3659, 3662, 3664, 3666, 3668, 3670, + 3672, 3674, 3676, 3678, 3680, 3682, 3684, 3686, 3688, 3690, + 3692, 3694, 3696, 3698, 3700, 3702, 3704, 3706, 3708, 3710, + 3712, 3714, 3716, 3718, 3720, 3722, 3724, 3727, 3729 }; #endif @@ -7673,69 +7673,64 @@ case 758: #line 3315 "parse.y" { finish_goto_stmt (yyvsp[-1].ttype); ; break;} -case 759: -#line 3317 "parse.y" -{ finish_stmt (); ; - break;} case 760: -#line 3319 "parse.y" +#line 3318 "parse.y" { error ("label must be followed by statement"); - yyungetc ('}', 0); - finish_stmt (); ; + yyungetc ('}', 0); ; break;} case 761: -#line 3323 "parse.y" +#line 3321 "parse.y" { finish_stmt (); ; break;} case 764: -#line 3327 "parse.y" +#line 3325 "parse.y" { do_local_using_decl (yyvsp[0].ttype); ; break;} case 766: -#line 3333 "parse.y" +#line 3331 "parse.y" { yyval.ttype = begin_function_try_block (); ; break;} case 767: -#line 3335 "parse.y" +#line 3333 "parse.y" { finish_function_try_block (yyvsp[-2].ttype); ; break;} case 768: -#line 3337 "parse.y" +#line 3335 "parse.y" { finish_function_handler_sequence (yyvsp[-4].ttype); yyval.itype = yyvsp[-3].itype; ; break;} case 769: -#line 3345 "parse.y" +#line 3343 "parse.y" { yyval.ttype = begin_try_block (); ; break;} case 770: -#line 3347 "parse.y" +#line 3345 "parse.y" { finish_try_block (yyvsp[-1].ttype); ; break;} case 771: -#line 3349 "parse.y" +#line 3347 "parse.y" { finish_handler_sequence (yyvsp[-3].ttype); ; break;} case 774: -#line 3359 "parse.y" +#line 3357 "parse.y" { yyval.ttype = begin_handler(); ; break;} case 775: -#line 3361 "parse.y" +#line 3359 "parse.y" { yyval.ttype = finish_handler_parms (yyvsp[0].ttype, yyvsp[-1].ttype); ; break;} case 776: -#line 3363 "parse.y" +#line 3361 "parse.y" { finish_handler (yyvsp[-1].ttype, yyvsp[-3].ttype); ; break;} case 779: -#line 3373 "parse.y" +#line 3371 "parse.y" { yyval.ttype = NULL_TREE; ; break;} case 780: -#line 3389 "parse.y" +#line 3387 "parse.y" { check_for_new_type ("inside exception declarations", yyvsp[-1].ftype); yyval.ttype = start_handler_parms (TREE_PURPOSE (yyvsp[-1].ftype.t), @@ -7743,102 +7738,102 @@ case 780: ; break;} case 781: -#line 3398 "parse.y" +#line 3396 "parse.y" { finish_label_stmt (yyvsp[-1].ttype); ; break;} case 782: -#line 3400 "parse.y" +#line 3398 "parse.y" { finish_label_stmt (yyvsp[-1].ttype); ; break;} case 783: -#line 3402 "parse.y" +#line 3400 "parse.y" { finish_label_stmt (yyvsp[-1].ttype); ; break;} case 784: -#line 3404 "parse.y" +#line 3402 "parse.y" { finish_label_stmt (yyvsp[-1].ttype); ; break;} case 785: -#line 3409 "parse.y" +#line 3407 "parse.y" { finish_expr_stmt (yyvsp[-1].ttype); ; break;} case 787: -#line 3412 "parse.y" +#line 3410 "parse.y" { if (pedantic) pedwarn ("ANSI C++ forbids compound statements inside for initializations"); ; break;} case 788: -#line 3421 "parse.y" +#line 3419 "parse.y" { emit_line_note (input_filename, lineno); yyval.ttype = NULL_TREE; ; break;} case 789: -#line 3424 "parse.y" +#line 3422 "parse.y" { emit_line_note (input_filename, lineno); ; break;} case 790: -#line 3429 "parse.y" +#line 3427 "parse.y" { yyval.ttype = NULL_TREE; ; break;} case 792: -#line 3432 "parse.y" +#line 3430 "parse.y" { yyval.ttype = NULL_TREE; ; break;} case 793: -#line 3439 "parse.y" +#line 3437 "parse.y" { yyval.ttype = NULL_TREE; ; break;} case 796: -#line 3446 "parse.y" +#line 3444 "parse.y" { yyval.ttype = chainon (yyval.ttype, yyvsp[0].ttype); ; break;} case 797: -#line 3451 "parse.y" +#line 3449 "parse.y" { yyval.ttype = build_tree_list (yyval.ttype, yyvsp[-1].ttype); ; break;} case 798: -#line 3456 "parse.y" +#line 3454 "parse.y" { yyval.ttype = tree_cons (NULL_TREE, yyval.ttype, NULL_TREE); ; break;} case 799: -#line 3458 "parse.y" +#line 3456 "parse.y" { yyval.ttype = tree_cons (NULL_TREE, yyvsp[0].ttype, yyval.ttype); ; break;} case 800: -#line 3469 "parse.y" +#line 3467 "parse.y" { yyval.ttype = empty_parms(); ; break;} case 802: -#line 3474 "parse.y" +#line 3472 "parse.y" { yyval.ttype = finish_parmlist (build_tree_list (NULL_TREE, yyvsp[0].ftype.t), 0); check_for_new_type ("inside parameter list", yyvsp[0].ftype); ; break;} case 803: -#line 3482 "parse.y" +#line 3480 "parse.y" { yyval.ttype = finish_parmlist (yyval.ttype, 0); ; break;} case 804: -#line 3484 "parse.y" +#line 3482 "parse.y" { yyval.ttype = finish_parmlist (yyvsp[-1].ttype, 1); ; break;} case 805: -#line 3487 "parse.y" +#line 3485 "parse.y" { yyval.ttype = finish_parmlist (yyvsp[-1].ttype, 1); ; break;} case 806: -#line 3489 "parse.y" +#line 3487 "parse.y" { yyval.ttype = finish_parmlist (build_tree_list (NULL_TREE, yyvsp[-1].ftype.t), 1); ; break;} case 807: -#line 3492 "parse.y" +#line 3490 "parse.y" { yyval.ttype = finish_parmlist (NULL_TREE, 1); ; break;} case 808: -#line 3494 "parse.y" +#line 3492 "parse.y" { /* This helps us recover from really nasty parse errors, for example, a missing right @@ -7850,7 +7845,7 @@ case 808: ; break;} case 809: -#line 3504 "parse.y" +#line 3502 "parse.y" { /* This helps us recover from really nasty parse errors, for example, a missing right @@ -7863,99 +7858,99 @@ case 809: ; break;} case 810: -#line 3519 "parse.y" +#line 3517 "parse.y" { maybe_snarf_defarg (); ; break;} case 811: -#line 3521 "parse.y" +#line 3519 "parse.y" { yyval.ttype = yyvsp[0].ttype; ; break;} case 814: -#line 3532 "parse.y" +#line 3530 "parse.y" { check_for_new_type ("in a parameter list", yyvsp[0].ftype); yyval.ttype = build_tree_list (NULL_TREE, yyvsp[0].ftype.t); ; break;} case 815: -#line 3535 "parse.y" +#line 3533 "parse.y" { check_for_new_type ("in a parameter list", yyvsp[-1].ftype); yyval.ttype = build_tree_list (yyvsp[0].ttype, yyvsp[-1].ftype.t); ; break;} case 816: -#line 3538 "parse.y" +#line 3536 "parse.y" { check_for_new_type ("in a parameter list", yyvsp[0].ftype); yyval.ttype = chainon (yyval.ttype, yyvsp[0].ftype.t); ; break;} case 817: -#line 3541 "parse.y" +#line 3539 "parse.y" { yyval.ttype = chainon (yyval.ttype, build_tree_list (NULL_TREE, yyvsp[0].ttype)); ; break;} case 818: -#line 3543 "parse.y" +#line 3541 "parse.y" { yyval.ttype = chainon (yyval.ttype, build_tree_list (yyvsp[0].ttype, yyvsp[-2].ttype)); ; break;} case 820: -#line 3549 "parse.y" +#line 3547 "parse.y" { check_for_new_type ("in a parameter list", yyvsp[-1].ftype); yyval.ttype = build_tree_list (NULL_TREE, yyvsp[-1].ftype.t); ; break;} case 821: -#line 3559 "parse.y" +#line 3557 "parse.y" { tree specs = strip_attrs (yyvsp[-1].ftype.t); yyval.ftype.new_type_flag = yyvsp[-1].ftype.new_type_flag; yyval.ftype.t = build_tree_list (specs, yyvsp[0].ttype); ; break;} case 822: -#line 3563 "parse.y" +#line 3561 "parse.y" { yyval.ftype.t = build_tree_list (yyvsp[-1].ftype.t, yyvsp[0].ttype); yyval.ftype.new_type_flag = yyvsp[-1].ftype.new_type_flag; ; break;} case 823: -#line 3566 "parse.y" +#line 3564 "parse.y" { yyval.ftype.t = build_tree_list (build_decl_list (NULL_TREE, yyvsp[-1].ftype.t), yyvsp[0].ttype); yyval.ftype.new_type_flag = yyvsp[-1].ftype.new_type_flag; ; break;} case 824: -#line 3570 "parse.y" +#line 3568 "parse.y" { tree specs = strip_attrs (yyvsp[-1].ftype.t); yyval.ftype.t = build_tree_list (specs, yyvsp[0].ttype); yyval.ftype.new_type_flag = yyvsp[-1].ftype.new_type_flag; ; break;} case 825: -#line 3574 "parse.y" +#line 3572 "parse.y" { tree specs = strip_attrs (yyvsp[0].ftype.t); yyval.ftype.t = build_tree_list (specs, NULL_TREE); yyval.ftype.new_type_flag = yyvsp[0].ftype.new_type_flag; ; break;} case 826: -#line 3578 "parse.y" +#line 3576 "parse.y" { tree specs = strip_attrs (yyvsp[-1].ttype); yyval.ftype.t = build_tree_list (specs, yyvsp[0].ttype); yyval.ftype.new_type_flag = 0; ; break;} case 827: -#line 3585 "parse.y" +#line 3583 "parse.y" { yyval.ftype.t = build_tree_list (NULL_TREE, yyvsp[0].ftype.t); yyval.ftype.new_type_flag = yyvsp[0].ftype.new_type_flag; ; break;} case 828: -#line 3588 "parse.y" +#line 3586 "parse.y" { yyval.ftype.t = build_tree_list (yyvsp[0].ttype, yyvsp[-1].ftype.t); yyval.ftype.new_type_flag = yyvsp[-1].ftype.new_type_flag; ; break;} case 831: -#line 3599 "parse.y" +#line 3597 "parse.y" { see_typename (); ; break;} case 832: -#line 3604 "parse.y" +#line 3602 "parse.y" { error ("type specifier omitted for parameter"); yyval.ttype = build_tree_list (integer_type_node, NULL_TREE); ; break;} case 833: -#line 3609 "parse.y" +#line 3607 "parse.y" { error ("type specifier omitted for parameter"); if (TREE_CODE (yyval.ttype) == SCOPE_REF @@ -7966,192 +7961,192 @@ case 833: ; break;} case 834: -#line 3621 "parse.y" +#line 3619 "parse.y" { yyval.ttype = NULL_TREE; ; break;} case 835: -#line 3623 "parse.y" +#line 3621 "parse.y" { yyval.ttype = yyvsp[-1].ttype; ; break;} case 836: -#line 3625 "parse.y" +#line 3623 "parse.y" { yyval.ttype = empty_except_spec; ; break;} case 837: -#line 3630 "parse.y" +#line 3628 "parse.y" { check_for_new_type ("exception specifier", yyvsp[0].ftype); yyval.ttype = groktypename (yyvsp[0].ftype.t); ; break;} case 838: -#line 3638 "parse.y" +#line 3636 "parse.y" { yyval.ttype = add_exception_specifier (NULL_TREE, yyvsp[0].ttype, 1); ; break;} case 839: -#line 3640 "parse.y" +#line 3638 "parse.y" { yyval.ttype = add_exception_specifier (yyvsp[-2].ttype, yyvsp[0].ttype, 1); ; break;} case 840: -#line 3645 "parse.y" +#line 3643 "parse.y" { yyval.ttype = NULL_TREE; ; break;} case 841: -#line 3647 "parse.y" +#line 3645 "parse.y" { yyval.ttype = make_pointer_declarator (yyvsp[-1].ttype, yyvsp[0].ttype); ; break;} case 842: -#line 3649 "parse.y" +#line 3647 "parse.y" { yyval.ttype = make_reference_declarator (yyvsp[-1].ttype, yyvsp[0].ttype); ; break;} case 843: -#line 3651 "parse.y" +#line 3649 "parse.y" { tree arg = make_pointer_declarator (yyvsp[-1].ttype, yyvsp[0].ttype); yyval.ttype = build_parse_node (SCOPE_REF, yyvsp[-2].ttype, arg); ; break;} case 844: -#line 3658 "parse.y" +#line 3656 "parse.y" { got_scope = NULL_TREE; ; break;} case 845: -#line 3663 "parse.y" +#line 3661 "parse.y" { yyval.ttype = ansi_opname[MULT_EXPR]; ; break;} case 846: -#line 3665 "parse.y" +#line 3663 "parse.y" { yyval.ttype = ansi_opname[TRUNC_DIV_EXPR]; ; break;} case 847: -#line 3667 "parse.y" +#line 3665 "parse.y" { yyval.ttype = ansi_opname[TRUNC_MOD_EXPR]; ; break;} case 848: -#line 3669 "parse.y" +#line 3667 "parse.y" { yyval.ttype = ansi_opname[PLUS_EXPR]; ; break;} case 849: -#line 3671 "parse.y" +#line 3669 "parse.y" { yyval.ttype = ansi_opname[MINUS_EXPR]; ; break;} case 850: -#line 3673 "parse.y" +#line 3671 "parse.y" { yyval.ttype = ansi_opname[BIT_AND_EXPR]; ; break;} case 851: -#line 3675 "parse.y" +#line 3673 "parse.y" { yyval.ttype = ansi_opname[BIT_IOR_EXPR]; ; break;} case 852: -#line 3677 "parse.y" +#line 3675 "parse.y" { yyval.ttype = ansi_opname[BIT_XOR_EXPR]; ; break;} case 853: -#line 3679 "parse.y" +#line 3677 "parse.y" { yyval.ttype = ansi_opname[BIT_NOT_EXPR]; ; break;} case 854: -#line 3681 "parse.y" +#line 3679 "parse.y" { yyval.ttype = ansi_opname[COMPOUND_EXPR]; ; break;} case 855: -#line 3683 "parse.y" +#line 3681 "parse.y" { yyval.ttype = ansi_opname[yyvsp[0].code]; ; break;} case 856: -#line 3685 "parse.y" +#line 3683 "parse.y" { yyval.ttype = ansi_opname[LT_EXPR]; ; break;} case 857: -#line 3687 "parse.y" +#line 3685 "parse.y" { yyval.ttype = ansi_opname[GT_EXPR]; ; break;} case 858: -#line 3689 "parse.y" +#line 3687 "parse.y" { yyval.ttype = ansi_opname[yyvsp[0].code]; ; break;} case 859: -#line 3691 "parse.y" +#line 3689 "parse.y" { yyval.ttype = ansi_assopname[yyvsp[0].code]; ; break;} case 860: -#line 3693 "parse.y" +#line 3691 "parse.y" { yyval.ttype = ansi_opname [MODIFY_EXPR]; ; break;} case 861: -#line 3695 "parse.y" +#line 3693 "parse.y" { yyval.ttype = ansi_opname[yyvsp[0].code]; ; break;} case 862: -#line 3697 "parse.y" +#line 3695 "parse.y" { yyval.ttype = ansi_opname[yyvsp[0].code]; ; break;} case 863: -#line 3699 "parse.y" +#line 3697 "parse.y" { yyval.ttype = ansi_opname[POSTINCREMENT_EXPR]; ; break;} case 864: -#line 3701 "parse.y" +#line 3699 "parse.y" { yyval.ttype = ansi_opname[PREDECREMENT_EXPR]; ; break;} case 865: -#line 3703 "parse.y" +#line 3701 "parse.y" { yyval.ttype = ansi_opname[TRUTH_ANDIF_EXPR]; ; break;} case 866: -#line 3705 "parse.y" +#line 3703 "parse.y" { yyval.ttype = ansi_opname[TRUTH_ORIF_EXPR]; ; break;} case 867: -#line 3707 "parse.y" +#line 3705 "parse.y" { yyval.ttype = ansi_opname[TRUTH_NOT_EXPR]; ; break;} case 868: -#line 3709 "parse.y" +#line 3707 "parse.y" { yyval.ttype = ansi_opname[COND_EXPR]; ; break;} case 869: -#line 3711 "parse.y" +#line 3709 "parse.y" { yyval.ttype = ansi_opname[yyvsp[0].code]; ; break;} case 870: -#line 3713 "parse.y" +#line 3711 "parse.y" { yyval.ttype = ansi_opname[COMPONENT_REF]; ; break;} case 871: -#line 3715 "parse.y" +#line 3713 "parse.y" { yyval.ttype = ansi_opname[MEMBER_REF]; ; break;} case 872: -#line 3717 "parse.y" +#line 3715 "parse.y" { yyval.ttype = ansi_opname[CALL_EXPR]; ; break;} case 873: -#line 3719 "parse.y" +#line 3717 "parse.y" { yyval.ttype = ansi_opname[ARRAY_REF]; ; break;} case 874: -#line 3721 "parse.y" +#line 3719 "parse.y" { yyval.ttype = ansi_opname[NEW_EXPR]; ; break;} case 875: -#line 3723 "parse.y" +#line 3721 "parse.y" { yyval.ttype = ansi_opname[DELETE_EXPR]; ; break;} case 876: -#line 3725 "parse.y" +#line 3723 "parse.y" { yyval.ttype = ansi_opname[VEC_NEW_EXPR]; ; break;} case 877: -#line 3727 "parse.y" +#line 3725 "parse.y" { yyval.ttype = ansi_opname[VEC_DELETE_EXPR]; ; break;} case 878: -#line 3730 "parse.y" +#line 3728 "parse.y" { yyval.ttype = grokoptypename (yyvsp[-1].ftype.t, yyvsp[0].ttype); ; break;} case 879: -#line 3732 "parse.y" +#line 3730 "parse.y" { yyval.ttype = ansi_opname[ERROR_MARK]; ; break;} } @@ -8376,7 +8371,7 @@ yyerrhandle: } return 1; } -#line 3735 "parse.y" +#line 3733 "parse.y" #ifdef SPEW_DEBUG diff --git a/gcc/cp/parse.y b/gcc/cp/parse.y index c3892eda90f..e9d8068e388 100644 --- a/gcc/cp/parse.y +++ b/gcc/cp/parse.y @@ -3314,11 +3314,9 @@ simple_stmt: | GOTO identifier ';' { finish_goto_stmt ($2); } | label_colon stmt - { finish_stmt (); } | label_colon '}' { error ("label must be followed by statement"); - yyungetc ('}', 0); - finish_stmt (); } + yyungetc ('}', 0); } | ';' { finish_stmt (); } | try_block diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c index fca18cce70d..9586ec2fb78 100644 --- a/gcc/cp/pt.c +++ b/gcc/cp/pt.c @@ -9807,29 +9807,6 @@ tsubst_expr_values (t, argvec) return first; } -void -begin_tree () -{ - if (current_function) - { - saved_trees = tree_cons (NULL_TREE, last_tree, saved_trees); - last_tree = NULL_TREE; - } - else - saved_trees = tree_cons (NULL_TREE, NULL_TREE, saved_trees); -} - - -void -end_tree () -{ - my_friendly_assert (saved_trees != NULL_TREE, 0); - - if (current_function) - last_tree = TREE_VALUE (saved_trees); - saved_trees = TREE_CHAIN (saved_trees); -} - /* D is an undefined function declaration in the presence of templates with the same name, listed in FNS. If one of them can produce D as an instantiation, remember this so we can instantiate it at EOF if D has diff --git a/gcc/cp/semantics.c b/gcc/cp/semantics.c index 95055358649..eb1767e850e 100644 --- a/gcc/cp/semantics.c +++ b/gcc/cp/semantics.c @@ -45,6 +45,12 @@ static tree expand_cond PROTO((tree)); static tree maybe_convert_cond PROTO((tree)); +/* Record the fact that STMT was the last statement added to the + statement tree. */ + +#define SET_LAST_STMT(stmt) \ + (current_stmt_tree->x_last_stmt = (stmt)) + /* When parsing a template, LAST_TREE contains the last statement parsed. These are chained together through the TREE_CHAIN field, but often need to be re-organized since the parse is performed @@ -55,7 +61,7 @@ static tree maybe_convert_cond PROTO((tree)); do { \ substmt = TREE_CHAIN (stmt); \ TREE_CHAIN (stmt) = NULL_TREE; \ - last_tree = stmt; \ + SET_LAST_STMT (stmt); \ } while (0) /* Finish processing the COND, the SUBSTMT condition for STMT. */ @@ -82,7 +88,8 @@ add_tree (t) tree t; { /* Add T to the statement-tree. */ - last_tree = TREE_CHAIN (last_tree) = t; + TREE_CHAIN (last_tree) = t; + SET_LAST_STMT (t); /* When we expand a statement-tree, we must know whether or not the statements are full-expresions. We record that fact here. */ @@ -201,7 +208,7 @@ finish_then_clause (if_stmt) if (building_stmt_tree ()) { RECHAIN_STMTS (if_stmt, THEN_CLAUSE (if_stmt)); - last_tree = if_stmt; + SET_LAST_STMT (if_stmt); return if_stmt; } else @@ -934,7 +941,8 @@ begin_compound_stmt (has_no_scope) /* If this is the outermost block of the function, declare the variables __FUNCTION__, __PRETTY_FUNCTION__, and so forth. */ - if (!current_function_name_declared + if (current_function + && !current_function_name_declared && !processing_template_decl && !has_no_scope) { @@ -1322,6 +1330,12 @@ finish_parenthesized_expr (expr) tree begin_stmt_expr () { + /* If we're outside a function, we won't have a statement-tree to + work with. But, if we see a statement-expression we need to + create one. */ + if (!current_function && !last_tree) + begin_stmt_tree (&scope_chain->x_saved_tree); + keep_next_level (1); /* If we're building a statement tree, then the upcoming compound statement will be chained onto the tree structure, starting at @@ -1359,12 +1373,18 @@ finish_stmt_expr (rtl_expr) /* Remove the compound statement from the tree structure; it is now saved in the STMT_EXPR. */ - last_tree = rtl_expr; + SET_LAST_STMT (rtl_expr); TREE_CHAIN (last_tree) = NULL_TREE; } else result = rtl_expr; + /* If we created a statement-tree for this statement-expression, + remove it now. */ + if (!current_function + && TREE_CHAIN (scope_chain->x_saved_tree) == NULL_TREE) + finish_stmt_tree (&scope_chain->x_saved_tree); + return result; } @@ -1840,11 +1860,6 @@ begin_class_definition (t) #endif reset_specialization(); - /* In case this is a local class within a template - function, we save the current tree structure so - that we can get it back later. */ - begin_tree (); - /* Make a declaration for this class in its own scope. */ build_self_reference (); @@ -1997,9 +2012,6 @@ finish_inline_definitions () { if (current_class_type == NULL_TREE) clear_inline_text_obstack (); - - /* Undo the begin_tree in begin_class_definition. */ - end_tree (); } /* Finish processing the declaration of a member class template @@ -2172,36 +2184,40 @@ finish_typeof (expr) return TREE_TYPE (expr); } -/* Create an empty statement tree for FN. */ +/* Create an empty statement tree rooted at T. */ void -begin_stmt_tree (fn) - tree fn; +begin_stmt_tree (t) + tree *t; { /* We create a trivial EXPR_STMT so that last_tree is never NULL in what follows. We remove the extraneous statement in finish_stmt_tree. */ - DECL_SAVED_TREE (fn) = build_nt (EXPR_STMT, void_zero_node); - last_tree = DECL_SAVED_TREE (fn); + *t = build_nt (EXPR_STMT, void_zero_node); + SET_LAST_STMT (*t); last_expr_type = NULL_TREE; } -/* Finish the statement tree for FN. */ +/* Finish the statement tree rooted at T. */ void -finish_stmt_tree (fn) - tree fn; +finish_stmt_tree (t) + tree *t; { tree stmt; /* Remove the fake extra statement added in begin_stmt_tree. */ - stmt = TREE_CHAIN (DECL_SAVED_TREE (fn)); - DECL_SAVED_TREE (fn) = stmt; + stmt = TREE_CHAIN (*t); + *t = stmt; + SET_LAST_STMT (NULL_TREE); - /* The line-number recorded in the outermost statement in a function - is the line number of the end of the function. */ - STMT_LINENO (stmt) = lineno; - STMT_LINENO_FOR_FN_P (stmt) = 1; + if (current_function) + { + /* The line-number recorded in the outermost statement in a function + is the line number of the end of the function. */ + STMT_LINENO (stmt) = lineno; + STMT_LINENO_FOR_FN_P (stmt) = 1; + } } /* We're about to expand T, a statement. Set up appropriate context diff --git a/gcc/cp/tree.c b/gcc/cp/tree.c index 96a15496b20..347668bc361 100644 --- a/gcc/cp/tree.c +++ b/gcc/cp/tree.c @@ -1617,7 +1617,6 @@ search_tree (tp, func) case TARGET_EXPR: case AGGR_INIT_EXPR: case NEW_EXPR: - case VEC_INIT_EXPR: TRY (TREE_OPERAND (t, 0)); TRY (TREE_OPERAND (t, 1)); TRY (TREE_OPERAND (t, 2)); @@ -1988,7 +1987,6 @@ mapcar (t, func) return t; case NEW_EXPR: - case VEC_INIT_EXPR: t = copy_node (t); TREE_OPERAND (t, 0) = mapcar (TREE_OPERAND (t, 0), func); TREE_OPERAND (t, 1) = mapcar (TREE_OPERAND (t, 1), func); diff --git a/gcc/testsuite/g++.old-deja/g++.ext/stmtexpr1.C b/gcc/testsuite/g++.old-deja/g++.ext/stmtexpr1.C new file mode 100644 index 00000000000..f28ac8e7e72 --- /dev/null +++ b/gcc/testsuite/g++.old-deja/g++.ext/stmtexpr1.C @@ -0,0 +1,8 @@ +// Build don't link: +// Origin: Mark Mitchell +// Special g++ Options: + +void f () +{ + int i = ({ l: 3; }); +}