aboutsummaryrefslogtreecommitdiff
path: root/gcc/ada/gcc-interface/decl.c
diff options
context:
space:
mode:
authorEric Botcazou <ebotcazou@adacore.com>2010-09-19 13:48:51 +0000
committerEric Botcazou <ebotcazou@gcc.gnu.org>2010-09-19 13:48:51 +0000
commit2231f17fa0b742bec5fdcad0894d02af2ddab08c (patch)
treeb62bef407ee1a1a7c6b27d747db9b145775e6634 /gcc/ada/gcc-interface/decl.c
parenta10623fb71eb10046cbd3d7ad7dc3b9cef781666 (diff)
downloadgcc-2231f17fa0b742bec5fdcad0894d02af2ddab08c.zip
gcc-2231f17fa0b742bec5fdcad0894d02af2ddab08c.tar.gz
gcc-2231f17fa0b742bec5fdcad0894d02af2ddab08c.tar.bz2
gigi.h (get_elaboration_procedure): Declare.
* gcc-interface/gigi.h (get_elaboration_procedure): Declare. (gnat_zaplevel): Likewise. * gcc-interface/decl.c (gnat_to_gnu_entity): Do not force global binding level for an external constant. <E_Constant>: Force the local context and create a fake scope before translating the defining expression of an external constant. <object>: Treat external constants at the global level explicitly for renaming declarations. (elaborate_expression_1): Force the variable to be static if the expression is global. * gcc-interface/trans.c (get_elaboration_procedure): New function. (call_to_gnu): Use it. (gnat_to_gnu): Likewise. <N_Object_Declaration>: Do not test Is_Public to force the creation of an initialization variable. (add_decl_expr): Discard the statement if the declaration is external. * gcc-interface/utils.c (gnat_pushdecl): Do not put the declaration in the current block if it is external. (create_var_decl_1): Do not test Is_Public to set TREE_STATIC. (gnat_zaplevel): New global function. From-SVN: r164416
Diffstat (limited to 'gcc/ada/gcc-interface/decl.c')
-rw-r--r--gcc/ada/gcc-interface/decl.c45
1 files changed, 36 insertions, 9 deletions
diff --git a/gcc/ada/gcc-interface/decl.c b/gcc/ada/gcc-interface/decl.c
index 850777d..32b499b 100644
--- a/gcc/ada/gcc-interface/decl.c
+++ b/gcc/ada/gcc-interface/decl.c
@@ -357,10 +357,12 @@ gnat_to_gnu_entity (Entity_Id gnat_entity, tree gnu_expr, int definition)
another compilation unit) public entities, show we are at global level
for the purpose of computing scopes. Don't do this for components or
discriminants since the relevant test is whether or not the record is
- being defined. */
+ being defined. Don't do this for constants either as we'll look into
+ their defining expression in the local context. */
if (!definition
&& kind != E_Component
&& kind != E_Discriminant
+ && kind != E_Constant
&& Is_Public (gnat_entity)
&& !Is_Statically_Allocated (gnat_entity))
force_global++, this_global = true;
@@ -430,7 +432,28 @@ gnat_to_gnu_entity (Entity_Id gnat_entity, tree gnu_expr, int definition)
&& Present (Expression (Declaration_Node (gnat_entity)))
&& Nkind (Expression (Declaration_Node (gnat_entity)))
!= N_Allocator)
- gnu_expr = gnat_to_gnu (Expression (Declaration_Node (gnat_entity)));
+ {
+ bool went_into_elab_proc = false;
+
+ /* The expression may contain N_Expression_With_Actions nodes and
+ thus object declarations from other units. In this case, even
+ though the expression will eventually be discarded since not a
+ constant, the declarations would be stuck either in the global
+ varpool or in the current scope. Therefore we force the local
+ context and create a fake scope that we'll zap at the end. */
+ if (!current_function_decl)
+ {
+ current_function_decl = get_elaboration_procedure ();
+ went_into_elab_proc = true;
+ }
+ gnat_pushlevel ();
+
+ gnu_expr = gnat_to_gnu (Expression (Declaration_Node (gnat_entity)));
+
+ gnat_zaplevel ();
+ if (went_into_elab_proc)
+ current_function_decl = NULL_TREE;
+ }
/* Ignore deferred constant definitions without address clause since
they are processed fully in the front-end. If No_Initialization
@@ -926,10 +949,12 @@ gnat_to_gnu_entity (Entity_Id gnat_entity, tree gnu_expr, int definition)
that for the renaming. At the global level, we can only do
this if we know no SAVE_EXPRs need be made, because the
expression we return might be used in arbitrary conditional
- branches so we must force the SAVE_EXPRs evaluation
- immediately and this requires a function context. */
+ branches so we must force the evaluation of the SAVE_EXPRs
+ immediately and this requires a proper function context.
+ Note that an external constant is at the global level. */
if (!Materialize_Entity (gnat_entity)
- && (!global_bindings_p ()
+ && (!((!definition && kind == E_Constant)
+ || global_bindings_p ())
|| (staticp (gnu_expr)
&& !TREE_SIDE_EFFECTS (gnu_expr))))
{
@@ -940,7 +965,8 @@ gnat_to_gnu_entity (Entity_Id gnat_entity, tree gnu_expr, int definition)
{
/* ??? No DECL_EXPR is created so we need to mark
the expression manually lest it is shared. */
- if (global_bindings_p ())
+ if ((!definition && kind == E_Constant)
+ || global_bindings_p ())
MARK_VISITED (maybe_stable_expr);
gnu_decl = maybe_stable_expr;
save_gnu_tree (gnat_entity, gnu_decl, true);
@@ -1359,11 +1385,12 @@ gnat_to_gnu_entity (Entity_Id gnat_entity, tree gnu_expr, int definition)
}
/* If this is a renaming pointer, attach the renamed object to it and
- register it if we are at top level. */
+ register it if we are at the global level. Note that an external
+ constant is at the global level. */
if (TREE_CODE (gnu_decl) == VAR_DECL && renamed_obj)
{
SET_DECL_RENAMED_OBJECT (gnu_decl, renamed_obj);
- if (global_bindings_p ())
+ if ((!definition && kind == E_Constant) || global_bindings_p ())
{
DECL_RENAMING_GLOBAL_P (gnu_decl) = 1;
record_global_renaming_pointer (gnu_decl);
@@ -5977,7 +6004,7 @@ elaborate_expression_1 (tree gnu_expr, Entity_Id gnat_entity, tree gnu_name,
IDENTIFIER_POINTER (gnu_name)),
NULL_TREE, TREE_TYPE (gnu_expr), gnu_expr,
!need_debug, Is_Public (gnat_entity),
- !definition, false, NULL, gnat_entity);
+ !definition, expr_global, NULL, gnat_entity);
/* We only need to use this variable if we are in global context since GCC
can do the right thing in the local case. */