[multiple changes]
2011-08-29 Robert Dewar <dewar@adacore.com> * a-exexpr-gcc.adb, a-synbar.adb, sem_ch13.adb: Minor reformatting. 2011-08-29 Bob Duff <duff@adacore.com> * sem_aggr.adb (Resolve_Aggr_Expr): Call this routine even in the case of <>, because this is the routine that checks for dimensionality errors (for example, for a two-dimensional array, (others => <>) should be (others => (others => <>)). 2011-08-29 Hristian Kirtchev <kirtchev@adacore.com> * impunit.adb: Add new run-time units. * freeze.adb, exp_ch7.ads, exp_ch7.adb, exp_util.ads, exp_util.adb, s-stposu.ads, s-stposu.adb: Code clean up. Handle protected class-wide or task class-wide types Handle C/C++/CIL/Java types. * s-spsufi.adb, s-spsufi.ads: New files. From-SVN: r178205
This commit is contained in:
parent
5accd7b6ca
commit
ca5af305a1
@ -1,3 +1,23 @@
|
||||
2011-08-29 Robert Dewar <dewar@adacore.com>
|
||||
|
||||
* a-exexpr-gcc.adb, a-synbar.adb, sem_ch13.adb: Minor reformatting.
|
||||
|
||||
2011-08-29 Bob Duff <duff@adacore.com>
|
||||
|
||||
* sem_aggr.adb (Resolve_Aggr_Expr): Call this routine even in the case
|
||||
of <>, because this is the routine that checks for dimensionality
|
||||
errors (for example, for a two-dimensional array, (others => <>) should
|
||||
be (others => (others => <>)).
|
||||
|
||||
2011-08-29 Hristian Kirtchev <kirtchev@adacore.com>
|
||||
|
||||
* impunit.adb: Add new run-time units.
|
||||
* freeze.adb, exp_ch7.ads, exp_ch7.adb, exp_util.ads, exp_util.adb,
|
||||
s-stposu.ads, s-stposu.adb: Code clean up.
|
||||
Handle protected class-wide or task class-wide types
|
||||
Handle C/C++/CIL/Java types.
|
||||
* s-spsufi.adb, s-spsufi.ads: New files.
|
||||
|
||||
2011-08-29 Yannick Moy <moy@adacore.com>
|
||||
|
||||
* sem_ch13.adb (Analyze_Aspect_Specifications): Reject test-case on
|
||||
|
@ -155,7 +155,6 @@ GNATRTL_NONTASKING_OBJS= \
|
||||
a-envvar$(objext) \
|
||||
a-except$(objext) \
|
||||
a-exctra$(objext) \
|
||||
a-fihema$(objext) \
|
||||
a-finali$(objext) \
|
||||
a-flteio$(objext) \
|
||||
a-fwteio$(objext) \
|
||||
@ -291,6 +290,7 @@ GNATRTL_NONTASKING_OBJS= \
|
||||
a-tiunio$(objext) \
|
||||
a-unccon$(objext) \
|
||||
a-uncdea$(objext) \
|
||||
a-undesu$(objext) \
|
||||
a-wichha$(objext) \
|
||||
a-wichun$(objext) \
|
||||
a-widcha$(objext) \
|
||||
@ -496,6 +496,7 @@ GNATRTL_NONTASKING_OBJS= \
|
||||
s-ficobl$(objext) \
|
||||
s-fileio$(objext) \
|
||||
s-filofl$(objext) \
|
||||
s-finmas$(objext) \
|
||||
s-finroo$(objext) \
|
||||
s-fishfl$(objext) \
|
||||
s-flocon$(objext) \
|
||||
@ -606,12 +607,14 @@ GNATRTL_NONTASKING_OBJS= \
|
||||
s-sequio$(objext) \
|
||||
s-shasto$(objext) \
|
||||
s-soflin$(objext) \
|
||||
s-spsufi$(objext) \
|
||||
s-stache$(objext) \
|
||||
s-stalib$(objext) \
|
||||
s-stausa$(objext) \
|
||||
s-stchop$(objext) \
|
||||
s-stoele$(objext) \
|
||||
s-stopoo$(objext) \
|
||||
s-stposu$(objext) \
|
||||
s-stratt$(objext) \
|
||||
s-strhas$(objext) \
|
||||
s-string$(objext) \
|
||||
|
@ -277,13 +277,15 @@ package body Exception_Propagation is
|
||||
|
||||
procedure GNAT_GCC_Exception_Cleanup
|
||||
(Reason : Unwind_Reason_Code;
|
||||
Excep : not null GNAT_GCC_Exception_Access) is
|
||||
Excep : not null GNAT_GCC_Exception_Access)
|
||||
is
|
||||
pragma Unreferenced (Reason);
|
||||
|
||||
procedure Free is new Unchecked_Deallocation
|
||||
(GNAT_GCC_Exception, GNAT_GCC_Exception_Access);
|
||||
|
||||
Copy : GNAT_GCC_Exception_Access := Excep;
|
||||
|
||||
begin
|
||||
-- Simply free the memory
|
||||
|
||||
@ -303,6 +305,7 @@ package body Exception_Propagation is
|
||||
UW_Argument : System.Address) return Unwind_Reason_Code
|
||||
is
|
||||
pragma Unreferenced (UW_Version, UW_Eclass, UW_Context, UW_Argument);
|
||||
|
||||
begin
|
||||
-- Terminate when the end of the stack is reached
|
||||
|
||||
@ -332,6 +335,7 @@ package body Exception_Propagation is
|
||||
Reraised : Boolean := False)
|
||||
is
|
||||
pragma Unreferenced (Excep, Current, Reraised);
|
||||
|
||||
begin
|
||||
-- In the GNAT-SJLJ case this "stack" only exists implicitly, by way of
|
||||
-- local occurrence declarations together with save/restore operations
|
||||
@ -345,8 +349,10 @@ package body Exception_Propagation is
|
||||
-------------------------
|
||||
|
||||
procedure Setup_Current_Excep
|
||||
(GCC_Exception : not null GCC_Exception_Access) is
|
||||
(GCC_Exception : not null GCC_Exception_Access)
|
||||
is
|
||||
Excep : constant EOA := Get_Current_Excep.all;
|
||||
|
||||
begin
|
||||
-- Setup the exception occurrence
|
||||
|
||||
@ -356,7 +362,7 @@ package body Exception_Propagation is
|
||||
|
||||
declare
|
||||
GNAT_Occurrence : constant GNAT_GCC_Exception_Access :=
|
||||
To_GNAT_GCC_Exception (GCC_Exception);
|
||||
To_GNAT_GCC_Exception (GCC_Exception);
|
||||
begin
|
||||
Excep.all := GNAT_Occurrence.Occurrence;
|
||||
end;
|
||||
@ -404,7 +410,8 @@ package body Exception_Propagation is
|
||||
-----------------------------
|
||||
|
||||
procedure Reraise_GCC_Exception
|
||||
(GCC_Exception : not null GCC_Exception_Access) is
|
||||
(GCC_Exception : not null GCC_Exception_Access)
|
||||
is
|
||||
begin
|
||||
-- Simply propagate it
|
||||
Propagate_GCC_Exception (GCC_Exception);
|
||||
@ -418,7 +425,8 @@ package body Exception_Propagation is
|
||||
-- the two phase scheme it implements.
|
||||
|
||||
procedure Propagate_GCC_Exception
|
||||
(GCC_Exception : not null GCC_Exception_Access) is
|
||||
(GCC_Exception : not null GCC_Exception_Access)
|
||||
is
|
||||
begin
|
||||
-- Perform a standard raise first. If a regular handler is found, it
|
||||
-- will be entered after all the intermediate cleanups have run. If
|
||||
@ -436,15 +444,15 @@ package body Exception_Propagation is
|
||||
|
||||
-- Now, un a forced unwind to trigger cleanups. Control should not
|
||||
-- resume there, if there are cleanups and in any cases as the
|
||||
-- unwinding hook calls Unhandled_Exception_Terminate when end of stack
|
||||
-- is reached.
|
||||
-- unwinding hook calls Unhandled_Exception_Terminate when end of
|
||||
-- stack is reached.
|
||||
|
||||
Unwind_ForcedUnwind (GCC_Exception,
|
||||
CleanupUnwind_Handler'Address,
|
||||
System.Null_Address);
|
||||
|
||||
-- We get here in case of error.
|
||||
-- The debugger has been notified before the second step above.
|
||||
-- We get here in case of error. The debugger has been notified before
|
||||
-- the second step above.
|
||||
|
||||
Setup_Current_Excep (GCC_Exception);
|
||||
Unhandled_Exception_Terminate;
|
||||
@ -455,8 +463,8 @@ package body Exception_Propagation is
|
||||
-------------------------
|
||||
|
||||
-- Build an object suitable for the libgcc processing and call
|
||||
-- Unwind_RaiseException to actually throw, taking care of handling
|
||||
-- the two phase scheme it implements.
|
||||
-- Unwind_RaiseException to actually do the raise, taking care of
|
||||
-- handling the two phase scheme it implements.
|
||||
|
||||
procedure Propagate_Exception
|
||||
(E : Exception_Id;
|
||||
@ -494,14 +502,16 @@ package body Exception_Propagation is
|
||||
|
||||
-- Allocate the GCC exception
|
||||
|
||||
GCC_Exception := new GNAT_GCC_Exception'
|
||||
(Header => (Class => GNAT_Exception_Class,
|
||||
Cleanup => GNAT_GCC_Exception_Cleanup'Address,
|
||||
Private1 => 0,
|
||||
Private2 => 0),
|
||||
Occurrence => Excep.all);
|
||||
GCC_Exception :=
|
||||
new GNAT_GCC_Exception'
|
||||
(Header => (Class => GNAT_Exception_Class,
|
||||
Cleanup => GNAT_GCC_Exception_Cleanup'Address,
|
||||
Private1 => 0,
|
||||
Private2 => 0),
|
||||
Occurrence => Excep.all);
|
||||
|
||||
-- Propagate it
|
||||
|
||||
-- Propagate it.
|
||||
Propagate_GCC_Exception (To_GCC_Exception (GCC_Exception));
|
||||
end Propagate_Exception;
|
||||
|
||||
|
@ -61,7 +61,6 @@ package body Ada.Synchronous_Barriers is
|
||||
|
||||
Notified := Wait'Count = 0;
|
||||
end Wait;
|
||||
|
||||
end Synchronous_Barrier;
|
||||
|
||||
----------------------
|
||||
|
@ -17,20 +17,15 @@
|
||||
|
||||
-- ??? What is the header version here, see a-uncdea.adb. No GPL?
|
||||
|
||||
with System.Storage_Pools.Subpools; use System.Storage_Pools.Subpools;
|
||||
with System.Storage_Pools.Subpools,
|
||||
System.Storage_Pools.Subpools.Finalization;
|
||||
|
||||
use System.Storage_Pools.Subpools,
|
||||
System.Storage_Pools.Subpools.Finalization;
|
||||
|
||||
procedure Ada.Unchecked_Deallocate_Subpool
|
||||
(Subpool : in out System.Storage_Pools.Subpools.Subpool_Handle)
|
||||
is
|
||||
begin
|
||||
-- Finalize all controlled objects allocated on the input subpool
|
||||
|
||||
-- ??? It is awkward to create a child of Storage_Pools.Subpools for the
|
||||
-- sole purpose of exporting Finalize_Subpool.
|
||||
|
||||
-- Finalize_Subpool (Subpool);
|
||||
|
||||
-- Dispatch to the user-defined implementation of Deallocate_Subpool
|
||||
|
||||
Deallocate_Subpool (Pool_Of_Subpool (Subpool).all, Subpool);
|
||||
Finalize_And_Deallocate (Subpool);
|
||||
end Ada.Unchecked_Deallocate_Subpool;
|
||||
|
@ -6626,35 +6626,31 @@ package body Exp_Ch3 is
|
||||
-- finalization support if not needed.
|
||||
|
||||
if not Comes_From_Source (Def_Id)
|
||||
and then not Has_Private_Declaration (Def_Id)
|
||||
and then not Has_Private_Declaration (Def_Id)
|
||||
then
|
||||
null;
|
||||
|
||||
elsif (Needs_Finalization (Desig_Type)
|
||||
and then Convention (Desig_Type) /= Convention_Java
|
||||
and then Convention (Desig_Type) /= Convention_CIL)
|
||||
-- An exception is made for types defined in the run-time because
|
||||
-- Ada.Tags.Tag itself is such a type and cannot afford this
|
||||
-- unnecessary overhead that would generates a loop in the
|
||||
-- expansion scheme. Another exception is if Restrictions
|
||||
-- (No_Finalization) is active, since then we know nothing is
|
||||
-- controlled.
|
||||
|
||||
elsif Restriction_Active (No_Finalization)
|
||||
or else In_Runtime (Def_Id)
|
||||
then
|
||||
null;
|
||||
|
||||
-- The machinery assumes that incomplete or private types are
|
||||
-- always completed by a controlled full vies.
|
||||
|
||||
elsif Needs_Finalization (Desig_Type)
|
||||
or else
|
||||
(Is_Incomplete_Or_Private_Type (Desig_Type)
|
||||
and then No (Full_View (Desig_Type))
|
||||
|
||||
-- An exception is made for types defined in the run-time
|
||||
-- because Ada.Tags.Tag itself is such a type and cannot
|
||||
-- afford this unnecessary overhead that would generates a
|
||||
-- loop in the expansion scheme...
|
||||
|
||||
and then not In_Runtime (Def_Id)
|
||||
|
||||
-- Another exception is if Restrictions (No_Finalization)
|
||||
-- is active, since then we know nothing is controlled.
|
||||
|
||||
and then not Restriction_Active (No_Finalization))
|
||||
|
||||
-- If the designated type is not frozen yet, its controlled
|
||||
-- status must be retrieved explicitly.
|
||||
|
||||
and then No (Full_View (Desig_Type)))
|
||||
or else
|
||||
(Is_Array_Type (Desig_Type)
|
||||
and then not Is_Frozen (Desig_Type)
|
||||
and then Needs_Finalization (Component_Type (Desig_Type)))
|
||||
then
|
||||
Build_Finalization_Master (Def_Id);
|
||||
|
@ -91,12 +91,13 @@ package body Exp_Ch4 is
|
||||
-- If a boolean array assignment can be done in place, build call to
|
||||
-- corresponding library procedure.
|
||||
|
||||
procedure Complete_Controlled_Allocation (Temp_Decl : Node_Id);
|
||||
-- Subsidiary to Expand_N_Allocator and Expand_Allocator_Expression. Formal
|
||||
-- Temp_Decl is the declaration of a temporary which hold the value of the
|
||||
-- original allocator. Create a custom Allocate routine for the expression
|
||||
-- of Temp_Decl. The routine does special processing for anonymous access
|
||||
-- types.
|
||||
function Current_Unit_First_Declaration return Node_Id;
|
||||
-- Return the current unit's first declaration. If the declaration list is
|
||||
-- empty, the routine generates a null statement and returns it.
|
||||
|
||||
function Current_Unit_Scope return Entity_Id;
|
||||
-- Return the scope of the current unit. If the current unit is a body,
|
||||
-- return the scope of the spec.
|
||||
|
||||
procedure Displace_Allocator_Pointer (N : Node_Id);
|
||||
-- Ada 2005 (AI-251): Subsidiary procedure to Expand_N_Allocator and
|
||||
@ -375,121 +376,78 @@ package body Exp_Ch4 is
|
||||
end Build_Boolean_Array_Proc_Call;
|
||||
|
||||
------------------------------------
|
||||
-- Complete_Controlled_Allocation --
|
||||
-- Current_Unit_First_Declaration --
|
||||
------------------------------------
|
||||
|
||||
procedure Complete_Controlled_Allocation (Temp_Decl : Node_Id) is
|
||||
pragma Assert (Nkind (Temp_Decl) = N_Object_Declaration);
|
||||
|
||||
Ptr_Typ : constant Entity_Id := Etype (Defining_Identifier (Temp_Decl));
|
||||
|
||||
function First_Declaration_Of_Current_Unit return Node_Id;
|
||||
-- Return the current unit's first declaration. If the declaration list
|
||||
-- is empty, the routine generates a null statement and returns it.
|
||||
|
||||
---------------------------------------
|
||||
-- First_Declaration_Of_Current_Unit --
|
||||
---------------------------------------
|
||||
|
||||
function First_Declaration_Of_Current_Unit return Node_Id is
|
||||
Sem_U : Node_Id := Unit (Cunit (Current_Sem_Unit));
|
||||
Decl : Node_Id;
|
||||
Decls : List_Id;
|
||||
|
||||
begin
|
||||
if Nkind (Sem_U) = N_Package_Declaration then
|
||||
Sem_U := Specification (Sem_U);
|
||||
Decls := Visible_Declarations (Sem_U);
|
||||
|
||||
if No (Decls) then
|
||||
Decl := Make_Null_Statement (Sloc (Sem_U));
|
||||
Decls := New_List (Decl);
|
||||
Set_Visible_Declarations (Sem_U, Decls);
|
||||
else
|
||||
Decl := First (Decls);
|
||||
end if;
|
||||
|
||||
else
|
||||
Decls := Declarations (Sem_U);
|
||||
|
||||
if No (Decls) then
|
||||
Decl := Make_Null_Statement (Sloc (Sem_U));
|
||||
Decls := New_List (Decl);
|
||||
Set_Declarations (Sem_U, Decls);
|
||||
else
|
||||
Decl := First (Decls);
|
||||
end if;
|
||||
end if;
|
||||
|
||||
return Decl;
|
||||
end First_Declaration_Of_Current_Unit;
|
||||
|
||||
-- Start of processing for Complete_Controlled_Allocation
|
||||
function Current_Unit_First_Declaration return Node_Id is
|
||||
Sem_U : Node_Id := Unit (Cunit (Current_Sem_Unit));
|
||||
Decl : Node_Id;
|
||||
Decls : List_Id;
|
||||
|
||||
begin
|
||||
-- Certain run-time configurations and targets do not provide support
|
||||
-- for controlled types.
|
||||
if Nkind (Sem_U) = N_Package_Declaration then
|
||||
Sem_U := Specification (Sem_U);
|
||||
Decls := Visible_Declarations (Sem_U);
|
||||
|
||||
if Restriction_Active (No_Finalization) then
|
||||
return;
|
||||
if No (Decls) then
|
||||
Decl := Make_Null_Statement (Sloc (Sem_U));
|
||||
Decls := New_List (Decl);
|
||||
Set_Visible_Declarations (Sem_U, Decls);
|
||||
|
||||
-- Do nothing if the access type may never allocate an object
|
||||
elsif Is_Empty_List (Decls) then
|
||||
Decl := Make_Null_Statement (Sloc (Sem_U));
|
||||
Append_To (Decls, Decl);
|
||||
|
||||
elsif No_Pool_Assigned (Ptr_Typ) then
|
||||
return;
|
||||
else
|
||||
Decl := First (Decls);
|
||||
end if;
|
||||
|
||||
-- Access-to-controlled types are not supported on .NET/JVM
|
||||
else
|
||||
Decls := Declarations (Sem_U);
|
||||
|
||||
elsif VM_Target /= No_VM then
|
||||
return;
|
||||
if No (Decls) then
|
||||
Decl := Make_Null_Statement (Sloc (Sem_U));
|
||||
Decls := New_List (Decl);
|
||||
Set_Declarations (Sem_U, Decls);
|
||||
|
||||
elsif Is_Empty_List (Decls) then
|
||||
Decl := Make_Null_Statement (Sloc (Sem_U));
|
||||
Append_To (Decls, Decl);
|
||||
|
||||
else
|
||||
Decl := First (Decls);
|
||||
end if;
|
||||
end if;
|
||||
|
||||
-- ??? Now that finalization masters act as heterogeneous lists, it
|
||||
-- might be worthed to revisit the global master approach.
|
||||
return Decl;
|
||||
end Current_Unit_First_Declaration;
|
||||
|
||||
-- Processing for anonymous access-to-controlled types. These access
|
||||
-- types receive a special finalization master which appears in the
|
||||
-- declarations of the enclosing semantic unit.
|
||||
------------------------
|
||||
-- Current_Unit_Scope --
|
||||
------------------------
|
||||
|
||||
if Ekind (Ptr_Typ) = E_Anonymous_Access_Type
|
||||
and then No (Finalization_Master (Ptr_Typ))
|
||||
and then
|
||||
(not Restriction_Active (No_Nested_Finalization)
|
||||
or else Is_Library_Level_Entity (Ptr_Typ))
|
||||
then
|
||||
declare
|
||||
Pool_Id : constant Entity_Id :=
|
||||
Get_Global_Pool_For_Access_Type (Ptr_Typ);
|
||||
Scop : Node_Id := Cunit_Entity (Current_Sem_Unit);
|
||||
function Current_Unit_Scope return Entity_Id is
|
||||
Scop_Id : Entity_Id := Cunit_Entity (Current_Sem_Unit);
|
||||
Subp_Bod : Node_Id;
|
||||
|
||||
begin
|
||||
-- Use the scope of the current semantic unit when analyzing
|
||||
begin
|
||||
if Ekind (Scop_Id) = E_Subprogram_Body then
|
||||
|
||||
if Ekind (Scop) = E_Subprogram_Body then
|
||||
Scop := Corresponding_Spec (Parent (Parent (Parent (Scop))));
|
||||
end if;
|
||||
-- When processing subprogram bodies, the proper scope is always
|
||||
-- that of the spec.
|
||||
|
||||
Build_Finalization_Master
|
||||
(Typ => Ptr_Typ,
|
||||
Ins_Node => First_Declaration_Of_Current_Unit,
|
||||
Encl_Scope => Scop);
|
||||
Subp_Bod := Scop_Id;
|
||||
while Present (Subp_Bod)
|
||||
and then Nkind (Subp_Bod) /= N_Subprogram_Body
|
||||
loop
|
||||
Subp_Bod := Parent (Subp_Bod);
|
||||
end loop;
|
||||
|
||||
-- Decorate the anonymous access type and the allocator node
|
||||
|
||||
Set_Associated_Storage_Pool (Ptr_Typ, Pool_Id);
|
||||
Set_Storage_Pool (Expression (Temp_Decl), Pool_Id);
|
||||
end;
|
||||
Scop_Id := Corresponding_Spec (Subp_Bod);
|
||||
end if;
|
||||
|
||||
-- Since the temporary object reuses the original allocator, generate a
|
||||
-- custom Allocate routine for the temporary.
|
||||
|
||||
if Present (Finalization_Master (Ptr_Typ)) then
|
||||
Build_Allocate_Deallocate_Proc
|
||||
(N => Temp_Decl,
|
||||
Is_Allocate => True);
|
||||
end if;
|
||||
end Complete_Controlled_Allocation;
|
||||
return Scop_Id;
|
||||
end Current_Unit_Scope;
|
||||
|
||||
--------------------------------
|
||||
-- Displace_Allocator_Pointer --
|
||||
@ -777,14 +735,13 @@ package body Exp_Ch4 is
|
||||
return;
|
||||
end if;
|
||||
|
||||
-- Actions inserted before:
|
||||
-- Temp : constant ptr_T := new T'(Expression);
|
||||
-- <no CW> Temp._tag := T'tag;
|
||||
-- <CTRL> Adjust (Finalizable (Temp.all));
|
||||
-- <CTRL> Attach_To_Final_List (Finalizable (Temp.all));
|
||||
-- Actions inserted before:
|
||||
-- Temp : constant ptr_T := new T'(Expression);
|
||||
-- Temp._tag = T'tag; -- when not class-wide
|
||||
-- [Deep_]Adjust (Temp.all);
|
||||
|
||||
-- We analyze by hand the new internal allocator to avoid
|
||||
-- any recursion and inappropriate call to Initialize
|
||||
-- We analyze by hand the new internal allocator to avoid any
|
||||
-- recursion and inappropriate call to Initialize
|
||||
|
||||
-- We don't want to remove side effects when the expression must be
|
||||
-- built in place. In the case of a build-in-place function call,
|
||||
@ -858,7 +815,7 @@ package body Exp_Ch4 is
|
||||
Set_No_Initialization (Expression (Temp_Decl));
|
||||
Insert_Action (N, Temp_Decl);
|
||||
|
||||
Complete_Controlled_Allocation (Temp_Decl);
|
||||
Build_Allocate_Deallocate_Proc (Temp_Decl, True);
|
||||
Convert_Aggr_In_Allocator (N, Temp_Decl, Exp);
|
||||
|
||||
-- Attach the object to the associated finalization master.
|
||||
@ -889,7 +846,7 @@ package body Exp_Ch4 is
|
||||
Expression => Node);
|
||||
|
||||
Insert_Action (N, Temp_Decl);
|
||||
Complete_Controlled_Allocation (Temp_Decl);
|
||||
Build_Allocate_Deallocate_Proc (Temp_Decl, True);
|
||||
|
||||
-- Attach the object to the associated finalization master.
|
||||
-- This is done manually on .NET/JVM since those compilers do
|
||||
@ -961,7 +918,7 @@ package body Exp_Ch4 is
|
||||
Set_No_Initialization (Expression (Temp_Decl));
|
||||
Insert_Action (N, Temp_Decl);
|
||||
|
||||
Complete_Controlled_Allocation (Temp_Decl);
|
||||
Build_Allocate_Deallocate_Proc (Temp_Decl, True);
|
||||
Convert_Aggr_In_Allocator (N, Temp_Decl, Exp);
|
||||
|
||||
else
|
||||
@ -976,7 +933,7 @@ package body Exp_Ch4 is
|
||||
Expression => Node);
|
||||
|
||||
Insert_Action (N, Temp_Decl);
|
||||
Complete_Controlled_Allocation (Temp_Decl);
|
||||
Build_Allocate_Deallocate_Proc (Temp_Decl, True);
|
||||
end if;
|
||||
|
||||
-- Generate an additional object containing the address of the
|
||||
@ -1119,7 +1076,7 @@ package body Exp_Ch4 is
|
||||
Set_No_Initialization (Expression (Temp_Decl));
|
||||
Insert_Action (N, Temp_Decl);
|
||||
|
||||
Complete_Controlled_Allocation (Temp_Decl);
|
||||
Build_Allocate_Deallocate_Proc (Temp_Decl, True);
|
||||
Convert_Aggr_In_Allocator (N, Temp_Decl, Exp);
|
||||
|
||||
-- Attach the object to the associated finalization master. Thisis
|
||||
@ -3250,8 +3207,9 @@ package body Exp_Ch4 is
|
||||
Etyp : constant Entity_Id := Etype (Expression (N));
|
||||
Loc : constant Source_Ptr := Sloc (N);
|
||||
Desig : Entity_Id;
|
||||
Temp : Entity_Id;
|
||||
Nod : Node_Id;
|
||||
Pool : Entity_Id;
|
||||
Temp : Entity_Id;
|
||||
|
||||
procedure Rewrite_Coextension (N : Node_Id);
|
||||
-- Static coextensions have the same lifetime as the entity they
|
||||
@ -3374,22 +3332,51 @@ package body Exp_Ch4 is
|
||||
|
||||
Validate_Remote_Access_To_Class_Wide_Type (N);
|
||||
|
||||
-- Set the Storage Pool
|
||||
-- Processing for anonymous access-to-controlled types. These access
|
||||
-- types receive a special finalization master which appears in the
|
||||
-- declarations of the enclosing semantic unit. This expansion is done
|
||||
-- now to ensure that any additional types generated by this routine
|
||||
-- or Expand_Allocator_Expression inherit the proper type attributes.
|
||||
|
||||
Set_Storage_Pool (N, Associated_Storage_Pool (Root_Type (PtrT)));
|
||||
if Ekind (PtrT) = E_Anonymous_Access_Type
|
||||
and then Needs_Finalization (Dtyp)
|
||||
then
|
||||
-- Anonymous access-to-controlled types allocate on the global pool
|
||||
|
||||
if Present (Storage_Pool (N)) then
|
||||
if Is_RTE (Storage_Pool (N), RE_SS_Pool) then
|
||||
if No (Associated_Storage_Pool (PtrT)) then
|
||||
Set_Associated_Storage_Pool (PtrT,
|
||||
Get_Global_Pool_For_Access_Type (PtrT));
|
||||
end if;
|
||||
|
||||
-- The finalization master must be inserted and analyzed as part of
|
||||
-- the current semantic unit.
|
||||
|
||||
if No (Finalization_Master (PtrT)) then
|
||||
Build_Finalization_Master
|
||||
(Typ => PtrT,
|
||||
Ins_Node => Current_Unit_First_Declaration,
|
||||
Encl_Scope => Current_Unit_Scope);
|
||||
end if;
|
||||
end if;
|
||||
|
||||
-- Set the storage pool and find the appropriate version of Allocate to
|
||||
-- call.
|
||||
|
||||
Pool := Associated_Storage_Pool (Root_Type (PtrT));
|
||||
Set_Storage_Pool (N, Pool);
|
||||
|
||||
if Present (Pool) then
|
||||
if Is_RTE (Pool, RE_SS_Pool) then
|
||||
if VM_Target = No_VM then
|
||||
Set_Procedure_To_Call (N, RTE (RE_SS_Allocate));
|
||||
end if;
|
||||
|
||||
elsif Is_Class_Wide_Type (Etype (Storage_Pool (N))) then
|
||||
elsif Is_Class_Wide_Type (Etype (Pool)) then
|
||||
Set_Procedure_To_Call (N, RTE (RE_Allocate_Any));
|
||||
|
||||
else
|
||||
Set_Procedure_To_Call (N,
|
||||
Find_Prim_Op (Etype (Storage_Pool (N)), Name_Allocate));
|
||||
Find_Prim_Op (Etype (Pool), Name_Allocate));
|
||||
end if;
|
||||
end if;
|
||||
|
||||
@ -3550,7 +3537,7 @@ package body Exp_Ch4 is
|
||||
and then Present (Finalization_Master (PtrT))
|
||||
then
|
||||
Build_Allocate_Deallocate_Proc
|
||||
(N => Parent (N),
|
||||
(N => N,
|
||||
Is_Allocate => True);
|
||||
end if;
|
||||
|
||||
@ -3788,14 +3775,13 @@ package body Exp_Ch4 is
|
||||
Nod := Relocate_Node (N);
|
||||
|
||||
-- Here is the transformation:
|
||||
-- input: new T
|
||||
-- output: Temp : constant ptr_T := new T;
|
||||
-- Init (Temp.all, ...);
|
||||
-- <CTRL> Attach_To_Final_List (Finalizable (Temp.all));
|
||||
-- <CTRL> Initialize (Finalizable (Temp.all));
|
||||
-- input: new Ctrl_Typ
|
||||
-- output: Temp : constant Ctrl_Typ_Ptr := new Ctrl_Typ;
|
||||
-- Ctrl_TypIP (Temp.all, ...);
|
||||
-- [Deep_]Initialize (Temp.all);
|
||||
|
||||
-- Here ptr_T is the pointer type for the allocator, and is the
|
||||
-- subtype of the allocator.
|
||||
-- Here Ctrl_Typ_Ptr is the pointer type for the allocator, and
|
||||
-- is the subtype of the allocator.
|
||||
|
||||
Temp_Decl :=
|
||||
Make_Object_Declaration (Loc,
|
||||
@ -3807,7 +3793,7 @@ package body Exp_Ch4 is
|
||||
Set_Assignment_OK (Temp_Decl);
|
||||
Insert_Action (N, Temp_Decl, Suppress => All_Checks);
|
||||
|
||||
Complete_Controlled_Allocation (Temp_Decl);
|
||||
Build_Allocate_Deallocate_Proc (Temp_Decl, True);
|
||||
|
||||
-- If the designated type is a task type or contains tasks,
|
||||
-- create block to activate created tasks, and insert
|
||||
@ -3844,7 +3830,7 @@ package body Exp_Ch4 is
|
||||
-- Special processing for .NET/JVM, the allocated object is
|
||||
-- attached to the finalization master. Generate:
|
||||
|
||||
-- Attach (<PtrT>FM, Root_Controlled_Ptr (Init_Arg1));
|
||||
-- Attach (<PtrT>FC, Root_Controlled_Ptr (Init_Arg1));
|
||||
|
||||
-- Types derived from [Limited_]Controlled are the only
|
||||
-- ones considered since they have fields Prev and Next.
|
||||
|
@ -777,9 +777,8 @@ package body Exp_Ch7 is
|
||||
|
||||
return
|
||||
Make_Exception_Handler (Loc,
|
||||
Exception_Choices => New_List (
|
||||
Make_Others_Choice (Loc)),
|
||||
|
||||
Exception_Choices =>
|
||||
New_List (Make_Others_Choice (Loc)),
|
||||
Statements => New_List (
|
||||
Make_If_Statement (Loc,
|
||||
Condition =>
|
||||
@ -807,6 +806,7 @@ package body Exp_Ch7 is
|
||||
Encl_Scope : Entity_Id := Empty)
|
||||
is
|
||||
Desig_Typ : constant Entity_Id := Directly_Designated_Type (Typ);
|
||||
Ptr_Typ : Entity_Id := Root_Type (Base_Type (Typ));
|
||||
|
||||
function In_Deallocation_Instance (E : Entity_Id) return Boolean;
|
||||
-- Determine whether entity E is inside a wrapper package created for
|
||||
@ -840,41 +840,57 @@ package body Exp_Ch7 is
|
||||
-- Start of processing for Build_Finalization_Master
|
||||
|
||||
begin
|
||||
if Is_Private_Type (Ptr_Typ)
|
||||
and then Present (Full_View (Ptr_Typ))
|
||||
then
|
||||
Ptr_Typ := Full_View (Ptr_Typ);
|
||||
end if;
|
||||
|
||||
-- Certain run-time configurations and targets do not provide support
|
||||
-- for controlled types.
|
||||
|
||||
if Restriction_Active (No_Finalization) then
|
||||
return;
|
||||
|
||||
-- Do not process C, C++, CIL and Java types since it is assumend that
|
||||
-- the non-Ada side will handle their clean up.
|
||||
|
||||
elsif Convention (Desig_Typ) = Convention_C
|
||||
or else Convention (Desig_Typ) = Convention_CIL
|
||||
or else Convention (Desig_Typ) = Convention_CPP
|
||||
or else Convention (Desig_Typ) = Convention_Java
|
||||
then
|
||||
return;
|
||||
|
||||
-- Various machinery such as freezing may have already created a
|
||||
-- finalization master.
|
||||
|
||||
elsif Present (Finalization_Master (Typ)) then
|
||||
elsif Present (Finalization_Master (Ptr_Typ)) then
|
||||
return;
|
||||
|
||||
-- Do not process types that return on the secondary stack
|
||||
|
||||
elsif Present (Associated_Storage_Pool (Typ))
|
||||
and then Is_RTE (Associated_Storage_Pool (Typ), RE_SS_Pool)
|
||||
elsif Present (Associated_Storage_Pool (Ptr_Typ))
|
||||
and then Is_RTE (Associated_Storage_Pool (Ptr_Typ), RE_SS_Pool)
|
||||
then
|
||||
return;
|
||||
|
||||
-- Do not process types which may never allocate an object
|
||||
|
||||
elsif No_Pool_Assigned (Typ) then
|
||||
elsif No_Pool_Assigned (Ptr_Typ) then
|
||||
return;
|
||||
|
||||
-- Do not process access types coming from Ada.Unchecked_Deallocation
|
||||
-- instances. Even though the designated type may be controlled, the
|
||||
-- access type will never participate in allocation.
|
||||
|
||||
elsif In_Deallocation_Instance (Typ) then
|
||||
elsif In_Deallocation_Instance (Ptr_Typ) then
|
||||
return;
|
||||
|
||||
-- Ignore the general use of anonymous access types unless the context
|
||||
-- requires a finalization master.
|
||||
|
||||
elsif Ekind (Typ) = E_Anonymous_Access_Type
|
||||
elsif Ekind (Ptr_Typ) = E_Anonymous_Access_Type
|
||||
and then No (Ins_Node)
|
||||
then
|
||||
return;
|
||||
@ -883,7 +899,7 @@ package body Exp_Ch7 is
|
||||
-- Finalization is in effect since masters are controlled objects.
|
||||
|
||||
elsif Restriction_Active (No_Nested_Finalization)
|
||||
and then not Is_Library_Level_Entity (Typ)
|
||||
and then not Is_Library_Level_Entity (Ptr_Typ)
|
||||
then
|
||||
return;
|
||||
|
||||
@ -898,19 +914,12 @@ package body Exp_Ch7 is
|
||||
end if;
|
||||
|
||||
declare
|
||||
Loc : constant Source_Ptr := Sloc (Typ);
|
||||
Loc : constant Source_Ptr := Sloc (Ptr_Typ);
|
||||
Actions : constant List_Id := New_List;
|
||||
Fin_Mas_Id : Entity_Id;
|
||||
Pool_Id : Entity_Id;
|
||||
Ptr_Typ : Entity_Id := Typ;
|
||||
|
||||
begin
|
||||
-- Access subtypes must use the storage pool of their base type
|
||||
|
||||
if Ekind (Ptr_Typ) = E_Access_Subtype then
|
||||
Ptr_Typ := Base_Type (Ptr_Typ);
|
||||
end if;
|
||||
|
||||
-- Generate:
|
||||
-- Fnn : aliased Finalization_Master;
|
||||
|
||||
@ -994,11 +1003,10 @@ package body Exp_Ch7 is
|
||||
|
||||
Pop_Scope;
|
||||
|
||||
elsif Ekind (Typ) = E_Access_Subtype
|
||||
or else (Ekind (Desig_Typ) = E_Incomplete_Type
|
||||
and then Has_Completion_In_Body (Desig_Typ))
|
||||
elsif Ekind (Desig_Typ) = E_Incomplete_Type
|
||||
and then Has_Completion_In_Body (Desig_Typ)
|
||||
then
|
||||
Insert_Actions (Parent (Typ), Actions);
|
||||
Insert_Actions (Parent (Ptr_Typ), Actions);
|
||||
|
||||
-- If the designated type is not yet frozen, then append the actions
|
||||
-- to that type's freeze actions. The actions need to be appended to
|
||||
@ -1013,10 +1021,10 @@ package body Exp_Ch7 is
|
||||
then
|
||||
Append_Freeze_Actions (Desig_Typ, Actions);
|
||||
|
||||
elsif Present (Freeze_Node (Typ))
|
||||
and then not Analyzed (Freeze_Node (Typ))
|
||||
elsif Present (Freeze_Node (Ptr_Typ))
|
||||
and then not Analyzed (Freeze_Node (Ptr_Typ))
|
||||
then
|
||||
Append_Freeze_Actions (Typ, Actions);
|
||||
Append_Freeze_Actions (Ptr_Typ, Actions);
|
||||
|
||||
-- If there's a pool created locally for the access type, then we
|
||||
-- need to ensure that the master gets created after the pool object,
|
||||
@ -1027,12 +1035,12 @@ package body Exp_Ch7 is
|
||||
-- this point. (This seems a little unclean.???)
|
||||
|
||||
elsif VM_Target = No_VM
|
||||
and then Scope (Pool_Id) = Scope (Typ)
|
||||
and then Scope (Pool_Id) = Scope (Ptr_Typ)
|
||||
then
|
||||
Insert_List_After_And_Analyze (Parent (Pool_Id), Actions);
|
||||
|
||||
else
|
||||
Insert_Actions (Parent (Typ), Actions);
|
||||
Insert_Actions (Parent (Ptr_Typ), Actions);
|
||||
end if;
|
||||
end;
|
||||
end Build_Finalization_Master;
|
||||
@ -1448,8 +1456,8 @@ package body Exp_Ch7 is
|
||||
-- The local exception does not need to be reraised for library-
|
||||
-- level finalizers. Generate:
|
||||
--
|
||||
-- if Raised then
|
||||
-- Raise_From_Controlled_Operation (E, Abort);
|
||||
-- if Raised and then not Abort then
|
||||
-- Raise_From_Controlled_Operation (E);
|
||||
-- end if;
|
||||
|
||||
if not For_Package
|
||||
@ -2297,6 +2305,10 @@ package body Exp_Ch7 is
|
||||
|
||||
if Is_Controlled (Typ) then
|
||||
Init := Find_Prim_Op (Typ, Name_Initialize);
|
||||
|
||||
if Present (Init) then
|
||||
Init := Ultimate_Alias (Init);
|
||||
end if;
|
||||
end if;
|
||||
|
||||
return
|
||||
@ -2349,6 +2361,12 @@ package body Exp_Ch7 is
|
||||
Utyp := Typ;
|
||||
end if;
|
||||
|
||||
if Is_Private_Type (Utyp)
|
||||
and then Present (Full_View (Utyp))
|
||||
then
|
||||
Utyp := Full_View (Utyp);
|
||||
end if;
|
||||
|
||||
-- The init procedures are arranged as follows:
|
||||
|
||||
-- Object : Controlled_Type;
|
||||
@ -3086,20 +3104,13 @@ package body Exp_Ch7 is
|
||||
E_Id : Entity_Id;
|
||||
Raised_Id : Entity_Id) return Node_Id
|
||||
is
|
||||
Params : List_Id;
|
||||
Proc_Id : Entity_Id;
|
||||
|
||||
begin
|
||||
-- The default parameter is the local exception occurrence
|
||||
|
||||
Params := New_List (New_Reference_To (E_Id, Loc));
|
||||
|
||||
-- Standard run-time, .NET/JVM targets, this case handles finalization
|
||||
-- exceptions raised during an abort.
|
||||
-- Standard run-time, .NET/JVM targets
|
||||
|
||||
if RTE_Available (RE_Raise_From_Controlled_Operation) then
|
||||
Proc_Id := RTE (RE_Raise_From_Controlled_Operation);
|
||||
Append_To (Params, New_Reference_To (Abort_Id, Loc));
|
||||
|
||||
-- Restricted runtime: exception messages are not supported and hence
|
||||
-- Raise_From_Controlled_Operation is not supported.
|
||||
@ -3109,17 +3120,24 @@ package body Exp_Ch7 is
|
||||
end if;
|
||||
|
||||
-- Generate:
|
||||
-- if Raised_Id then
|
||||
-- if Raised_Id and then not Abort_Id then
|
||||
-- <Proc_Id> (<Params>);
|
||||
-- end if;
|
||||
|
||||
return
|
||||
Make_If_Statement (Loc,
|
||||
Condition => New_Reference_To (Raised_Id, Loc),
|
||||
Condition =>
|
||||
Make_And_Then (Loc,
|
||||
Left_Opnd => New_Reference_To (Raised_Id, Loc),
|
||||
Right_Opnd =>
|
||||
Make_Op_Not (Loc,
|
||||
Right_Opnd => New_Reference_To (Abort_Id, Loc))),
|
||||
|
||||
Then_Statements => New_List (
|
||||
Make_Procedure_Call_Statement (Loc,
|
||||
Name => New_Reference_To (Proc_Id, Loc),
|
||||
Parameter_Associations => Params)));
|
||||
Parameter_Associations =>
|
||||
New_List (New_Reference_To (E_Id, Loc)))));
|
||||
end Build_Raise_Statement;
|
||||
|
||||
-----------------------------
|
||||
@ -4325,8 +4343,8 @@ package body Exp_Ch7 is
|
||||
|
||||
-- exception
|
||||
-- when others =>
|
||||
-- if not Rnn then
|
||||
-- Rnn := True;
|
||||
-- if not Raised then
|
||||
-- Raised := True;
|
||||
-- Save_Occurrence
|
||||
-- (Enn, Get_Current_Excep.all.all);
|
||||
-- end if;
|
||||
@ -4405,8 +4423,8 @@ package body Exp_Ch7 is
|
||||
end loop;
|
||||
|
||||
-- Generate:
|
||||
-- if Rnn then
|
||||
-- Raise_From_Controlled_Operation (E, Abort);
|
||||
-- if Raised and then not Abort then
|
||||
-- Raise_From_Controlled_Operation (E);
|
||||
-- end if;
|
||||
|
||||
if Built
|
||||
@ -4723,8 +4741,8 @@ package body Exp_Ch7 is
|
||||
-- ...
|
||||
-- end loop;
|
||||
--
|
||||
-- if Raised then
|
||||
-- Raise_From_Controlled_Operation (E, Abort);
|
||||
-- if Raised and then not Abort then
|
||||
-- Raise_From_Controlled_Operation (E);
|
||||
-- end if;
|
||||
-- end;
|
||||
|
||||
@ -4789,8 +4807,8 @@ package body Exp_Ch7 is
|
||||
-- end loop;
|
||||
-- end;
|
||||
|
||||
-- if Raised then
|
||||
-- Raise_From_Controlled_Operation (E, Abort);
|
||||
-- if Raised and then not Abort then
|
||||
-- Raise_From_Controlled_Operation (E);
|
||||
-- end if;
|
||||
|
||||
-- raise;
|
||||
@ -4957,8 +4975,8 @@ package body Exp_Ch7 is
|
||||
-- begin
|
||||
-- <core loop>
|
||||
|
||||
-- if Raised then -- Expection handlers allowed
|
||||
-- Raise_From_Controlled_Operation (E, Abort);
|
||||
-- if Raised and then not Abort then -- Expection handlers OK
|
||||
-- Raise_From_Controlled_Operation (E);
|
||||
-- end if;
|
||||
-- end;
|
||||
|
||||
@ -5249,11 +5267,11 @@ package body Exp_Ch7 is
|
||||
|
||||
-- <final loop>
|
||||
|
||||
-- if Raised then -- Exception handlers allowed
|
||||
-- Raise_From_Controlled_Operation (E, Abort);
|
||||
-- if Raised and then not Abort then -- Exception handlers OK
|
||||
-- Raise_From_Controlled_Operation (E);
|
||||
-- end if;
|
||||
|
||||
-- raise; -- Exception handlers allowed
|
||||
-- raise; -- Exception handlers OK
|
||||
-- end;
|
||||
|
||||
Stmts := New_List (Build_Counter_Assignment, Final_Loop);
|
||||
@ -5537,8 +5555,8 @@ package body Exp_Ch7 is
|
||||
-- end;
|
||||
-- end if;
|
||||
--
|
||||
-- if Raised then
|
||||
-- Raise_From_Controlled_Object (E, Abort);
|
||||
-- if Raised and then not Abort then
|
||||
-- Raise_From_Controlled_Operation (E);
|
||||
-- end if;
|
||||
-- end;
|
||||
|
||||
@ -5622,8 +5640,8 @@ package body Exp_Ch7 is
|
||||
-- end if;
|
||||
-- end;
|
||||
--
|
||||
-- if Raised then
|
||||
-- Raise_From_Controlled_Object (E, Abort);
|
||||
-- if Raised and then not Abort then
|
||||
-- Raise_From_Controlled_Operation (E);
|
||||
-- end if;
|
||||
-- end;
|
||||
|
||||
@ -6036,8 +6054,8 @@ package body Exp_Ch7 is
|
||||
-- begin
|
||||
-- <adjust statements>
|
||||
|
||||
-- if Raised then
|
||||
-- Raise_From_Controlled_Operation (E, Abort);
|
||||
-- if Raised and then not Abort then
|
||||
-- Raise_From_Controlled_Operation (E);
|
||||
-- end if;
|
||||
-- end;
|
||||
|
||||
@ -6618,15 +6636,10 @@ package body Exp_Ch7 is
|
||||
-- Raised : Boolean := False;
|
||||
|
||||
-- begin
|
||||
-- if V.Finalized then
|
||||
-- return;
|
||||
-- end if;
|
||||
|
||||
-- <finalize statements>
|
||||
-- V.Finalized := True;
|
||||
|
||||
-- if Raised then
|
||||
-- Raise_From_Controlled_Operation (E, Abort);
|
||||
-- if Raised and then not Abort then
|
||||
-- Raise_From_Controlled_Operation (E);
|
||||
-- end if;
|
||||
-- end;
|
||||
|
||||
@ -6917,16 +6930,29 @@ package body Exp_Ch7 is
|
||||
--------------------------------
|
||||
|
||||
procedure Make_Finalize_Address_Body (Typ : Entity_Id) is
|
||||
Is_Task : constant Boolean :=
|
||||
Ekind (Typ) = E_Record_Type
|
||||
and then Is_Concurrent_Record_Type (Typ)
|
||||
and then Ekind (Corresponding_Concurrent_Type (Typ)) =
|
||||
E_Task_Type;
|
||||
Loc : constant Source_Ptr := Sloc (Typ);
|
||||
Proc_Id : Entity_Id;
|
||||
Stmts : List_Id;
|
||||
|
||||
begin
|
||||
-- The corresponding records of task types are not controlled by design.
|
||||
-- For the sake of completeness, create an empty Finalize_Address to be
|
||||
-- used in task class-wide allocations.
|
||||
|
||||
if Is_Task then
|
||||
null;
|
||||
|
||||
-- Nothing to do if the type is not controlled or it already has a
|
||||
-- TSS entry for Finalize_Address. Skip class-wide subtypes which do not
|
||||
-- come from source. These are usually generated for completeness and
|
||||
-- do not need the Finalize_Address primitive.
|
||||
|
||||
if not Needs_Finalization (Typ)
|
||||
elsif not Needs_Finalization (Typ)
|
||||
or else Is_Abstract_Type (Typ)
|
||||
or else Present (TSS (Typ, TSS_Finalize_Address))
|
||||
or else
|
||||
@ -6944,7 +6970,9 @@ package body Exp_Ch7 is
|
||||
-- Generate:
|
||||
-- procedure <Typ>FD (V : System.Address) is
|
||||
-- begin
|
||||
-- declare
|
||||
-- null; -- for tasks
|
||||
--
|
||||
-- declare -- for all other types
|
||||
-- type Pnn is access all Typ;
|
||||
-- for Pnn'Storage_Size use 0;
|
||||
-- begin
|
||||
@ -6952,6 +6980,12 @@ package body Exp_Ch7 is
|
||||
-- end;
|
||||
-- end TypFD;
|
||||
|
||||
if Is_Task then
|
||||
Stmts := New_List (Make_Null_Statement (Loc));
|
||||
else
|
||||
Stmts := Make_Finalize_Address_Stmts (Typ);
|
||||
end if;
|
||||
|
||||
Discard_Node (
|
||||
Make_Subprogram_Body (Loc,
|
||||
Specification =>
|
||||
@ -6969,8 +7003,7 @@ package body Exp_Ch7 is
|
||||
|
||||
Handled_Statement_Sequence =>
|
||||
Make_Handled_Sequence_Of_Statements (Loc,
|
||||
Statements =>
|
||||
Make_Finalize_Address_Stmts (Typ))));
|
||||
Statements => Stmts)));
|
||||
|
||||
Set_TSS (Typ, Proc_Id);
|
||||
end Make_Finalize_Address_Body;
|
||||
@ -7218,7 +7251,7 @@ package body Exp_Ch7 is
|
||||
-- Generate:
|
||||
|
||||
-- when E : others =>
|
||||
-- Raise_From_Controlled_Operation (E, False);
|
||||
-- Raise_From_Controlled_Operation (E);
|
||||
|
||||
-- or:
|
||||
|
||||
@ -7250,8 +7283,7 @@ package body Exp_Ch7 is
|
||||
New_Reference_To
|
||||
(RTE (RE_Raise_From_Controlled_Operation), Loc),
|
||||
Parameter_Associations => New_List (
|
||||
New_Reference_To (E_Occ, Loc),
|
||||
New_Reference_To (Standard_False, Loc)));
|
||||
New_Reference_To (E_Occ, Loc)));
|
||||
|
||||
-- Restricted runtime: exception messages are not supported
|
||||
|
||||
|
@ -84,8 +84,8 @@ package Exp_Ch7 is
|
||||
-- Subsidiary to routines Build_Finalizer, Make_Deep_Array_Body and Make_
|
||||
-- Deep_Record_Body. Generate the following conditional raise statement:
|
||||
--
|
||||
-- if Raised_Id then
|
||||
-- Raise_From_Controlled_Operation (E_Id, Abort_Id);
|
||||
-- if Raised_Id and then not Abort_Id then
|
||||
-- Raise_From_Controlled_Operation (E_Id);
|
||||
-- end if;
|
||||
--
|
||||
-- Abort_Id is a local boolean flag which is set when the finalization was
|
||||
|
@ -327,10 +327,11 @@ package body Exp_Util is
|
||||
(N : Node_Id;
|
||||
Is_Allocate : Boolean)
|
||||
is
|
||||
Expr : constant Node_Id := Expression (N);
|
||||
Ptr_Typ : constant Entity_Id := Etype (Expr);
|
||||
Desig_Typ : constant Entity_Id :=
|
||||
Available_View (Designated_Type (Ptr_Typ));
|
||||
Desig_Typ : Entity_Id;
|
||||
Expr : Node_Id;
|
||||
Pool_Id : Entity_Id;
|
||||
Proc_To_Call : Node_Id := Empty;
|
||||
Ptr_Typ : Entity_Id;
|
||||
|
||||
function Find_Finalize_Address (Typ : Entity_Id) return Entity_Id;
|
||||
-- Locate TSS primitive Finalize_Address in type Typ
|
||||
@ -351,13 +352,33 @@ package body Exp_Util is
|
||||
Utyp : Entity_Id := Typ;
|
||||
|
||||
begin
|
||||
-- Handle protected class-wide or task class-wide types
|
||||
|
||||
if Is_Class_Wide_Type (Utyp) then
|
||||
if Is_Concurrent_Type (Root_Type (Utyp)) then
|
||||
Utyp := Root_Type (Utyp);
|
||||
|
||||
elsif Is_Private_Type (Root_Type (Utyp))
|
||||
and then Present (Full_View (Root_Type (Utyp)))
|
||||
and then Is_Concurrent_Type (Full_View (Root_Type (Utyp)))
|
||||
then
|
||||
Utyp := Full_View (Root_Type (Utyp));
|
||||
end if;
|
||||
end if;
|
||||
|
||||
-- Handle private types
|
||||
|
||||
if Is_Private_Type (Utyp)
|
||||
and then Present (Full_View (Utyp))
|
||||
then
|
||||
Utyp := Full_View (Utyp);
|
||||
end if;
|
||||
|
||||
if Is_Concurrent_Type (Utyp) then
|
||||
-- Handle protected and task types
|
||||
|
||||
if Is_Concurrent_Type (Utyp)
|
||||
and then Present (Corresponding_Record_Type (Utyp))
|
||||
then
|
||||
Utyp := Corresponding_Record_Type (Utyp);
|
||||
end if;
|
||||
|
||||
@ -459,18 +480,91 @@ package body Exp_Util is
|
||||
-- Start of processing for Build_Allocate_Deallocate_Proc
|
||||
|
||||
begin
|
||||
-- The allocation / deallocation of a non-controlled object does not
|
||||
-- need the machinery created by this routine.
|
||||
-- Obtain the attributes of the allocation / deallocation
|
||||
|
||||
if not Needs_Finalization (Desig_Typ) then
|
||||
if Nkind (N) = N_Free_Statement then
|
||||
Expr := Expression (N);
|
||||
Ptr_Typ := Base_Type (Etype (Expr));
|
||||
Proc_To_Call := Procedure_To_Call (N);
|
||||
|
||||
else
|
||||
if Nkind (N) = N_Object_Declaration then
|
||||
Expr := Expression (N);
|
||||
else
|
||||
Expr := N;
|
||||
end if;
|
||||
|
||||
Ptr_Typ := Base_Type (Etype (Expr));
|
||||
|
||||
-- The allocator may have been rewritten into something else
|
||||
|
||||
if Nkind (Expr) = N_Allocator then
|
||||
Proc_To_Call := Procedure_To_Call (Expr);
|
||||
end if;
|
||||
end if;
|
||||
|
||||
Pool_Id := Associated_Storage_Pool (Ptr_Typ);
|
||||
Desig_Typ := Available_View (Designated_Type (Ptr_Typ));
|
||||
|
||||
-- Handle concurrent types
|
||||
|
||||
if Is_Concurrent_Type (Desig_Typ)
|
||||
and then Present (Corresponding_Record_Type (Desig_Typ))
|
||||
then
|
||||
Desig_Typ := Corresponding_Record_Type (Desig_Typ);
|
||||
end if;
|
||||
|
||||
-- Do not process allocations / deallocations without a pool
|
||||
|
||||
if No (Pool_Id) then
|
||||
return;
|
||||
|
||||
-- The allocator or free statement has already been expanded and already
|
||||
-- has a custom Allocate / Deallocate routine.
|
||||
-- Do not process allocations on / deallocations from the secondary
|
||||
-- stack.
|
||||
|
||||
elsif Is_RTE (Pool_Id, RE_SS_Pool) then
|
||||
return;
|
||||
|
||||
-- Do not replicate the machinery if the allocator / free has already
|
||||
-- been expanded and has a custom Allocate / Deallocate.
|
||||
|
||||
elsif Present (Proc_To_Call)
|
||||
and then Is_Allocate_Deallocate_Proc (Proc_To_Call)
|
||||
then
|
||||
return;
|
||||
end if;
|
||||
|
||||
if Needs_Finalization (Desig_Typ) then
|
||||
|
||||
-- Certain run-time configurations and targets do not provide support
|
||||
-- for controlled types.
|
||||
|
||||
if Restriction_Active (No_Finalization) then
|
||||
return;
|
||||
|
||||
-- Do nothing if the access type may never allocate / deallocate
|
||||
-- objects.
|
||||
|
||||
elsif No_Pool_Assigned (Ptr_Typ) then
|
||||
return;
|
||||
|
||||
-- Access-to-controlled types are not supported on .NET/JVM since
|
||||
-- these targets cannot support pools and address arithmetic.
|
||||
|
||||
elsif VM_Target /= No_VM then
|
||||
return;
|
||||
end if;
|
||||
|
||||
-- The allocation / deallocation of a controlled object must be
|
||||
-- chained on / detached from a finalization master.
|
||||
|
||||
pragma Assert (Present (Finalization_Master (Ptr_Typ)));
|
||||
|
||||
-- The only other kind of allocation / deallocation supported by this
|
||||
-- routine is on / from a subpool.
|
||||
|
||||
elsif Nkind (Expr) = N_Allocator
|
||||
and then Present (Procedure_To_Call (Expr))
|
||||
and then Is_Allocate_Deallocate_Proc (Procedure_To_Call (Expr))
|
||||
and then No (Subpool_Handle_Name (Expr))
|
||||
then
|
||||
return;
|
||||
end if;
|
||||
@ -486,36 +580,27 @@ package body Exp_Util is
|
||||
Fin_Addr_Id : Entity_Id;
|
||||
Fin_Mas_Act : Node_Id;
|
||||
Fin_Mas_Id : Entity_Id;
|
||||
Fin_Mas_Typ : Entity_Id;
|
||||
Proc_To_Call : Entity_Id;
|
||||
Subpool : Node_Id := Empty;
|
||||
|
||||
begin
|
||||
-- When dealing with an access subtype, always use the base type
|
||||
-- since it carries all the attributes.
|
||||
|
||||
if Ekind (Ptr_Typ) = E_Access_Subtype then
|
||||
Fin_Mas_Typ := Base_Type (Ptr_Typ);
|
||||
else
|
||||
Fin_Mas_Typ := Ptr_Typ;
|
||||
end if;
|
||||
|
||||
Actuals := New_List;
|
||||
|
||||
-- Step 1: Construct all the actuals for the call to library routine
|
||||
-- Allocate_Any_Controlled / Deallocate_Any_Controlled.
|
||||
|
||||
-- a) Storage pool
|
||||
|
||||
Append_To (Actuals,
|
||||
New_Reference_To (Associated_Storage_Pool (Fin_Mas_Typ), Loc));
|
||||
Actuals := New_List (New_Reference_To (Pool_Id, Loc));
|
||||
|
||||
if Is_Allocate then
|
||||
|
||||
-- b) Subpool
|
||||
|
||||
if Present (Subpool_Handle_Name (Expr)) then
|
||||
Append_To (Actuals,
|
||||
New_Reference_To (Entity (Subpool_Handle_Name (Expr)), Loc));
|
||||
if Nkind (Expr) = N_Allocator then
|
||||
Subpool := Subpool_Handle_Name (Expr);
|
||||
end if;
|
||||
|
||||
if Present (Subpool) then
|
||||
Append_To (Actuals, New_Reference_To (Entity (Subpool), Loc));
|
||||
else
|
||||
Append_To (Actuals, Make_Null (Loc));
|
||||
end if;
|
||||
@ -523,7 +608,7 @@ package body Exp_Util is
|
||||
-- c) Finalization master
|
||||
|
||||
if Needs_Finalization (Desig_Typ) then
|
||||
Fin_Mas_Id := Finalization_Master (Fin_Mas_Typ);
|
||||
Fin_Mas_Id := Finalization_Master (Ptr_Typ);
|
||||
Fin_Mas_Act := New_Reference_To (Fin_Mas_Id, Loc);
|
||||
|
||||
-- Handle the case where the master is actually a pointer to a
|
||||
@ -545,7 +630,9 @@ package body Exp_Util is
|
||||
|
||||
Fin_Addr_Id := Find_Finalize_Address (Desig_Typ);
|
||||
|
||||
if Present (Fin_Addr_Id) then
|
||||
if Needs_Finalization (Desig_Typ) then
|
||||
pragma Assert (Present (Fin_Addr_Id));
|
||||
|
||||
Append_To (Actuals,
|
||||
Make_Attribute_Reference (Loc,
|
||||
Prefix => New_Reference_To (Fin_Addr_Id, Loc),
|
||||
@ -654,11 +741,23 @@ package body Exp_Util is
|
||||
|
||||
Append_To (Actuals, New_Reference_To (Flag_Id, Loc));
|
||||
end;
|
||||
|
||||
-- The object is statically known to be controlled
|
||||
|
||||
else
|
||||
Append_To (Actuals, New_Reference_To (Standard_True, Loc));
|
||||
end if;
|
||||
else
|
||||
Append_To (Actuals, New_Reference_To (Standard_False, Loc));
|
||||
end if;
|
||||
|
||||
-- i) On_Subpool
|
||||
|
||||
if Is_Allocate then
|
||||
Append_To (Actuals,
|
||||
New_Reference_To (Boolean_Literals (Present (Subpool)), Loc));
|
||||
end if;
|
||||
|
||||
-- Step 2: Build a wrapper Allocate / Deallocate which internally
|
||||
-- calls Allocate_Any_Controlled / Deallocate_Any_Controlled.
|
||||
|
||||
@ -5296,6 +5395,16 @@ package body Exp_Util is
|
||||
if Restriction_Active (No_Finalization) then
|
||||
return False;
|
||||
|
||||
-- C, C++, CIL and Java types are not considered controlled. It is
|
||||
-- assumed that the non-Ada side will handle their clean up.
|
||||
|
||||
elsif Convention (T) = Convention_C
|
||||
or else Convention (T) = Convention_CIL
|
||||
or else Convention (T) = Convention_CPP
|
||||
or else Convention (T) = Convention_Java
|
||||
then
|
||||
return False;
|
||||
|
||||
else
|
||||
-- Class-wide types are treated as controlled because derivations
|
||||
-- from the root type can introduce controlled components.
|
||||
|
@ -198,8 +198,13 @@ package Exp_Util is
|
||||
(N : Node_Id;
|
||||
Is_Allocate : Boolean);
|
||||
-- Create a custom Allocate/Deallocate to be associated with an allocation
|
||||
-- or deallocation of a controlled or class-wide object. In the case of
|
||||
-- allocation, N is the declaration of the temporary variable which
|
||||
-- or deallocation:
|
||||
--
|
||||
-- 1) controlled objects
|
||||
-- 2) class-wide objects
|
||||
-- 3) any kind of object on a subpool
|
||||
--
|
||||
-- N must be an allocator or the declaration of a temporary variable which
|
||||
-- represents the expression of the original allocator node, otherwise N
|
||||
-- must be a free statement. If flag Is_Allocate is set, the generated
|
||||
-- routine is allocate, deallocate otherwise.
|
||||
|
@ -1439,27 +1439,24 @@ package body Freeze is
|
||||
end loop;
|
||||
end;
|
||||
|
||||
-- We add finalization collections to access types whose designated
|
||||
-- types require finalization. This is normally done when freezing
|
||||
-- the type, but this misses recursive type definitions where the
|
||||
-- later members of the recursion introduce controlled components
|
||||
-- (such as can happen when incomplete types are involved), as well
|
||||
-- cases where a component type is private and the controlled full
|
||||
-- type occurs after the access type is frozen. Cases that don't
|
||||
-- need a finalization collection are generic formal types (the
|
||||
-- actual type will have it) and types with Java and CIL conventions,
|
||||
-- since those are used for API bindings. (Are there any other cases
|
||||
-- that should be excluded here???)
|
||||
-- We add finalization masters to access types whose designated types
|
||||
-- require finalization. This is normally done when freezing the
|
||||
-- type, but this misses recursive type definitions where the later
|
||||
-- members of the recursion introduce controlled components (such as
|
||||
-- can happen when incomplete types are involved), as well cases
|
||||
-- where a component type is private and the controlled full type
|
||||
-- occurs after the access type is frozen. Cases that don't need a
|
||||
-- finalization master are generic formal types (the actual type will
|
||||
-- have it) and types with Java and CIL conventions, since those are
|
||||
-- used for API bindings. (Are there any other cases that should be
|
||||
-- excluded here???)
|
||||
|
||||
elsif Is_Access_Type (E)
|
||||
and then Comes_From_Source (E)
|
||||
and then not Is_Generic_Type (E)
|
||||
and then Needs_Finalization (Designated_Type (E))
|
||||
and then No (Associated_Collection (E))
|
||||
and then Convention (Designated_Type (E)) /= Convention_Java
|
||||
and then Convention (Designated_Type (E)) /= Convention_CIL
|
||||
then
|
||||
Build_Finalization_Collection (E);
|
||||
Build_Finalization_Master (E);
|
||||
end if;
|
||||
|
||||
Next_Entity (E);
|
||||
|
@ -346,6 +346,7 @@ package body Impunit is
|
||||
|
||||
"s-addima", -- System.Address_Image
|
||||
"s-assert", -- System.Assertions
|
||||
"s-finmas", -- System.Finalization_Masters
|
||||
"s-memory", -- System.Memory
|
||||
"s-parint", -- System.Partition_Interface
|
||||
"s-pooglo", -- System.Pool_Global
|
||||
@ -508,6 +509,7 @@ package body Impunit is
|
||||
Non_Imp_File_Names_12 : constant File_List := (
|
||||
"s-multip", -- System.Multiprocessors
|
||||
"s-mudido", -- System.Multiprocessors.Dispatching_Domains
|
||||
"s-stposu", -- System.Storage_Pools.Subpools
|
||||
"a-cobove", -- Ada.Containers.Bounded_Vectors
|
||||
"a-cbdlli", -- Ada.Containers.Bounded_Doubly_Linked_Lists
|
||||
"a-cborse", -- Ada.Containers.Bounded_Ordered_Sets
|
||||
@ -521,11 +523,13 @@ package body Impunit is
|
||||
"a-extiin", -- Ada.Execution_Time.Interrupts
|
||||
"a-iteint", -- Ada.Iterator_Interfaces
|
||||
"a-synbar", -- Ada.Synchronous_Barriers
|
||||
"a-undesu", -- Ada.Unchecked_Deallocate_Subpool
|
||||
|
||||
-----------------------------------------
|
||||
-- GNAT Defined Additions to Ada 20012 --
|
||||
-----------------------------------------
|
||||
|
||||
"s-spsufi", -- System.Storage_Pools.Subpools.Finalization
|
||||
"a-cofove", -- Ada.Containers.Formal_Vectors
|
||||
"a-cfdlli", -- Ada.Containers.Formal_Doubly_Linked_Lists
|
||||
"a-cforse", -- Ada.Containers.Formal_Ordered_Sets
|
||||
|
@ -35,6 +35,8 @@ with Ada.Unchecked_Conversion;
|
||||
with System.Storage_Elements;
|
||||
with System.Storage_Pools;
|
||||
|
||||
pragma Compiler_Unit;
|
||||
|
||||
package System.Finalization_Masters is
|
||||
pragma Preelaborate (System.Finalization_Masters);
|
||||
|
||||
|
62
gcc/ada/s-spsufi.adb
Normal file
62
gcc/ada/s-spsufi.adb
Normal file
@ -0,0 +1,62 @@
|
||||
------------------------------------------------------------------------------
|
||||
-- --
|
||||
-- GNAT COMPILER COMPONENTS --
|
||||
-- --
|
||||
-- S Y S T E M . S T O R A G E _ P O O L S . S U B P O O L S . --
|
||||
-- F I N A L I Z A T I O N --
|
||||
-- --
|
||||
-- B o d y --
|
||||
-- --
|
||||
-- Copyright (C) 2011, Free Software Foundation, Inc. --
|
||||
-- --
|
||||
-- GNAT is free software; you can redistribute it and/or modify it under --
|
||||
-- terms of the GNU General Public License as published by the Free Soft- --
|
||||
-- ware Foundation; either version 3, or (at your option) any later ver- --
|
||||
-- sion. GNAT is distributed in the hope that it will be useful, but WITH- --
|
||||
-- OUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY --
|
||||
-- or FITNESS FOR A PARTICULAR PURPOSE. --
|
||||
-- --
|
||||
-- As a special exception under Section 7 of GPL version 3, you are granted --
|
||||
-- additional permissions described in the GCC Runtime Library Exception, --
|
||||
-- version 3.1, as published by the Free Software Foundation. --
|
||||
-- --
|
||||
-- You should have received a copy of the GNU General Public License and --
|
||||
-- a copy of the GCC Runtime Library Exception along with this program; --
|
||||
-- see the files COPYING3 and COPYING.RUNTIME respectively. If not, see --
|
||||
-- <http://www.gnu.org/licenses/>. --
|
||||
-- --
|
||||
-- GNAT was originally developed by the GNAT team at New York University. --
|
||||
-- Extensive contributions were provided by Ada Core Technologies Inc. --
|
||||
-- --
|
||||
------------------------------------------------------------------------------
|
||||
|
||||
package body System.Storage_Pools.Subpools.Finalization is
|
||||
|
||||
-----------------------------
|
||||
-- Finalize_And_Deallocate --
|
||||
-----------------------------
|
||||
|
||||
procedure Finalize_And_Deallocate (Subpool : in out Subpool_Handle) is
|
||||
begin
|
||||
-- Do nothing if the subpool was never created or never used. The latter
|
||||
-- case may arise with an array of subpool implementations.
|
||||
|
||||
if Subpool = null
|
||||
or else Subpool.Owner = null
|
||||
or else Subpool.Node = null
|
||||
then
|
||||
return;
|
||||
end if;
|
||||
|
||||
-- Clean up all controlled objects allocated through the subpool
|
||||
|
||||
Finalize_Subpool (Subpool);
|
||||
|
||||
-- Dispatch to the user-defined implementation of Deallocate_Subpool
|
||||
|
||||
Deallocate_Subpool (Pool_Of_Subpool (Subpool).all, Subpool);
|
||||
|
||||
Subpool := null;
|
||||
end Finalize_And_Deallocate;
|
||||
|
||||
end System.Storage_Pools.Subpools.Finalization;
|
44
gcc/ada/s-spsufi.ads
Normal file
44
gcc/ada/s-spsufi.ads
Normal file
@ -0,0 +1,44 @@
|
||||
------------------------------------------------------------------------------
|
||||
-- --
|
||||
-- GNAT COMPILER COMPONENTS --
|
||||
-- --
|
||||
-- S Y S T E M . S T O R A G E _ P O O L S . S U B P O O L S . --
|
||||
-- F I N A L I Z A T I O N --
|
||||
-- --
|
||||
-- S p e c --
|
||||
-- --
|
||||
-- Copyright (C) 2011, Free Software Foundation, Inc. --
|
||||
-- --
|
||||
-- GNAT is free software; you can redistribute it and/or modify it under --
|
||||
-- terms of the GNU General Public License as published by the Free Soft- --
|
||||
-- ware Foundation; either version 3, or (at your option) any later ver- --
|
||||
-- sion. GNAT is distributed in the hope that it will be useful, but WITH- --
|
||||
-- OUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY --
|
||||
-- or FITNESS FOR A PARTICULAR PURPOSE. --
|
||||
-- --
|
||||
-- As a special exception under Section 7 of GPL version 3, you are granted --
|
||||
-- additional permissions described in the GCC Runtime Library Exception, --
|
||||
-- version 3.1, as published by the Free Software Foundation. --
|
||||
-- --
|
||||
-- You should have received a copy of the GNU General Public License and --
|
||||
-- a copy of the GCC Runtime Library Exception along with this program; --
|
||||
-- see the files COPYING3 and COPYING.RUNTIME respectively. If not, see --
|
||||
-- <http://www.gnu.org/licenses/>. --
|
||||
-- --
|
||||
-- GNAT was originally developed by the GNAT team at New York University. --
|
||||
-- Extensive contributions were provided by Ada Core Technologies Inc. --
|
||||
-- --
|
||||
------------------------------------------------------------------------------
|
||||
|
||||
pragma Compiler_Unit;
|
||||
|
||||
package System.Storage_Pools.Subpools.Finalization is
|
||||
|
||||
procedure Finalize_And_Deallocate (Subpool : in out Subpool_Handle);
|
||||
-- This routine performs the following actions:
|
||||
-- 1) Finalize all objects chained on the subpool's master
|
||||
-- 2) Remove the the subpool from the owner's list of subpools
|
||||
-- 3) Deallocate the doubly linked list node associated with the subpool
|
||||
-- 4) Call Deallocate_Subpool
|
||||
|
||||
end System.Storage_Pools.Subpools.Finalization;
|
@ -61,10 +61,6 @@ package body System.Storage_Pools.Subpools is
|
||||
Alignment : System.Storage_Elements.Storage_Count)
|
||||
is
|
||||
begin
|
||||
-- ??? The use of Allocate is very dangerous as it does not handle
|
||||
-- controlled objects properly. Perhaps we should provide an
|
||||
-- implementation which raises Program_Error instead.
|
||||
|
||||
-- Dispatch to the user-defined implementations of Allocate_From_Subpool
|
||||
-- and Default_Subpool_For_Pool.
|
||||
|
||||
@ -83,13 +79,14 @@ package body System.Storage_Pools.Subpools is
|
||||
|
||||
procedure Allocate_Any_Controlled
|
||||
(Pool : in out Root_Storage_Pool'Class;
|
||||
Context_Subpool : Subpool_Handle := null;
|
||||
Context_Master : Finalization_Masters.Finalization_Master_Ptr := null;
|
||||
Fin_Address : Finalization_Masters.Finalize_Address_Ptr := null;
|
||||
Context_Subpool : Subpool_Handle;
|
||||
Context_Master : Finalization_Masters.Finalization_Master_Ptr;
|
||||
Fin_Address : Finalization_Masters.Finalize_Address_Ptr;
|
||||
Addr : out System.Address;
|
||||
Storage_Size : System.Storage_Elements.Storage_Count;
|
||||
Alignment : System.Storage_Elements.Storage_Count;
|
||||
Is_Controlled : Boolean := True)
|
||||
Is_Controlled : Boolean;
|
||||
On_Subpool : Boolean)
|
||||
is
|
||||
Is_Subpool_Allocation : constant Boolean :=
|
||||
Pool in Root_Storage_Pool_With_Subpools'Class;
|
||||
@ -108,7 +105,7 @@ package body System.Storage_Pools.Subpools is
|
||||
-- Step 1: Pool-related runtime checks
|
||||
|
||||
-- Allocation on a pool_with_subpools. In this scenario there is a
|
||||
-- master for each subpool.
|
||||
-- master for each subpool. The master of the access type is ignored.
|
||||
|
||||
if Is_Subpool_Allocation then
|
||||
|
||||
@ -120,26 +117,21 @@ package body System.Storage_Pools.Subpools is
|
||||
Default_Subpool_For_Pool
|
||||
(Root_Storage_Pool_With_Subpools'Class (Pool));
|
||||
|
||||
-- Ensure proper ownership
|
||||
|
||||
if Subpool.Owner /=
|
||||
Root_Storage_Pool_With_Subpools'Class (Pool)'Unchecked_Access
|
||||
then
|
||||
raise Program_Error with "incorrect owner of default subpool";
|
||||
end if;
|
||||
|
||||
-- Allocation with a Subpool_Handle
|
||||
|
||||
else
|
||||
Subpool := Context_Subpool;
|
||||
end if;
|
||||
|
||||
-- Ensure proper ownership
|
||||
-- Ensure proper ownership and chaining of the subpool
|
||||
|
||||
if Subpool.Owner /=
|
||||
Root_Storage_Pool_With_Subpools'Class (Pool)'Unchecked_Access
|
||||
then
|
||||
raise Program_Error with "incorrect owner of subpool";
|
||||
end if;
|
||||
if Subpool.Owner /=
|
||||
Root_Storage_Pool_With_Subpools'Class (Pool)'Unchecked_Access
|
||||
or else Subpool.Node = null
|
||||
or else Subpool.Node.Prev = null
|
||||
or else Subpool.Node.Next = null
|
||||
then
|
||||
raise Program_Error with "incorrect owner of subpool";
|
||||
end if;
|
||||
|
||||
Master := Subpool.Master'Unchecked_Access;
|
||||
@ -148,25 +140,35 @@ package body System.Storage_Pools.Subpools is
|
||||
-- each access-to-controlled type. No context subpool should be present.
|
||||
|
||||
else
|
||||
|
||||
-- If the master is missing, then the expansion of the access type
|
||||
-- failed to create one. This is a serious error.
|
||||
|
||||
if Context_Master = null then
|
||||
raise Program_Error with "missing master in pool allocation";
|
||||
end if;
|
||||
|
||||
-- If a subpool is present, then this is the result of erroneous
|
||||
-- allocator expansion. This is not a serious error, but it should
|
||||
-- still be detected.
|
||||
|
||||
elsif Context_Subpool /= null then
|
||||
if Context_Subpool /= null then
|
||||
raise Program_Error with "subpool not required in pool allocation";
|
||||
end if;
|
||||
|
||||
-- If the allocation is intended to be on a subpool, but the access
|
||||
-- type's pool does not support subpools, then this is the result of
|
||||
-- erroneous end-user code.
|
||||
|
||||
if On_Subpool then
|
||||
raise Program_Error
|
||||
with "pool of access type does not support subpools";
|
||||
end if;
|
||||
|
||||
Master := Context_Master;
|
||||
end if;
|
||||
|
||||
-- Step 2: Master-related runtime checks and size calculations
|
||||
-- Step 2: Master and Finalize_Address-related runtime checks and size
|
||||
-- calculations.
|
||||
|
||||
-- Allocation of a descendant from [Limited_]Controlled, a class-wide
|
||||
-- object or a record with controlled components.
|
||||
@ -180,6 +182,15 @@ package body System.Storage_Pools.Subpools is
|
||||
raise Program_Error with "allocation after finalization started";
|
||||
end if;
|
||||
|
||||
-- Check whether primitive Finalize_Address is available. If it is
|
||||
-- not, then either the expansion of the designated type failed or
|
||||
-- the expansion of the allocator failed. This is a serious error.
|
||||
|
||||
if Fin_Address = null then
|
||||
raise Program_Error
|
||||
with "primitive Finalize_Address not available";
|
||||
end if;
|
||||
|
||||
-- The size must acount for the hidden header preceding the object.
|
||||
-- Account for possible padding space before the header due to a
|
||||
-- larger alignment.
|
||||
@ -224,29 +235,20 @@ package body System.Storage_Pools.Subpools is
|
||||
-- due to larger alignment, the header is placed right next to the
|
||||
-- object:
|
||||
|
||||
-- N_Addr N_Ptr
|
||||
-- | |
|
||||
-- V V
|
||||
-- +-------+---------------+----------------------+
|
||||
-- |Padding| Header | Object |
|
||||
-- +-------+---------------+----------------------+
|
||||
-- ^ ^ ^
|
||||
-- | +- Header_Size -+
|
||||
-- | |
|
||||
-- +- Header_And_Padding --+
|
||||
-- N_Addr N_Ptr
|
||||
-- | |
|
||||
-- V V
|
||||
-- +-------+---------------+----------------------+
|
||||
-- |Padding| Header | Object |
|
||||
-- +-------+---------------+----------------------+
|
||||
-- ^ ^ ^
|
||||
-- | +- Header_Size -+
|
||||
-- | |
|
||||
-- +- Header_And_Padding --+
|
||||
|
||||
N_Ptr :=
|
||||
Address_To_FM_Node_Ptr (N_Addr + Header_And_Padding - Header_Size);
|
||||
|
||||
-- Check whether primitive Finalize_Address is available. If it is
|
||||
-- not, then either the expansion of the designated type failed or
|
||||
-- the expansion of the allocator failed. This is a serious error.
|
||||
|
||||
if Fin_Address = null then
|
||||
raise Program_Error
|
||||
with "primitive Finalize_Address not available";
|
||||
end if;
|
||||
|
||||
N_Ptr.Finalize_Address := Fin_Address;
|
||||
|
||||
-- Prepend the allocated object to the finalization master
|
||||
@ -268,6 +270,10 @@ package body System.Storage_Pools.Subpools is
|
||||
|
||||
procedure Attach (N : not null SP_Node_Ptr; L : not null SP_Node_Ptr) is
|
||||
begin
|
||||
-- Ensure that the node has not been attached already
|
||||
|
||||
pragma Assert (N.Prev = null and then N.Next = null);
|
||||
|
||||
Lock_Task.all;
|
||||
|
||||
L.Next.Prev := N;
|
||||
@ -290,7 +296,7 @@ package body System.Storage_Pools.Subpools is
|
||||
Addr : System.Address;
|
||||
Storage_Size : System.Storage_Elements.Storage_Count;
|
||||
Alignment : System.Storage_Elements.Storage_Count;
|
||||
Is_Controlled : Boolean := True)
|
||||
Is_Controlled : Boolean)
|
||||
is
|
||||
N_Addr : Address;
|
||||
N_Ptr : FM_Node_Ptr;
|
||||
@ -360,7 +366,7 @@ package body System.Storage_Pools.Subpools is
|
||||
|
||||
procedure Detach (N : not null SP_Node_Ptr) is
|
||||
begin
|
||||
-- N must be attached to some list
|
||||
-- Ensure that the node is attached to some list
|
||||
|
||||
pragma Assert (N.Next /= null and then N.Prev /= null);
|
||||
|
||||
@ -379,22 +385,22 @@ package body System.Storage_Pools.Subpools is
|
||||
-- Finalize --
|
||||
--------------
|
||||
|
||||
overriding procedure Finalize
|
||||
(Pool : in out Root_Storage_Pool_With_Subpools)
|
||||
is
|
||||
overriding procedure Finalize (Controller : in out Pool_Controller) is
|
||||
begin
|
||||
Finalize_Pool (Controller.Enclosing_Pool.all);
|
||||
end Finalize;
|
||||
|
||||
-------------------
|
||||
-- Finalize_Pool --
|
||||
-------------------
|
||||
|
||||
procedure Finalize_Pool (Pool : in out Root_Storage_Pool_With_Subpools) is
|
||||
Curr_Ptr : SP_Node_Ptr;
|
||||
Ex_Occur : Exception_Occurrence;
|
||||
Next_Ptr : SP_Node_Ptr;
|
||||
Raised : Boolean := False;
|
||||
|
||||
begin
|
||||
-- Uninitialized pools do not have subpools and do not contain objects
|
||||
-- of any kind.
|
||||
|
||||
if not Pool.Initialized then
|
||||
return;
|
||||
end if;
|
||||
|
||||
-- It is possible for multiple tasks to cause the finalization of a
|
||||
-- common pool. Allow only one task to finalize the contents.
|
||||
|
||||
@ -415,11 +421,12 @@ package body System.Storage_Pools.Subpools is
|
||||
while Curr_Ptr /= Pool.Subpools'Unchecked_Access loop
|
||||
Next_Ptr := Curr_Ptr.Next;
|
||||
|
||||
-- Remove the subpool node from the subpool list
|
||||
-- Perform the following actions:
|
||||
|
||||
Detach (Curr_Ptr);
|
||||
|
||||
-- Finalize the current subpool
|
||||
-- 1) Finalize all objects chained on the subpool's master
|
||||
-- 2) Remove the the subpool from the owner's list of subpools
|
||||
-- 3) Deallocate the doubly linked list node associated with the
|
||||
-- subpool.
|
||||
|
||||
begin
|
||||
Finalize_Subpool (Curr_Ptr.Subpool);
|
||||
@ -432,11 +439,6 @@ package body System.Storage_Pools.Subpools is
|
||||
end if;
|
||||
end;
|
||||
|
||||
-- Since subpool nodes are not allocated on the owner pool, they must
|
||||
-- be explicitly destroyed.
|
||||
|
||||
Free (Curr_Ptr);
|
||||
|
||||
Curr_Ptr := Next_Ptr;
|
||||
end loop;
|
||||
|
||||
@ -446,7 +448,7 @@ package body System.Storage_Pools.Subpools is
|
||||
if Raised then
|
||||
Reraise_Occurrence (Ex_Occur);
|
||||
end if;
|
||||
end Finalize;
|
||||
end Finalize_Pool;
|
||||
|
||||
----------------------
|
||||
-- Finalize_Subpool --
|
||||
@ -454,9 +456,49 @@ package body System.Storage_Pools.Subpools is
|
||||
|
||||
procedure Finalize_Subpool (Subpool : not null Subpool_Handle) is
|
||||
begin
|
||||
-- Do nothing if the subpool was never used
|
||||
|
||||
if Subpool.Owner = null
|
||||
or else Subpool.Node = null
|
||||
then
|
||||
return;
|
||||
end if;
|
||||
|
||||
-- Clean up all controlled objects chained on the subpool's master
|
||||
|
||||
Finalize (Subpool.Master);
|
||||
|
||||
-- Remove the subpool from its owner's list of subpools
|
||||
|
||||
Detach (Subpool.Node);
|
||||
|
||||
-- Destroy the associated doubly linked list node which was created in
|
||||
-- Set_Pool_Of_Subpool.
|
||||
|
||||
Free (Subpool.Node);
|
||||
end Finalize_Subpool;
|
||||
|
||||
----------------
|
||||
-- Initialize --
|
||||
----------------
|
||||
|
||||
overriding procedure Initialize (Controller : in out Pool_Controller) is
|
||||
begin
|
||||
Initialize_Pool (Controller.Enclosing_Pool.all);
|
||||
end Initialize;
|
||||
|
||||
---------------------
|
||||
-- Initialize_Pool --
|
||||
---------------------
|
||||
|
||||
procedure Initialize_Pool (Pool : in out Root_Storage_Pool_With_Subpools) is
|
||||
begin
|
||||
-- The dummy head must point to itself in both directions
|
||||
|
||||
Pool.Subpools.Next := Pool.Subpools'Unchecked_Access;
|
||||
Pool.Subpools.Prev := Pool.Subpools'Unchecked_Access;
|
||||
end Initialize_Pool;
|
||||
|
||||
---------------------
|
||||
-- Pool_Of_Subpool --
|
||||
---------------------
|
||||
@ -478,15 +520,6 @@ package body System.Storage_Pools.Subpools is
|
||||
N_Ptr : SP_Node_Ptr;
|
||||
|
||||
begin
|
||||
if not Pool.Initialized then
|
||||
|
||||
-- The dummy head must point to itself in both directions
|
||||
|
||||
Pool.Subpools.Next := Pool.Subpools'Unchecked_Access;
|
||||
Pool.Subpools.Prev := Pool.Subpools'Unchecked_Access;
|
||||
Pool.Initialized := True;
|
||||
end if;
|
||||
|
||||
-- If the subpool is already owned, raise Program_Error. This is a
|
||||
-- direct violation of the RM rules.
|
||||
|
||||
@ -502,13 +535,15 @@ package body System.Storage_Pools.Subpools is
|
||||
with "subpool creation after finalization started";
|
||||
end if;
|
||||
|
||||
-- Create a subpool node, decorate it and associate it with the subpool
|
||||
-- list of Pool.
|
||||
Subpool.Owner := Pool'Unchecked_Access;
|
||||
|
||||
-- Create a subpool node and decorate it. Since this node is not
|
||||
-- allocated on the owner's pool, it must be explicitly destroyed by
|
||||
-- Finalize_And_Detach.
|
||||
|
||||
N_Ptr := new SP_Node;
|
||||
|
||||
Subpool.Owner := Pool'Unchecked_Access;
|
||||
N_Ptr.Subpool := Subpool;
|
||||
Subpool.Node := N_Ptr;
|
||||
|
||||
Attach (N_Ptr, Pool.Subpools'Unchecked_Access);
|
||||
end Set_Pool_Of_Subpool;
|
||||
|
@ -33,6 +33,8 @@
|
||||
-- --
|
||||
------------------------------------------------------------------------------
|
||||
|
||||
with Ada.Finalization;
|
||||
|
||||
with System.Finalization_Masters;
|
||||
with System.Storage_Elements;
|
||||
|
||||
@ -61,7 +63,8 @@ package System.Storage_Pools.Subpools is
|
||||
Size_In_Storage_Elements : System.Storage_Elements.Storage_Count;
|
||||
Alignment : System.Storage_Elements.Storage_Count);
|
||||
-- Allocate an object described by Size_In_Storage_Elements and Alignment
|
||||
-- on the default subpool of Pool.
|
||||
-- on the default subpool of Pool. Controlled types allocated through this
|
||||
-- routine will NOT be handled properly.
|
||||
|
||||
procedure Allocate_From_Subpool
|
||||
(Pool : in out Root_Storage_Pool_With_Subpools;
|
||||
@ -126,50 +129,45 @@ package System.Storage_Pools.Subpools is
|
||||
|
||||
private
|
||||
-- Model
|
||||
-- Pool_With_Subpools
|
||||
-- +----> +---------------------+ <----+
|
||||
-- | +---------- Subpools | |
|
||||
-- | | +---------------------+ |
|
||||
-- | | : User data : |
|
||||
-- | | '.....................' |
|
||||
-- | | |
|
||||
-- | | SP_Node SP_Node |
|
||||
-- | +-> +-------+ +-------+ |
|
||||
-- | | Prev <-----> Prev | |
|
||||
-- | +-------+ +-------+ |
|
||||
-- | | Next <---->| Next | |
|
||||
-- | +-------+ +-------+ |
|
||||
-- | +----Subpool| |Subpool----+ |
|
||||
-- | | +-------+ +-------+ | |
|
||||
-- | | | |
|
||||
-- | | Subpool Subpool | |
|
||||
-- | +-> +-------+ +-------+ <-+ |
|
||||
-- +------- Owner | | Owner -------+
|
||||
-- +-------+ +-------+
|
||||
-- +------------------- Master| | Master---------------+
|
||||
-- | +-------+ +-------+ |
|
||||
-- | : User : : User : |
|
||||
-- | : Data : : Data : |
|
||||
-- | '.......' '.......' |
|
||||
-- | |
|
||||
-- | Heap |
|
||||
-- .. | ..................................................... | ..
|
||||
-- : | | :
|
||||
-- : | Object Object Object Object | :
|
||||
-- : +-> +------+ +------+ +------+ +------+ <-+ :
|
||||
-- : | Prev <--> Prev <--> Prev | | Prev | :
|
||||
-- : +------+ +------+ +------+ +------+ :
|
||||
-- : | Next <--> Next <--> Next | | Next | :
|
||||
-- : +------+ +------+ +------+ +------+ :
|
||||
-- : | FA | | FA | | FA | | FA | :
|
||||
-- : +------+ +------+ +------+ +------+ :
|
||||
-- : : : : : : : : : :
|
||||
-- : : : : : : : : : :
|
||||
-- : '......' '......' '......' '......' :
|
||||
-- : :
|
||||
-- '.............................................................'
|
||||
-- Pool_With_Subpools SP_Node SP_Node SP_Node
|
||||
-- +-->+--------------------+ +-----+ +-----+ +-----+
|
||||
-- | | Subpools -------->| ------->| ------->| ------->
|
||||
-- | +--------------------+ +-----+ +-----+ +-----+
|
||||
-- | |Finalization_Started|<------ |<------- |<------- |<---
|
||||
-- | +--------------------+ +-----+ +-----+ +-----+
|
||||
-- +--- Controller.Encl_Pool| | nul | | + | | + |
|
||||
-- | +--------------------+ +-----+ +--|--+ +--:--+
|
||||
-- | : : Dummy | ^ :
|
||||
-- | : : | | :
|
||||
-- | Root_Subpool V |
|
||||
-- | +-------------+ |
|
||||
-- +-------------------------------- Owner | |
|
||||
-- FM_Node FM_Node +-------------+ |
|
||||
-- +-----+ +-----+<-- Master.Objects| |
|
||||
-- <------ |<------ | +-------------+ |
|
||||
-- +-----+ +-----+ | Node -------+
|
||||
-- | ------>| -----> +-------------+
|
||||
-- +-----+ +-----+ : :
|
||||
-- |ctrl | Dummy : :
|
||||
-- | obj |
|
||||
-- +-----+
|
||||
--
|
||||
-- SP_Nodes are created on the heap. FM_Nodes and associated objects are
|
||||
-- created on the pool_with_subpools.
|
||||
|
||||
type Any_Storage_Pool_With_Subpools_Ptr
|
||||
is access all Root_Storage_Pool_With_Subpools'Class;
|
||||
for Any_Storage_Pool_With_Subpools_Ptr'Storage_Size use 0;
|
||||
|
||||
-- A pool controller is a special controlled object which ensures the
|
||||
-- proper initialization and finalization of the enclosing pool.
|
||||
|
||||
type Pool_Controller (Enclosing_Pool : Any_Storage_Pool_With_Subpools_Ptr)
|
||||
is new Ada.Finalization.Limited_Controlled with null record;
|
||||
|
||||
-- Subpool list types. Each pool_with_subpools contains a list of subpools.
|
||||
-- This is an indirect doubly linked list since subpools are not supposed
|
||||
-- to be allocatable by language design.
|
||||
|
||||
type SP_Node;
|
||||
type SP_Node_Ptr is access all SP_Node;
|
||||
@ -180,19 +178,26 @@ private
|
||||
Subpool : Subpool_Handle := null;
|
||||
end record;
|
||||
|
||||
-- Root_Storage_Pool_With_Subpools internal structure
|
||||
-- Root_Storage_Pool_With_Subpools internal structure. The type uses a
|
||||
-- special controller to perform initialization and finalization actions
|
||||
-- on itself. This is necessary because the end user of this package may
|
||||
-- decide to override Initialize and Finalize, thus disabling the desired
|
||||
-- behavior.
|
||||
|
||||
-- Pool_With_Subpools SP_Node SP_Node SP_Node
|
||||
-- +-->+--------------------+ +-----+ +-----+ +-----+
|
||||
-- | | Subpools -------->| ------->| ------->| ------->
|
||||
-- | +--------------------+ +-----+ +-----+ +-----+
|
||||
-- | |Finalization_Started| : : : : : :
|
||||
-- | +--------------------+
|
||||
-- +--- Controller.Encl_Pool|
|
||||
-- +--------------------+
|
||||
-- : End-user :
|
||||
-- : components :
|
||||
|
||||
type Root_Storage_Pool_With_Subpools is abstract
|
||||
new Root_Storage_Pool with
|
||||
record
|
||||
Initialized : Boolean := False;
|
||||
pragma Atomic (Initialized);
|
||||
-- Even though this type is derived from Limited_Controlled, overriding
|
||||
-- Initialize would have no effect since the type is abstract. Routine
|
||||
-- Set_Pool_Of_Subpool is tasked with the initialization of a pool with
|
||||
-- subpools because it has to be called at some point. This flag is used
|
||||
-- to prevent the resetting of the subpool chain.
|
||||
|
||||
Subpools : aliased SP_Node;
|
||||
-- A doubly linked list of subpools
|
||||
|
||||
@ -201,22 +206,47 @@ private
|
||||
-- A flag which prevents the creation of new subpools while the master
|
||||
-- pool is being finalized. The flag needs to be atomic because it is
|
||||
-- accessed without Lock_Task / Unlock_Task.
|
||||
end record;
|
||||
|
||||
type Any_Storage_Pool_With_Subpools_Ptr
|
||||
is access all Root_Storage_Pool_With_Subpools'Class;
|
||||
for Any_Storage_Pool_With_Subpools_Ptr'Storage_Size use 0;
|
||||
Controller : Pool_Controller
|
||||
(Root_Storage_Pool_With_Subpools'Unchecked_Access);
|
||||
-- A component which ensures that the enclosing pool is initialized and
|
||||
-- finalized at the appropriate places.
|
||||
end record;
|
||||
|
||||
-- A subpool is an abstraction layer which sits on top of a pool. It
|
||||
-- contains links to all controlled objects allocated on a particular
|
||||
-- subpool.
|
||||
|
||||
-- Pool_With_Subpools SP_Node SP_Node SP_Node
|
||||
-- +-->+----------------+ +-----+ +-----+ +-----+
|
||||
-- | | Subpools ------>| ------->| ------->| ------->
|
||||
-- | +----------------+ +-----+ +-----+ +-----+
|
||||
-- | : :<------ |<------- |<------- |
|
||||
-- | : : +-----+ +-----+ +-----+
|
||||
-- | |null | | + | | + |
|
||||
-- | +-----+ +--|--+ +--:--+
|
||||
-- | | ^ :
|
||||
-- | Root_Subpool V |
|
||||
-- | +-------------+ |
|
||||
-- +---------------------------- Owner | |
|
||||
-- +-------------+ |
|
||||
-- .......... Master | |
|
||||
-- +-------------+ |
|
||||
-- | Node -------+
|
||||
-- +-------------+
|
||||
-- : End-user :
|
||||
-- : components :
|
||||
|
||||
type Root_Subpool is abstract tagged limited record
|
||||
Owner : Any_Storage_Pool_With_Subpools_Ptr := null;
|
||||
-- A reference to the master pool_with_subpools
|
||||
|
||||
Master : aliased System.Finalization_Masters.Finalization_Master;
|
||||
-- A collection of controlled objects
|
||||
|
||||
Node : SP_Node_Ptr := null;
|
||||
-- A link to the doubly linked list node which contains the subpool.
|
||||
-- This back pointer is used in subpool deallocation.
|
||||
end record;
|
||||
|
||||
-- ??? Once Storage_Pools.Allocate_Any is removed, this should be renamed
|
||||
@ -224,32 +254,86 @@ private
|
||||
|
||||
procedure Allocate_Any_Controlled
|
||||
(Pool : in out Root_Storage_Pool'Class;
|
||||
Context_Subpool : Subpool_Handle := null;
|
||||
Context_Master : Finalization_Masters.Finalization_Master_Ptr := null;
|
||||
Fin_Address : Finalization_Masters.Finalize_Address_Ptr := null;
|
||||
Context_Subpool : Subpool_Handle;
|
||||
Context_Master : Finalization_Masters.Finalization_Master_Ptr;
|
||||
Fin_Address : Finalization_Masters.Finalize_Address_Ptr;
|
||||
Addr : out System.Address;
|
||||
Storage_Size : System.Storage_Elements.Storage_Count;
|
||||
Alignment : System.Storage_Elements.Storage_Count;
|
||||
Is_Controlled : Boolean := True);
|
||||
Is_Controlled : Boolean;
|
||||
On_Subpool : Boolean);
|
||||
-- Compiler interface. This version of Allocate handles all possible cases,
|
||||
-- either on a pool or a pool_with_subpools.
|
||||
-- either on a pool or a pool_with_subpools, regardless of the controlled
|
||||
-- status of the allocated object. Parameter usage:
|
||||
--
|
||||
-- * Pool - The pool associated with the access type. Pool can be any
|
||||
-- derivation from Root_Storage_Pool, including a pool_with_subpools.
|
||||
--
|
||||
-- * Context_Subpool - The subpool handle name of an allocator. If no
|
||||
-- subpool handle is present at the point of allocation, the actual
|
||||
-- would be null.
|
||||
--
|
||||
-- * Context_Master - The finalization master associated with the access
|
||||
-- type. If the access type's designated type is not controlled, the
|
||||
-- actual would be null.
|
||||
--
|
||||
-- * Fin_Address - TSS routine Finalize_Address of the designated type.
|
||||
-- If the designated type is not controlled, the actual would be null.
|
||||
--
|
||||
-- * Addr - The address of the allocated object.
|
||||
--
|
||||
-- * Storage_Size - The size of the allocated object.
|
||||
--
|
||||
-- * Alignment - The alignment of the allocated object.
|
||||
--
|
||||
-- * Is_Controlled - A flag which determines whether the allocated object
|
||||
-- is controlled. When set to True, the machinery generates additional
|
||||
-- data.
|
||||
--
|
||||
-- * On_Subpool - A flag which determines whether the a subpool handle
|
||||
-- name is present at the point of allocation. This is used for error
|
||||
-- diagnostics.
|
||||
|
||||
procedure Deallocate_Any_Controlled
|
||||
(Pool : in out Root_Storage_Pool'Class;
|
||||
Addr : System.Address;
|
||||
Storage_Size : System.Storage_Elements.Storage_Count;
|
||||
Alignment : System.Storage_Elements.Storage_Count;
|
||||
Is_Controlled : Boolean := True);
|
||||
Is_Controlled : Boolean);
|
||||
-- Compiler interface. This version of Deallocate handles all possible
|
||||
-- cases, either from a pool or a pool_with_subpools.
|
||||
-- cases, either from a pool or a pool_with_subpools, regardless of the
|
||||
-- controlled status of the deallocated object. Parameter usage:
|
||||
--
|
||||
-- * Pool - The pool associated with the access type. Pool can be any
|
||||
-- derivation from Root_Storage_Pool, including a pool_with_subpools.
|
||||
--
|
||||
-- * Addr - The address of the allocated object.
|
||||
--
|
||||
-- * Storage_Size - The size of the allocated object.
|
||||
--
|
||||
-- * Alignment - The alignment of the allocated object.
|
||||
--
|
||||
-- * Is_Controlled - A flag which determines whether the allocated object
|
||||
-- is controlled. When set to True, the machinery generates additional
|
||||
-- data.
|
||||
|
||||
overriding procedure Finalize
|
||||
(Pool : in out Root_Storage_Pool_With_Subpools);
|
||||
overriding procedure Finalize (Controller : in out Pool_Controller);
|
||||
-- Buffer routine, calls Finalize_Pool
|
||||
|
||||
procedure Finalize_Pool (Pool : in out Root_Storage_Pool_With_Subpools);
|
||||
-- Iterate over all subpools of Pool, detach them one by one and finalize
|
||||
-- their masters. This action first detaches a controlled object from a
|
||||
-- particular master, then invokes its Finalize_Address primitive.
|
||||
|
||||
procedure Finalize_Subpool (Subpool : not null Subpool_Handle);
|
||||
-- Finalize the master of a subpool
|
||||
-- Finalize all controlled objects chained on Subpool's master. Remove the
|
||||
-- subpool from its owner's list. Deallocate the associated doubly linked
|
||||
-- list node.
|
||||
|
||||
overriding procedure Initialize (Controller : in out Pool_Controller);
|
||||
-- Buffer routine, calls Initialize_Pool
|
||||
|
||||
procedure Initialize_Pool (Pool : in out Root_Storage_Pool_With_Subpools);
|
||||
-- Setup the doubly linked list of subpools
|
||||
|
||||
end System.Storage_Pools.Subpools;
|
||||
|
@ -1309,6 +1309,10 @@ package body Sem_Aggr is
|
||||
-- for discrete choices such as "L .. H => Expr" or the OTHERS choice).
|
||||
-- In this event we do not resolve Expr unless expansion is disabled.
|
||||
-- To know why, see the DELAYED COMPONENT RESOLUTION note above.
|
||||
--
|
||||
-- NOTE: In the case of "... => <>", we pass the in the
|
||||
-- N_Component_Association node as Expr, since there is no Expression in
|
||||
-- that case, and we need a Sloc for the error message.
|
||||
|
||||
---------
|
||||
-- Add --
|
||||
@ -1635,6 +1639,13 @@ package body Sem_Aggr is
|
||||
end if;
|
||||
end if;
|
||||
|
||||
-- If it's "... => <>", nothing to resolve
|
||||
|
||||
if Nkind (Expr) = N_Component_Association then
|
||||
pragma Assert (Box_Present (Expr));
|
||||
return Success;
|
||||
end if;
|
||||
|
||||
-- Ada 2005 (AI-231): Propagate the type to the nested aggregate.
|
||||
-- Required to check the null-exclusion attribute (if present).
|
||||
-- This value may be overridden later on.
|
||||
@ -1644,19 +1655,29 @@ package body Sem_Aggr is
|
||||
Resolution_OK := Resolve_Array_Aggregate
|
||||
(Expr, Nxt_Ind, Nxt_Ind_Constr, Component_Typ, Others_Allowed);
|
||||
|
||||
-- Do not resolve the expressions of discrete or others choices
|
||||
-- unless the expression covers a single component, or the expander
|
||||
-- is inactive.
|
||||
else
|
||||
|
||||
elsif Single_Elmt
|
||||
or else not Expander_Active
|
||||
or else In_Spec_Expression
|
||||
then
|
||||
Analyze_And_Resolve (Expr, Component_Typ);
|
||||
Check_Expr_OK_In_Limited_Aggregate (Expr);
|
||||
Check_Non_Static_Context (Expr);
|
||||
Aggregate_Constraint_Checks (Expr, Component_Typ);
|
||||
Check_Unset_Reference (Expr);
|
||||
-- If it's "... => <>", nothing to resolve
|
||||
|
||||
if Nkind (Expr) = N_Component_Association then
|
||||
pragma Assert (Box_Present (Expr));
|
||||
return Success;
|
||||
end if;
|
||||
|
||||
-- Do not resolve the expressions of discrete or others choices
|
||||
-- unless the expression covers a single component, or the
|
||||
-- expander is inactive.
|
||||
|
||||
if Single_Elmt
|
||||
or else not Expander_Active
|
||||
or else In_Spec_Expression
|
||||
then
|
||||
Analyze_And_Resolve (Expr, Component_Typ);
|
||||
Check_Expr_OK_In_Limited_Aggregate (Expr);
|
||||
Check_Non_Static_Context (Expr);
|
||||
Aggregate_Constraint_Checks (Expr, Component_Typ);
|
||||
Check_Unset_Reference (Expr);
|
||||
end if;
|
||||
end if;
|
||||
|
||||
if Raises_Constraint_Error (Expr)
|
||||
@ -1988,9 +2009,15 @@ package body Sem_Aggr is
|
||||
|
||||
-- Ada 2005 (AI-287): In case of default initialization of a
|
||||
-- component the expander will generate calls to the
|
||||
-- corresponding initialization subprogram.
|
||||
-- corresponding initialization subprogram. We need to call
|
||||
-- Resolve_Aggr_Expr to check the rules about
|
||||
-- dimensionality.
|
||||
|
||||
null;
|
||||
if not Resolve_Aggr_Expr (Assoc,
|
||||
Single_Elmt => Single_Choice)
|
||||
then
|
||||
return Failure;
|
||||
end if;
|
||||
|
||||
elsif not Resolve_Aggr_Expr (Expression (Assoc),
|
||||
Single_Elmt => Single_Choice)
|
||||
@ -2321,9 +2348,13 @@ package body Sem_Aggr is
|
||||
|
||||
-- Ada 2005 (AI-287): In case of default initialization of a
|
||||
-- component the expander will generate calls to the
|
||||
-- corresponding initialization subprogram.
|
||||
-- corresponding initialization subprogram. We need to call
|
||||
-- Resolve_Aggr_Expr to check the rules about
|
||||
-- dimensionality.
|
||||
|
||||
null;
|
||||
if not Resolve_Aggr_Expr (Assoc, Single_Elmt => False) then
|
||||
return Failure;
|
||||
end if;
|
||||
|
||||
elsif not Resolve_Aggr_Expr (Expression (Assoc),
|
||||
Single_Elmt => False)
|
||||
|
@ -1471,6 +1471,7 @@ package body Sem_Ch13 is
|
||||
|
||||
else
|
||||
case A_Id is
|
||||
|
||||
-- For Pre/Post cases, insert immediately after the
|
||||
-- entity declaration, since that is the required pragma
|
||||
-- placement.
|
||||
|
@ -2348,7 +2348,7 @@ package body Sem_Ch6 is
|
||||
-- the proper back-annotations.
|
||||
|
||||
if not Is_Frozen (Spec_Id)
|
||||
and then (Expander_Active or ASIS_Mode)
|
||||
and then (Expander_Active or else ASIS_Mode)
|
||||
then
|
||||
-- Force the generation of its freezing node to ensure proper
|
||||
-- management of access types in the backend.
|
||||
@ -6081,14 +6081,13 @@ package body Sem_Ch6 is
|
||||
end if;
|
||||
|
||||
-- In the case of functions whose result type needs finalization,
|
||||
-- add an extra formal of type Ada.Finalization.Heap_Management.
|
||||
-- Finalization_Collection_Ptr.
|
||||
-- add an extra formal which represents the finalization master.
|
||||
|
||||
if Needs_BIP_Collection (E) then
|
||||
if Needs_BIP_Finalization_Master (E) then
|
||||
Discard :=
|
||||
Add_Extra_Formal
|
||||
(E, RTE (RE_Finalization_Collection_Ptr),
|
||||
E, BIP_Formal_Suffix (BIP_Collection));
|
||||
(E, RTE (RE_Finalization_Master_Ptr),
|
||||
E, BIP_Formal_Suffix (BIP_Finalization_Master));
|
||||
end if;
|
||||
|
||||
-- If the result type contains tasks, we have two extra formals:
|
||||
|
Loading…
Reference in New Issue
Block a user