* 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
+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
/* 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
&& 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
/* 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
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));
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));
/* 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 */
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. */
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) \
/* 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;
= 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));
}
}
/* 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. */
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. */
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
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));
/* 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);
}
}
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;
tree r;
r = build_stmt (WHILE_STMT, NULL_TREE, NULL_TREE);
add_stmt (r);
- do_pushlevel ();
+ do_pushlevel (sk_block);
return r;
}
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;
{
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
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;
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;
}
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
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
genrtl_handler (t);
break;
- case RETURN_INIT:
- genrtl_named_return_value ();
- break;
-
case USING_STMT:
break;
switch (code)
{
case CTOR_INITIALIZER:
- case RETURN_INIT:
case TRY_BLOCK:
case HANDLER:
case EH_SPEC_BLOCK:
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.
--- /dev/null
+struct T {
+ T ();
+};
+
+void f () {
+ T t[2];
+ for (int i = 0; i < 10; ++i);
+ int i = 0;
+}