decl2.c (start_objects, [...]): Split out from...
* decl2.c (start_objects, finish_objects, do_dtors, do_ctors): Split out from... (finish_file): ...here. From-SVN: r19904
This commit is contained in:
parent
2a3215614b
commit
961ec1a55f
|
@ -1,3 +1,9 @@
|
|||
Wed May 20 02:16:01 1998 Jason Merrill <jason@yorick.cygnus.com>
|
||||
|
||||
* decl2.c (start_objects, finish_objects, do_dtors,
|
||||
do_ctors): Split out from...
|
||||
(finish_file): ...here.
|
||||
|
||||
Tue May 19 20:36:23 1998 Jason Merrill <jason@yorick.cygnus.com>
|
||||
|
||||
* tree.c (is_overloaded_fn): Don't abort on placeholders from
|
||||
|
@ -65,10 +71,6 @@ Tue May 19 02:43:25 1998 Jason Merrill <jason@yorick.cygnus.com>
|
|||
|
||||
Mon May 18 23:22:52 1998 Jason Merrill <jason@yorick.cygnus.com>
|
||||
|
||||
* decl2.c (setup_initp, start_objects, finish_objects): New fns.
|
||||
(do_dtors, do_ctors): Split out from...
|
||||
(finish_file): ...here. Support init_priority.
|
||||
|
||||
* decl2.c (get_sentry): Use end_temporary_allocation.
|
||||
Don't declare permanent_obstack.
|
||||
|
||||
|
@ -9610,10 +9612,3 @@ Wed Oct 11 16:30:34 1995 Brendan Kehoe <brendan@lisa.cygnus.com>
|
|||
|
||||
* parse.y (fn.def1): Call split_specs_attrs in
|
||||
declmods notype_declarator case.
|
||||
|
||||
Use a consistent time stamp format in ChangeLog entries.
|
||||
Not everyone has Emacs 20 yet, so stick with Emacs 19 format for now.
|
||||
|
||||
Local Variables:
|
||||
add-log-time-format: current-time-string
|
||||
End:
|
||||
|
|
|
@ -3926,12 +3926,10 @@ compare_ics (ics1, ics2)
|
|||
if (is_subseq (ics2, ics1))
|
||||
return -1;
|
||||
}
|
||||
else
|
||||
/* One sequence cannot be a subsequence of the other; they don't
|
||||
start with the same type. This can happen when comparing the
|
||||
second standard conversion sequence in two user-defined
|
||||
conversion sequences. */
|
||||
;
|
||||
/* Otherwise, one sequence cannot be a subsequence of the other; they
|
||||
don't start with the same type. This can happen when comparing the
|
||||
second standard conversion sequence in two user-defined conversion
|
||||
sequences. */
|
||||
|
||||
/* [over.ics.rank]
|
||||
|
||||
|
|
384
gcc/cp/decl2.c
384
gcc/cp/decl2.c
|
@ -2800,6 +2800,204 @@ get_sentry (base)
|
|||
return sentry;
|
||||
}
|
||||
|
||||
/* Start the process of running a particular set of global constructors
|
||||
or destructors. Subroutine of do_[cd]tors. */
|
||||
|
||||
static void
|
||||
start_objects (method_type)
|
||||
int method_type;
|
||||
{
|
||||
tree fnname;
|
||||
|
||||
/* Make ctor or dtor function. METHOD_TYPE may be 'I' or 'D'. */
|
||||
|
||||
fnname = get_file_function_name (method_type);
|
||||
|
||||
start_function (void_list_node,
|
||||
make_call_declarator (fnname, void_list_node, NULL_TREE,
|
||||
NULL_TREE),
|
||||
NULL_TREE, 0);
|
||||
|
||||
store_parm_decls ();
|
||||
pushlevel (0);
|
||||
clear_last_expr ();
|
||||
push_momentary ();
|
||||
expand_start_bindings (0);
|
||||
}
|
||||
|
||||
/* Finish the process of running a particular set of global constructors
|
||||
or destructors. Subroutine of do_[cd]tors. */
|
||||
|
||||
static void
|
||||
finish_objects (method_type)
|
||||
int method_type;
|
||||
{
|
||||
char *fnname;
|
||||
|
||||
tree list = (method_type == 'I' ? static_ctors : static_dtors);
|
||||
|
||||
if (! current_function_decl && list)
|
||||
start_objects (method_type);
|
||||
|
||||
for (; list; list = TREE_CHAIN (list))
|
||||
expand_expr_stmt (build_function_call (TREE_VALUE (list), NULL_TREE));
|
||||
|
||||
if (! current_function_decl)
|
||||
return;
|
||||
|
||||
fnname = XSTR (XEXP (DECL_RTL (current_function_decl), 0), 0);
|
||||
|
||||
/* Finish up. */
|
||||
expand_end_bindings (getdecls (), 1, 0);
|
||||
poplevel (1, 0, 0);
|
||||
pop_momentary ();
|
||||
finish_function (lineno, 0, 0);
|
||||
|
||||
if (method_type == 'I')
|
||||
assemble_constructor (fnname);
|
||||
else
|
||||
assemble_destructor (fnname);
|
||||
}
|
||||
|
||||
/* Generate a function to run a set of global destructors. Subroutine of
|
||||
finish_file. */
|
||||
|
||||
static void
|
||||
do_dtors ()
|
||||
{
|
||||
tree vars = static_aggregates;
|
||||
|
||||
for (; vars; vars = TREE_CHAIN (vars))
|
||||
{
|
||||
tree decl = TREE_VALUE (vars);
|
||||
tree type = TREE_TYPE (decl);
|
||||
tree temp;
|
||||
|
||||
if (TYPE_NEEDS_DESTRUCTOR (type) && ! TREE_STATIC (vars)
|
||||
&& ! DECL_EXTERNAL (decl))
|
||||
{
|
||||
int protect = (TREE_PUBLIC (decl) && (DECL_COMMON (decl)
|
||||
|| DECL_ONE_ONLY (decl)
|
||||
|| DECL_WEAK (decl)));
|
||||
|
||||
if (! current_function_decl)
|
||||
start_objects ('D');
|
||||
|
||||
temp = build_cleanup (decl);
|
||||
|
||||
if (protect)
|
||||
{
|
||||
tree sentry = get_sentry (DECL_ASSEMBLER_NAME (decl));
|
||||
sentry = build_unary_op (PREDECREMENT_EXPR, sentry, 0);
|
||||
sentry = build_binary_op (EQ_EXPR, sentry, integer_zero_node, 1);
|
||||
expand_start_cond (sentry, 0);
|
||||
}
|
||||
|
||||
expand_expr_stmt (temp);
|
||||
|
||||
if (protect)
|
||||
expand_end_cond ();
|
||||
}
|
||||
}
|
||||
|
||||
finish_objects ('D');
|
||||
}
|
||||
|
||||
/* Generate a function to run a set of global constructors. Subroutine of
|
||||
finish_file. */
|
||||
|
||||
static void
|
||||
do_ctors ()
|
||||
{
|
||||
tree vars = static_aggregates;
|
||||
|
||||
/* Reverse the list so it's in the right order for ctors. */
|
||||
vars = nreverse (vars);
|
||||
|
||||
for (; vars; vars = TREE_CHAIN (vars))
|
||||
{
|
||||
tree decl = TREE_VALUE (vars);
|
||||
tree init = TREE_PURPOSE (vars);
|
||||
|
||||
/* If this was a static attribute within some function's scope,
|
||||
then don't initialize it here. Also, don't bother
|
||||
with initializers that contain errors. */
|
||||
if (TREE_STATIC (vars)
|
||||
|| DECL_EXTERNAL (decl)
|
||||
|| (init && TREE_CODE (init) == TREE_LIST
|
||||
&& value_member (error_mark_node, init)))
|
||||
continue;
|
||||
|
||||
if (TREE_CODE (decl) == VAR_DECL)
|
||||
{
|
||||
int protect = (TREE_PUBLIC (decl) && (DECL_COMMON (decl)
|
||||
|| DECL_ONE_ONLY (decl)
|
||||
|| DECL_WEAK (decl)));
|
||||
|
||||
if (! current_function_decl)
|
||||
start_objects ('I');
|
||||
|
||||
/* Set these global variables so that GDB at least puts
|
||||
us near the declaration which required the initialization. */
|
||||
input_filename = DECL_SOURCE_FILE (decl);
|
||||
lineno = DECL_SOURCE_LINE (decl);
|
||||
emit_note (input_filename, lineno);
|
||||
|
||||
/* 9.5p5: The initializer of a static member of a class has
|
||||
the same access rights as a member function. */
|
||||
if (member_p (decl))
|
||||
{
|
||||
DECL_CLASS_CONTEXT (current_function_decl)
|
||||
= DECL_CONTEXT (decl);
|
||||
DECL_STATIC_FUNCTION_P (current_function_decl) = 1;
|
||||
}
|
||||
|
||||
if (protect)
|
||||
{
|
||||
tree sentry = get_sentry (DECL_ASSEMBLER_NAME (decl));
|
||||
sentry = build_unary_op (PREINCREMENT_EXPR, sentry, 0);
|
||||
sentry = build_binary_op
|
||||
(EQ_EXPR, sentry, integer_one_node, 1);
|
||||
expand_start_cond (sentry, 0);
|
||||
}
|
||||
|
||||
expand_start_target_temps ();
|
||||
|
||||
if (IS_AGGR_TYPE (TREE_TYPE (decl))
|
||||
|| TREE_CODE (TREE_TYPE (decl)) == ARRAY_TYPE)
|
||||
expand_aggr_init (decl, init, 0, 0);
|
||||
else if (TREE_CODE (init) == TREE_VEC)
|
||||
{
|
||||
expand_expr (expand_vec_init (decl, TREE_VEC_ELT (init, 0),
|
||||
TREE_VEC_ELT (init, 1),
|
||||
TREE_VEC_ELT (init, 2), 0),
|
||||
const0_rtx, VOIDmode, EXPAND_NORMAL);
|
||||
}
|
||||
else
|
||||
expand_assignment (decl, init, 0, 0);
|
||||
|
||||
/* The expression might have involved increments and
|
||||
decrements. */
|
||||
emit_queue ();
|
||||
|
||||
/* Cleanup any temporaries needed for the initial value. */
|
||||
expand_end_target_temps ();
|
||||
|
||||
if (protect)
|
||||
expand_end_cond ();
|
||||
|
||||
DECL_CLASS_CONTEXT (current_function_decl) = NULL_TREE;
|
||||
DECL_STATIC_FUNCTION_P (current_function_decl) = 0;
|
||||
}
|
||||
else if (decl == error_mark_node)
|
||||
/* OK */;
|
||||
else
|
||||
my_friendly_abort (22);
|
||||
}
|
||||
|
||||
finish_objects ('I');
|
||||
}
|
||||
|
||||
/* This routine is called from the last rule in yyparse ().
|
||||
Its job is to create all the code needed to initialize and
|
||||
destroy the global aggregates. We do the destruction
|
||||
|
@ -2901,193 +3099,19 @@ finish_file ()
|
|||
|
||||
if (static_ctors || vars)
|
||||
needs_messing_up = 1;
|
||||
if (static_dtors)
|
||||
if (static_dtors || vars)
|
||||
needs_cleaning = 1;
|
||||
|
||||
/* See if we really need the hassle. */
|
||||
while (vars && needs_cleaning == 0)
|
||||
/* The aggregates are listed in reverse declaration order, for cleaning. */
|
||||
if (needs_cleaning)
|
||||
{
|
||||
tree decl = TREE_VALUE (vars);
|
||||
tree type = TREE_TYPE (decl);
|
||||
if (TYPE_NEEDS_DESTRUCTOR (type) && ! TREE_STATIC (vars))
|
||||
{
|
||||
needs_cleaning = 1;
|
||||
break;
|
||||
}
|
||||
|
||||
vars = TREE_CHAIN (vars);
|
||||
do_dtors ();
|
||||
}
|
||||
|
||||
if (needs_cleaning == 0)
|
||||
goto mess_up;
|
||||
|
||||
fnname = get_file_function_name ('D');
|
||||
start_function (void_list_node,
|
||||
make_call_declarator (fnname, void_list_node, NULL_TREE,
|
||||
NULL_TREE),
|
||||
NULL_TREE, 0);
|
||||
fnname = DECL_ASSEMBLER_NAME (current_function_decl);
|
||||
store_parm_decls ();
|
||||
|
||||
pushlevel (0);
|
||||
clear_last_expr ();
|
||||
push_momentary ();
|
||||
expand_start_bindings (0);
|
||||
|
||||
/* These must be done in backward order to destroy,
|
||||
in which they happen to be! */
|
||||
for (vars = static_aggregates; vars; vars = TREE_CHAIN (vars))
|
||||
{
|
||||
tree decl = TREE_VALUE (vars);
|
||||
tree type = TREE_TYPE (decl);
|
||||
tree temp = TREE_PURPOSE (vars);
|
||||
|
||||
if (TYPE_NEEDS_DESTRUCTOR (type) && ! TREE_STATIC (vars)
|
||||
&& ! DECL_EXTERNAL (decl))
|
||||
{
|
||||
int protect = (TREE_PUBLIC (decl) && (DECL_COMMON (decl)
|
||||
|| DECL_ONE_ONLY (decl)
|
||||
|| DECL_WEAK (decl)));
|
||||
|
||||
temp = build_cleanup (decl);
|
||||
|
||||
if (protect)
|
||||
{
|
||||
tree sentry = get_sentry (DECL_ASSEMBLER_NAME (decl));
|
||||
sentry = build_unary_op (PREDECREMENT_EXPR, sentry, 0);
|
||||
sentry = build_binary_op (EQ_EXPR, sentry, integer_zero_node, 1);
|
||||
expand_start_cond (sentry, 0);
|
||||
}
|
||||
|
||||
expand_expr_stmt (temp);
|
||||
|
||||
if (protect)
|
||||
expand_end_cond ();
|
||||
}
|
||||
}
|
||||
|
||||
for (; static_dtors; static_dtors = TREE_CHAIN (static_dtors))
|
||||
expand_expr_stmt (build_function_call (TREE_VALUE (static_dtors),
|
||||
NULL_TREE));
|
||||
|
||||
expand_end_bindings (getdecls (), 1, 0);
|
||||
poplevel (1, 0, 0);
|
||||
pop_momentary ();
|
||||
|
||||
finish_function (lineno, 0, 0);
|
||||
|
||||
assemble_destructor (IDENTIFIER_POINTER (fnname));
|
||||
|
||||
/* If it needed cleaning, then it will need messing up: drop through. */
|
||||
|
||||
mess_up:
|
||||
/* Must do this while we think we are at the top level. */
|
||||
vars = nreverse (static_aggregates);
|
||||
/* do_ctors will reverse the lists for messing up. */
|
||||
if (needs_messing_up)
|
||||
{
|
||||
fnname = get_file_function_name ('I');
|
||||
start_function (void_list_node,
|
||||
make_call_declarator (fnname, void_list_node, NULL_TREE,
|
||||
NULL_TREE),
|
||||
NULL_TREE, 0);
|
||||
fnname = DECL_ASSEMBLER_NAME (current_function_decl);
|
||||
store_parm_decls ();
|
||||
|
||||
pushlevel (0);
|
||||
clear_last_expr ();
|
||||
push_momentary ();
|
||||
expand_start_bindings (0);
|
||||
|
||||
while (vars)
|
||||
{
|
||||
tree decl = TREE_VALUE (vars);
|
||||
tree init = TREE_PURPOSE (vars);
|
||||
|
||||
/* If this was a static attribute within some function's scope,
|
||||
then don't initialize it here. Also, don't bother
|
||||
with initializers that contain errors. */
|
||||
if (TREE_STATIC (vars)
|
||||
|| DECL_EXTERNAL (decl)
|
||||
|| (init && TREE_CODE (init) == TREE_LIST
|
||||
&& value_member (error_mark_node, init)))
|
||||
goto next_mess;
|
||||
|
||||
if (TREE_CODE (decl) == VAR_DECL)
|
||||
{
|
||||
int protect = (TREE_PUBLIC (decl) && (DECL_COMMON (decl)
|
||||
|| DECL_ONE_ONLY (decl)
|
||||
|| DECL_WEAK (decl)));
|
||||
|
||||
/* Set these global variables so that GDB at least puts
|
||||
us near the declaration which required the initialization. */
|
||||
input_filename = DECL_SOURCE_FILE (decl);
|
||||
lineno = DECL_SOURCE_LINE (decl);
|
||||
emit_note (input_filename, lineno);
|
||||
|
||||
/* 9.5p5: The initializer of a static member of a class has
|
||||
the same access rights as a member function. */
|
||||
if (member_p (decl))
|
||||
{
|
||||
DECL_CLASS_CONTEXT (current_function_decl)
|
||||
= DECL_CONTEXT (decl);
|
||||
DECL_STATIC_FUNCTION_P (current_function_decl) = 1;
|
||||
}
|
||||
|
||||
if (protect)
|
||||
{
|
||||
tree sentry = get_sentry (DECL_ASSEMBLER_NAME (decl));
|
||||
sentry = build_unary_op (PREINCREMENT_EXPR, sentry, 0);
|
||||
sentry = build_binary_op
|
||||
(EQ_EXPR, sentry, integer_one_node, 1);
|
||||
expand_start_cond (sentry, 0);
|
||||
}
|
||||
|
||||
expand_start_target_temps ();
|
||||
|
||||
if (IS_AGGR_TYPE (TREE_TYPE (decl))
|
||||
|| TREE_CODE (TREE_TYPE (decl)) == ARRAY_TYPE)
|
||||
expand_aggr_init (decl, init, 0, 0);
|
||||
else if (TREE_CODE (init) == TREE_VEC)
|
||||
{
|
||||
expand_expr (expand_vec_init (decl, TREE_VEC_ELT (init, 0),
|
||||
TREE_VEC_ELT (init, 1),
|
||||
TREE_VEC_ELT (init, 2), 0),
|
||||
const0_rtx, VOIDmode, EXPAND_NORMAL);
|
||||
}
|
||||
else
|
||||
expand_assignment (decl, init, 0, 0);
|
||||
|
||||
/* The expression might have involved increments and
|
||||
decrements. */
|
||||
emit_queue ();
|
||||
|
||||
/* Cleanup any temporaries needed for the initial value. */
|
||||
expand_end_target_temps ();
|
||||
|
||||
if (protect)
|
||||
expand_end_cond ();
|
||||
|
||||
DECL_CLASS_CONTEXT (current_function_decl) = NULL_TREE;
|
||||
DECL_STATIC_FUNCTION_P (current_function_decl) = 0;
|
||||
}
|
||||
else if (decl == error_mark_node)
|
||||
;
|
||||
else my_friendly_abort (22);
|
||||
|
||||
next_mess:
|
||||
vars = TREE_CHAIN (vars);
|
||||
}
|
||||
|
||||
for (; static_ctors; static_ctors = TREE_CHAIN (static_ctors))
|
||||
expand_expr_stmt (build_function_call (TREE_VALUE (static_ctors),
|
||||
NULL_TREE));
|
||||
|
||||
expand_end_bindings (getdecls (), 1, 0);
|
||||
poplevel (1, 0, 0);
|
||||
pop_momentary ();
|
||||
|
||||
finish_function (lineno, 0, 0);
|
||||
assemble_constructor (IDENTIFIER_POINTER (fnname));
|
||||
do_ctors ();
|
||||
}
|
||||
|
||||
permanent_allocation (1);
|
||||
|
|
Loading…
Reference in New Issue