summaryrefslogtreecommitdiff
path: root/gcc/c-common.c
diff options
context:
space:
mode:
authormmitchel <mmitchel@138bc75d-0d04-0410-961f-82ee72b054a4>2007-02-25 18:47:05 +0000
committermmitchel <mmitchel@138bc75d-0d04-0410-961f-82ee72b054a4>2007-02-25 18:47:05 +0000
commit9af7fd5b82a9d848526e5f5edf0411d6dd2693fc (patch)
treecfcdaf9660cd0bdc1216594b6e66f5e22560aa3e /gcc/c-common.c
parentfc128a8dad1a9328a7a8a26a98b934f06fb175d5 (diff)
downloadgcc-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.c84
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