summaryrefslogtreecommitdiff
path: root/gcc/ada/exp_util.adb
diff options
context:
space:
mode:
authorcharlet <charlet@138bc75d-0d04-0410-961f-82ee72b054a4>2011-08-29 09:52:57 +0000
committercharlet <charlet@138bc75d-0d04-0410-961f-82ee72b054a4>2011-08-29 09:52:57 +0000
commit57acff55fe858d74d732dbe8c9e4829ff4415aa3 (patch)
treef70a40b65e9047bcf6e86a203d73f616a8c976dd /gcc/ada/exp_util.adb
parent20486e0be73a3de2b7afbf0e1309a928f166c893 (diff)
downloadgcc-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.adb329
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