diff options
author | Mark Mitchell <mark@codesourcery.com> | 1999-10-21 08:05:57 +0000 |
---|---|---|
committer | Mark Mitchell <mmitchel@gcc.gnu.org> | 1999-10-21 08:05:57 +0000 |
commit | 8f471b0d0f739afb82360cfef9fc44479bea3c50 (patch) | |
tree | a7226b57f6affb547543c6a726c4112b3877d63f /gcc/cp | |
parent | 070cd782ac3d0c321937088b45b142c7831eec44 (diff) | |
download | gcc-8f471b0d0f739afb82360cfef9fc44479bea3c50.zip gcc-8f471b0d0f739afb82360cfef9fc44479bea3c50.tar.gz gcc-8f471b0d0f739afb82360cfef9fc44479bea3c50.tar.bz2 |
cp-tree.h (SCOPE_PARTIAL_P): New macro.
* cp-tree.h (SCOPE_PARTIAL_P): New macro.
(pushlevel_temporary): Remove.
(add_scope_stmt): New function.
* decl.c (pushlevel_temporary): Remove.
(poplevel): Use add_scope_stmt.
(start_decl_1): Likewise.
* semantics.c (add_scope_stmt): New function.
(do_pushlevel): Use it.
(do_poplevel): Use it.
(expand_stmt): Check SCOPE_PARTIAL_P.
From-SVN: r30118
Diffstat (limited to 'gcc/cp')
-rw-r--r-- | gcc/cp/ChangeLog | 11 | ||||
-rw-r--r-- | gcc/cp/cp-tree.h | 18 | ||||
-rw-r--r-- | gcc/cp/decl.c | 32 | ||||
-rw-r--r-- | gcc/cp/semantics.c | 55 |
4 files changed, 80 insertions, 36 deletions
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index 2c146e3..f703089 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,5 +1,16 @@ 1999-10-21 Mark Mitchell <mark@codesourcery.com> + * cp-tree.h (SCOPE_PARTIAL_P): New macro. + (pushlevel_temporary): Remove. + (add_scope_stmt): New function. + * decl.c (pushlevel_temporary): Remove. + (poplevel): Use add_scope_stmt. + (start_decl_1): Likewise. + * semantics.c (add_scope_stmt): New function. + (do_pushlevel): Use it. + (do_poplevel): Use it. + (expand_stmt): Check SCOPE_PARTIAL_P. + * cp-tree.def (EMPTY_CLASS_EXPR): New tree node. * call.c (build_call): Use EMPTY_CLASS_EXPR instead of RTL_EXPR. * expr.c (cplus_expand_expr): Expand it. diff --git a/gcc/cp/cp-tree.h b/gcc/cp/cp-tree.h index 425ca18..b71c162 100644 --- a/gcc/cp/cp-tree.h +++ b/gcc/cp/cp-tree.h @@ -69,6 +69,7 @@ Boston, MA 02111-1307, USA. */ TREE_HAS_CONSTRUCTOR (in INDIRECT_REF, SAVE_EXPR, CONSTRUCTOR, or FIELD_DECL). NEED_TEMPORARY_P (in REF_BIND, BASE_CONV) + SCOPE_PARTIAL_P (in SCOPE_STMT) 5: Not used. 6: Not used. @@ -2651,6 +2652,21 @@ extern int flag_new_for_scope; #define SCOPE_NULLIFIED_P(NODE) \ (TREE_LANG_FLAG_3 (SCOPE_STMT_CHECK (NODE))) +/* Nonzero for a SCOPE_STMT if this statement is for a partial scope. + For example, in: + + S s; + l: + S s2; + goto l; + + there is (implicitly) a new scope after `l', even though there are + no curly braces. In particular, when we hit the goto, we must + destroy s2 and then re-construct it. For the implicit scope, + SCOPE_PARTIAL_P will be set. */ +#define SCOPE_PARTIAL_P(NODE) \ + (TREE_LANG_FLAG_4 (SCOPE_STMT_CHECK (NODE))) + /* Nonzero for an ASM_STMT if the assembly statement is volatile. */ #define ASM_VOLATILE_P(NODE) \ (ASM_CV_QUAL (ASM_STMT_CHECK (NODE)) != NULL_TREE) @@ -3336,7 +3352,6 @@ extern int pseudo_global_level_p PROTO((void)); extern void set_class_shadows PROTO((tree)); extern void pushlevel PROTO((int)); extern void note_level_for_for PROTO((void)); -extern void pushlevel_temporary PROTO((int)); extern void resume_level PROTO((struct binding_level *)); extern void delete_block PROTO((tree)); extern void insert_block PROTO((tree)); @@ -3886,6 +3901,7 @@ extern void expand_body PROTO((tree)); extern void begin_stmt_tree PROTO((tree *)); extern void finish_stmt_tree PROTO((tree *)); extern void prep_stmt PROTO((tree)); +extern void add_scope_stmt PROTO((int, int)); extern void do_pushlevel PROTO((void)); extern tree do_poplevel PROTO((void)); /* Non-zero if we are presently building a statement tree, rather diff --git a/gcc/cp/decl.c b/gcc/cp/decl.c index 122b025..746e498 100644 --- a/gcc/cp/decl.c +++ b/gcc/cp/decl.c @@ -825,21 +825,6 @@ note_level_for_for () current_binding_level->is_for_scope = 1; } -void -pushlevel_temporary (tag_transparent) - int tag_transparent; -{ - pushlevel (tag_transparent); - current_binding_level->keep = 2; - clear_last_expr (); - - /* Note we don't call push_momentary() here. Otherwise, it would cause - cleanups to be allocated on the momentary obstack, and they will be - overwritten by the next statement. */ - - expand_start_bindings (0); -} - /* For a binding between a name and an entity at a block scope, this is the `struct binding_level' for the block. */ #define BINDING_LEVEL(NODE) \ @@ -1458,13 +1443,13 @@ poplevel (keep, reverse, functionbody) /* Take care of compiler's internal binding structures. */ if (tmp == 2) { - expand_end_bindings (getdecls (), keep, 1); + add_scope_stmt (/*begin_p=*/0, /*partial_p=*/1); /* Each and every BLOCK node created here in `poplevel' is important (e.g. for proper debugging information) so if we created one earlier, mark it as "used". */ if (block) TREE_USED (block) = 1; - block = poplevel (keep, reverse, real_functionbody); + block = poplevel (keep, reverse, functionbody); } /* Each and every BLOCK node created here in `poplevel' is important @@ -6874,12 +6859,17 @@ start_decl_1 (decl) if (type == error_mark_node) return; - /* If this type of object needs a cleanup, and control may - jump past it, make a new binding level so that it is cleaned - up only when it is initialized first. */ + /* If this type of object needs a cleanup, but we're not allowed to + add any more objects with cleanups to the current scope, create a + new binding level. */ if (TYPE_NEEDS_DESTRUCTOR (type) && current_binding_level->more_cleanups_ok == 0) - pushlevel_temporary (1); + { + keep_next_level (2); + pushlevel (1); + clear_last_expr (); + add_scope_stmt (/*begin_p=*/1, /*partial_p=*/1); + } if (initialized) /* Is it valid for this decl to have an initializer at all? diff --git a/gcc/cp/semantics.c b/gcc/cp/semantics.c index 4c91e16..d015719 100644 --- a/gcc/cp/semantics.c +++ b/gcc/cp/semantics.c @@ -1248,6 +1248,43 @@ setup_vtbl_ptr () vtbls_set_up_p = 1; } +/* Add a scope-statement to the statement-tree. BEGIN_P indicates + whether this statements opens or closes a scope. PARTIAL_P is true + for a partial scope, i.e, the scope that begins after a label when + an object that needs a cleanup is created. */ + +void +add_scope_stmt (begin_p, partial_p) + int begin_p; + int partial_p; +{ + tree ss; + + /* Build the statement. */ + ss = build_min_nt (SCOPE_STMT); + SCOPE_BEGIN_P (ss) = begin_p; + SCOPE_PARTIAL_P (ss) = partial_p; + + /* If we're finishing a scope, figure out whether the scope was + really necessary. */ + if (!begin_p) + { + SCOPE_NULLIFIED_P (ss) = !kept_level_p (); + SCOPE_NULLIFIED_P (TREE_VALUE (current_scope_stmt_stack)) + = SCOPE_NULLIFIED_P (ss); + } + + /* Keep the scope stack up to date. */ + if (begin_p) + current_scope_stmt_stack + = tree_cons (NULL_TREE, ss, current_scope_stmt_stack); + else + current_scope_stmt_stack = TREE_CHAIN (current_scope_stmt_stack); + + /* Add the new statement to the statement-tree. */ + add_tree (ss); +} + /* Begin a new scope. */ void @@ -1266,13 +1303,7 @@ do_pushlevel () && !current_function->x_whole_function_mode_p) expand_start_bindings (0); else if (building_stmt_tree () && !processing_template_decl) - { - tree ss = build_min_nt (SCOPE_STMT); - SCOPE_BEGIN_P (ss) = 1; - add_tree (ss); - current_scope_stmt_stack - = tree_cons (NULL_TREE, ss, current_scope_stmt_stack); - } + add_scope_stmt (/*begin_p=*/1, /*partial_p=*/0); } } @@ -1290,12 +1321,7 @@ do_poplevel () expand_end_bindings (getdecls (), kept_level_p (), 0); else if (building_stmt_tree () && !processing_template_decl) { - tree ss = build_min_nt (SCOPE_STMT); - SCOPE_NULLIFIED_P (ss) = !kept_level_p (); - SCOPE_NULLIFIED_P (TREE_VALUE (current_scope_stmt_stack)) - = SCOPE_NULLIFIED_P (ss); - add_tree (ss); - current_scope_stmt_stack = TREE_CHAIN (current_scope_stmt_stack); + add_scope_stmt (/*begin_p=*/0, /*partial_p=*/0); /* When not in function-at-a-time mode, expand_end_bindings will warn about unused variables. But, in @@ -2455,7 +2481,8 @@ expand_stmt (t) if (SCOPE_BEGIN_P (t)) expand_start_bindings (2 * SCOPE_NULLIFIED_P (t)); else if (SCOPE_END_P (t)) - expand_end_bindings (NULL_TREE, !SCOPE_NULLIFIED_P (t), 0); + expand_end_bindings (NULL_TREE, !SCOPE_NULLIFIED_P (t), + SCOPE_PARTIAL_P (t)); break; case RETURN_INIT: |