diff options
author | mmitchel <mmitchel@138bc75d-0d04-0410-961f-82ee72b054a4> | 2007-02-25 18:47:05 +0000 |
---|---|---|
committer | mmitchel <mmitchel@138bc75d-0d04-0410-961f-82ee72b054a4> | 2007-02-25 18:47:05 +0000 |
commit | 9af7fd5b82a9d848526e5f5edf0411d6dd2693fc (patch) | |
tree | cfcdaf9660cd0bdc1216594b6e66f5e22560aa3e /gcc/c-common.c | |
parent | fc128a8dad1a9328a7a8a26a98b934f06fb175d5 (diff) | |
download | gcc-9af7fd5b82a9d848526e5f5edf0411d6dd2693fc.tar.gz |
* 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.
git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@122315 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc/c-common.c')
-rw-r--r-- | gcc/c-common.c | 84 |
1 files changed, 78 insertions, 6 deletions
diff --git a/gcc/c-common.c b/gcc/c-common.c index 51fd22672cf..4eb0265a7a2 100644 --- a/gcc/c-common.c +++ b/gcc/c-common.c @@ -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 |