mirror of
git://gcc.gnu.org/git/gcc.git
synced 2025-03-11 02:16:48 +08:00
cp-tree.h (language_function): Rename expanding_p to x_expanding_p.
* cp-tree.h (language_function): Rename expanding_p to x_expanding_p. Rename named_label_uses to x_named_label_uses. (expanding_p): Adjust accordingly. (TREE_VIA_PRIVATE): Fix typo in comment. (DECL_REFERENCE_SLOT): Remove. (SET_DECL_REFERENCE_SLOT): Likewise. * decl.c (named_label_uses): Adjust. Remove chicken comment. (push_overloaded_decl): Don't truncate the chain of bindings when adding an overloaded function. (grok_reference_init): Don't use DECL_REFERENCE_SLOT. (initialize_local_var): Fix typo in comment. (store_parm_decls): Don't set DECL_REFERENCE_SLOT. Tidy up. * decl2.c (start_objects): Make the fact that we are expanding the generated function right away explicit. (start_static_storage_duration_function): Likewise. (finish_file): Fix typo in comment. * init.c (build_vec_init): Correct bugs in handling cleanups. * semantics.c (maybe_convert_cond): New function. (FINISH_COND): Always store the condition, even if there's a declaration. (finish_if_stmt_cond): Use maybe_convert_cond. (finish_while_stmt_cond): Likewise. (finish_do_stmt): Likewise. (finish_for_cond): Likewise. (expand_cond): Adjust. From-SVN: r29265
This commit is contained in:
parent
efa8eda3b8
commit
ed5511d94e
@ -1,5 +1,31 @@
|
||||
1999-09-10 Mark Mitchell <mark@codesourcery.com>
|
||||
|
||||
* cp-tree.h (language_function): Rename expanding_p to
|
||||
x_expanding_p. Rename named_label_uses to x_named_label_uses.
|
||||
(expanding_p): Adjust accordingly.
|
||||
(TREE_VIA_PRIVATE): Fix typo in comment.
|
||||
(DECL_REFERENCE_SLOT): Remove.
|
||||
(SET_DECL_REFERENCE_SLOT): Likewise.
|
||||
* decl.c (named_label_uses): Adjust. Remove chicken comment.
|
||||
(push_overloaded_decl): Don't truncate the chain of bindings when
|
||||
adding an overloaded function.
|
||||
(grok_reference_init): Don't use DECL_REFERENCE_SLOT.
|
||||
(initialize_local_var): Fix typo in comment.
|
||||
(store_parm_decls): Don't set DECL_REFERENCE_SLOT. Tidy up.
|
||||
* decl2.c (start_objects): Make the fact that we are expanding
|
||||
the generated function right away explicit.
|
||||
(start_static_storage_duration_function): Likewise.
|
||||
(finish_file): Fix typo in comment.
|
||||
* init.c (build_vec_init): Correct bugs in handling cleanups.
|
||||
* semantics.c (maybe_convert_cond): New function.
|
||||
(FINISH_COND): Always store the condition, even if there's
|
||||
a declaration.
|
||||
(finish_if_stmt_cond): Use maybe_convert_cond.
|
||||
(finish_while_stmt_cond): Likewise.
|
||||
(finish_do_stmt): Likewise.
|
||||
(finish_for_cond): Likewise.
|
||||
(expand_cond): Adjust.
|
||||
|
||||
* cp-tree.h (FN_TRY_BLOCK_P): New macro.
|
||||
* init.c (perform_member_init): Remove obstack machinations.
|
||||
(expand_cleanup_for_base): Likewise.
|
||||
|
@ -634,10 +634,10 @@ struct language_function
|
||||
int temp_name_counter;
|
||||
int static_labelno;
|
||||
int in_function_try_handler;
|
||||
int expanding_p;
|
||||
int x_expanding_p;
|
||||
int stmts_are_full_exprs_p;
|
||||
|
||||
struct named_label_list *named_label_uses;
|
||||
struct named_label_list *x_named_label_uses;
|
||||
struct binding_level *bindings;
|
||||
};
|
||||
|
||||
@ -719,7 +719,7 @@ struct language_function
|
||||
When this is zero, we just accumulate tree structure, without
|
||||
interacting with the back end. */
|
||||
|
||||
#define expanding_p cp_function_chain->expanding_p
|
||||
#define expanding_p cp_function_chain->x_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
|
||||
@ -1384,7 +1384,7 @@ struct lang_type
|
||||
|
||||
We use TREE_VIA_PROTECTED and TREE_VIA_PUBLIC, but private
|
||||
inheritance is indicated by the absence of the other two flags, not
|
||||
by TREE_VIAR_PRIVATE, which is unused.
|
||||
by TREE_VIA_PRIVATE, which is unused.
|
||||
|
||||
The TREE_CHAIN is for scratch space in search.c. */
|
||||
|
||||
@ -2185,11 +2185,6 @@ extern int flag_new_for_scope;
|
||||
protected_access_node will appear in the DECL_ACCESS for the node. */
|
||||
#define DECL_ACCESS(NODE) (DECL_LANG_SPECIFIC(NODE)->decl_flags.access)
|
||||
|
||||
/* C++: all of these are overloaded!
|
||||
These apply to PARM_DECLs and VAR_DECLs. */
|
||||
#define DECL_REFERENCE_SLOT(NODE) ((tree)(NODE)->decl.arguments)
|
||||
#define SET_DECL_REFERENCE_SLOT(NODE,VAL) ((NODE)->decl.arguments=VAL)
|
||||
|
||||
/* Accessor macros for C++ template decl nodes. */
|
||||
|
||||
/* The DECL_TEMPLATE_PARMS are a list. The TREE_PURPOSE of each node
|
||||
|
@ -338,24 +338,10 @@ struct named_label_list
|
||||
struct named_label_list *next;
|
||||
};
|
||||
|
||||
/* A list (chain of TREE_LIST nodes) of named label uses.
|
||||
The TREE_PURPOSE field is the list of variables defined
|
||||
in the label's scope defined at the point of use.
|
||||
The TREE_VALUE field is the LABEL_DECL used.
|
||||
The TREE_TYPE field holds `current_binding_level' at the
|
||||
point of the label's use.
|
||||
/* Used only for jumps to as-yet undefined labels, since jumps to
|
||||
defined labels can have their validity checked by stmt.c. */
|
||||
|
||||
BWAHAHAAHAHahhahahahaah. No, no, no, said the little chicken.
|
||||
|
||||
Look at the pretty struct named_label_list. See the pretty struct
|
||||
with the pretty named fields that describe what they do. See the
|
||||
pretty lack of gratuitous casts. Notice the code got a lot cleaner.
|
||||
|
||||
Used only for jumps to as-yet undefined labels, since
|
||||
jumps to defined labels can have their validity checked
|
||||
by stmt.c. */
|
||||
|
||||
#define named_label_uses cp_function_chain->named_label_uses
|
||||
#define named_label_uses cp_function_chain->x_named_label_uses
|
||||
|
||||
/* A list of objects which have constructors or destructors
|
||||
which reside in the global scope. The decl is stored in
|
||||
@ -4529,7 +4515,8 @@ push_overloaded_decl (decl, flags)
|
||||
TREE_VALUE (*d) = new_binding;
|
||||
else
|
||||
/* Build a TREE_LIST to wrap the OVERLOAD. */
|
||||
*d = build_tree_list (NULL_TREE, new_binding);
|
||||
*d = tree_cons (NULL_TREE, new_binding,
|
||||
TREE_CHAIN (*d));
|
||||
|
||||
/* And update the CPLUS_BINDING node. */
|
||||
BINDING_VALUE (IDENTIFIER_BINDING (name))
|
||||
@ -7118,19 +7105,14 @@ grok_reference_init (decl, type, init)
|
||||
if ((DECL_LANG_SPECIFIC (decl) == 0
|
||||
|| DECL_IN_AGGR_P (decl) == 0)
|
||||
&& ! DECL_THIS_EXTERN (decl))
|
||||
{
|
||||
cp_error ("`%D' declared as reference but not initialized", decl);
|
||||
if (TREE_CODE (decl) == VAR_DECL)
|
||||
SET_DECL_REFERENCE_SLOT (decl, error_mark_node);
|
||||
}
|
||||
cp_error ("`%D' declared as reference but not initialized", decl);
|
||||
return;
|
||||
}
|
||||
|
||||
if (init == error_mark_node)
|
||||
return;
|
||||
|
||||
if (TREE_CODE (type) == REFERENCE_TYPE
|
||||
&& TREE_CODE (init) == CONSTRUCTOR)
|
||||
if (TREE_CODE (init) == CONSTRUCTOR)
|
||||
{
|
||||
cp_error ("ANSI C++ forbids use of initializer list to initialize reference `%D'", decl);
|
||||
return;
|
||||
@ -7154,7 +7136,7 @@ grok_reference_init (decl, type, init)
|
||||
LOOKUP_SPECULATIVELY|LOOKUP_NORMAL|DIRECT_BIND, decl);
|
||||
|
||||
if (tmp == error_mark_node)
|
||||
goto fail;
|
||||
return;
|
||||
else if (tmp != NULL_TREE)
|
||||
{
|
||||
init = tmp;
|
||||
@ -7163,16 +7145,13 @@ grok_reference_init (decl, type, init)
|
||||
else
|
||||
{
|
||||
cp_error ("cannot initialize `%T' from `%T'", type, TREE_TYPE (init));
|
||||
goto fail;
|
||||
return;
|
||||
}
|
||||
|
||||
/* ?? Can this be optimized in some cases to
|
||||
hand back the DECL_INITIAL slot?? */
|
||||
if (TYPE_SIZE (TREE_TYPE (type)))
|
||||
{
|
||||
init = convert_from_reference (decl);
|
||||
SET_DECL_REFERENCE_SLOT (decl, init);
|
||||
}
|
||||
init = convert_from_reference (decl);
|
||||
|
||||
if (TREE_STATIC (decl) && ! TREE_CONSTANT (DECL_INITIAL (decl)))
|
||||
{
|
||||
@ -7180,11 +7159,6 @@ grok_reference_init (decl, type, init)
|
||||
DECL_INITIAL (decl) = NULL_TREE;
|
||||
}
|
||||
return;
|
||||
|
||||
fail:
|
||||
if (TREE_CODE (decl) == VAR_DECL)
|
||||
SET_DECL_REFERENCE_SLOT (decl, error_mark_node);
|
||||
return;
|
||||
}
|
||||
|
||||
/* Fill in DECL_INITIAL with some magical value to prevent expand_decl from
|
||||
@ -7686,7 +7660,7 @@ maybe_inject_for_scope_var (decl)
|
||||
}
|
||||
}
|
||||
|
||||
/* Generate code to initialized DECL (a local variable). */
|
||||
/* Generate code to initialize DECL (a local variable). */
|
||||
|
||||
void
|
||||
initialize_local_var (decl, init, flags)
|
||||
@ -13342,26 +13316,7 @@ store_parm_decls ()
|
||||
else if (TREE_CODE (TREE_TYPE (parm)) == VOID_TYPE)
|
||||
cp_error ("parameter `%D' declared void", parm);
|
||||
else
|
||||
{
|
||||
/* Now fill in DECL_REFERENCE_SLOT for any of the parm decls.
|
||||
A parameter is assumed not to have any side effects.
|
||||
If this should change for any reason, then this
|
||||
will have to wrap the bashed reference type in a save_expr.
|
||||
|
||||
Also, if the parameter type is declared to be an X
|
||||
and there is an X(X&) constructor, we cannot lay it
|
||||
into the stack (any more), so we make this parameter
|
||||
look like it is really of reference type. Functions
|
||||
which pass parameters to this function will know to
|
||||
create a temporary in their frame, and pass a reference
|
||||
to that. */
|
||||
|
||||
if (TREE_CODE (TREE_TYPE (parm)) == REFERENCE_TYPE
|
||||
&& TYPE_SIZE (TREE_TYPE (TREE_TYPE (parm))))
|
||||
SET_DECL_REFERENCE_SLOT (parm, convert_from_reference (parm));
|
||||
|
||||
pushdecl (parm);
|
||||
}
|
||||
pushdecl (parm);
|
||||
if (! building_stmt_tree ()
|
||||
&& (cleanup = maybe_build_cleanup (parm), cleanup))
|
||||
{
|
||||
@ -13418,9 +13373,12 @@ store_parm_decls ()
|
||||
should not be called before the parm can be used. */
|
||||
if (cleanups && !building_stmt_tree ())
|
||||
{
|
||||
for (cleanups = nreverse (cleanups); cleanups; cleanups = TREE_CHAIN (cleanups))
|
||||
for (cleanups = nreverse (cleanups);
|
||||
cleanups;
|
||||
cleanups = TREE_CHAIN (cleanups))
|
||||
{
|
||||
if (! expand_decl_cleanup (TREE_PURPOSE (cleanups), TREE_VALUE (cleanups)))
|
||||
if (! expand_decl_cleanup (TREE_PURPOSE (cleanups),
|
||||
TREE_VALUE (cleanups)))
|
||||
cp_error ("parser lost in parsing declaration of `%D'",
|
||||
TREE_PURPOSE (cleanups));
|
||||
}
|
||||
|
@ -2819,7 +2819,7 @@ start_objects (method_type, initp)
|
||||
start_function (void_list_node,
|
||||
make_call_declarator (fnname, void_list_node, NULL_TREE,
|
||||
NULL_TREE),
|
||||
NULL_TREE, SF_DEFAULT);
|
||||
NULL_TREE, SF_DEFAULT | SF_EXPAND);
|
||||
|
||||
#if defined(ASM_OUTPUT_CONSTRUCTOR) && defined(ASM_OUTPUT_DESTRUCTOR)
|
||||
/* It can be a static function as long as collect2 does not have
|
||||
@ -3008,7 +3008,7 @@ start_static_storage_duration_function ()
|
||||
start_function (/*specs=*/NULL_TREE,
|
||||
ssdf_decl,
|
||||
/*attrs=*/NULL_TREE,
|
||||
SF_DEFAULT | SF_PRE_PARSED);
|
||||
SF_PRE_PARSED | SF_EXPAND);
|
||||
|
||||
/* Set up the scope of the outermost block in the function. */
|
||||
store_parm_decls ();
|
||||
@ -3640,7 +3640,7 @@ finish_file ()
|
||||
finish_repo ();
|
||||
|
||||
/* The entire file is now complete. If requested, dump everything
|
||||
file. */
|
||||
to a file. */
|
||||
if (flag_dump_translation_unit)
|
||||
dump_node_to_file (global_namespace, flag_dump_translation_unit);
|
||||
|
||||
|
@ -2732,6 +2732,7 @@ build_vec_init (decl, base, maxindex, init, from_array)
|
||||
tree compound_stmt;
|
||||
int destroy_temps;
|
||||
tree try_block = NULL_TREE;
|
||||
tree try_body;
|
||||
int num_initialized_elts = 0;
|
||||
|
||||
maxindex = cp_convert (ptrdiff_type_node, maxindex);
|
||||
@ -2796,7 +2797,10 @@ build_vec_init (decl, base, maxindex, init, from_array)
|
||||
/* Protect the entire array initialization so that we can destroy
|
||||
the partially constructed array if an exception is thrown. */
|
||||
if (flag_exceptions && TYPE_NEEDS_DESTRUCTOR (type))
|
||||
try_block = begin_try_block ();
|
||||
{
|
||||
try_block = begin_try_block ();
|
||||
try_body = begin_compound_stmt (/*has_no_scope=*/1);
|
||||
}
|
||||
|
||||
if (init != NULL_TREE && TREE_CODE (init) == CONSTRUCTOR
|
||||
&& (!decl || same_type_p (TREE_TYPE (init), TREE_TYPE (decl))))
|
||||
@ -2991,10 +2995,8 @@ build_vec_init (decl, base, maxindex, init, from_array)
|
||||
{
|
||||
tree e;
|
||||
|
||||
/* Because CLEANUP will not be processed until later, it must go
|
||||
on the temporary obstack. */
|
||||
push_obstacks_nochange ();
|
||||
resume_temporary_allocation ();
|
||||
finish_compound_stmt (/*has_no_scope=*/1, try_body);
|
||||
finish_cleanup_try_block (try_block);
|
||||
e = build_vec_delete_1 (rval,
|
||||
build_binary_op (MINUS_EXPR, maxindex,
|
||||
iterator),
|
||||
@ -3002,7 +3004,6 @@ build_vec_init (decl, base, maxindex, init, from_array)
|
||||
/*auto_delete_vec=*/integer_zero_node,
|
||||
/*auto_delete=*/integer_zero_node,
|
||||
/*use_global_delete=*/0);
|
||||
pop_obstacks ();
|
||||
finish_cleanup (e, try_block);
|
||||
}
|
||||
|
||||
|
@ -45,6 +45,7 @@ static void do_pushlevel PROTO((void));
|
||||
static tree do_poplevel PROTO((void));
|
||||
static void finish_expr_stmt_real PROTO((tree, int));
|
||||
static tree expand_cond PROTO((tree));
|
||||
static tree maybe_convert_cond PROTO((tree));
|
||||
|
||||
/* When parsing a template, LAST_TREE contains the last statement
|
||||
parsed. These are chained together through the TREE_CHAIN field,
|
||||
@ -61,12 +62,19 @@ static tree expand_cond PROTO((tree));
|
||||
|
||||
/* Finish processing the COND, the SUBSTMT condition for STMT. */
|
||||
|
||||
#define FINISH_COND(cond, stmt, substmt) \
|
||||
do { \
|
||||
if (last_tree != stmt) \
|
||||
RECHAIN_STMTS (stmt, substmt); \
|
||||
else \
|
||||
substmt = cond; \
|
||||
#define FINISH_COND(cond, stmt, substmt) \
|
||||
do { \
|
||||
if (last_tree != stmt) \
|
||||
{ \
|
||||
RECHAIN_STMTS (stmt, substmt); \
|
||||
if (!processing_template_decl) \
|
||||
{ \
|
||||
cond = build_tree_list (substmt, cond); \
|
||||
substmt = cond; \
|
||||
} \
|
||||
} \
|
||||
else \
|
||||
substmt = cond; \
|
||||
} while (0)
|
||||
|
||||
/* T is a statement. Add it to the statement-tree. */
|
||||
@ -84,6 +92,26 @@ add_tree (t)
|
||||
STMT_IS_FULL_EXPR_P (last_tree) = stmts_are_full_exprs_p;
|
||||
}
|
||||
|
||||
/* COND is the condition-expression for an if, while, etc.,
|
||||
statement. Convert it to a boolean value, if appropriate. */
|
||||
|
||||
static tree
|
||||
maybe_convert_cond (cond)
|
||||
tree cond;
|
||||
{
|
||||
/* Empty conditions remain empty. */
|
||||
if (!cond)
|
||||
return NULL_TREE;
|
||||
|
||||
/* Wait until we instantiate templates before doing conversion. */
|
||||
if (processing_template_decl)
|
||||
return cond;
|
||||
|
||||
/* Do the conversion. */
|
||||
cond = convert_from_reference (cond);
|
||||
return condition_conversion (cond);
|
||||
}
|
||||
|
||||
/* Finish an expression-statement, whose EXPRESSION is as indicated.
|
||||
If ASSIGNED_THIS is non-zero, then this statement just assigned to
|
||||
the `this' pointer. */
|
||||
@ -171,12 +199,14 @@ finish_if_stmt_cond (cond, if_stmt)
|
||||
tree cond;
|
||||
tree if_stmt;
|
||||
{
|
||||
cond = maybe_convert_cond (cond);
|
||||
|
||||
if (building_stmt_tree ())
|
||||
FINISH_COND (cond, if_stmt, IF_COND (if_stmt));
|
||||
else
|
||||
{
|
||||
emit_line_note (input_filename, lineno);
|
||||
expand_start_cond (condition_conversion (cond), 0);
|
||||
expand_start_cond (cond, 0);
|
||||
}
|
||||
}
|
||||
|
||||
@ -263,12 +293,14 @@ finish_while_stmt_cond (cond, while_stmt)
|
||||
tree cond;
|
||||
tree while_stmt;
|
||||
{
|
||||
cond = maybe_convert_cond (cond);
|
||||
|
||||
if (building_stmt_tree ())
|
||||
FINISH_COND (cond, while_stmt, WHILE_COND (while_stmt));
|
||||
else
|
||||
{
|
||||
emit_line_note (input_filename, lineno);
|
||||
expand_exit_loop_if_false (0, condition_conversion (cond));
|
||||
expand_exit_loop_if_false (0, cond);
|
||||
}
|
||||
|
||||
/* If COND wasn't a declaration, clear out the
|
||||
@ -337,12 +369,14 @@ finish_do_stmt (cond, do_stmt)
|
||||
tree cond;
|
||||
tree do_stmt;
|
||||
{
|
||||
cond = maybe_convert_cond (cond);
|
||||
|
||||
if (building_stmt_tree ())
|
||||
DO_COND (do_stmt) = cond;
|
||||
else
|
||||
{
|
||||
emit_line_note (input_filename, lineno);
|
||||
expand_exit_loop_if_false (0, condition_conversion (cond));
|
||||
expand_exit_loop_if_false (0, cond);
|
||||
expand_end_loop ();
|
||||
}
|
||||
|
||||
@ -423,13 +457,15 @@ finish_for_cond (cond, for_stmt)
|
||||
tree cond;
|
||||
tree for_stmt;
|
||||
{
|
||||
cond = maybe_convert_cond (cond);
|
||||
|
||||
if (building_stmt_tree ())
|
||||
FINISH_COND (cond, for_stmt, FOR_COND (for_stmt));
|
||||
else
|
||||
{
|
||||
emit_line_note (input_filename, lineno);
|
||||
if (cond)
|
||||
expand_exit_loop_if_false (0, condition_conversion (cond));
|
||||
expand_exit_loop_if_false (0, cond);
|
||||
}
|
||||
|
||||
/* If the cond wasn't a declaration, clear out the
|
||||
@ -2038,10 +2074,10 @@ static tree
|
||||
expand_cond (t)
|
||||
tree t;
|
||||
{
|
||||
if (t && TREE_CODE (t) == DECL_STMT)
|
||||
if (t && TREE_CODE (t) == TREE_LIST)
|
||||
{
|
||||
expand_stmt (t);
|
||||
return convert_from_reference (DECL_STMT_DECL (t));
|
||||
expand_stmt (TREE_PURPOSE (t));
|
||||
return TREE_VALUE (t);
|
||||
}
|
||||
else
|
||||
return t;
|
||||
|
Loading…
Reference in New Issue
Block a user