diff options
author | Mark Mitchell <mark@codesourcery.com> | 1999-12-05 00:49:26 +0000 |
---|---|---|
committer | Mark Mitchell <mmitchel@gcc.gnu.org> | 1999-12-05 00:49:26 +0000 |
commit | d9b2d9da75c2a7624a50ef9843376c643560dbb0 (patch) | |
tree | 5dbc0fc3b366c061db6ce54fee8b5bca88b6eb07 /gcc/cp/semantics.c | |
parent | 2c0f17dc4f33028746fa39329f1779a98ad8b0ac (diff) | |
download | gcc-d9b2d9da75c2a7624a50ef9843376c643560dbb0.zip gcc-d9b2d9da75c2a7624a50ef9843376c643560dbb0.tar.gz gcc-d9b2d9da75c2a7624a50ef9843376c643560dbb0.tar.bz2 |
cp-tree.def (SCOPE_STMT): Take one operand.
* cp-tree.def (SCOPE_STMT): Take one operand.
* cp-tree.h (SCOPE_STMT_BLOCK): New macro.
(SCOPE_NULLIFIED_P): Redefine.
(SCOPE_NO_CLEANUPS_P): New macro.
(add_scope_stmt): Change prototype.
* decl.c (poplevel): Tidy. Warn about unused variables here.
Record SCOPE_STMT_BLOCKs.
(finish_function): Keep DECL_INITIAL for functions that might be
inlined.
* ir.texi: Document SCOPE_NO_CLEANUPS_P.
* semantics.c: Include rtl.h.
(add_scope_stmt): Return the new scope statement and, for an
end-of-scope statement, its matching begin statement. Don't set
SCOPE_NULLIFIED_P.
(do_pushlevel): Simplify, now that we are always
function-at-a-time.
(do_poplevel): Likewise. Record SCOPE_STMT_BLOCKs.
(expand_stmt): Don't call expand_start_bindings or
expand_end_bindings for a scope with SCOPE_NO_CLEANUPS_P set.
* tree.c (copy_tree_r): Clear SCOPE_STMT_BLOCK rather than setting
SCOPE_NULLIFIED_P.
From-SVN: r30779
Diffstat (limited to 'gcc/cp/semantics.c')
-rw-r--r-- | gcc/cp/semantics.c | 91 |
1 files changed, 53 insertions, 38 deletions
diff --git a/gcc/cp/semantics.c b/gcc/cp/semantics.c index fa69540..028279f 100644 --- a/gcc/cp/semantics.c +++ b/gcc/cp/semantics.c @@ -33,6 +33,7 @@ #include "toplev.h" #include "flags.h" #include "ggc.h" +#include "rtl.h" /* There routines provide a modular interface to perform many parsing operations. They may therefore be used during actual parsing, or @@ -1264,38 +1265,44 @@ setup_vtbl_ptr () /* 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. */ + an object that needs a cleanup is created. If BEGIN_P is nonzero, + returns a new TREE_LIST representing the top of the SCOPE_STMT + stack. The TREE_PURPOSE is the new SCOPE_STMT. If BEGIN_P is + zero, returns a TREE_LIST whose TREE_VALUE is the new SCOPE_STMT, + and whose TREE_PURPOSE is the matching SCOPE_STMT iwth + SCOPE_BEGIN_P set. */ -void +tree add_scope_stmt (begin_p, partial_p) int begin_p; int partial_p; { tree ss; + tree top; /* Build the statement. */ - ss = build_min_nt (SCOPE_STMT); + ss = build_min_nt (SCOPE_STMT, NULL_TREE); 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); + { + current_scope_stmt_stack + = tree_cons (ss, NULL_TREE, current_scope_stmt_stack); + top = current_scope_stmt_stack; + } else - current_scope_stmt_stack = TREE_CHAIN (current_scope_stmt_stack); + { + top = current_scope_stmt_stack; + TREE_VALUE (top) = ss; + current_scope_stmt_stack = TREE_CHAIN (top); + } /* Add the new statement to the statement-tree. */ add_tree (ss); + + return top; } /* Begin a new scope. */ @@ -1313,8 +1320,9 @@ do_pushlevel () pushlevel (0); if (!building_stmt_tree () && !current_function->x_whole_function_mode_p) - expand_start_bindings (0); - else if (building_stmt_tree () && !processing_template_decl) + my_friendly_abort (19991129); + + if (building_stmt_tree () && !processing_template_decl) add_scope_stmt (/*begin_p=*/1, /*partial_p=*/0); } } @@ -1324,28 +1332,27 @@ do_pushlevel () tree do_poplevel () { - tree t = NULL_TREE; + tree block = NULL_TREE; if (stmts_are_full_exprs_p) { - if (!building_stmt_tree () - && !current_function->x_whole_function_mode_p) - expand_end_bindings (getdecls (), kept_level_p (), 0); - else if (building_stmt_tree () && !processing_template_decl) + tree scope_stmts; + int keep = kept_level_p (); + + if (building_stmt_tree () && !processing_template_decl) + scope_stmts = add_scope_stmt (/*begin_p=*/0, /*partial_p=*/0); + else + scope_stmts = NULL_TREE; + + block = poplevel (kept_level_p (), 1, 0); + if (block && !processing_template_decl) { - 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 - function-at-a-time mode expand_end_bindings is not passed - the list of variables in the current scope, and therefore - no warning is emitted. So, we explicitly warn here. */ - warn_about_unused_variables (getdecls ()); + SCOPE_STMT_BLOCK (TREE_PURPOSE (scope_stmts)) = block; + SCOPE_STMT_BLOCK (TREE_VALUE (scope_stmts)) = block; } - - t = poplevel (kept_level_p (), 1, 0); } - return t; + + return block; } /* Finish a parenthesized expression EXPR. */ @@ -2473,11 +2480,19 @@ expand_stmt (t) break; case SCOPE_STMT: - 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), - SCOPE_PARTIAL_P (t)); + if (!SCOPE_NO_CLEANUPS_P (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), + SCOPE_PARTIAL_P (t)); + } + else if (!SCOPE_NULLIFIED_P (t)) + emit_note (NULL, + (SCOPE_BEGIN_P (t) + ? NOTE_INSN_BLOCK_BEG + : NOTE_INSN_BLOCK_END)); break; case RETURN_INIT: |