aboutsummaryrefslogtreecommitdiff
path: root/gcc/ada/utils.c
diff options
context:
space:
mode:
authorEric Botcazou <ebotcazou@adacore.com>2005-07-04 15:27:21 +0200
committerArnaud Charlet <charlet@gcc.gnu.org>2005-07-04 15:27:21 +0200
commitd9e0a58787285a0753791dd83a5d831bbbc92117 (patch)
tree617e7a72024f1df19ef1395e2e890a2461922a3f /gcc/ada/utils.c
parentc73ae90f23fab6c872b09e02b0d1e34727883056 (diff)
downloadgcc-d9e0a58787285a0753791dd83a5d831bbbc92117.zip
gcc-d9e0a58787285a0753791dd83a5d831bbbc92117.tar.gz
gcc-d9e0a58787285a0753791dd83a5d831bbbc92117.tar.bz2
decl.c (prepend_attributes): New case.
2005-07-04 Eric Botcazou <ebotcazou@adacore.com> * decl.c (prepend_attributes) <Pragma_Linker_Constructor>: New case. <Pragma_Linker_Destructor>: Likewise. * einfo.ads (Has_Gigi_Rep_Item): Document Pragma_Linker_Constructor and Pragma_Linker_Destructor. * gigi.h (attr_type): Add ATTR_LINK_CONSTRUCTOR and ATTR_LINK_DESTRUCTOR. (static_ctors, static_dtors): New variables. * misc.c (gnat_expand_body): Output current function as constructor and destructor if requested. * par-prag.adb: Add processing for pragma Linker_Constructor and Linker_Destructor. * sem_prag.adb (Find_Unique_Parameterless_Procedure): New function extracted from Check_Interrupt_Or_Attach_Handler. (Check_Interrupt_Or_Attach_Handler): Invoke it. Implement pragma Linker_Constructor and Linker_Destructor with the help of Find_Unique_Parameterless_Procedure. Replace Name_Alias with Name_Target for pragma Linker_Alias. * snames.h, snames.ads, snames.adb: Add Name_Linker_Constructor and Name_Linker_Destructor. Add Pragma_Linker_Constructor and Pragma_Linker_Destructor. * snames.adb: Remove Name_Alias. * trans.c: Include cgraph.h. (build_global_cdtor): New function. (Compilation_Unit_to_gnu): Build global constructor and destructor if needed. (tree_transform) <N_Identifier>: Substitute renaming of view-conversions of objects too. (addressable_p) <COMPONENT_REF>: Unconditionally test DECL_NONADDRESSABLE_P on STRICT_ALIGNMENT platforms. * utils.c (process_attributes) <ATTR_LINK_ALIAS>: Do not assemble the variable if it is external. (static_ctors, static_dtors): New global variables. (process_attributes) <ATTR_LINK_CONSTRUCTOR>: New case. <ATTR_LINK_DESTRUCTOR>: Likewise. (end_subprog_body): Chain function as constructor and destructor if requested. * exp_util.adb (Force_Evaluation): Unconditionally invoke Remove_Side_Effects with Variable_Ref set to true. (Remove_Side_Effects): Handle scalar types first. Use a renaming for non-scalar types even if Variable_Ref is true and for class-wide expressions. From-SVN: r101576
Diffstat (limited to 'gcc/ada/utils.c')
-rw-r--r--gcc/ada/utils.c30
1 files changed, 28 insertions, 2 deletions
diff --git a/gcc/ada/utils.c b/gcc/ada/utils.c
index 4c2a7c9..b19cb45 100644
--- a/gcc/ada/utils.c
+++ b/gcc/ada/utils.c
@@ -74,6 +74,11 @@ tree gnat_std_decls[(int) ADT_LAST];
/* Functions to call for each of the possible raise reasons. */
tree gnat_raise_decls[(int) LAST_REASON_CODE + 1];
+/* List of functions called automatically at the beginning and
+ end of execution, on targets without .ctors/.dtors sections. */
+tree static_ctors;
+tree static_dtors;
+
/* Associates a GNAT tree node to a GCC tree node. It is used in
`save_gnu_tree', `get_gnu_tree' and `present_gnu_tree'. See documentation
of `save_gnu_tree' for more info. */
@@ -1509,8 +1514,11 @@ process_attributes (tree decl, struct attrib *attr_list)
break;
case ATTR_LINK_ALIAS:
- TREE_STATIC (decl) = 1;
- assemble_alias (decl, attr_list->name);
+ if (! DECL_EXTERNAL (decl))
+ {
+ TREE_STATIC (decl) = 1;
+ assemble_alias (decl, attr_list->name);
+ }
break;
case ATTR_WEAK_EXTERNAL:
@@ -1533,6 +1541,16 @@ process_attributes (tree decl, struct attrib *attr_list)
post_error ("?section attributes are not supported for this target",
attr_list->error_point);
break;
+
+ case ATTR_LINK_CONSTRUCTOR:
+ DECL_STATIC_CONSTRUCTOR (decl) = 1;
+ TREE_USED (decl) = 1;
+ break;
+
+ case ATTR_LINK_DESTRUCTOR:
+ DECL_STATIC_DESTRUCTOR (decl) = 1;
+ TREE_USED (decl) = 1;
+ break;
}
}
@@ -1728,6 +1746,14 @@ end_subprog_body (tree body)
if (type_annotate_only)
return;
+ /* If we don't have .ctors/.dtors sections, and this is a static
+ constructor or destructor, it must be recorded now. */
+ if (DECL_STATIC_CONSTRUCTOR (fndecl) && !targetm.have_ctors_dtors)
+ static_ctors = tree_cons (NULL_TREE, fndecl, static_ctors);
+
+ if (DECL_STATIC_DESTRUCTOR (fndecl) && !targetm.have_ctors_dtors)
+ static_dtors = tree_cons (NULL_TREE, fndecl, static_dtors);
+
/* We do different things for nested and non-nested functions.
??? This should be in cgraph. */
if (!DECL_CONTEXT (fndecl))