aboutsummaryrefslogtreecommitdiff
path: root/gcc/ada/utils.c
diff options
context:
space:
mode:
authorArnaud Charlet <charlet@gcc.gnu.org>2004-05-17 15:20:48 +0200
committerArnaud Charlet <charlet@gcc.gnu.org>2004-05-17 15:20:48 +0200
commitb5e792e209cfee6fe3437eef9470e7765acda53f (patch)
tree2b5692e6b47e044d030ae4b10881296d50e2f101 /gcc/ada/utils.c
parent646ca712a1d3d4b6642b8d9c3f0d24e463102b76 (diff)
downloadgcc-b5e792e209cfee6fe3437eef9470e7765acda53f.zip
gcc-b5e792e209cfee6fe3437eef9470e7765acda53f.tar.gz
gcc-b5e792e209cfee6fe3437eef9470e7765acda53f.tar.bz2
[multiple changes]
2004-05-17 Richard Kenner <kenner@vlsi1.ultra.nyu.edu> Part of function-at-a-time conversion * misc.c (adjust_decl_rtl): Deleted. (LANG_HOOKS_PUSHLEVEL, LANG_HOOKS_POPLEVEL, LANG_HOOKS_SET_BLOCK): Define. * gigi.h: (adjust_decl_rtl, kept_level_p, set_block): Deleted. (add_decl_stmt, add_stmt, block_has_vars): New functions. (gnat_pushlevel, gnat_poplevel): Renamed from pushlevel and poplevel. * decl.c (elaborate_expression, maybe_pad_type): Call add_decl_stmt when making a decl. (gnat_to_gnu_entity): Likewise. Use add_stmt to update setjmp buffer. Set TREE_ADDRESSABLE instead of calling put_var_into_stack and flush_addressof. No longer call adjust_decl_rtl. (DECL_INIT_BY_ASSIGN_P): New macro. (DECL_STMT_VAR): Likewise. * trans.c (gigi): Call start_block_stmt to make the outermost BLOCK_STMT. (gnat_to_code, gnu_to_gnu, tree_transform, process_decls, process_type): Call start_block_stmt and end_block_stmt temporarily. Use gnat_expand_stmt instead of expand_expr_stmt. (add_decl_stmt): New function. (tree_transform): Call it. (add_stmt): Also emit initializing assignment for DECL_STMT if needed. (end_block_stmt): Set type and NULL_STMT. (gnat_expand_stmt): Make recursize call instead of calling expand_expr_stmt. (gnat_expand_stmt, case DECL_STMT): New case. (set_lineno_from_sloc): Do nothing if global. (gnu_block_stmt_node, gnu_block_stmt_free_list): New variables. (start_block_stmt, add_stmt, end_block_stmt): New functions. (build_block_stmt): Call them. (gnat_to_code): Don't expand NULL_STMT. (build_unit_elab): Rename pushlevel and poplevel to gnat_* and change args. (tree_transform): Likewise. (tree_transform, case N_Null_Statement): Return NULL_STMT. (gnat_expand_stmt, case NULL_STMT): New case. (gnat_expand_stmt, case IF_STMT): Allow nested IF_STMT to have no IF_STMT_TRUE. * utils2.c (gnat_mark_addressable, case VAR_DECL): Do not set TREE_ADDRESSABLE. * utils.c (create_var_decl): Do not call expand_decl or expand_decl_init. Set TREE_ADDRESSABLE instead of calling gnat_mark_addressable. Set DECL_INIT_BY_ASSIGN_P when needed and do not generate MODIFY_EXPR here. (struct e_stack): Add chain_next to GTY. (struct binding_level): Deleted. (struct ada_binding_level): New struct. (free_block_chain): New. (global_binding_level, clear_binding_level): Deleted. (global_bindings_p): Rework to see if no chain. (kept_level_p, set_block): Deleted. (gnat_pushlevel): Renamed from pushlevel and extensive reworked to use new data structure and work directly on BLOCK node. (gnat_poplevel): Similarly. (get_decls): Look at BLOCK_VARS. (insert_block): Work directly on BLOCK node. (block_has_var): New function. (pushdecl): Rework for new binding structures. (gnat_init_decl_processing): Rename and rework calls to pushlevel and poplevel. (build_subprog_body): Likewise. (end_subprog_body): Likewise; also set up BLOCK in DECL_INITIAL. * ada-tree.def (DECL_STMT, NULL_STMT): New codes. * ada-tree.h: (DECL_INIT_BY_ASSIGN_P): New macro. (DECL_STMT_VAR): Likewise. 2004-05-17 Robert Dewar <dewar@gnat.com> * restrict.ads, restrict.adb (Process_Restriction_Synonym): New procedure * sem_prag.adb (Analyze_Pragma, case Restrictions): Cleanup handling of restriction synonyums by using Restrict.Process_Restriction_Synonyms. * snames.ads, snames.adb: Add entries for Process_Restriction_Synonym * s-restri.ads (Tasking_Allowed): Correct missing comment * s-rident.ads: Add entries for restriction synonyms * ali.adb: Fix some problems with badly formatted ALI files that can result in infinite loops. * s-taprop-lynxos.adb, s-tpopsp-lynxos.adb, s-taprop-tru64.adb, s-tpopsp-posix-foreign.adb, s-taprop-irix.adb, s-interr-sigaction.adb, s-taprop-irix-athread.adb, s-taprop-hpux-dce.adb, s-taprop-linux.adb, s-taprop-dummy.adb, s-interr-dummy.adb, s-taprop-os2.adb, s-taprop-solaris.adb, s-tpopsp-solaris.adb, s-asthan-vms.adb, s-inmaop-vms.adb, s-interr-vms.adb, s-taprop-vms.adb, s-tpopde-vms.adb, s-taprop-mingw.adb, s-interr-vxworks.adb, s-taprop-vxworks.adb, s-tpopsp-vxworks.adb, s-taprop-posix.adb, s-tpopsp-posix.adb, s-tratas-default.adb, a-dynpri.adb, a-tasatt.adb, a-taside.adb, a-taside.ads, exp_attr.adb, exp_ch9.adb, g-thread.adb, rtsfind.ads, sem_attr.adb, s-interr.adb, s-interr.ads, s-soflin.ads, s-taasde.adb, s-taasde.ads, s-taenca.adb, s-taenca.ads, s-taprop.ads, s-tarest.adb, s-tarest.ads, s-tasdeb.adb, s-tasdeb.ads, s-tasini.adb, s-tasini.ads, s-taskin.adb, s-taskin.ads, s-tasque.adb, s-tasque.ads, s-tasren.adb, s-tasren.ads, s-tassta.adb, s-tassta.ads, s-tasuti.adb, s-tasuti.ads, s-tataat.adb, s-tataat.ads, s-tpinop.adb, s-tpinop.ads, s-tpoben.adb, s-tpobop.adb, s-tpobop.ads, s-tporft.adb, s-tposen.adb, s-tposen.ads, s-tratas.adb, s-tratas.ads: Change Task_ID to Task_Id (minor cleanup). 2004-05-17 Vincent Celier <celier@gnat.com> * g-os_lib.adb (Normalize_Pathname.Final_Value): Remove trailing directory separator. * prj-proc.adb (Recursive_Process): Inherit attribute Languages from project being extended, if Languages is not declared in extending project. 2004-05-17 Javier Miranda <miranda@gnat.com> * sem_ch10.adb (Install_Limited_Withed_Unit): Do not install the limited view of a visible sibling. From-SVN: r81935
Diffstat (limited to 'gcc/ada/utils.c')
-rw-r--r--gcc/ada/utils.c304
1 files changed, 95 insertions, 209 deletions
diff --git a/gcc/ada/utils.c b/gcc/ada/utils.c
index 6022dbf..ead346f 100644
--- a/gcc/ada/utils.c
+++ b/gcc/ada/utils.c
@@ -84,7 +84,7 @@ static GTY(()) tree pending_elaborations;
/* This stack allows us to momentarily switch to generating elaboration
lists for an inner context. */
-struct e_stack GTY(()) {
+struct e_stack GTY((chain_next ("%h.next"))) {
struct e_stack *next;
tree elab_list;
};
@@ -110,36 +110,22 @@ static GTY(()) tree float_types[NUM_MACHINE_MODES];
Binding contours are used to create GCC tree BLOCK nodes. */
-struct binding_level GTY(())
+struct ada_binding_level GTY((chain_next ("%h.chain")))
{
- /* A chain of ..._DECL nodes for all variables, constants, functions,
- parameters and type declarations. These ..._DECL nodes are chained
- through the TREE_CHAIN field. Note that these ..._DECL nodes are stored
- in the reverse of the order supplied to be compatible with the
- back-end. */
- tree names;
- /* For each level (except the global one), a chain of BLOCK nodes for all
- the levels that were entered and exited one level down from this one. */
- tree blocks;
- /* The BLOCK node for this level, if one has been preallocated.
- If 0, the BLOCK is allocated (if needed) when the level is popped. */
- tree this_block;
/* The binding level containing this one (the enclosing binding level). */
- struct binding_level *level_chain;
+ struct ada_binding_level *chain;
+ /* The BLOCK node for this level. */
+ tree block;
};
/* The binding level currently in effect. */
-static GTY(()) struct binding_level *current_binding_level;
+static GTY(()) struct ada_binding_level *current_binding_level;
-/* A chain of binding_level structures awaiting reuse. */
-static GTY((deletable (""))) struct binding_level *free_binding_level;
+/* A chain of ada_binding_level structures awaiting reuse. */
+static GTY((deletable)) struct ada_binding_level *free_binding_level;
-/* The outermost binding level. This binding level is created when the
- compiler is started and it will exist through the entire compilation. */
-static struct binding_level *global_binding_level;
-
-/* Binding level structures are initialized by copying this one. */
-static struct binding_level clear_binding_level = {NULL, NULL, NULL, NULL};
+/* A chain of unused BLOCK nodes. */
+static GTY((deletable)) tree free_block_chain;
struct language_function GTY(())
{
@@ -219,8 +205,7 @@ present_gnu_tree (Entity_Id gnat_entity)
int
global_bindings_p (void)
{
- return (force_global != 0 || current_binding_level == global_binding_level
- ? -1 : 0);
+ return (force_global != 0 || current_binding_level->chain == 0 ? -1 : 0);
}
/* Return the list of declarations in the current level. Note that this list
@@ -229,163 +214,102 @@ global_bindings_p (void)
tree
getdecls (void)
{
- return current_binding_level->names;
-}
-
-/* Nonzero if the current level needs to have a BLOCK made. */
-
-int
-kept_level_p (void)
-{
- return (current_binding_level->names != 0);
+ return BLOCK_VARS (current_binding_level->block);
}
-/* Enter a new binding level. The input parameter is ignored, but has to be
- specified for back-end compatibility. */
+/* Enter a new binding level. */
void
-pushlevel (int ignore ATTRIBUTE_UNUSED)
+gnat_pushlevel ()
{
- struct binding_level *newlevel = NULL;
+ struct ada_binding_level *newlevel = NULL;
/* Reuse a struct for this binding level, if there is one. */
if (free_binding_level)
{
newlevel = free_binding_level;
- free_binding_level = free_binding_level->level_chain;
+ free_binding_level = free_binding_level->chain;
}
else
newlevel
- = (struct binding_level *) ggc_alloc (sizeof (struct binding_level));
+ = (struct ada_binding_level *)
+ ggc_alloc (sizeof (struct ada_binding_level));
- *newlevel = clear_binding_level;
+ /* Use a free BLOCK, if any; otherwise, allocate one. */
+ if (free_block_chain)
+ {
+ newlevel->block = free_block_chain;
+ free_block_chain = TREE_CHAIN (free_block_chain);
+ TREE_CHAIN (newlevel->block) = NULL_TREE;
+ }
+ else
+ newlevel->block = make_node (BLOCK);
+
+ /* Point the BLOCK we just made to its parent. */
+ if (current_binding_level)
+ BLOCK_SUPERCONTEXT (newlevel->block) = current_binding_level->block;
+
+ BLOCK_VARS (newlevel->block) = BLOCK_SUBBLOCKS (newlevel->block) = NULL_TREE;
/* Add this level to the front of the chain (stack) of levels that are
active. */
- newlevel->level_chain = current_binding_level;
+ newlevel->chain = current_binding_level;
current_binding_level = newlevel;
}
-/* Exit a binding level.
- Pop the level off, and restore the state of the identifier-decl mappings
- that were in effect when this level was entered.
-
- If KEEP is nonzero, this level had explicit declarations, so
- and create a "block" (a BLOCK node) for the level
- to record its declarations and subblocks for symbol table output.
+/* Exit a binding level. */
- If FUNCTIONBODY is nonzero, this level is the body of a function,
- so create a block as if KEEP were set and also clear out all
- label names.
-
- If REVERSE is nonzero, reverse the order of decls before putting
- them into the BLOCK. */
-
-tree
-poplevel (int keep, int reverse, int functionbody)
+void
+gnat_poplevel ()
{
- /* Points to a GCC BLOCK tree node. This is the BLOCK node construted for the
- binding level that we are about to exit and which is returned by this
- routine. */
- tree block = NULL_TREE;
- tree decl_chain;
- tree decl_node;
- tree subblock_chain = current_binding_level->blocks;
- tree subblock_node;
- int block_previously_created;
-
- /* Reverse the list of XXXX_DECL nodes if desired. Note that the ..._DECL
- nodes chained through the `names' field of current_binding_level are in
- reverse order except for PARM_DECL node, which are explicitly stored in
- the right order. */
- current_binding_level->names
- = decl_chain = (reverse) ? nreverse (current_binding_level->names)
- : current_binding_level->names;
+ struct ada_binding_level *level = current_binding_level;
+ tree block = level->block;
+ tree decl;
+
+ BLOCK_VARS (block) = nreverse (BLOCK_VARS (block));
+ BLOCK_SUBBLOCKS (block) = nreverse (BLOCK_SUBBLOCKS (block));
/* Output any nested inline functions within this block which must be
compiled because their address is needed. */
- for (decl_node = decl_chain; decl_node; decl_node = TREE_CHAIN (decl_node))
- if (TREE_CODE (decl_node) == FUNCTION_DECL
- && ! TREE_ASM_WRITTEN (decl_node) && TREE_ADDRESSABLE (decl_node)
- && DECL_INITIAL (decl_node) != 0)
+ for (decl = BLOCK_VARS (block); decl; decl = TREE_CHAIN (decl))
+ if (TREE_CODE (decl) == FUNCTION_DECL
+ && ! TREE_ASM_WRITTEN (decl) && TREE_ADDRESSABLE (decl)
+ && DECL_INITIAL (decl) != 0)
{
push_function_context ();
/* ??? This is temporary. */
ggc_push_context ();
- output_inline_function (decl_node);
+ output_inline_function (decl);
ggc_pop_context ();
pop_function_context ();
}
- block = 0;
- block_previously_created = (current_binding_level->this_block != 0);
- if (block_previously_created)
- block = current_binding_level->this_block;
- else if (keep || functionbody)
- block = make_node (BLOCK);
- if (block != 0)
- {
- BLOCK_VARS (block) = keep ? decl_chain : 0;
- BLOCK_SUBBLOCKS (block) = subblock_chain;
- }
-
- /* Record the BLOCK node just built as the subblock its enclosing scope. */
- for (subblock_node = subblock_chain; subblock_node;
- subblock_node = TREE_CHAIN (subblock_node))
- BLOCK_SUPERCONTEXT (subblock_node) = block;
-
- /* Clear out the meanings of the local variables of this level. */
-
- for (subblock_node = decl_chain; subblock_node;
- subblock_node = TREE_CHAIN (subblock_node))
- if (DECL_NAME (subblock_node) != 0)
- /* If the identifier was used or addressed via a local extern decl,
- don't forget that fact. */
- if (DECL_EXTERNAL (subblock_node))
- {
- if (TREE_USED (subblock_node))
- TREE_USED (DECL_NAME (subblock_node)) = 1;
- if (TREE_ADDRESSABLE (subblock_node))
- TREE_ADDRESSABLE (DECL_ASSEMBLER_NAME (subblock_node)) = 1;
- }
-
- {
- /* Pop the current level, and free the structure for reuse. */
- struct binding_level *level = current_binding_level;
- current_binding_level = current_binding_level->level_chain;
- level->level_chain = free_binding_level;
- free_binding_level = level;
- }
-
- if (functionbody)
+ /* If this is a function-level BLOCK don't do anything. Otherwise, if there
+ are no variables free the block and merge its subblocks into those of its
+ parent block. Otherwise, add it to the list of its parent. */
+ if (TREE_CODE (BLOCK_SUPERCONTEXT (block)) == FUNCTION_DECL)
+ ;
+ else if (BLOCK_VARS (block) == 0)
{
- /* This is the top level block of a function. The ..._DECL chain stored
- in BLOCK_VARS are the function's parameters (PARM_DECL nodes). Don't
- leave them in the BLOCK because they are found in the FUNCTION_DECL
- instead. */
- DECL_INITIAL (current_function_decl) = block;
- BLOCK_VARS (block) = 0;
+ BLOCK_SUBBLOCKS (level->chain->block)
+ = chainon (BLOCK_SUBBLOCKS (block),
+ BLOCK_SUBBLOCKS (level->chain->block));
+ TREE_CHAIN (block) = free_block_chain;
+ free_block_chain = block;
}
- else if (block)
+ else
{
- if (!block_previously_created)
- current_binding_level->blocks
- = chainon (current_binding_level->blocks, block);
+ TREE_CHAIN (block) = BLOCK_SUBBLOCKS (level->chain->block);
+ BLOCK_SUBBLOCKS (level->chain->block) = block;
+ TREE_USED (block) = 1;
}
- /* If we did not make a block for the level just exited, any blocks made for
- inner levels (since they cannot be recorded as subblocks in that level)
- must be carried forward so they will later become subblocks of something
- else. */
- else if (subblock_chain)
- current_binding_level->blocks
- = chainon (current_binding_level->blocks, subblock_chain);
- if (block)
- TREE_USED (block) = 1;
-
- return block;
+ /* Free this binding structure. */
+ current_binding_level = level->chain;
+ level->chain = free_binding_level;
+ free_binding_level = level;
}
-
+
/* Insert BLOCK at the end of the list of subblocks of the
current binding level. This is used when a BIND_EXPR is expanded,
to handle the BLOCK node inside the BIND_EXPR. */
@@ -394,55 +318,42 @@ void
insert_block (tree block)
{
TREE_USED (block) = 1;
- current_binding_level->blocks
- = chainon (current_binding_level->blocks, block);
+ TREE_CHAIN (block) = BLOCK_SUBBLOCKS (current_binding_level->block);
+ BLOCK_SUBBLOCKS (current_binding_level->block) = block;
}
-/* Set the BLOCK node for the innermost scope
- (the one we are currently in). */
+/* Return nonzero if the current binding has any variables. This means
+ it will have a BLOCK node. */
-void
-set_block (tree block)
+int
+block_has_vars ()
{
- current_binding_level->this_block = block;
- current_binding_level->names = chainon (current_binding_level->names,
- BLOCK_VARS (block));
- current_binding_level->blocks = chainon (current_binding_level->blocks,
- BLOCK_SUBBLOCKS (block));
+ return BLOCK_VARS (current_binding_level->block) != 0;
}
-
+
/* Records a ..._DECL node DECL as belonging to the current lexical scope.
Returns the ..._DECL node. */
tree
pushdecl (tree decl)
{
- struct binding_level *b;
-
/* If at top level, there is no context. But PARM_DECLs always go in the
level of its function. */
if (global_bindings_p () && TREE_CODE (decl) != PARM_DECL)
- {
- b = global_binding_level;
- DECL_CONTEXT (decl) = 0;
- }
+ DECL_CONTEXT (decl) = 0;
else
- {
- b = current_binding_level;
- DECL_CONTEXT (decl) = current_function_decl;
- }
+ DECL_CONTEXT (decl) = current_function_decl;
/* Put the declaration on the list. The list of declarations is in reverse
- order. The list will be reversed later if necessary. This needs to be
- this way for compatibility with the back-end.
+ order. The list will be reversed later.
Don't put TYPE_DECLs for UNCONSTRAINED_ARRAY_TYPE into the list. They
will cause trouble with the debugger and aren't needed anyway. */
if (TREE_CODE (decl) != TYPE_DECL
|| TREE_CODE (TREE_TYPE (decl)) != UNCONSTRAINED_ARRAY_TYPE)
{
- TREE_CHAIN (decl) = b->names;
- b->names = decl;
+ TREE_CHAIN (decl) = BLOCK_VARS (current_binding_level->block);
+ BLOCK_VARS (current_binding_level->block) = decl;
}
/* For the declaration of a type, set its name if it either is not already
@@ -478,8 +389,7 @@ gnat_init_decl_processing (void)
current_function_decl = 0;
current_binding_level = 0;
free_binding_level = 0;
- pushlevel (0);
- global_binding_level = current_binding_level;
+ gnat_pushlevel ();
build_common_tree_nodes (0);
@@ -1294,15 +1204,9 @@ create_type_decl (tree type_name,
it indicates whether to always allocate storage to the variable. */
tree
-create_var_decl (tree var_name,
- tree asm_name,
- tree type,
- tree var_init,
- int const_flag,
- int public_flag,
- int extern_flag,
- int static_flag,
- struct attrib *attr_list)
+create_var_decl (tree var_name, tree asm_name, tree type, tree var_init,
+ int const_flag, int public_flag, int extern_flag,
+ int static_flag, struct attrib *attr_list)
{
int init_const
= (var_init == 0
@@ -1321,7 +1225,6 @@ create_var_decl (tree var_name,
&& 0 >= compare_tree_int (TYPE_SIZE_UNIT (type),
GET_MODE_SIZE (DCmode)))
? CONST_DECL : VAR_DECL, var_name, type);
- tree assign_init = 0;
/* If this is external, throw away any initializations unless this is a
CONST_DECL (meaning we have a constant); they will be done elsewhere. If
@@ -1346,7 +1249,7 @@ create_var_decl (tree var_name,
&& ((TYPE_MAIN_VARIANT (TREE_TYPE (var_init))
!= TYPE_MAIN_VARIANT (type))
|| (static_flag && ! init_const)))
- assign_init = var_init, var_init = 0;
+ DECL_INIT_BY_ASSIGN_P (var_decl) = 1;
DECL_INITIAL (var_decl) = var_init;
TREE_READONLY (var_decl) = const_flag;
@@ -1369,32 +1272,13 @@ create_var_decl (tree var_name,
/* Add this decl to the current binding level and generate any
needed code and RTL. */
var_decl = pushdecl (var_decl);
- expand_decl (var_decl);
-
- if (DECL_CONTEXT (var_decl) != 0)
- expand_decl_init (var_decl);
- /* If this is volatile, force it into memory. */
if (TREE_SIDE_EFFECTS (var_decl))
- gnat_mark_addressable (var_decl);
+ TREE_ADDRESSABLE (var_decl) = 1;
if (TREE_CODE (var_decl) != CONST_DECL)
rest_of_decl_compilation (var_decl, 0, global_bindings_p (), 0);
- if (assign_init != 0)
- {
- /* If VAR_DECL has a padded type, convert it to the unpadded
- type so the assignment is done properly. */
- tree lhs = var_decl;
-
- if (TREE_CODE (TREE_TYPE (lhs)) == RECORD_TYPE
- && TYPE_IS_PADDING_P (TREE_TYPE (lhs)))
- lhs = convert (TREE_TYPE (TYPE_FIELDS (TREE_TYPE (lhs))), lhs);
-
- expand_expr_stmt (build_binary_op (MODIFY_EXPR, NULL_TREE, lhs,
- assign_init));
- }
-
return var_decl;
}
@@ -1859,8 +1743,7 @@ begin_subprog_body (tree subprog_decl)
announce_function (subprog_decl);
/* Make this field nonzero so further routines know that this is not
- tentative. error_mark_node is replaced below (in poplevel) with the
- adequate BLOCK. */
+ tentative. error_mark_node is replaced below with the adequate BLOCK. */
DECL_INITIAL (subprog_decl) = error_mark_node;
/* This function exists in static storage. This does not mean `static' in
@@ -1870,7 +1753,7 @@ begin_subprog_body (tree subprog_decl)
/* Enter a new binding level and show that all the parameters belong to
this function. */
current_function_decl = subprog_decl;
- pushlevel (0);
+ gnat_pushlevel ();
for (param_decl = DECL_ARGUMENTS (subprog_decl); param_decl;
param_decl = TREE_CHAIN (param_decl))
@@ -1896,9 +1779,12 @@ end_subprog_body (void)
tree decl;
tree cico_list;
- poplevel (1, 0, 1);
- BLOCK_SUPERCONTEXT (DECL_INITIAL (current_function_decl))
- = current_function_decl;
+ /* Mark the BLOCK for this level as being for this function and pop the
+ level. Since the vars in it are the parameters, clear them. */
+ BLOCK_VARS (current_binding_level->block) = 0;
+ BLOCK_SUPERCONTEXT (current_binding_level->block) = current_function_decl;
+ DECL_INITIAL (current_function_decl) = current_binding_level->block;
+ gnat_poplevel ();
/* Mark the RESULT_DECL as being in this subprogram. */
DECL_CONTEXT (DECL_RESULT (current_function_decl)) = current_function_decl;