diff options
author | Eric Botcazou <ebotcazou@adacore.com> | 2005-07-04 15:27:21 +0200 |
---|---|---|
committer | Arnaud Charlet <charlet@gcc.gnu.org> | 2005-07-04 15:27:21 +0200 |
commit | d9e0a58787285a0753791dd83a5d831bbbc92117 (patch) | |
tree | 617e7a72024f1df19ef1395e2e890a2461922a3f /gcc/ada/trans.c | |
parent | c73ae90f23fab6c872b09e02b0d1e34727883056 (diff) | |
download | gcc-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/trans.c')
-rw-r--r-- | gcc/ada/trans.c | 45 |
1 files changed, 41 insertions, 4 deletions
diff --git a/gcc/ada/trans.c b/gcc/ada/trans.c index cdb5506..3a3327a 100644 --- a/gcc/ada/trans.c +++ b/gcc/ada/trans.c @@ -35,6 +35,7 @@ #include "rtl.h" #include "expr.h" #include "ggc.h" +#include "cgraph.h" #include "function.h" #include "except.h" #include "debug.h" @@ -164,6 +165,7 @@ static tree pos_to_constructor (Node_Id, tree, Entity_Id); static tree maybe_implicit_deref (tree); static tree gnat_stabilize_reference_1 (tree, bool); static void annotate_with_node (tree, Node_Id); +static void build_global_cdtor (int, tree *); /* This is the main program of the back-end. It sets up all the table @@ -410,7 +412,11 @@ Identifier_to_gnu (Node_Id gnat_node, tree *gnu_result_type_p) && (! DECL_RENAMING_GLOBAL_P (gnu_result) || global_bindings_p ()) /* Make sure it's an lvalue like INDIRECT_REF. */ - && (DECL_P (renamed_obj) || REFERENCE_CLASS_P (renamed_obj))) + && (DECL_P (renamed_obj) + || REFERENCE_CLASS_P (renamed_obj) + || (TREE_CODE (renamed_obj) == VIEW_CONVERT_EXPR + && (DECL_P (TREE_OPERAND (renamed_obj, 0)) + || REFERENCE_CLASS_P (TREE_OPERAND (renamed_obj,0)))))) gnu_result = renamed_obj; else gnu_result = build_unary_op (INDIRECT_REF, NULL_TREE, @@ -2405,7 +2411,7 @@ Compilation_Unit_to_gnu (Node_Id gnat_node) Sloc_to_locus (Sloc (gnat_unit_entity), &cfun->function_end_locus); cfun = 0; - /* For a body, first process the spec if there is one. */ + /* For a body, first process the spec if there is one. */ if (Nkind (Unit (gnat_node)) == N_Package_Body || (Nkind (Unit (gnat_node)) == N_Subprogram_Body && !Acts_As_Spec (gnat_node))) @@ -2445,6 +2451,15 @@ Compilation_Unit_to_gnu (Node_Id gnat_node) /* Generate elaboration code for this unit, if necessary, and say whether we did or not. */ pop_stack (&gnu_elab_proc_stack); + + /* Generate functions to call static constructors and destructors + for targets that do not support .ctors/.dtors sections. These + functions have magic names which are detected by collect2. */ + if (static_ctors) + build_global_cdtor ('I', &static_ctors); + + if (static_dtors) + build_global_cdtor ('D', &static_dtors); } /* This function is the driver of the GNAT to GCC tree transformation @@ -5353,8 +5368,8 @@ addressable_p (tree gnu_expr) case COMPONENT_REF: return (!DECL_BIT_FIELD (TREE_OPERAND (gnu_expr, 1)) - && (!DECL_NONADDRESSABLE_P (TREE_OPERAND (gnu_expr, 1)) - || !flag_strict_aliasing) + && !(STRICT_ALIGNMENT + && DECL_NONADDRESSABLE_P (TREE_OPERAND (gnu_expr, 1))) && addressable_p (TREE_OPERAND (gnu_expr, 0))); case ARRAY_REF: case ARRAY_RANGE_REF: @@ -5859,6 +5874,28 @@ gnat_stabilize_reference_1 (tree e, bool force) TREE_SIDE_EFFECTS (result) |= TREE_SIDE_EFFECTS (e); return result; } + +/* Build a global constructor or destructor function. METHOD_TYPE gives + the type of the function and CDTORS points to the list of constructor + or destructor functions to be invoked. FIXME: Migrate into cgraph. */ + +static void +build_global_cdtor (int method_type, tree *cdtors) +{ + tree body = 0; + + for (; *cdtors; *cdtors = TREE_CHAIN (*cdtors)) + { + tree fn = TREE_VALUE (*cdtors); + tree fntype = TREE_TYPE (fn); + tree fnaddr = build1 (ADDR_EXPR, build_pointer_type (fntype), fn); + tree fncall = build3 (CALL_EXPR, TREE_TYPE (fntype), fnaddr, NULL_TREE, + NULL_TREE); + append_to_statement_list (fncall, &body); + } + + cgraph_build_static_cdtor (method_type, body, DEFAULT_INIT_PRIORITY); +} extern char *__gnat_to_canonical_file_spec (char *); |