mirror of
git://gcc.gnu.org/git/gcc.git
synced 2024-12-30 21:06:03 +08:00
cp-tree.def (RETURN_INIT): Remove.
* cp-tree.def (RETURN_INIT): Remove. * cp-tree.h (DECL_IN_MEMORY_P): Remove. (scope_kind): Add sk_block, sk_try, sk_catch, sk_for. (note_level_for_for): Remove. (note_level_for_try): Likewise. (note_level_for_catch): Likewise. (finish_named_return_value): Likewise. (do_pushlevel): Change prototype. (pending_lang_change): Remove. * decl.c (begin_scope): Handle sk_block, sk_try, sk_catch, sk_for. (note_level_for_for): Remove. (note_level_for_try): Likewise. (note_level_for_catch): Likewise. (maybe_inject_for_scope_var): Remove use of DECL_IN_MEMORY_P. * parser.c (cp_parser_context_free_list): Make it "deletable". (cp_parser_template_argument): Remove misleading comment. * pt.c (tsubst_expr): Remove RETURN_INIT code. * semantics.c (genrtl_named_return_value): Remove. (do_pushlevel): Take a scope kind as an argument. (begin_if_stmt): Adjust. (begin_while_stmt): Likewise. (begin_for_stmt): Likewise. (finish_for_init_stmt): Likewise. (begin_switch_stmt): Likewise. (begin_handler): Likewise. (begin_compound_stmt): Likewise. (finish_named_return_value): Remove. (cp_expand_stmt): Remove RETURN_INIT case. * tree.c (cp_statement_code_p): Remove RETURN_INIT case. * g++.dg/init/array9.C: New test. From-SVN: r60707
This commit is contained in:
parent
abda8efeda
commit
92bc132346
@ -1,3 +1,36 @@
|
||||
2002-12-31 Mark Mitchell <mark@codesourcery.com>
|
||||
|
||||
* cp-tree.def (RETURN_INIT): Remove.
|
||||
* cp-tree.h (DECL_IN_MEMORY_P): Remove.
|
||||
(scope_kind): Add sk_block, sk_try, sk_catch, sk_for.
|
||||
(note_level_for_for): Remove.
|
||||
(note_level_for_try): Likewise.
|
||||
(note_level_for_catch): Likewise.
|
||||
(finish_named_return_value): Likewise.
|
||||
(do_pushlevel): Change prototype.
|
||||
(pending_lang_change): Remove.
|
||||
* decl.c (begin_scope): Handle sk_block, sk_try, sk_catch,
|
||||
sk_for.
|
||||
(note_level_for_for): Remove.
|
||||
(note_level_for_try): Likewise.
|
||||
(note_level_for_catch): Likewise.
|
||||
(maybe_inject_for_scope_var): Remove use of DECL_IN_MEMORY_P.
|
||||
* parser.c (cp_parser_context_free_list): Make it "deletable".
|
||||
(cp_parser_template_argument): Remove misleading comment.
|
||||
* pt.c (tsubst_expr): Remove RETURN_INIT code.
|
||||
* semantics.c (genrtl_named_return_value): Remove.
|
||||
(do_pushlevel): Take a scope kind as an argument.
|
||||
(begin_if_stmt): Adjust.
|
||||
(begin_while_stmt): Likewise.
|
||||
(begin_for_stmt): Likewise.
|
||||
(finish_for_init_stmt): Likewise.
|
||||
(begin_switch_stmt): Likewise.
|
||||
(begin_handler): Likewise.
|
||||
(begin_compound_stmt): Likewise.
|
||||
(finish_named_return_value): Remove.
|
||||
(cp_expand_stmt): Remove RETURN_INIT case.
|
||||
* tree.c (cp_statement_code_p): Remove RETURN_INIT case.
|
||||
|
||||
2002-12-31 Mark Mitchell <mark@codesourcery.com>
|
||||
|
||||
PR c++/9112
|
||||
|
@ -256,7 +256,6 @@ DEFTREECODE (PSEUDO_DTOR_EXPR, "pseudo_dtor_expr", 'e', 3)
|
||||
/* CTOR_INITIALIZER is a placeholder in template code for a call to
|
||||
setup_vtbl_pointer (and appears in all functions, not just ctors). */
|
||||
DEFTREECODE (CTOR_INITIALIZER, "ctor_initializer", 'e', 1)
|
||||
DEFTREECODE (RETURN_INIT, "return_init", 'e', 2)
|
||||
DEFTREECODE (TRY_BLOCK, "try_block", 'e', 2)
|
||||
DEFTREECODE (EH_SPEC_BLOCK, "eh_spec_block", 'e', 2)
|
||||
/* A HANDLER wraps a catch handler for the HANDLER_TYPE. If this is
|
||||
|
@ -1857,14 +1857,6 @@ struct lang_decl GTY(())
|
||||
&& TREE_SYMBOL_REFERENCED (DECL_ASSEMBLER_NAME (DECL))) \
|
||||
|| (flag_syntax_only && TREE_USED (DECL)))
|
||||
|
||||
/* Nonzero iff DECL is memory-based. The DECL_RTL of
|
||||
certain const variables might be a CONST_INT, or a REG
|
||||
in some cases. We cannot use `memory_operand' as a test
|
||||
here because on most RISC machines, a variable's address
|
||||
is not, by itself, a legitimate address. */
|
||||
#define DECL_IN_MEMORY_P(NODE) \
|
||||
(DECL_RTL_SET_P (NODE) && GET_CODE (DECL_RTL (NODE)) == MEM)
|
||||
|
||||
/* For a FUNCTION_DECL or a VAR_DECL, the language linkage for the
|
||||
declaration. Some entities (like a member function in a local
|
||||
class, or a local variable) do not have linkage at all, and this
|
||||
@ -3043,6 +3035,11 @@ typedef enum cp_lvalue_kind {
|
||||
|
||||
/* The kinds of scopes we recognize. */
|
||||
typedef enum scope_kind {
|
||||
sk_block, /* An ordinary block scope. */
|
||||
sk_try, /* A try-block. */
|
||||
sk_catch, /* A catch-block. */
|
||||
sk_for, /* The scope of the variable declared in a
|
||||
for-init-statement. */
|
||||
sk_template_parms, /* A scope for template parameters. */
|
||||
sk_template_spec /* A scope corresponding to a template
|
||||
specialization. There is never anything in
|
||||
@ -3689,9 +3686,6 @@ extern void set_class_shadows PARAMS ((tree));
|
||||
extern void maybe_push_cleanup_level PARAMS ((tree));
|
||||
extern void begin_scope PARAMS ((scope_kind));
|
||||
extern void finish_scope PARAMS ((void));
|
||||
extern void note_level_for_for PARAMS ((void));
|
||||
extern void note_level_for_try PARAMS ((void));
|
||||
extern void note_level_for_catch PARAMS ((void));
|
||||
extern void resume_level PARAMS ((struct cp_binding_level *));
|
||||
extern void delete_block PARAMS ((tree));
|
||||
extern void add_block_current_level PARAMS ((tree));
|
||||
@ -4224,10 +4218,9 @@ extern tree finish_sizeof PARAMS ((tree));
|
||||
extern tree finish_alignof PARAMS ((tree));
|
||||
extern void finish_decl_cleanup PARAMS ((tree, tree));
|
||||
extern void finish_eh_cleanup PARAMS ((tree));
|
||||
extern void finish_named_return_value PARAMS ((tree, tree));
|
||||
extern void expand_body PARAMS ((tree));
|
||||
extern tree nullify_returns_r PARAMS ((tree *, int *, void *));
|
||||
extern void do_pushlevel PARAMS ((void));
|
||||
extern void do_pushlevel (scope_kind);
|
||||
extern tree do_poplevel PARAMS ((void));
|
||||
extern void begin_mem_initializers (void);
|
||||
extern void finish_mem_initializers PARAMS ((tree));
|
||||
@ -4427,9 +4420,6 @@ extern tree mangle_ref_init_variable PARAMS ((tree));
|
||||
/* in dump.c */
|
||||
extern int cp_dump_tree PARAMS ((void *, tree));
|
||||
|
||||
/* in parser.c */
|
||||
extern int pending_lang_change;
|
||||
|
||||
/* -- end of C++ */
|
||||
|
||||
#endif /* ! GCC_CP_TREE_H */
|
||||
|
@ -855,6 +855,21 @@ begin_scope (sk)
|
||||
|
||||
switch (sk)
|
||||
{
|
||||
case sk_block:
|
||||
break;
|
||||
|
||||
case sk_try:
|
||||
current_binding_level->is_try_scope = 1;
|
||||
break;
|
||||
|
||||
case sk_catch:
|
||||
current_binding_level->is_catch_scope = 1;
|
||||
break;
|
||||
|
||||
case sk_for:
|
||||
current_binding_level->is_for_scope = 1;
|
||||
break;
|
||||
|
||||
case sk_template_spec:
|
||||
current_binding_level->template_spec_p = 1;
|
||||
/* Fall through. */
|
||||
@ -876,28 +891,6 @@ finish_scope ()
|
||||
poplevel (0, 0, 0);
|
||||
}
|
||||
|
||||
void
|
||||
note_level_for_for ()
|
||||
{
|
||||
current_binding_level->is_for_scope = 1;
|
||||
}
|
||||
|
||||
/* Record that the current binding level represents a try block. */
|
||||
|
||||
void
|
||||
note_level_for_try ()
|
||||
{
|
||||
current_binding_level->is_try_scope = 1;
|
||||
}
|
||||
|
||||
/* Record that the current binding level represents a catch block. */
|
||||
|
||||
void
|
||||
note_level_for_catch ()
|
||||
{
|
||||
current_binding_level->is_catch_scope = 1;
|
||||
}
|
||||
|
||||
/* For a binding between a name and an entity at a block scope,
|
||||
this is the `struct cp_binding_level' for the block. */
|
||||
#define BINDING_LEVEL(NODE) \
|
||||
@ -1394,7 +1387,7 @@ poplevel (keep, reverse, functionbody)
|
||||
|
||||
/* We still support the old for-scope rules, whereby the variables
|
||||
in a for-init statement were in scope after the for-statement
|
||||
ended. We only use the new rules in flag_new_for_scope is
|
||||
ended. We only use the new rules if flag_new_for_scope is
|
||||
nonzero. */
|
||||
leaving_for_scope
|
||||
= current_binding_level->is_for_scope && flag_new_for_scope == 1;
|
||||
@ -8199,8 +8192,6 @@ maybe_inject_for_scope_var (decl)
|
||||
= DECL_SHADOWED_FOR_VAR (BINDING_VALUE (outer_binding));
|
||||
current_binding_level->is_for_scope = 0;
|
||||
}
|
||||
else if (DECL_IN_MEMORY_P (decl))
|
||||
preserve_temp_slots (DECL_RTL (decl));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1198,7 +1198,7 @@ static cp_parser_context *cp_parser_context_new
|
||||
|
||||
/* Class variables. */
|
||||
|
||||
static GTY(()) cp_parser_context* cp_parser_context_free_list;
|
||||
static GTY((deletable (""))) cp_parser_context* cp_parser_context_free_list;
|
||||
|
||||
/* Constructors and destructors. */
|
||||
|
||||
@ -8332,7 +8332,6 @@ cp_parser_template_argument (parser)
|
||||
|
||||
Therefore, we try a type-id first. */
|
||||
cp_parser_parse_tentatively (parser);
|
||||
/* Otherwise, try a type-id. */
|
||||
argument = cp_parser_type_id (parser);
|
||||
/* If the next token isn't a `,' or a `>', then this argument wasn't
|
||||
really finished. */
|
||||
|
@ -7483,13 +7483,6 @@ tsubst_expr (t, args, complain, in_decl)
|
||||
|
||||
switch (TREE_CODE (t))
|
||||
{
|
||||
case RETURN_INIT:
|
||||
prep_stmt (t);
|
||||
finish_named_return_value
|
||||
(TREE_OPERAND (t, 0),
|
||||
tsubst_expr (TREE_OPERAND (t, 1), args, complain, in_decl));
|
||||
break;
|
||||
|
||||
case CTOR_INITIALIZER:
|
||||
prep_stmt (t);
|
||||
finish_mem_initializers (tsubst_initializer_list
|
||||
|
@ -58,7 +58,6 @@ static void emit_associated_thunks PARAMS ((tree));
|
||||
static void genrtl_try_block PARAMS ((tree));
|
||||
static void genrtl_eh_spec_block PARAMS ((tree));
|
||||
static void genrtl_handler PARAMS ((tree));
|
||||
static void genrtl_named_return_value PARAMS ((void));
|
||||
static void cp_expand_stmt PARAMS ((tree));
|
||||
static void genrtl_start_function PARAMS ((tree));
|
||||
static void genrtl_finish_function PARAMS ((tree));
|
||||
@ -145,13 +144,13 @@ do_poplevel ()
|
||||
/* Begin a new scope. */
|
||||
|
||||
void
|
||||
do_pushlevel ()
|
||||
do_pushlevel (scope_kind sk)
|
||||
{
|
||||
if (stmts_are_full_exprs_p ())
|
||||
{
|
||||
if (!processing_template_decl)
|
||||
add_scope_stmt (/*begin_p=*/1, /*partial_p=*/0);
|
||||
pushlevel (0);
|
||||
begin_scope (sk);
|
||||
}
|
||||
}
|
||||
|
||||
@ -245,7 +244,7 @@ tree
|
||||
begin_if_stmt ()
|
||||
{
|
||||
tree r;
|
||||
do_pushlevel ();
|
||||
do_pushlevel (sk_block);
|
||||
r = build_stmt (IF_STMT, NULL_TREE, NULL_TREE, NULL_TREE);
|
||||
add_stmt (r);
|
||||
return r;
|
||||
@ -309,7 +308,7 @@ begin_while_stmt ()
|
||||
tree r;
|
||||
r = build_stmt (WHILE_STMT, NULL_TREE, NULL_TREE);
|
||||
add_stmt (r);
|
||||
do_pushlevel ();
|
||||
do_pushlevel (sk_block);
|
||||
return r;
|
||||
}
|
||||
|
||||
@ -429,10 +428,7 @@ begin_for_stmt ()
|
||||
NULL_TREE, NULL_TREE);
|
||||
NEW_FOR_SCOPE_P (r) = flag_new_for_scope > 0;
|
||||
if (NEW_FOR_SCOPE_P (r))
|
||||
{
|
||||
do_pushlevel ();
|
||||
note_level_for_for ();
|
||||
}
|
||||
do_pushlevel (sk_for);
|
||||
add_stmt (r);
|
||||
|
||||
return r;
|
||||
@ -447,7 +443,7 @@ finish_for_init_stmt (for_stmt)
|
||||
{
|
||||
if (last_tree != for_stmt)
|
||||
RECHAIN_STMTS (for_stmt, FOR_INIT_STMT (for_stmt));
|
||||
do_pushlevel ();
|
||||
do_pushlevel (sk_block);
|
||||
}
|
||||
|
||||
/* Finish the COND of a for-statement, which may be given by
|
||||
@ -534,7 +530,7 @@ tree
|
||||
begin_switch_stmt ()
|
||||
{
|
||||
tree r;
|
||||
do_pushlevel ();
|
||||
do_pushlevel (sk_block);
|
||||
r = build_stmt (SWITCH_STMT, NULL_TREE, NULL_TREE, NULL_TREE);
|
||||
add_stmt (r);
|
||||
return r;
|
||||
@ -766,8 +762,7 @@ begin_handler ()
|
||||
add_stmt (r);
|
||||
/* Create a binding level for the eh_info and the exception object
|
||||
cleanup. */
|
||||
do_pushlevel ();
|
||||
note_level_for_catch ();
|
||||
do_pushlevel (sk_catch);
|
||||
return r;
|
||||
}
|
||||
|
||||
@ -834,11 +829,7 @@ begin_compound_stmt (has_no_scope)
|
||||
last_expr_type = NULL_TREE;
|
||||
|
||||
if (!has_no_scope)
|
||||
{
|
||||
do_pushlevel ();
|
||||
if (is_try)
|
||||
note_level_for_try ();
|
||||
}
|
||||
do_pushlevel (is_try ? sk_try : sk_block);
|
||||
else
|
||||
/* Normally, we try hard to keep the BLOCK for a
|
||||
statement-expression. But, if it's a statement-expression with
|
||||
@ -1013,88 +1004,6 @@ finish_eh_cleanup (cleanup)
|
||||
add_stmt (r);
|
||||
}
|
||||
|
||||
/* Generate the RTL for a RETURN_INIT. */
|
||||
|
||||
static void
|
||||
genrtl_named_return_value ()
|
||||
{
|
||||
tree decl = DECL_RESULT (current_function_decl);
|
||||
|
||||
/* If this named return value comes in a register, put it in a
|
||||
pseudo-register. */
|
||||
if (DECL_REGISTER (decl))
|
||||
{
|
||||
/* Note that the mode of the old DECL_RTL may be wider than the
|
||||
mode of DECL_RESULT, depending on the calling conventions for
|
||||
the processor. For example, on the Alpha, a 32-bit integer
|
||||
is returned in a DImode register -- the DECL_RESULT has
|
||||
SImode but the DECL_RTL for the DECL_RESULT has DImode. So,
|
||||
here, we use the mode the back-end has already assigned for
|
||||
the return value. */
|
||||
SET_DECL_RTL (decl, gen_reg_rtx (GET_MODE (DECL_RTL (decl))));
|
||||
if (TREE_ADDRESSABLE (decl))
|
||||
put_var_into_stack (decl);
|
||||
}
|
||||
|
||||
emit_local_var (decl);
|
||||
}
|
||||
|
||||
/* Bind a name and initialization to the return value of
|
||||
the current function. */
|
||||
|
||||
void
|
||||
finish_named_return_value (return_id, init)
|
||||
tree return_id, init;
|
||||
{
|
||||
tree decl = DECL_RESULT (current_function_decl);
|
||||
|
||||
/* Give this error as many times as there are occurrences, so that
|
||||
users can use Emacs compilation buffers to find and fix all such
|
||||
places. */
|
||||
if (pedantic)
|
||||
pedwarn ("ISO C++ does not permit named return values");
|
||||
cp_deprecated ("the named return value extension");
|
||||
|
||||
if (return_id != NULL_TREE)
|
||||
{
|
||||
if (DECL_NAME (decl) == NULL_TREE)
|
||||
DECL_NAME (decl) = return_id;
|
||||
else
|
||||
{
|
||||
error ("return identifier `%D' already in place", return_id);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
/* Can't let this happen for constructors. */
|
||||
if (DECL_CONSTRUCTOR_P (current_function_decl))
|
||||
{
|
||||
error ("can't redefine default return value for constructors");
|
||||
return;
|
||||
}
|
||||
|
||||
/* If we have a named return value, put that in our scope as well. */
|
||||
if (DECL_NAME (decl) != NULL_TREE)
|
||||
{
|
||||
/* Let `cp_finish_decl' know that this initializer is ok. */
|
||||
DECL_INITIAL (decl) = init;
|
||||
if (doing_semantic_analysis_p ())
|
||||
pushdecl (decl);
|
||||
if (!processing_template_decl)
|
||||
{
|
||||
cp_finish_decl (decl, init, NULL_TREE, 0);
|
||||
add_stmt (build_stmt (RETURN_INIT, NULL_TREE, NULL_TREE));
|
||||
}
|
||||
else
|
||||
add_stmt (build_stmt (RETURN_INIT, return_id, init));
|
||||
}
|
||||
|
||||
/* Don't use tree-inlining for functions with named return values.
|
||||
That doesn't work properly because we don't do any translation of
|
||||
the RETURN_INITs when they are copied. */
|
||||
DECL_UNINLINABLE (current_function_decl) = 1;
|
||||
}
|
||||
|
||||
/* Begin processing a mem-initializer-list. */
|
||||
|
||||
void
|
||||
@ -2267,10 +2176,6 @@ cp_expand_stmt (t)
|
||||
genrtl_handler (t);
|
||||
break;
|
||||
|
||||
case RETURN_INIT:
|
||||
genrtl_named_return_value ();
|
||||
break;
|
||||
|
||||
case USING_STMT:
|
||||
break;
|
||||
|
||||
|
@ -1104,7 +1104,6 @@ cp_statement_code_p (code)
|
||||
switch (code)
|
||||
{
|
||||
case CTOR_INITIALIZER:
|
||||
case RETURN_INIT:
|
||||
case TRY_BLOCK:
|
||||
case HANDLER:
|
||||
case EH_SPEC_BLOCK:
|
||||
|
@ -1,5 +1,7 @@
|
||||
2002-12-31 Mark Mitchell <mark@codesourcery.com>
|
||||
|
||||
* g++.dg/init/array9.C: New test.
|
||||
|
||||
PR c++/9112
|
||||
* g++.dg/parse/expr1.C: New test.
|
||||
|
||||
|
9
gcc/testsuite/g++.dg/init/array9.C
Normal file
9
gcc/testsuite/g++.dg/init/array9.C
Normal file
@ -0,0 +1,9 @@
|
||||
struct T {
|
||||
T ();
|
||||
};
|
||||
|
||||
void f () {
|
||||
T t[2];
|
||||
for (int i = 0; i < 10; ++i);
|
||||
int i = 0;
|
||||
}
|
Loading…
Reference in New Issue
Block a user