diff options
author | Tristan Gingold <gingold@adacore.com> | 2008-05-20 14:44:43 +0200 |
---|---|---|
committer | Arnaud Charlet <charlet@gcc.gnu.org> | 2008-05-20 14:44:43 +0200 |
commit | e7841bacf5a86bd2523a39abb8e6f6385297b6fd (patch) | |
tree | 8e2cbf2aa50782a9ae8bbcfee5b13e1a490c22ba /gcc/ada/decl.c | |
parent | 5b6a0e43da82d4c4a82fadf2af3b2fa8d39bec63 (diff) | |
download | gcc-e7841bacf5a86bd2523a39abb8e6f6385297b6fd.zip gcc-e7841bacf5a86bd2523a39abb8e6f6385297b6fd.tar.gz gcc-e7841bacf5a86bd2523a39abb8e6f6385297b6fd.tar.bz2 |
decl.c: Do not emit a variable for a object that has an address representation clause...
2008-05-20 Tristan Gingold <gingold@adacore.com>
* decl.c: Do not emit a variable for a object that has an address
representation clause whose value is known at compile time.
When a variable has an address clause whose value is known at compile
time, refer to this variable by using directly the address instead of
dereferencing a pointer.
From-SVN: r135618
Diffstat (limited to 'gcc/ada/decl.c')
-rw-r--r-- | gcc/ada/decl.c | 39 |
1 files changed, 36 insertions, 3 deletions
diff --git a/gcc/ada/decl.c b/gcc/ada/decl.c index 8565305..8f29ca7 100644 --- a/gcc/ada/decl.c +++ b/gcc/ada/decl.c @@ -122,6 +122,17 @@ static void check_ok_for_atomic (tree, Entity_Id, bool); static int compatible_signatures_p (tree ftype1, tree ftype2); static void rest_of_type_decl_compilation_no_defer (tree); +/* Return true if GNAT_ADDRESS is a compile time known value. + In particular catch System'To_Address. */ + +static bool +compile_time_known_address_p (Node_Id gnat_address) +{ + return ((Nkind (gnat_address) == N_Unchecked_Type_Conversion + && Compile_Time_Known_Value (Expression (gnat_address))) + || Compile_Time_Known_Value (gnat_address)); +} + /* Given GNAT_ENTITY, an entity in the incoming GNAT tree, return a GCC type corresponding to that entity. GNAT_ENTITY is assumed to refer to an Ada type. */ @@ -1026,7 +1037,9 @@ gnat_to_gnu_entity (Entity_Id gnat_entity, tree gnu_expr, int definition) = build_reference_type_for_mode (gnu_type, ptr_mode, true); gnu_address = convert (gnu_type, gnu_address); used_by_ref = true; - const_flag = !Is_Public (gnat_entity); + const_flag = !Is_Public (gnat_entity) + || compile_time_known_address_p (Expression (Address_Clause + (gnat_entity))); /* If we don't have an initializing expression for the underlying variable, the initializing expression for the pointer is the @@ -1058,9 +1071,24 @@ gnat_to_gnu_entity (Entity_Id gnat_entity, tree gnu_expr, int definition) = build_reference_type_for_mode (gnu_type, ptr_mode, true); gnu_size = NULL_TREE; - gnu_expr = NULL_TREE; /* No point in taking the address of an initializing expression that isn't going to be used. */ + gnu_expr = NULL_TREE; + + /* If it has an address clause whose value is known at compile + time, make the object a CONST_DECL. This will avoid a + useless dereference. */ + if (Present (Address_Clause (gnat_entity))) + { + Node_Id gnat_address + = Expression (Address_Clause (gnat_entity)); + + if (compile_time_known_address_p (gnat_address)) + { + gnu_expr = gnat_to_gnu (gnat_address); + const_flag = true; + } + } used_by_ref = true; } @@ -1258,7 +1286,8 @@ gnat_to_gnu_entity (Entity_Id gnat_entity, tree gnu_expr, int definition) for these. */ if (TREE_CODE (gnu_decl) == CONST_DECL && (definition || Sloc (gnat_entity) > Standard_Location) - && (Is_Public (gnat_entity) + && ((Is_Public (gnat_entity) + && !Present (Address_Clause (gnat_entity))) || optimize == 0 || Address_Taken (gnat_entity) || Is_Aliased (gnat_entity) @@ -1271,6 +1300,10 @@ gnat_to_gnu_entity (Entity_Id gnat_entity, tree gnu_expr, int definition) gnat_entity); SET_DECL_CONST_CORRESPONDING_VAR (gnu_decl, gnu_corr_var); + + /* As debugging information will be generated for the variable, + do not generate information for the constant. */ + DECL_IGNORED_P (gnu_decl) = true; } /* If this is declared in a block that contains a block with an |