function Is_Package_Or_Subprogram (Id : Entity_Id) return Boolean;
-- Determine whether arbitrary Id denotes a package or subprogram [body]
- function Find_Enclosing_Transient_Scope return Entity_Id;
+ function Find_Enclosing_Transient_Scope return Int;
-- Examine the scope stack looking for the nearest enclosing transient
-- scope within the innermost enclosing package or subprogram. Return
- -- Empty if no such scope exists.
+ -- its index in the table or else -1 if no such scope exists.
function Find_Transient_Context (N : Node_Id) return Node_Id;
-- Locate a suitable context for arbitrary node N which may need to be
-- Find_Enclosing_Transient_Scope --
------------------------------------
- function Find_Enclosing_Transient_Scope return Entity_Id is
+ function Find_Enclosing_Transient_Scope return Int is
begin
for Index in reverse Scope_Stack.First .. Scope_Stack.Last loop
declare
exit;
elsif Scope.Is_Transient then
- return Scope.Entity;
+ return Index;
end if;
end;
end loop;
- return Empty;
+ return -1;
end Find_Enclosing_Transient_Scope;
----------------------------
-- Local variables
- Trans_Id : constant Entity_Id := Find_Enclosing_Transient_Scope;
- Context : Node_Id;
+ Trans_Idx : constant Int := Find_Enclosing_Transient_Scope;
+ Context : Node_Id;
-- Start of processing for Establish_Transient_Scope
-- Do not create a new transient scope if there is already an enclosing
-- transient scope within the innermost enclosing package or subprogram.
- if Present (Trans_Id) then
+ if Trans_Idx >= 0 then
-- If the transient scope was requested for purposes of managing the
- -- secondary stack, then the existing scope must perform this task.
+ -- secondary stack, then the existing scope must perform this task,
+ -- unless the node to be wrapped is a return statement of a function
+ -- that requires secondary stack management, because the function's
+ -- result would be reclaimed too early (see Find_Transient_Context).
if Manage_Sec_Stack then
- Set_Uses_Sec_Stack (Trans_Id);
+ declare
+ SE : Scope_Stack_Entry renames Scope_Stack.Table (Trans_Idx);
+
+ begin
+ if Nkind (SE.Node_To_Be_Wrapped) /= N_Simple_Return_Statement
+ or else not
+ Needs_Secondary_Stack
+ (Etype
+ (Return_Applies_To
+ (Return_Statement_Entity (SE.Node_To_Be_Wrapped))))
+ then
+ Set_Uses_Sec_Stack (SE.Entity);
+ end if;
+ end;
end if;
return;