diff options
author | charlet <charlet@138bc75d-0d04-0410-961f-82ee72b054a4> | 2011-08-29 09:52:57 +0000 |
---|---|---|
committer | charlet <charlet@138bc75d-0d04-0410-961f-82ee72b054a4> | 2011-08-29 09:52:57 +0000 |
commit | 57acff55fe858d74d732dbe8c9e4829ff4415aa3 (patch) | |
tree | f70a40b65e9047bcf6e86a203d73f616a8c976dd /gcc/ada/exp_util.adb | |
parent | 20486e0be73a3de2b7afbf0e1309a928f166c893 (diff) | |
download | gcc-57acff55fe858d74d732dbe8c9e4829ff4415aa3.tar.gz |
2011-08-29 Hristian Kirtchev <kirtchev@adacore.com>
* a-fihema.ads, a-fihema.adb: Unit removed.
* a-undesu.ads, a-undesu.adb: New unit implementing
Ada.Unchecked_Deallocate_Subpool.
* einfo.adb: Remove Associated_Collection from the node usage.
Add Finalization_Master to the node usage.
(Associated_Collection): Removed.
(Finalization_Master): New routine.
(Set_Associated_Collection): Removed.
(Set_Finalization_Master): New routine.
(Write_Field23_Name): Remove Associated_Collection from the output. Add
Finalization_Master to the output.
* einfo.ads: Remove attribute Associated_Collection and its uses in
entities.
Add new attribute Finalization_Master along with its uses in entitites.
(Associated_Collection): Removed along with its pragma import.
(Finalization_Master): New routine along with a pragma import.
(Set_Associated_Collection): Removed along with its pragma import.
(Set_Finalization_Master): New routine along with a pragma import.
* exp_ch3.adb (Expand_Freeze_Array_Type): Replace call to
Build_Finalization_Collection with Build_Finalization_Master.
(Expand_Freeze_Record_Type): Move the generation of Finalize_Address
before the bodies of the predefined routines. Add comment explaining
this. Replace call to Build_Finalization_Collection with
Build_Finalization_Master.
(Freeze_Type): Replace call to Build_Finalization_Collection with
Build_Finalization_Master.
(Make_Finalize_Address_Body): Comment reformatting.
(Make_Predefined_Primitive_Specs): Code reformatting.
(Stream_Operation_OK): Update comment mentioning finalization
collections. Replace RE_Finalization_Collection with
RE_Finalization_Master.
* exp_ch4.adb (Complete_Controlled_Allocation): Replace call to
Associated_Collection with Finalization_Master. Replace call to
Build_Finalization_Collection with Build_Finalization_Master.
(Expand_Allocator_Expression): Replace call to Associated_Collection
with Finalization_Master. Replace call to Set_Associated_Collection with
Set_Finalization_Master. Remove the generation of
Set_Finalize_Address_Ptr.
(Expand_N_Allocator): Replace call to Associated_Collection with
Finalization_Master. Remove the generation of Set_Finalize_Address_Ptr.
* exp_ch6.adb (Add_Collection_Actual_To_Build_In_Place_Call): Renamed to
Add_Finalization_Master_Actual_To_Build_In_Place_Call. Update the
comment on usage. Replace call to Needs_BIP_Collection with
Needs_BIP_Finalization_Master Remplace BIP_Collection with
BIP_Finalization_Master. Update all comments which mention finalization
collections. Replace Associated_Collection with
Finalization_Master. Replace Build_Finalization_Collection with
Build_Finalization_Master.
(BIP_Formal_Suffix): Update BIP_Collection's case.
(Build_Heap_Allocator): Update the related comment. Rename local
variable Collect to Fin_Mas_Id and update its occurrences. Update
comments which mention finalization collections. Replace
Set_Associated_Collection with Set_Finalization_Master.
(Expand_Call): Update the code which detects a special piece of library
code for .NET/JVM.
(Make_Build_In_Place_Call_In_Allocator): Replace the call to
Add_Collection_Actual_To_Build_In_Place_Call with
Add_Finalization_Master_Actual_To_Build_In_Place_Call. Remove the code
which generates a call to Make_Set_Finalize_Address_Ptr_Call.
(Make_Build_In_Place_Call_In_Anonymous_Context): Replace call to
Add_Collection_Actual_To_Build_In_Place_Call with
Add_Finalization_Master_Actual_To_Build_In_Place_Call.
(Make_Build_In_Place_Call_In_Assignment): Replace call to
Add_Collection_Actual_To_Build_In_Place_Call with
Add_Finalization_Master_Actual_To_Build_In_Place_Call.
(Needs_BIP_Collection): Renamed to Needs_BIP_Finalization_Master.
* exp_ch6.ads: Rename BIP_Collection to BIP_Finalization_Master.
(Needs_BIP_Collection): Renamed to Needs_BIP_Finalization_Master.
* exp_ch7.adb (Build_BIP_Cleanup_Stmts): Update comment on usage.
Rename local variable Collect to Fin_Mas_Id and update its occurrences.
Replace call to Set_Associated_Collection with Set_Finalization_Master.
(Build_Finalization_Collection): Renamed to Build_Finalization_Master.
Replace the call to Associated_Collection with Finalization_Master.
Rename local variable Coll_Id to Fin_Mas_Id and update its occurrences.
Update the way finalization master names are generated. Update the
retrieval of the correct access type which will carry the pool and
master attributes.
(Make_Final_Call): Reimplement the way [Deep_]Finalize is retrieved.
(Make_Finalize_Address_Body): Abstract types do not need
Finalize_Address. Code reformatting.
(Make_Finalize_Address_Stmts): Update comment on usage.
(Make_Set_Finalize_Address_Ptr_Call): Removed.
(Process_Declarations): Update comments.
* exp_ch7.ads (Build_Finalization_Collection): Renamed to
Build_Finalization_Master. Update associated comment.
(Make_Set_Finalize_Address_Ptr_Call): Removed.
* exp_ch13.adb: Update comments which mention finalization collections.
(Expand_N_Free_Statement): Replace the call to Associated_Collection
with Finalization_Master.
* exp_util.adb (Build_Allocate_Deallocate_Proc): Reimplemented to
create calls to routines Allocate_Any_Controlled and
Deallocate_Any_Controlled.
(Find_Finalize_Address): New routine.
(Is_Allocate_Deallocate_Proc): Update the RTE entities used in the
comparison.
(Requires_Cleanup_Actions): Update the comment on freeze node
inspection.
* exp_util.ads: Remove comment on generated code for
Build_Allocate_Deallocate_Proc. The code is now quite complex and it
is better to simply look in the body.
* freeze.adb (Freeze_All): Update the comment of finalization
collections. Replace the call to Associated_Collection with
Finalization_Master. Replace the call to Build_Finalization_Collection
with Build_Finalization_Master.
* impunit.adb: Add a-undesu and s-stposu to the list of units.
* Makefile.rtl: Add files a-undesu, s-finmas and s-stposu. Remove file
a-fihema.
* rtsfind.adb (Get_Unit_Name): Remove the processing for children of
Ada.Finalization. Add processing for children of System.Storage_Pools.
* rtsfind.ads: Remove the naming of second level children of
Ada.Finalization.
Remove Ada_Finalization_Heap_Management from the list of units.
Remove subtype Ada_Finalization_Child.
Remove the following subprogram entities:
RE_Allocate
RE_Deallocate
RE_Finalization_Collection
RE_Finalization_Collection_Ptr
RE_Set_Finalize_Address_Ptr
Add the naming of second level children of System.Storage_Pools.
Add System_Finalization_Masters and System_Storage_Pools_Subpools to
the list of units.
Add subtype System_Storage_Pools_Child.
Add the following subprogram entities to System.Finalization_Masters:
RE_Finalization_Master
RE_Finalization_Master_Ptr
Add the following subprogram entities to System.Storage_Pools.Subpools:
RE_Allocate_Any_Controlled
RE_Deallocate_Any_Controlled
RE_Root_Storage_Pool_With_Subpools
RE_Root_Subpool
RE_Subpool_Handle
Move the following subprogram entities from
Ada.Finalization.Heap_Management to System.Finalization_Masters:
RE_Add_Offset_To_Address
RE_Attach
RE_Base_Pool
RE_Detach
* sem_ch3.adb (Access_Type_Declaration): Replace the call to
Set_Associated_Collection with Set_Finalization_Master.
* sem_ch6.adb (Create_Extra_Formals): Update the way extra formal
BIP_Finalization_Master is created.
* s-finmas.adb: New unit System.Finalization_Masters.
* s-finmas.ads: New unit System.Finalization_Masters.
* s-stopoo.ads, s-stopoo.adb: Minor code reformatting.
* s-stposu.ads, s-stposu.adb: New unit implementing
System.Storage_Pools.Subpools.
2011-08-29 Bob Duff <duff@adacore.com>
* tbuild.adb: Add assertion.
git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@178183 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc/ada/exp_util.adb')
-rw-r--r-- | gcc/ada/exp_util.adb | 329 |
1 files changed, 216 insertions, 113 deletions
diff --git a/gcc/ada/exp_util.adb b/gcc/ada/exp_util.adb index 64a6b6d3ffb..a23a923f418 100644 --- a/gcc/ada/exp_util.adb +++ b/gcc/ada/exp_util.adb @@ -332,6 +332,9 @@ package body Exp_Util is Desig_Typ : constant Entity_Id := Available_View (Designated_Type (Ptr_Typ)); + function Find_Finalize_Address (Typ : Entity_Id) return Entity_Id; + -- Locate TSS primitive Finalize_Address in type Typ + function Find_Object (E : Node_Id) return Node_Id; -- Given an arbitrary expression of an allocator, try to find an object -- reference in it, otherwise return the original expression. @@ -340,6 +343,57 @@ package body Exp_Util is -- Determine whether subprogram Subp denotes a custom allocate or -- deallocate. + --------------------------- + -- Find_Finalize_Address -- + --------------------------- + + function Find_Finalize_Address (Typ : Entity_Id) return Entity_Id is + Utyp : Entity_Id := Typ; + + begin + if Is_Private_Type (Utyp) + and then Present (Full_View (Utyp)) + then + Utyp := Full_View (Utyp); + end if; + + if Is_Concurrent_Type (Utyp) then + Utyp := Corresponding_Record_Type (Utyp); + end if; + + Utyp := Underlying_Type (Base_Type (Utyp)); + + -- Deal with non-tagged derivation of private views. If the parent is + -- now known to be protected, the finalization routine is the one + -- defined on the corresponding record of the ancestor (corresponding + -- records do not automatically inherit operations, but maybe they + -- should???) + + if Is_Untagged_Derivation (Typ) then + if Is_Protected_Type (Typ) then + Utyp := Corresponding_Record_Type (Root_Type (Base_Type (Typ))); + else + Utyp := Underlying_Type (Root_Type (Base_Type (Typ))); + + if Is_Protected_Type (Utyp) then + Utyp := Corresponding_Record_Type (Utyp); + end if; + end if; + end if; + + -- If the underlying_type is a subtype, we are dealing with the + -- completion of a private type. We need to access the base type and + -- generate a conversion to it. + + if Utyp /= Base_Type (Utyp) then + pragma Assert (Is_Private_Type (Typ)); + + Utyp := Base_Type (Utyp); + end if; + + return TSS (Utyp, TSS_Finalize_Address); + end Find_Finalize_Address; + ----------------- -- Find_Object -- ----------------- @@ -375,8 +429,7 @@ package body Exp_Util is function Is_Allocate_Deallocate_Proc (Subp : Entity_Id) return Boolean is begin -- Look for a subprogram body with only one statement which is a - -- call to one of the Allocate / Deallocate routines in package - -- Ada.Finalization.Heap_Management. + -- call to Allocate_Any_Controlled / Deallocate_Any_Controlled. if Ekind (Subp) = E_Procedure and then Nkind (Parent (Parent (Subp))) = N_Subprogram_Body @@ -394,8 +447,8 @@ package body Exp_Util is Proc := Entity (Name (First (Statements (HSS)))); return - Is_RTE (Proc, RE_Allocate) - or else Is_RTE (Proc, RE_Deallocate); + Is_RTE (Proc, RE_Allocate_Any_Controlled) + or else Is_RTE (Proc, RE_Deallocate_Any_Controlled); end if; end; end if; @@ -430,137 +483,191 @@ package body Exp_Util is Size_Id : constant Entity_Id := Make_Temporary (Loc, 'S'); Actuals : List_Id; - Collect_Act : Node_Id; - Collect_Id : Entity_Id; - Collect_Typ : Entity_Id; + 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; begin - -- When dealing with an access subtype, use the collection of the - -- base type. + -- 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 - Collect_Typ := Base_Type (Ptr_Typ); + Fin_Mas_Typ := Base_Type (Ptr_Typ); else - Collect_Typ := Ptr_Typ; + Fin_Mas_Typ := Ptr_Typ; end if; - Collect_Id := Associated_Collection (Collect_Typ); - Collect_Act := New_Reference_To (Collect_Id, Loc); + Actuals := New_List; - -- Handle the case where the collection is actually a pointer to a - -- collection. This case arises in build-in-place functions. + -- Step 1: Construct all the actuals for the call to library routine + -- Allocate_Any_Controlled / Deallocate_Any_Controlled. - if Is_Access_Type (Etype (Collect_Id)) then - Collect_Act := - Make_Explicit_Dereference (Loc, - Prefix => Collect_Act); - end if; + -- a) Storage pool - -- Create the actuals for the call to Allocate / Deallocate + Append_To (Actuals, + New_Reference_To (Associated_Storage_Pool (Fin_Mas_Typ), Loc)); - Actuals := New_List ( - Collect_Act, - New_Reference_To (Addr_Id, Loc), - New_Reference_To (Size_Id, Loc), - New_Reference_To (Alig_Id, Loc)); + if Is_Allocate then - -- Generate a run-time check to determine whether a class-wide object - -- is truly controlled. + -- b) Subpool - if Is_Class_Wide_Type (Desig_Typ) - or else Is_Generic_Actual_Type (Desig_Typ) - then - declare - Flag_Id : constant Entity_Id := Make_Temporary (Loc, 'F'); - Flag_Expr : Node_Id; - Param : Node_Id; - Temp : Node_Id; + if Present (Subpool_Handle_Name (Expr)) then + Append_To (Actuals, + New_Reference_To (Entity (Subpool_Handle_Name (Expr)), Loc)); + else + Append_To (Actuals, Make_Null (Loc)); + end if; - begin - if Is_Allocate then - Temp := Find_Object (Expression (Expr)); + -- c) Finalization master + + if Needs_Finalization (Desig_Typ) then + Fin_Mas_Id := Finalization_Master (Fin_Mas_Typ); + Fin_Mas_Act := New_Reference_To (Fin_Mas_Id, Loc); + + -- Handle the case where the master is actually a pointer to a + -- master. This case arises in build-in-place functions. + + if Is_Access_Type (Etype (Fin_Mas_Id)) then + Append_To (Actuals, Fin_Mas_Act); else - Temp := Expr; + Append_To (Actuals, + Make_Attribute_Reference (Loc, + Prefix => Fin_Mas_Act, + Attribute_Name => Name_Unrestricted_Access)); end if; + else + Append_To (Actuals, Make_Null (Loc)); + end if; - -- Processing for generic actuals + -- d) Finalize_Address - if Is_Generic_Actual_Type (Desig_Typ) then - Flag_Expr := - New_Reference_To (Boolean_Literals - (Needs_Finalization (Base_Type (Desig_Typ))), Loc); + Fin_Addr_Id := Find_Finalize_Address (Desig_Typ); - -- Processing for subtype indications + if Present (Fin_Addr_Id) then + Append_To (Actuals, + Make_Attribute_Reference (Loc, + Prefix => New_Reference_To (Fin_Addr_Id, Loc), + Attribute_Name => Name_Unrestricted_Access)); + else + Append_To (Actuals, Make_Null (Loc)); + end if; + end if; - elsif Nkind (Temp) in N_Has_Entity - and then Is_Type (Entity (Temp)) - then - Flag_Expr := - New_Reference_To (Boolean_Literals - (Needs_Finalization (Entity (Temp))), Loc); + -- e) Address + -- f) Storage_Size + -- g) Alignment - -- Generate a runtime check to test the controlled state of an - -- object for the purposes of allocation / deallocation. + Append_To (Actuals, New_Reference_To (Addr_Id, Loc)); + Append_To (Actuals, New_Reference_To (Size_Id, Loc)); + Append_To (Actuals, New_Reference_To (Alig_Id, Loc)); - else - -- The following case arises when allocating through an - -- interface class-wide type, generate: - -- - -- Temp.all + -- h) Is_Controlled - if Is_RTE (Etype (Temp), RE_Tag_Ptr) then - Param := - Make_Explicit_Dereference (Loc, - Prefix => - Relocate_Node (Temp)); + -- Generate a run-time check to determine whether a class-wide object + -- is truly controlled. - -- Generate: - -- Temp'Tag + if Needs_Finalization (Desig_Typ) then + if Is_Class_Wide_Type (Desig_Typ) + or else Is_Generic_Actual_Type (Desig_Typ) + then + declare + Flag_Id : constant Entity_Id := Make_Temporary (Loc, 'F'); + Flag_Expr : Node_Id; + Param : Node_Id; + Temp : Node_Id; + begin + if Is_Allocate then + Temp := Find_Object (Expression (Expr)); else - Param := - Make_Attribute_Reference (Loc, - Prefix => - Relocate_Node (Temp), - Attribute_Name => Name_Tag); + Temp := Expr; end if; - -- Generate: - -- Needs_Finalization (Param) + -- Processing for generic actuals - Flag_Expr := - Make_Function_Call (Loc, - Name => - New_Reference_To (RTE (RE_Needs_Finalization), Loc), - Parameter_Associations => New_List (Param)); - end if; + if Is_Generic_Actual_Type (Desig_Typ) then + Flag_Expr := + New_Reference_To (Boolean_Literals + (Needs_Finalization (Base_Type (Desig_Typ))), Loc); - -- Create the temporary which represents the finalization state - -- of the expression. Generate: - -- - -- F : constant Boolean := <Flag_Expr>; + -- Processing for subtype indications - Insert_Action (N, - Make_Object_Declaration (Loc, - Defining_Identifier => Flag_Id, - Constant_Present => True, - Object_Definition => - New_Reference_To (Standard_Boolean, Loc), - Expression => Flag_Expr)); + elsif Nkind (Temp) in N_Has_Entity + and then Is_Type (Entity (Temp)) + then + Flag_Expr := + New_Reference_To (Boolean_Literals + (Needs_Finalization (Entity (Temp))), Loc); - -- The flag acts as the fifth actual + -- Generate a runtime check to test the controlled state of + -- an object for the purposes of allocation / deallocation. - Append_To (Actuals, New_Reference_To (Flag_Id, Loc)); - end; + else + -- The following case arises when allocating through an + -- interface class-wide type, generate: + -- + -- Temp.all + + if Is_RTE (Etype (Temp), RE_Tag_Ptr) then + Param := + Make_Explicit_Dereference (Loc, + Prefix => + Relocate_Node (Temp)); + + -- Generate: + -- Temp'Tag + + else + Param := + Make_Attribute_Reference (Loc, + Prefix => + Relocate_Node (Temp), + Attribute_Name => Name_Tag); + end if; + + -- Generate: + -- Needs_Finalization (<Param>) + + Flag_Expr := + Make_Function_Call (Loc, + Name => + New_Reference_To (RTE (RE_Needs_Finalization), Loc), + Parameter_Associations => New_List (Param)); + end if; + + -- Create the temporary which represents the finalization + -- state of the expression. Generate: + -- + -- F : constant Boolean := <Flag_Expr>; + + Insert_Action (N, + Make_Object_Declaration (Loc, + Defining_Identifier => Flag_Id, + Constant_Present => True, + Object_Definition => + New_Reference_To (Standard_Boolean, Loc), + Expression => Flag_Expr)); + + -- The flag acts as the last actual + + Append_To (Actuals, New_Reference_To (Flag_Id, Loc)); + end; + end if; + else + Append_To (Actuals, New_Reference_To (Standard_False, Loc)); end if; + -- Step 2: Build a wrapper Allocate / Deallocate which internally + -- calls Allocate_Any_Controlled / Deallocate_Any_Controlled. + -- Select the proper routine to call if Is_Allocate then - Proc_To_Call := RTE (RE_Allocate); + Proc_To_Call := RTE (RE_Allocate_Any_Controlled); else - Proc_To_Call := RTE (RE_Deallocate); + Proc_To_Call := RTE (RE_Deallocate_Any_Controlled); end if; -- Create a custom Allocate / Deallocate routine which has identical @@ -611,10 +718,6 @@ package body Exp_Util is Handled_Statement_Sequence => Make_Handled_Sequence_Of_Statements (Loc, Statements => New_List ( - - -- Allocate / Deallocate - -- (<Ptr_Typ collection>, A, S, L[, F]); - Make_Procedure_Call_Statement (Loc, Name => New_Reference_To (Proc_To_Call, Loc), @@ -3752,7 +3855,7 @@ package body Exp_Util is and then Nkind (Rel_Node) /= N_Simple_Return_Statement -- Do not consider transient objects allocated on the heap since they - -- are attached to a finalization collection. + -- are attached to a finalization master. and then not Is_Allocated (Obj_Id) @@ -6431,16 +6534,16 @@ package body Exp_Util is return True; end if; - -- Inspect the freeze node of an access-to-controlled type and - -- look for a delayed finalization collection. This case arises - -- when the freeze actions are inserted at a later time than the - -- expansion of the context. Since Build_Finalizer is never called - -- on a single construct twice, the collection will be ultimately - -- left out and never finalized. This is also needed for freeze - -- actions of designated types themselves, since in some cases the - -- finalization collection is associated with a designated type's - -- freeze node rather than that of the access type (see handling - -- for freeze actions in Build_Finalization_Collection). + -- Inspect the freeze node of an access-to-controlled type and look + -- for a delayed finalization master. This case arises when the + -- freeze actions are inserted at a later time than the expansion of + -- the context. Since Build_Finalizer is never called on a single + -- construct twice, the master will be ultimately left out and never + -- finalized. This is also needed for freeze actions of designated + -- types themselves, since in some cases the finalization master is + -- associated with a designated type's freeze node rather than that + -- of the access type (see handling for freeze actions in + -- Build_Finalization_Master). elsif Nkind (Decl) = N_Freeze_Entity and then Present (Actions (Decl)) @@ -6451,9 +6554,9 @@ package body Exp_Util is and then not Is_Access_Subprogram_Type (Typ) and then Needs_Finalization (Available_View (Designated_Type (Typ)))) - or else - (Is_Type (Typ) - and then Needs_Finalization (Typ))) + or else + (Is_Type (Typ) + and then Needs_Finalization (Typ))) and then Requires_Cleanup_Actions (Actions (Decl), For_Package, Nested_Constructs) then |