extend.texi: Document optional priority argument to constructors and destructors.
* doc/extend.texi: Document optional priority argument to constructors and destructors. * tree.c (init_priority_for_decl): Adjust GTY markers. (init_ttree): Use priority-info hash functions for init_priority_for_decl. (tree_map_eq): Rename to ... (tree_map_base_eq): ... this. (tree_map_marked_p): Rename to ... (tree_map_base_marked_p): ... this. (tree_map_base_hash): New function. (decl_init_priority_lookup): Rework. (decl_fini_priority_lookup): New function. (decl_priority_info): New function. (decl_init_priority_insert): Use it. (decl_fini_priority_insert): Likewise. (decl_restrict_base_lookup): Adjust for refactoring of tree_map hierarchy. (decl_restrict_base_insert): Likewise. (decl_debug_expr_insert): Likewise. (decl_value_expr_lookup): Likewise. (decl_value_expr_insert): Likewise. * tree.h (priority_type): New type. (decl_init_priority_lookup): Use priority_type. (decl_fini_priority_lookup): New function. (decl_init_priority_insert): Use priority_type. (decl_fini_priority_insert): New function. (DECL_HAS_INIT_PRIORITY): Tweak comments. (DECL_INIT_PRIORITY): Likewise. (SET_DECL_INIT_PRIORITY): Add comment. (DECL_FINI_PRIORITY): New macro. (SET_DECL_FINI_PRIORITY): Likewise. (DEFAULT_INIT_PRIORITY): Document. (MAX_INIT_PRIORITY): Likewise. (MAX_RESERVED_INIT_PRIORITY): Likewise. (tree_map_base): New type. (tree_map_base_eq): New function. (tree_map_base_hash): Likewise. (tree_map_base_marked_p): Likewise. (tree_map): Inherit from tree_map_base. (tree_map_eq): Make it a macro. (tree_map_marked_p): Likewise. (tree_int_map): Inherit from tree_map_base. (tree_int_map_eq): Make it a macro. (tree_int_map_hash): Likewise. (tree_int_map_marked_p): Likewise. (tree_priority_map): New type. (tree_priority_map_eq): New macro. (tree_priority_map_hash): Likewise. (tree_priority_map_marked_p): Likewise. * varasm.c (emults_decl): Adjust for refactoring of tree_map hierarchy. (emutls_common_1): Likewise. * lambda-code.c (replace_uses_equiv_to_x_with_y): Likewise. * tree-ssa-structalias.c (heapvar_lookup): Adjust for refactoring of tree_map hierarchy. * tree-cfg.c (move_stmt_r): Likewise. (new_label_mapper): Likewise. * c-tree.h (c_expand_body): Move to ... * c-common.h (c_expand_body): ... here. * c-decl.c (c_expand_body): Move to ... * c-common.c (c_expand_body): ... here. (c_common_attribute_table): Allow 1 argument for the constructor and destructor attributes. (get_priority): New function. (handle_constructor_attribute): Set DECL_INIT_PRIORITY. (handle_destructor_attribute): Set DECL_FINI_PRIORITY. * cp-tree.h (static_ctors): Remove. * cp-tree.h (static_dtors): Likewise. * cp-objcp-common.c (decl_shadowed_for_var_lookup): Adjust for refactoring of tree_map hierarchy. (decl_shadowed_for_var_insert): Likewise. * semantics.c (expand_body): Use c_expand_body. (expand_or_defer_fn): Don't update static_ctors or static_dtors. * decl2.c (static_ctors): Remove. (static_dtors): Likewise. (generate_ctor_or_dtor_function): Pass NULL_TREE to objc_generate_static_init_call. Do not call static_[cd]tors. (generate_ctor_and_dtor_functions_for_priority): Do not check for static_[cd]tors. (cp_write_global_declarations): Likewise. * decl.c (annotate_value): Adjust for refactoring of tree_map hierarchy. * gcc.dg/initpri1.c: New test. * gcc.dg/initpri2.c: Likewise. * g++.dg/special/initpri1.C: New test. * g++.dg/special/initpri2.C: Likewise. * g++.dg/special/conpr-1.C: Use init_priority effective target. * g++.dg/special/conpr-2.C: Likewise. * g++.dg/special/conpr-3.C: Likewise. * g++.dg/special/conpr-4.C: Likewise. * g++.dg/special/initp1.C: Likewise. * g++.dg/special/ecos.exp: Remove code to detect availability of constructor priorities. * lib/target-support.exp (target_init_priority): New function. From-SVN: r122315
This commit is contained in:
parent
2a025b54f6
commit
fc8600f9c1
@ -1,3 +1,72 @@
|
||||
2007-02-25 Mark Mitchell <mark@codesourcery.com>
|
||||
|
||||
* doc/extend.texi: Document optional priority argument to
|
||||
constructors and destructors.
|
||||
* tree.c (init_priority_for_decl): Adjust GTY markers.
|
||||
(init_ttree): Use priority-info hash functions for
|
||||
init_priority_for_decl.
|
||||
(tree_map_eq): Rename to ...
|
||||
(tree_map_base_eq): ... this.
|
||||
(tree_map_marked_p): Rename to ...
|
||||
(tree_map_base_marked_p): ... this.
|
||||
(tree_map_base_hash): New function.
|
||||
(decl_init_priority_lookup): Rework.
|
||||
(decl_fini_priority_lookup): New function.
|
||||
(decl_priority_info): New function.
|
||||
(decl_init_priority_insert): Use it.
|
||||
(decl_fini_priority_insert): Likewise.
|
||||
(decl_restrict_base_lookup): Adjust for refactoring of tree_map
|
||||
hierarchy.
|
||||
(decl_restrict_base_insert): Likewise.
|
||||
(decl_debug_expr_insert): Likewise.
|
||||
(decl_value_expr_lookup): Likewise.
|
||||
(decl_value_expr_insert): Likewise.
|
||||
* tree.h (priority_type): New type.
|
||||
(decl_init_priority_lookup): Use priority_type.
|
||||
(decl_fini_priority_lookup): New function.
|
||||
(decl_init_priority_insert): Use priority_type.
|
||||
(decl_fini_priority_insert): New function.
|
||||
(DECL_HAS_INIT_PRIORITY): Tweak comments.
|
||||
(DECL_INIT_PRIORITY): Likewise.
|
||||
(SET_DECL_INIT_PRIORITY): Add comment.
|
||||
(DECL_FINI_PRIORITY): New macro.
|
||||
(SET_DECL_FINI_PRIORITY): Likewise.
|
||||
(DEFAULT_INIT_PRIORITY): Document.
|
||||
(MAX_INIT_PRIORITY): Likewise.
|
||||
(MAX_RESERVED_INIT_PRIORITY): Likewise.
|
||||
(tree_map_base): New type.
|
||||
(tree_map_base_eq): New function.
|
||||
(tree_map_base_hash): Likewise.
|
||||
(tree_map_base_marked_p): Likewise.
|
||||
(tree_map): Inherit from tree_map_base.
|
||||
(tree_map_eq): Make it a macro.
|
||||
(tree_map_marked_p): Likewise.
|
||||
(tree_int_map): Inherit from tree_map_base.
|
||||
(tree_int_map_eq): Make it a macro.
|
||||
(tree_int_map_hash): Likewise.
|
||||
(tree_int_map_marked_p): Likewise.
|
||||
(tree_priority_map): New type.
|
||||
(tree_priority_map_eq): New macro.
|
||||
(tree_priority_map_hash): Likewise.
|
||||
(tree_priority_map_marked_p): Likewise.
|
||||
* varasm.c (emults_decl): Adjust for refactoring of tree_map
|
||||
hierarchy.
|
||||
(emutls_common_1): Likewise.
|
||||
* lambda-code.c (replace_uses_equiv_to_x_with_y): Likewise.
|
||||
* tree-ssa-structalias.c (heapvar_lookup): Adjust for refactoring
|
||||
of tree_map hierarchy.
|
||||
* tree-cfg.c (move_stmt_r): Likewise.
|
||||
(new_label_mapper): Likewise.
|
||||
* c-tree.h (c_expand_body): Move to ...
|
||||
* c-common.h (c_expand_body): ... here.
|
||||
* c-decl.c (c_expand_body): Move to ...
|
||||
* c-common.c (c_expand_body): ... here.
|
||||
(c_common_attribute_table): Allow 1 argument for the constructor
|
||||
and destructor attributes.
|
||||
(get_priority): New function.
|
||||
(handle_constructor_attribute): Set DECL_INIT_PRIORITY.
|
||||
(handle_destructor_attribute): Set DECL_FINI_PRIORITY.
|
||||
|
||||
2007-02-24 Jan Hubicka <jh@suse.cz>
|
||||
|
||||
PR middle-end/30509
|
||||
|
@ -1,3 +1,8 @@
|
||||
2007-02-24 Mark Mitchell <mark@codesourcery.com>
|
||||
|
||||
* decl.c (annotate_value): Adjust for refactoring of tree_map
|
||||
hierarchy.
|
||||
|
||||
2007-02-21 Ed Schonberg <schonberg@adacore.com>
|
||||
|
||||
PR ada/18819
|
||||
|
@ -5890,7 +5890,7 @@ annotate_value (tree gnu_size)
|
||||
if (!annotate_value_cache)
|
||||
annotate_value_cache = htab_create_ggc (512, tree_int_map_hash,
|
||||
tree_int_map_eq, 0);
|
||||
in.from = gnu_size;
|
||||
in.base.from = gnu_size;
|
||||
h = (struct tree_int_map **)
|
||||
htab_find_slot (annotate_value_cache, &in, INSERT);
|
||||
|
||||
|
@ -598,9 +598,9 @@ const struct attribute_spec c_common_attribute_table[] =
|
||||
handle_const_attribute },
|
||||
{ "transparent_union", 0, 0, false, false, false,
|
||||
handle_transparent_union_attribute },
|
||||
{ "constructor", 0, 0, true, false, false,
|
||||
{ "constructor", 0, 1, true, false, false,
|
||||
handle_constructor_attribute },
|
||||
{ "destructor", 0, 0, true, false, false,
|
||||
{ "destructor", 0, 1, true, false, false,
|
||||
handle_destructor_attribute },
|
||||
{ "mode", 1, 1, false, true, false,
|
||||
handle_mode_attribute },
|
||||
@ -4220,6 +4220,29 @@ c_expand_expr (tree exp, rtx target, enum machine_mode tmode,
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* Generate the RTL for the body of FNDECL. */
|
||||
|
||||
void
|
||||
c_expand_body (tree fndecl)
|
||||
{
|
||||
|
||||
if (!DECL_INITIAL (fndecl)
|
||||
|| DECL_INITIAL (fndecl) == error_mark_node)
|
||||
return;
|
||||
|
||||
tree_rest_of_compilation (fndecl);
|
||||
|
||||
if (DECL_STATIC_CONSTRUCTOR (fndecl)
|
||||
&& targetm.have_ctors_dtors)
|
||||
targetm.asm_out.constructor (XEXP (DECL_RTL (fndecl), 0),
|
||||
decl_init_priority_lookup (fndecl));
|
||||
if (DECL_STATIC_DESTRUCTOR (fndecl)
|
||||
&& targetm.have_ctors_dtors)
|
||||
targetm.asm_out.destructor (XEXP (DECL_RTL (fndecl), 0),
|
||||
decl_fini_priority_lookup (fndecl));
|
||||
}
|
||||
|
||||
/* Hook used by staticp to handle language-specific tree codes. */
|
||||
|
||||
tree
|
||||
@ -4655,12 +4678,56 @@ handle_transparent_union_attribute (tree *node, tree name,
|
||||
return NULL_TREE;
|
||||
}
|
||||
|
||||
/* Subroutine of handle_{con,de}structor_attribute. Evaluate ARGS to
|
||||
get the requested priority for a constructor or destructor,
|
||||
possibly issuing diagnostics for invalid or reserved
|
||||
priorities. */
|
||||
|
||||
static priority_type
|
||||
get_priority (tree args, bool is_destructor)
|
||||
{
|
||||
HOST_WIDE_INT pri;
|
||||
|
||||
if (!args)
|
||||
return DEFAULT_INIT_PRIORITY;
|
||||
|
||||
if (!host_integerp (TREE_VALUE (args), /*pos=*/0))
|
||||
goto invalid;
|
||||
|
||||
pri = tree_low_cst (TREE_VALUE (args), /*pos=*/0);
|
||||
if (pri < 0 || pri > MAX_INIT_PRIORITY)
|
||||
goto invalid;
|
||||
|
||||
if (pri <= MAX_RESERVED_INIT_PRIORITY)
|
||||
{
|
||||
if (is_destructor)
|
||||
warning (0,
|
||||
"destructor priorities from 0 to %d are reserved "
|
||||
"for the implementation",
|
||||
MAX_RESERVED_INIT_PRIORITY);
|
||||
else
|
||||
warning (0,
|
||||
"constructor priorities from 0 to %d are reserved "
|
||||
"for the implementation",
|
||||
MAX_RESERVED_INIT_PRIORITY);
|
||||
}
|
||||
return pri;
|
||||
|
||||
invalid:
|
||||
if (is_destructor)
|
||||
error ("destructor priorities must be integers from 0 to %d inclusive",
|
||||
MAX_INIT_PRIORITY);
|
||||
else
|
||||
error ("constructor priorities must be integers from 0 to %d inclusive",
|
||||
MAX_INIT_PRIORITY);
|
||||
return DEFAULT_INIT_PRIORITY;
|
||||
}
|
||||
|
||||
/* Handle a "constructor" attribute; arguments as in
|
||||
struct attribute_spec.handler. */
|
||||
|
||||
static tree
|
||||
handle_constructor_attribute (tree *node, tree name,
|
||||
tree ARG_UNUSED (args),
|
||||
handle_constructor_attribute (tree *node, tree name, tree args,
|
||||
int ARG_UNUSED (flags),
|
||||
bool *no_add_attrs)
|
||||
{
|
||||
@ -4671,7 +4738,10 @@ handle_constructor_attribute (tree *node, tree name,
|
||||
&& TREE_CODE (type) == FUNCTION_TYPE
|
||||
&& decl_function_context (decl) == 0)
|
||||
{
|
||||
priority_type priority;
|
||||
DECL_STATIC_CONSTRUCTOR (decl) = 1;
|
||||
priority = get_priority (args, /*is_destructor=*/false);
|
||||
SET_DECL_INIT_PRIORITY (decl, priority);
|
||||
TREE_USED (decl) = 1;
|
||||
}
|
||||
else
|
||||
@ -4687,8 +4757,7 @@ handle_constructor_attribute (tree *node, tree name,
|
||||
struct attribute_spec.handler. */
|
||||
|
||||
static tree
|
||||
handle_destructor_attribute (tree *node, tree name,
|
||||
tree ARG_UNUSED (args),
|
||||
handle_destructor_attribute (tree *node, tree name, tree args,
|
||||
int ARG_UNUSED (flags),
|
||||
bool *no_add_attrs)
|
||||
{
|
||||
@ -4699,7 +4768,10 @@ handle_destructor_attribute (tree *node, tree name,
|
||||
&& TREE_CODE (type) == FUNCTION_TYPE
|
||||
&& decl_function_context (decl) == 0)
|
||||
{
|
||||
priority_type priority;
|
||||
DECL_STATIC_DESTRUCTOR (decl) = 1;
|
||||
priority = get_priority (args, /*is_destructor=*/true);
|
||||
SET_DECL_FINI_PRIORITY (decl, priority);
|
||||
TREE_USED (decl) = 1;
|
||||
}
|
||||
else
|
||||
|
@ -810,6 +810,7 @@ extern tree lookup_name (tree);
|
||||
extern bool vector_types_convertible_p (tree t1, tree t2, bool emit_lax_note);
|
||||
|
||||
extern rtx c_expand_expr (tree, rtx, enum machine_mode, int, rtx *);
|
||||
extern void c_expand_body (tree);
|
||||
|
||||
extern tree c_staticp (tree);
|
||||
|
||||
|
22
gcc/c-decl.c
22
gcc/c-decl.c
@ -6828,28 +6828,6 @@ finish_function (void)
|
||||
cfun = NULL;
|
||||
current_function_decl = NULL;
|
||||
}
|
||||
|
||||
/* Generate the RTL for the body of FNDECL. */
|
||||
|
||||
void
|
||||
c_expand_body (tree fndecl)
|
||||
{
|
||||
|
||||
if (!DECL_INITIAL (fndecl)
|
||||
|| DECL_INITIAL (fndecl) == error_mark_node)
|
||||
return;
|
||||
|
||||
tree_rest_of_compilation (fndecl);
|
||||
|
||||
if (DECL_STATIC_CONSTRUCTOR (fndecl)
|
||||
&& targetm.have_ctors_dtors)
|
||||
targetm.asm_out.constructor (XEXP (DECL_RTL (fndecl), 0),
|
||||
DEFAULT_INIT_PRIORITY);
|
||||
if (DECL_STATIC_DESTRUCTOR (fndecl)
|
||||
&& targetm.have_ctors_dtors)
|
||||
targetm.asm_out.destructor (XEXP (DECL_RTL (fndecl), 0),
|
||||
DEFAULT_INIT_PRIORITY);
|
||||
}
|
||||
|
||||
/* Check the declarations given in a for-loop for satisfying the C99
|
||||
constraints. If exactly one such decl is found, return it. */
|
||||
|
@ -441,7 +441,6 @@ extern int global_bindings_p (void);
|
||||
extern void push_scope (void);
|
||||
extern tree pop_scope (void);
|
||||
extern void insert_block (tree);
|
||||
extern void c_expand_body (tree);
|
||||
|
||||
extern void c_init_decl_processing (void);
|
||||
extern void c_dup_lang_specific_decl (tree);
|
||||
|
@ -1,3 +1,20 @@
|
||||
2007-02-25 Mark Mitchell <mark@codesourcery.com>
|
||||
|
||||
* cp-tree.h (static_ctors): Remove.
|
||||
* cp-tree.h (static_dtors): Likewise.
|
||||
* cp-objcp-common.c (decl_shadowed_for_var_lookup): Adjust for
|
||||
refactoring of tree_map hierarchy.
|
||||
(decl_shadowed_for_var_insert): Likewise.
|
||||
* semantics.c (expand_body): Use c_expand_body.
|
||||
(expand_or_defer_fn): Don't update static_ctors or static_dtors.
|
||||
* decl2.c (static_ctors): Remove.
|
||||
(static_dtors): Likewise.
|
||||
(generate_ctor_or_dtor_function): Pass NULL_TREE to
|
||||
objc_generate_static_init_call. Do not call static_[cd]tors.
|
||||
(generate_ctor_and_dtor_functions_for_priority): Do not check for
|
||||
static_[cd]tors.
|
||||
(cp_write_global_declarations): Likewise.
|
||||
|
||||
2007-02-23 Richard Guenther <rguenther@suse.de>
|
||||
|
||||
* class.c (note_name_declared_in_class): Make declaration
|
||||
|
@ -228,7 +228,7 @@ tree
|
||||
decl_shadowed_for_var_lookup (tree from)
|
||||
{
|
||||
struct tree_map *h, in;
|
||||
in.from = from;
|
||||
in.base.from = from;
|
||||
|
||||
h = (struct tree_map *) htab_find_with_hash (shadowed_var_for_decl, &in,
|
||||
htab_hash_pointer (from));
|
||||
@ -247,7 +247,7 @@ decl_shadowed_for_var_insert (tree from, tree to)
|
||||
|
||||
h = GGC_NEW (struct tree_map);
|
||||
h->hash = htab_hash_pointer (from);
|
||||
h->from = from;
|
||||
h->base.from = from;
|
||||
h->to = to;
|
||||
loc = htab_find_slot_with_hash (shadowed_var_for_decl, h, h->hash, INSERT);
|
||||
*(struct tree_map **) loc = h;
|
||||
|
@ -3479,11 +3479,6 @@ extern int at_eof;
|
||||
TREE_PURPOSE slot. */
|
||||
extern GTY(()) tree static_aggregates;
|
||||
|
||||
/* Functions called along with real static constructors and destructors. */
|
||||
|
||||
extern GTY(()) tree static_ctors;
|
||||
extern GTY(()) tree static_dtors;
|
||||
|
||||
enum overload_flags { NO_SPECIAL = 0, DTOR_FLAG, OP_FLAG, TYPENAME_FLAG };
|
||||
|
||||
/* These are uses as bits in flags passed to various functions to
|
||||
|
@ -97,11 +97,6 @@ static GTY(()) VEC(tree,gc) *deferred_fns;
|
||||
|
||||
int at_eof;
|
||||
|
||||
/* Functions called along with real static constructors and destructors. */
|
||||
|
||||
tree static_ctors;
|
||||
tree static_dtors;
|
||||
|
||||
|
||||
|
||||
/* Return a member function type (a METHOD_TYPE), given FNTYPE (a
|
||||
@ -2847,7 +2842,7 @@ generate_ctor_or_dtor_function (bool constructor_p, int priority,
|
||||
&& constructor_p && objc_static_init_needed_p ())
|
||||
{
|
||||
body = start_objects (function_key, priority);
|
||||
static_ctors = objc_generate_static_init_call (static_ctors);
|
||||
objc_generate_static_init_call (NULL_TREE);
|
||||
}
|
||||
|
||||
/* Call the static storage duration function with appropriate
|
||||
@ -2870,29 +2865,6 @@ generate_ctor_or_dtor_function (bool constructor_p, int priority,
|
||||
}
|
||||
}
|
||||
|
||||
/* If we're generating code for the DEFAULT_INIT_PRIORITY, throw in
|
||||
calls to any functions marked with attributes indicating that
|
||||
they should be called at initialization- or destruction-time. */
|
||||
if (priority == DEFAULT_INIT_PRIORITY)
|
||||
{
|
||||
tree fns;
|
||||
|
||||
for (fns = constructor_p ? static_ctors : static_dtors;
|
||||
fns;
|
||||
fns = TREE_CHAIN (fns))
|
||||
{
|
||||
fndecl = TREE_VALUE (fns);
|
||||
|
||||
/* Calls to pure/const functions will expand to nothing. */
|
||||
if (! (flags_from_decl_or_type (fndecl) & (ECF_CONST | ECF_PURE)))
|
||||
{
|
||||
if (! body)
|
||||
body = start_objects (function_key, priority);
|
||||
finish_expr_stmt (build_function_call (fndecl, NULL_TREE));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Close out the function. */
|
||||
if (body)
|
||||
finish_objects (function_key, priority, body);
|
||||
@ -2910,11 +2882,9 @@ generate_ctor_and_dtor_functions_for_priority (splay_tree_node n, void * data)
|
||||
|
||||
/* Generate the functions themselves, but only if they are really
|
||||
needed. */
|
||||
if (pi->initializations_p
|
||||
|| (priority == DEFAULT_INIT_PRIORITY && static_ctors))
|
||||
if (pi->initializations_p)
|
||||
generate_ctor_or_dtor_function (/*constructor_p=*/true, priority, locus);
|
||||
if (pi->destructions_p
|
||||
|| (priority == DEFAULT_INIT_PRIORITY && static_dtors))
|
||||
if (pi->destructions_p)
|
||||
generate_ctor_or_dtor_function (/*constructor_p=*/false, priority, locus);
|
||||
|
||||
/* Keep iterating. */
|
||||
@ -3309,17 +3279,11 @@ cp_write_global_declarations (void)
|
||||
splay_tree_foreach (priority_info_map,
|
||||
generate_ctor_and_dtor_functions_for_priority,
|
||||
/*data=*/&locus);
|
||||
else
|
||||
{
|
||||
/* If we have a ctor or this is obj-c++ and we need a static init,
|
||||
call generate_ctor_or_dtor_function. */
|
||||
if (static_ctors || (c_dialect_objc () && objc_static_init_needed_p ()))
|
||||
generate_ctor_or_dtor_function (/*constructor_p=*/true,
|
||||
DEFAULT_INIT_PRIORITY, &locus);
|
||||
if (static_dtors)
|
||||
generate_ctor_or_dtor_function (/*constructor_p=*/false,
|
||||
DEFAULT_INIT_PRIORITY, &locus);
|
||||
}
|
||||
else if (c_dialect_objc () && objc_static_init_needed_p ())
|
||||
/* If this is obj-c++ and we need a static init, call
|
||||
generate_ctor_or_dtor_function. */
|
||||
generate_ctor_or_dtor_function (/*constructor_p=*/true,
|
||||
DEFAULT_INIT_PRIORITY, &locus);
|
||||
|
||||
/* We're done with the splay-tree now. */
|
||||
if (priority_info_map)
|
||||
|
@ -3099,7 +3099,7 @@ expand_body (tree fn)
|
||||
generating trees for a function. */
|
||||
gcc_assert (function_depth == 0);
|
||||
|
||||
tree_rest_of_compilation (fn);
|
||||
c_expand_body (fn);
|
||||
|
||||
current_function_decl = saved_function;
|
||||
|
||||
@ -3159,18 +3159,6 @@ expand_or_defer_fn (tree fn)
|
||||
return;
|
||||
}
|
||||
|
||||
/* If this function is marked with the constructor attribute, add it
|
||||
to the list of functions to be called along with constructors
|
||||
from static duration objects. */
|
||||
if (DECL_STATIC_CONSTRUCTOR (fn))
|
||||
static_ctors = tree_cons (NULL_TREE, fn, static_ctors);
|
||||
|
||||
/* If this function is marked with the destructor attribute, add it
|
||||
to the list of functions to be called along with destructors from
|
||||
static duration objects. */
|
||||
if (DECL_STATIC_DESTRUCTOR (fn))
|
||||
static_dtors = tree_cons (NULL_TREE, fn, static_dtors);
|
||||
|
||||
/* We make a decision about linkage for these functions at the end
|
||||
of the compilation. Until that point, we do not want the back
|
||||
end to output them -- but we do want it to see the bodies of
|
||||
|
@ -1667,6 +1667,8 @@ specifies that the @samp{const} must be attached to the return value.
|
||||
|
||||
@item constructor
|
||||
@itemx destructor
|
||||
@itemx constructor (@var{priority})
|
||||
@itemx destructor (@var{priority})
|
||||
@cindex @code{constructor} function attribute
|
||||
@cindex @code{destructor} function attribute
|
||||
The @code{constructor} attribute causes the function to be called
|
||||
@ -1677,6 +1679,16 @@ been called. Functions with these attributes are useful for
|
||||
initializing data that will be used implicitly during the execution of
|
||||
the program.
|
||||
|
||||
You may provide an optional integer priority to control the order in
|
||||
which constructor and destructor functions are run. A constructor
|
||||
with a smaller priority number runs before a constructor with a larger
|
||||
priority number; the opposite relationship holds for destructors. So,
|
||||
if you have a constructor that allocates a resource and a destructor
|
||||
that deallocates the same resource, both functions typically have the
|
||||
same priority. The priorities for constructor and destructor
|
||||
functions are the same as those specified for namespace-scope C++
|
||||
objects (@pxref{C++ Attributes}).
|
||||
|
||||
These attributes are not currently implemented for Objective-C@.
|
||||
|
||||
@item deprecated
|
||||
|
@ -2153,7 +2153,7 @@ replace_uses_equiv_to_x_with_y (struct loop *loop, tree stmt, tree x,
|
||||
/* Use REPLACEMENTS hash table to cache already created
|
||||
temporaries. */
|
||||
in.hash = htab_hash_pointer (use);
|
||||
in.from = use;
|
||||
in.base.from = use;
|
||||
h = htab_find_with_hash (replacements, &in, in.hash);
|
||||
if (h != NULL)
|
||||
{
|
||||
@ -2198,7 +2198,7 @@ replace_uses_equiv_to_x_with_y (struct loop *loop, tree stmt, tree x,
|
||||
SET_USE (use_p, var);
|
||||
h = ggc_alloc (sizeof (struct tree_map));
|
||||
h->hash = in.hash;
|
||||
h->from = use;
|
||||
h->base.from = use;
|
||||
h->to = var;
|
||||
loc = htab_find_slot_with_hash (replacements, h, in.hash, INSERT);
|
||||
gcc_assert ((*(struct tree_map **)loc) == NULL);
|
||||
|
@ -1,3 +1,18 @@
|
||||
2007-02-25 Mark Mitchell <mark@codesourcery.com>
|
||||
|
||||
* gcc.dg/initpri1.c: New test.
|
||||
* gcc.dg/initpri2.c: Likewise.
|
||||
* g++.dg/special/initpri1.C: New test.
|
||||
* g++.dg/special/initpri2.C: Likewise.
|
||||
* g++.dg/special/conpr-1.C: Use init_priority effective target.
|
||||
* g++.dg/special/conpr-2.C: Likewise.
|
||||
* g++.dg/special/conpr-3.C: Likewise.
|
||||
* g++.dg/special/conpr-4.C: Likewise.
|
||||
* g++.dg/special/initp1.C: Likewise.
|
||||
* g++.dg/special/ecos.exp: Remove code to detect availability of
|
||||
constructor priorities.
|
||||
* lib/target-support.exp (target_init_priority): New function.
|
||||
|
||||
2007-02-24 Jan Hubicka <jh@suse.cz>
|
||||
|
||||
* gcc.c-torture/execute/pr30778.c: New testcase.
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* { dg-do run } */
|
||||
/* { dg-do run { target init_priority } } */
|
||||
|
||||
#include <stdlib.h>
|
||||
|
||||
|
@ -1,5 +1,4 @@
|
||||
/* This doesn't work on solaris2 for reasons described in PR 6482. */
|
||||
/* { dg-do run { xfail *-*-solaris2* } } */
|
||||
/* { dg-do run { target init_priority } } */
|
||||
/* { dg-additional-sources "conpr-2a.cc" } */
|
||||
|
||||
#include <stdlib.h>
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* { dg-do run } */
|
||||
/* { dg-do run { target init_priority } } */
|
||||
/* { dg-additional-sources "conpr-3a.cc conpr-3b.cc" } */
|
||||
|
||||
#include <stdlib.h>
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* { dg-do run } */
|
||||
/* { dg-do run { target init_priority } } */
|
||||
/* { dg-additional-sources "conpr-3b.cc conpr-3a.cc" } */
|
||||
|
||||
#include <stdlib.h>
|
||||
|
@ -24,16 +24,6 @@
|
||||
# Load support procs.
|
||||
load_lib g++-dg.exp
|
||||
|
||||
# Test for whether or not __attribute__((init_priority)) is supported
|
||||
# by the platform.
|
||||
|
||||
set comp_output [g++_target_compile \
|
||||
"$srcdir/$subdir/initp1.C" "initp1.S" assembly ""]
|
||||
remove-build-file "initp1.S"
|
||||
if { [string match "*init_priority*" $comp_output] } {
|
||||
return 0
|
||||
}
|
||||
|
||||
# Initialize 'dg'.
|
||||
dg-init
|
||||
|
||||
|
@ -1,5 +1,4 @@
|
||||
/* This doesn't work on solaris2 for reasons described in PR 6482. */
|
||||
/* { dg-do run { xfail *-*-solaris2* } } */
|
||||
/* { dg-do run { target init_priority } } */
|
||||
#include <stdlib.h>
|
||||
|
||||
class Two {
|
||||
|
62
gcc/testsuite/g++.dg/special/initpri1.C
Normal file
62
gcc/testsuite/g++.dg/special/initpri1.C
Normal file
@ -0,0 +1,62 @@
|
||||
/* { dg-do run { target init_priority } } */
|
||||
|
||||
extern "C" void abort ();
|
||||
|
||||
int i;
|
||||
int j;
|
||||
|
||||
void c1() __attribute__((constructor (500)));
|
||||
void c2() __attribute__((constructor (700)));
|
||||
void c3() __attribute__((constructor (600)));
|
||||
|
||||
void c1() {
|
||||
if (i++ != 0)
|
||||
abort ();
|
||||
}
|
||||
|
||||
void c2() {
|
||||
if (i++ != 2)
|
||||
abort ();
|
||||
}
|
||||
|
||||
void c3() {
|
||||
if (i++ != 1)
|
||||
abort ();
|
||||
}
|
||||
|
||||
void d1() __attribute__((destructor (500)));
|
||||
void d2() __attribute__((destructor (700)));
|
||||
void d3() __attribute__((destructor (600)));
|
||||
|
||||
void d1() {
|
||||
if (--i != 0)
|
||||
abort ();
|
||||
}
|
||||
|
||||
void d2() {
|
||||
if (--i != 2)
|
||||
abort ();
|
||||
}
|
||||
|
||||
void d3() {
|
||||
if (j != 2)
|
||||
abort ();
|
||||
if (--i != 1)
|
||||
abort ();
|
||||
}
|
||||
|
||||
void cd4() __attribute__((constructor (800), destructor (800)));
|
||||
|
||||
void cd4() {
|
||||
if (i != 3)
|
||||
abort ();
|
||||
++j;
|
||||
}
|
||||
|
||||
int main () {
|
||||
if (i != 3)
|
||||
return 1;
|
||||
if (j != 1)
|
||||
abort ();
|
||||
return 0;
|
||||
}
|
18
gcc/testsuite/g++.dg/special/initpri2.C
Normal file
18
gcc/testsuite/g++.dg/special/initpri2.C
Normal file
@ -0,0 +1,18 @@
|
||||
/* { dg-do compile { target init_priority } } */
|
||||
|
||||
/* Priorities must be in the range [0, 65535]. */
|
||||
void c1()
|
||||
__attribute__((constructor (-1))); /* { dg-error "priorities" } */
|
||||
void c2()
|
||||
__attribute__((constructor (65536))); /* { dg-error "priorities" } */
|
||||
void d1()
|
||||
__attribute__((destructor (-1))); /* { dg-error "priorities" } */
|
||||
void d2()
|
||||
__attribute__((destructor (65536))); /* { dg-error "priorities" } */
|
||||
|
||||
/* Priorities 0-100 are reserved for system libraries. */
|
||||
void c3()
|
||||
__attribute__((constructor (50))); /* { dg-warning "reserved" } */
|
||||
void d3()
|
||||
__attribute__((constructor (50))); /* { dg-warning "reserved" } */
|
||||
|
62
gcc/testsuite/gcc.dg/initpri1.c
Normal file
62
gcc/testsuite/gcc.dg/initpri1.c
Normal file
@ -0,0 +1,62 @@
|
||||
/* { dg-do run { target init_priority } } */
|
||||
|
||||
extern void abort ();
|
||||
|
||||
int i;
|
||||
int j;
|
||||
|
||||
void c1() __attribute__((constructor (500)));
|
||||
void c2() __attribute__((constructor (700)));
|
||||
void c3() __attribute__((constructor (600)));
|
||||
|
||||
void c1() {
|
||||
if (i++ != 0)
|
||||
abort ();
|
||||
}
|
||||
|
||||
void c2() {
|
||||
if (i++ != 2)
|
||||
abort ();
|
||||
}
|
||||
|
||||
void c3() {
|
||||
if (i++ != 1)
|
||||
abort ();
|
||||
}
|
||||
|
||||
void d1() __attribute__((destructor (500)));
|
||||
void d2() __attribute__((destructor (700)));
|
||||
void d3() __attribute__((destructor (600)));
|
||||
|
||||
void d1() {
|
||||
if (--i != 0)
|
||||
abort ();
|
||||
}
|
||||
|
||||
void d2() {
|
||||
if (--i != 2)
|
||||
abort ();
|
||||
}
|
||||
|
||||
void d3() {
|
||||
if (j != 2)
|
||||
abort ();
|
||||
if (--i != 1)
|
||||
abort ();
|
||||
}
|
||||
|
||||
void cd4() __attribute__((constructor (800), destructor (800)));
|
||||
|
||||
void cd4() {
|
||||
if (i != 3)
|
||||
abort ();
|
||||
++j;
|
||||
}
|
||||
|
||||
int main () {
|
||||
if (i != 3)
|
||||
return 1;
|
||||
if (j != 1)
|
||||
abort ();
|
||||
return 0;
|
||||
}
|
18
gcc/testsuite/gcc.dg/initpri2.c
Normal file
18
gcc/testsuite/gcc.dg/initpri2.c
Normal file
@ -0,0 +1,18 @@
|
||||
/* { dg-do compile { target init_priority } } */
|
||||
|
||||
/* Priorities must be in the range [0, 65535]. */
|
||||
void c1()
|
||||
__attribute__((constructor (-1))); /* { dg-error "priorities" } */
|
||||
void c2()
|
||||
__attribute__((constructor (65536))); /* { dg-error "priorities" } */
|
||||
void d1()
|
||||
__attribute__((destructor (-1))); /* { dg-error "priorities" } */
|
||||
void d2()
|
||||
__attribute__((destructor (65536))); /* { dg-error "priorities" } */
|
||||
|
||||
/* Priorities 0-100 are reserved for system libraries. */
|
||||
void c3()
|
||||
__attribute__((constructor (50))); /* { dg-warning "reserved" } */
|
||||
void d3()
|
||||
__attribute__((constructor (50))); /* { dg-warning "reserved" } */
|
||||
|
@ -2089,6 +2089,23 @@ proc check_effective_target_dummy_wcsftime {} {
|
||||
return [check_effective_target_uclibc]
|
||||
}
|
||||
|
||||
# Return 1 if constructors with initialization priority arguments are
|
||||
# supposed on this target.
|
||||
|
||||
proc check_effective_target_init_priority {} {
|
||||
# On Solaris2, initialization priorities are only supported with
|
||||
# GNU ld, but the compiler accepts them even when using Sun ld.
|
||||
# For more information, see PR 6482.
|
||||
if { [istarget *-solaris2*] } {
|
||||
return 1
|
||||
}
|
||||
|
||||
return [check_no_compiler_messages init_priority assembly "
|
||||
void f() __attribute__((constructor (1000)));
|
||||
void f() \{\}
|
||||
"]
|
||||
}
|
||||
|
||||
# Return 1 if the target matches the effective target 'arg', 0 otherwise.
|
||||
# This can be used with any check_* proc that takes no argument and
|
||||
# returns only 1 or 0. It could be used with check_* procs that take
|
||||
|
@ -4606,7 +4606,7 @@ move_stmt_r (tree *tp, int *walk_subtrees, void *data)
|
||||
if (p->new_label_map)
|
||||
{
|
||||
struct tree_map in, *out;
|
||||
in.from = t;
|
||||
in.base.from = t;
|
||||
out = htab_find_with_hash (p->new_label_map, &in, DECL_UID (t));
|
||||
if (out)
|
||||
*tp = t = out->to;
|
||||
@ -4795,7 +4795,7 @@ new_label_mapper (tree decl, void *data)
|
||||
|
||||
m = xmalloc (sizeof (struct tree_map));
|
||||
m->hash = DECL_UID (decl);
|
||||
m->from = decl;
|
||||
m->base.from = decl;
|
||||
m->to = create_artificial_label ();
|
||||
LABEL_DECL_UID (m->to) = LABEL_DECL_UID (decl);
|
||||
|
||||
|
@ -330,7 +330,7 @@ static tree
|
||||
heapvar_lookup (tree from)
|
||||
{
|
||||
struct tree_map *h, in;
|
||||
in.from = from;
|
||||
in.base.from = from;
|
||||
|
||||
h = htab_find_with_hash (heapvar_for_stmt, &in, htab_hash_pointer (from));
|
||||
if (h)
|
||||
@ -349,7 +349,7 @@ heapvar_insert (tree from, tree to)
|
||||
|
||||
h = ggc_alloc (sizeof (struct tree_map));
|
||||
h->hash = htab_hash_pointer (from);
|
||||
h->from = from;
|
||||
h->base.from = from;
|
||||
h->to = to;
|
||||
loc = htab_find_slot_with_hash (heapvar_for_stmt, h, h->hash, INSERT);
|
||||
*(struct tree_map **) loc = h;
|
||||
|
150
gcc/tree.c
150
gcc/tree.c
@ -146,7 +146,8 @@ static GTY ((if_marked ("tree_map_marked_p"), param_is (struct tree_map)))
|
||||
static GTY ((if_marked ("tree_map_marked_p"), param_is (struct tree_map)))
|
||||
htab_t value_expr_for_decl;
|
||||
|
||||
static GTY ((if_marked ("tree_int_map_marked_p"), param_is (struct tree_int_map)))
|
||||
static GTY ((if_marked ("tree_priority_map_marked_p"),
|
||||
param_is (struct tree_priority_map)))
|
||||
htab_t init_priority_for_decl;
|
||||
|
||||
static GTY ((if_marked ("tree_map_marked_p"), param_is (struct tree_map)))
|
||||
@ -220,8 +221,8 @@ init_ttree (void)
|
||||
|
||||
value_expr_for_decl = htab_create_ggc (512, tree_map_hash,
|
||||
tree_map_eq, 0);
|
||||
init_priority_for_decl = htab_create_ggc (512, tree_int_map_hash,
|
||||
tree_int_map_eq, 0);
|
||||
init_priority_for_decl = htab_create_ggc (512, tree_priority_map_hash,
|
||||
tree_priority_map_eq, 0);
|
||||
restrict_base_for_decl = htab_create_ggc (256, tree_map_hash,
|
||||
tree_map_eq, 0);
|
||||
|
||||
@ -4195,18 +4196,18 @@ build_variant_type_copy (tree type)
|
||||
/* Return true if the from tree in both tree maps are equal. */
|
||||
|
||||
int
|
||||
tree_map_eq (const void *va, const void *vb)
|
||||
tree_map_base_eq (const void *va, const void *vb)
|
||||
{
|
||||
const struct tree_map *a = va, *b = vb;
|
||||
const struct tree_map_base *a = va, *b = vb;
|
||||
return (a->from == b->from);
|
||||
}
|
||||
|
||||
/* Hash a from tree in a tree_map. */
|
||||
|
||||
unsigned int
|
||||
tree_map_hash (const void *item)
|
||||
tree_map_base_hash (const void *item)
|
||||
{
|
||||
return (((const struct tree_map *) item)->hash);
|
||||
return htab_hash_pointer (((const struct tree_map_base *)item)->from);
|
||||
}
|
||||
|
||||
/* Return true if this tree map structure is marked for garbage collection
|
||||
@ -4214,70 +4215,97 @@ tree_map_hash (const void *item)
|
||||
structure goes away when the from tree goes away. */
|
||||
|
||||
int
|
||||
tree_map_marked_p (const void *p)
|
||||
tree_map_base_marked_p (const void *p)
|
||||
{
|
||||
tree from = ((struct tree_map *) p)->from;
|
||||
|
||||
return ggc_marked_p (from);
|
||||
return ggc_marked_p (((struct tree_map_base *) p)->from);
|
||||
}
|
||||
|
||||
/* Return true if the trees in the tree_int_map *'s VA and VB are equal. */
|
||||
|
||||
int
|
||||
tree_int_map_eq (const void *va, const void *vb)
|
||||
{
|
||||
const struct tree_int_map *a = va, *b = vb;
|
||||
return (a->from == b->from);
|
||||
}
|
||||
|
||||
/* Hash a from tree in the tree_int_map * ITEM. */
|
||||
|
||||
unsigned int
|
||||
tree_int_map_hash (const void *item)
|
||||
tree_map_hash (const void *item)
|
||||
{
|
||||
return htab_hash_pointer (((const struct tree_int_map *)item)->from);
|
||||
return (((const struct tree_map *) item)->hash);
|
||||
}
|
||||
|
||||
/* Return true if this tree int map structure is marked for garbage collection
|
||||
purposes. We simply return true if the from tree_int_map *P's from tree is marked, so that this
|
||||
structure goes away when the from tree goes away. */
|
||||
/* Return the initialization priority for DECL. */
|
||||
|
||||
int
|
||||
tree_int_map_marked_p (const void *p)
|
||||
priority_type
|
||||
decl_init_priority_lookup (tree decl)
|
||||
{
|
||||
tree from = ((struct tree_int_map *) p)->from;
|
||||
struct tree_priority_map *h;
|
||||
struct tree_map_base in;
|
||||
|
||||
return ggc_marked_p (from);
|
||||
}
|
||||
/* Lookup an init priority for FROM, and return it if we find one. */
|
||||
|
||||
unsigned short
|
||||
decl_init_priority_lookup (tree from)
|
||||
{
|
||||
struct tree_int_map *h, in;
|
||||
in.from = from;
|
||||
|
||||
h = htab_find_with_hash (init_priority_for_decl,
|
||||
&in, htab_hash_pointer (from));
|
||||
if (h)
|
||||
return h->to;
|
||||
return 0;
|
||||
gcc_assert (VAR_OR_FUNCTION_DECL_P (decl));
|
||||
gcc_assert (TREE_CODE (decl) == VAR_DECL
|
||||
? DECL_HAS_INIT_PRIORITY_P (decl)
|
||||
: DECL_STATIC_CONSTRUCTOR (decl));
|
||||
in.from = decl;
|
||||
h = htab_find (init_priority_for_decl, &in);
|
||||
return h ? h->init : DEFAULT_INIT_PRIORITY;
|
||||
}
|
||||
|
||||
/* Insert a mapping FROM->TO in the init priority hashtable. */
|
||||
/* Return the finalization priority for DECL. */
|
||||
|
||||
void
|
||||
decl_init_priority_insert (tree from, unsigned short to)
|
||||
priority_type
|
||||
decl_fini_priority_lookup (tree decl)
|
||||
{
|
||||
struct tree_int_map *h;
|
||||
struct tree_priority_map *h;
|
||||
struct tree_map_base in;
|
||||
|
||||
gcc_assert (TREE_CODE (decl) == FUNCTION_DECL);
|
||||
gcc_assert (DECL_STATIC_DESTRUCTOR (decl));
|
||||
in.from = decl;
|
||||
h = htab_find (init_priority_for_decl, &in);
|
||||
return h ? h->fini : DEFAULT_INIT_PRIORITY;
|
||||
}
|
||||
|
||||
/* Return the initialization and finalization priority information for
|
||||
DECL. If there is no previous priority information, a freshly
|
||||
allocated structure is returned. */
|
||||
|
||||
static struct tree_priority_map *
|
||||
decl_priority_info (tree decl)
|
||||
{
|
||||
struct tree_priority_map in;
|
||||
struct tree_priority_map *h;
|
||||
void **loc;
|
||||
|
||||
h = ggc_alloc (sizeof (struct tree_int_map));
|
||||
h->from = from;
|
||||
h->to = to;
|
||||
loc = htab_find_slot_with_hash (init_priority_for_decl, h,
|
||||
htab_hash_pointer (from), INSERT);
|
||||
*(struct tree_int_map **) loc = h;
|
||||
in.base.from = decl;
|
||||
loc = htab_find_slot (init_priority_for_decl, &in, INSERT);
|
||||
h = *loc;
|
||||
if (!h)
|
||||
{
|
||||
h = GGC_CNEW (struct tree_priority_map);
|
||||
*loc = h;
|
||||
h->base.from = decl;
|
||||
h->init = DEFAULT_INIT_PRIORITY;
|
||||
h->fini = DEFAULT_INIT_PRIORITY;
|
||||
}
|
||||
|
||||
return h;
|
||||
}
|
||||
|
||||
/* Set the initialization priority for DECL to PRIORITY. */
|
||||
|
||||
void
|
||||
decl_init_priority_insert (tree decl, priority_type priority)
|
||||
{
|
||||
struct tree_priority_map *h;
|
||||
|
||||
gcc_assert (VAR_OR_FUNCTION_DECL_P (decl));
|
||||
h = decl_priority_info (decl);
|
||||
h->init = priority;
|
||||
}
|
||||
|
||||
/* Set the finalization priority for DECL to PRIORITY. */
|
||||
|
||||
void
|
||||
decl_fini_priority_insert (tree decl, priority_type priority)
|
||||
{
|
||||
struct tree_priority_map *h;
|
||||
|
||||
gcc_assert (TREE_CODE (decl) == FUNCTION_DECL);
|
||||
h = decl_priority_info (decl);
|
||||
h->fini = priority;
|
||||
}
|
||||
|
||||
/* Look up a restrict qualified base decl for FROM. */
|
||||
@ -4288,7 +4316,7 @@ decl_restrict_base_lookup (tree from)
|
||||
struct tree_map *h;
|
||||
struct tree_map in;
|
||||
|
||||
in.from = from;
|
||||
in.base.from = from;
|
||||
h = htab_find_with_hash (restrict_base_for_decl, &in,
|
||||
htab_hash_pointer (from));
|
||||
return h ? h->to : NULL_TREE;
|
||||
@ -4304,7 +4332,7 @@ decl_restrict_base_insert (tree from, tree to)
|
||||
|
||||
h = ggc_alloc (sizeof (struct tree_map));
|
||||
h->hash = htab_hash_pointer (from);
|
||||
h->from = from;
|
||||
h->base.from = from;
|
||||
h->to = to;
|
||||
loc = htab_find_slot_with_hash (restrict_base_for_decl, h, h->hash, INSERT);
|
||||
*(struct tree_map **) loc = h;
|
||||
@ -4352,7 +4380,7 @@ tree
|
||||
decl_debug_expr_lookup (tree from)
|
||||
{
|
||||
struct tree_map *h, in;
|
||||
in.from = from;
|
||||
in.base.from = from;
|
||||
|
||||
h = htab_find_with_hash (debug_expr_for_decl, &in, htab_hash_pointer (from));
|
||||
if (h)
|
||||
@ -4370,7 +4398,7 @@ decl_debug_expr_insert (tree from, tree to)
|
||||
|
||||
h = ggc_alloc (sizeof (struct tree_map));
|
||||
h->hash = htab_hash_pointer (from);
|
||||
h->from = from;
|
||||
h->base.from = from;
|
||||
h->to = to;
|
||||
loc = htab_find_slot_with_hash (debug_expr_for_decl, h, h->hash, INSERT);
|
||||
*(struct tree_map **) loc = h;
|
||||
@ -4382,7 +4410,7 @@ tree
|
||||
decl_value_expr_lookup (tree from)
|
||||
{
|
||||
struct tree_map *h, in;
|
||||
in.from = from;
|
||||
in.base.from = from;
|
||||
|
||||
h = htab_find_with_hash (value_expr_for_decl, &in, htab_hash_pointer (from));
|
||||
if (h)
|
||||
@ -4400,7 +4428,7 @@ decl_value_expr_insert (tree from, tree to)
|
||||
|
||||
h = ggc_alloc (sizeof (struct tree_map));
|
||||
h->hash = htab_hash_pointer (from);
|
||||
h->from = from;
|
||||
h->base.from = from;
|
||||
h->to = to;
|
||||
loc = htab_find_slot_with_hash (value_expr_for_decl, h, h->hash, INSERT);
|
||||
*(struct tree_map **) loc = h;
|
||||
|
90
gcc/tree.h
90
gcc/tree.h
@ -2599,13 +2599,6 @@ struct tree_memory_partition_tag GTY(())
|
||||
a C99 "extern inline" function. */
|
||||
#define DECL_EXTERNAL(NODE) (DECL_COMMON_CHECK (NODE)->decl_common.decl_flag_2)
|
||||
|
||||
/* In a VAR_DECL for a RECORD_TYPE, sets number for non-init_priority
|
||||
initializations. */
|
||||
#define DEFAULT_INIT_PRIORITY 65535
|
||||
#define MAX_INIT_PRIORITY 65535
|
||||
#define MAX_RESERVED_INIT_PRIORITY 100
|
||||
|
||||
|
||||
/* Nonzero in a ..._DECL means this variable is ref'd from a nested function.
|
||||
For VAR_DECL nodes, PARM_DECL nodes, and FUNCTION_DECL nodes.
|
||||
|
||||
@ -3065,20 +3058,46 @@ extern void decl_debug_expr_insert (tree, tree);
|
||||
#define SET_DECL_DEBUG_EXPR(NODE, VAL) \
|
||||
(decl_debug_expr_insert (VAR_DECL_CHECK (NODE), VAL))
|
||||
|
||||
/* An initializationp priority. */
|
||||
typedef unsigned short priority_type;
|
||||
|
||||
extern unsigned short decl_init_priority_lookup (tree);
|
||||
extern void decl_init_priority_insert (tree, unsigned short);
|
||||
|
||||
/* In a non-local VAR_DECL with static storage duration, this is the
|
||||
initialization priority. If this value is zero, the NODE will be
|
||||
initialized at the DEFAULT_INIT_PRIORITY. Only used by C++ FE*/
|
||||
extern priority_type decl_init_priority_lookup (tree);
|
||||
extern priority_type decl_fini_priority_lookup (tree);
|
||||
extern void decl_init_priority_insert (tree, priority_type);
|
||||
extern void decl_fini_priority_insert (tree, priority_type);
|
||||
|
||||
/* In a non-local VAR_DECL with static storage duration, true if the
|
||||
variable has an initialization priority. If false, the variable
|
||||
will be initialized at the DEFAULT_INIT_PRIORITY. */
|
||||
#define DECL_HAS_INIT_PRIORITY_P(NODE) \
|
||||
(VAR_DECL_CHECK (NODE)->decl_with_vis.init_priority_p)
|
||||
|
||||
/* For a VAR_DECL or FUNCTION_DECL with DECL_HAS_INIT_PRIORITY_P set,
|
||||
the initialization priority of NODE. */
|
||||
#define DECL_INIT_PRIORITY(NODE) \
|
||||
(decl_init_priority_lookup (VAR_DECL_CHECK (NODE)))
|
||||
(decl_init_priority_lookup (NODE))
|
||||
/* Set the initialization priority for NODE to VAL. */
|
||||
#define SET_DECL_INIT_PRIORITY(NODE, VAL) \
|
||||
(decl_init_priority_insert (VAR_DECL_CHECK (NODE), VAL))
|
||||
(decl_init_priority_insert (NODE, VAL))
|
||||
|
||||
/* For a FUNCTION_DECL with DECL_HAS_INIT_PRIORITY_P set, the
|
||||
finalization priority of NODE. */
|
||||
#define DECL_FINI_PRIORITY(NODE) \
|
||||
(decl_fini_priority_lookup (NODE))
|
||||
/* Set the finalization priority for NODE to VAL. */
|
||||
#define SET_DECL_FINI_PRIORITY(NODE, VAL) \
|
||||
(decl_fini_priority_insert (NODE, VAL))
|
||||
|
||||
/* The initialization priority for entities for which no explicit
|
||||
initialization priority has been specified. */
|
||||
#define DEFAULT_INIT_PRIORITY 65535
|
||||
|
||||
/* The maximum allowed initialization priority. */
|
||||
#define MAX_INIT_PRIORITY 65535
|
||||
|
||||
/* The largest priority value reserved for use by system runtime
|
||||
libraries. */
|
||||
#define MAX_RESERVED_INIT_PRIORITY 100
|
||||
|
||||
/* In a VAR_DECL, the model to use if the data should be allocated from
|
||||
thread-local storage. */
|
||||
@ -4800,26 +4819,53 @@ extern tree get_base_address (tree t);
|
||||
extern void vect_set_verbosity_level (const char *);
|
||||
|
||||
/* In tree.c. */
|
||||
|
||||
struct tree_map_base GTY(())
|
||||
{
|
||||
tree from;
|
||||
};
|
||||
|
||||
extern int tree_map_base_eq (const void *, const void *);
|
||||
extern unsigned int tree_map_base_hash (const void *);
|
||||
extern int tree_map_base_marked_p (const void *);
|
||||
|
||||
/* Map from a tree to another tree. */
|
||||
|
||||
struct tree_map GTY(())
|
||||
{
|
||||
struct tree_map_base base;
|
||||
unsigned int hash;
|
||||
tree from;
|
||||
tree to;
|
||||
};
|
||||
|
||||
#define tree_map_eq tree_map_base_eq
|
||||
extern unsigned int tree_map_hash (const void *);
|
||||
extern int tree_map_marked_p (const void *);
|
||||
extern int tree_map_eq (const void *, const void *);
|
||||
#define tree_map_marked_p tree_map_base_marked_p
|
||||
|
||||
/* Map from a tree to an int. */
|
||||
|
||||
struct tree_int_map GTY(())
|
||||
{
|
||||
tree from;
|
||||
struct tree_map_base base;
|
||||
unsigned int to;
|
||||
};
|
||||
|
||||
extern unsigned int tree_int_map_hash (const void *);
|
||||
extern int tree_int_map_eq (const void *, const void *);
|
||||
extern int tree_int_map_marked_p (const void *);
|
||||
#define tree_int_map_eq tree_map_base_eq
|
||||
#define tree_int_map_hash tree_map_base_hash
|
||||
#define tree_int_map_marked_p tree_map_base_marked_p
|
||||
|
||||
/* Map from a tree to initialization/finalization priorities. */
|
||||
|
||||
struct tree_priority_map GTY(())
|
||||
{
|
||||
struct tree_map_base base;
|
||||
priority_type init;
|
||||
priority_type fini;
|
||||
};
|
||||
|
||||
#define tree_priority_map_eq tree_map_base_eq
|
||||
#define tree_priority_map_hash tree_map_base_hash
|
||||
#define tree_priority_map_marked_p tree_map_base_marked_p
|
||||
|
||||
/* In tree-ssa-address.c. */
|
||||
extern tree tree_mem_ref_addr (tree, tree);
|
||||
|
14
gcc/varasm.c
14
gcc/varasm.c
@ -343,7 +343,7 @@ emutls_decl (tree decl)
|
||||
of the decl's pointer. In emutls_finish we iterate through the
|
||||
hash table, and we want this traversal to be predictable. */
|
||||
in.hash = htab_hash_string (IDENTIFIER_POINTER (name));
|
||||
in.from = decl;
|
||||
in.base.from = decl;
|
||||
loc = htab_find_slot_with_hash (emutls_htab, &in, in.hash, INSERT);
|
||||
h = *loc;
|
||||
if (h != NULL)
|
||||
@ -355,7 +355,7 @@ emutls_decl (tree decl)
|
||||
|
||||
h = ggc_alloc (sizeof (struct tree_map));
|
||||
h->hash = in.hash;
|
||||
h->from = decl;
|
||||
h->base.from = decl;
|
||||
h->to = to;
|
||||
*(struct tree_map **) loc = h;
|
||||
|
||||
@ -394,9 +394,9 @@ emutls_common_1 (void **loc, void *xstmts)
|
||||
tree args, x, *pstmts = (tree *) xstmts;
|
||||
tree word_type_node;
|
||||
|
||||
if (! DECL_COMMON (h->from)
|
||||
|| (DECL_INITIAL (h->from)
|
||||
&& DECL_INITIAL (h->from) != error_mark_node))
|
||||
if (! DECL_COMMON (h->base.from)
|
||||
|| (DECL_INITIAL (h->base.from)
|
||||
&& DECL_INITIAL (h->base.from) != error_mark_node))
|
||||
return 1;
|
||||
|
||||
word_type_node = lang_hooks.types.type_for_mode (word_mode, 1);
|
||||
@ -407,9 +407,9 @@ emutls_common_1 (void **loc, void *xstmts)
|
||||
output. */
|
||||
x = null_pointer_node;
|
||||
args = tree_cons (NULL, x, NULL);
|
||||
x = build_int_cst (word_type_node, DECL_ALIGN_UNIT (h->from));
|
||||
x = build_int_cst (word_type_node, DECL_ALIGN_UNIT (h->base.from));
|
||||
args = tree_cons (NULL, x, args);
|
||||
x = fold_convert (word_type_node, DECL_SIZE_UNIT (h->from));
|
||||
x = fold_convert (word_type_node, DECL_SIZE_UNIT (h->base.from));
|
||||
args = tree_cons (NULL, x, args);
|
||||
x = build_fold_addr_expr (h->to);
|
||||
args = tree_cons (NULL, x, args);
|
||||
|
Loading…
Reference in New Issue
Block a user