-- are writing into.
procedure Convert_Array_Aggr_In_Allocator
- (Decl : Node_Id;
+ (N : Node_Id;
Aggr : Node_Id;
Target : Node_Id);
-- If the aggregate appears within an allocator and can be expanded in
-------------------------------
procedure Convert_Aggr_In_Allocator
- (Alloc : Node_Id;
- Decl : Node_Id;
- Aggr : Node_Id)
+ (N : Node_Id;
+ Aggr : Node_Id;
+ Temp : Entity_Id)
is
Loc : constant Source_Ptr := Sloc (Aggr);
Typ : constant Entity_Id := Etype (Aggr);
- Temp : constant Entity_Id := Defining_Identifier (Decl);
Occ : constant Node_Id :=
Unchecked_Convert_To (Typ,
begin
if Is_Array_Type (Typ) then
- Convert_Array_Aggr_In_Allocator (Decl, Aggr, Occ);
+ Convert_Array_Aggr_In_Allocator (N, Aggr, Occ);
elsif Has_Default_Init_Comps (Aggr) then
declare
- L : constant List_Id := New_List;
- Init_Stmts : List_Id;
+ Init_Stmts : constant List_Id := Late_Expansion (Aggr, Typ, Occ);
begin
- Init_Stmts := Late_Expansion (Aggr, Typ, Occ);
-
if Has_Task (Typ) then
- Build_Task_Allocate_Block (L, Aggr, Init_Stmts);
- Insert_Actions (Alloc, L);
+ declare
+ Actions : constant List_Id := New_List;
+
+ begin
+ Build_Task_Allocate_Block (Actions, Aggr, Init_Stmts);
+ Insert_Actions (N, Actions);
+ end;
+
else
- Insert_Actions (Alloc, Init_Stmts);
+ Insert_Actions (N, Init_Stmts);
end if;
end;
else
- Insert_Actions (Alloc, Late_Expansion (Aggr, Typ, Occ));
+ Insert_Actions (N, Late_Expansion (Aggr, Typ, Occ));
end if;
end Convert_Aggr_In_Allocator;
-------------------------------------
procedure Convert_Array_Aggr_In_Allocator
- (Decl : Node_Id;
+ (N : Node_Id;
Aggr : Node_Id;
Target : Node_Id)
is
Scalar_Comp => Is_Scalar_Type (Ctyp));
end if;
- Insert_Actions_After (Decl, Aggr_Code);
+ Insert_Actions (N, Aggr_Code);
end Convert_Array_Aggr_In_Allocator;
------------------------
procedure Expand_N_Delta_Aggregate (N : Node_Id);
procedure Expand_N_Extension_Aggregate (N : Node_Id);
- function Is_Delayed_Aggregate (N : Node_Id) return Boolean;
- -- Returns True if N is an aggregate of some kind whose Expansion_Delayed
- -- flag is set (see sinfo for meaning of flag).
-
- procedure Convert_Aggr_In_Object_Decl (N : Node_Id);
- -- N is a N_Object_Declaration with an expression which must be an
- -- N_Aggregate or N_Extension_Aggregate with Expansion_Delayed.
- -- This procedure performs in-place aggregate assignment.
-
procedure Convert_Aggr_In_Allocator
- (Alloc : Node_Id;
- Decl : Node_Id;
- Aggr : Node_Id);
- -- Alloc is the allocator whose expression is the aggregate Aggr.
- -- Decl is an N_Object_Declaration created during allocator expansion.
- -- This procedure performs in-place aggregate assignment into the
- -- temporary declared in Decl, and the allocator becomes an access to
- -- that temporary.
+ (N : Node_Id;
+ Aggr : Node_Id;
+ Temp : Entity_Id);
+ -- N is an N_Allocator whose (ultimate) expression is the aggregate Aggr.
+ -- This procedure performs an in-place aggregate assignment into an object
+ -- allocated with the subtype of Aggr and designated by Temp, so that N
+ -- can be rewritten as a mere occurrence of Temp.
procedure Convert_Aggr_In_Assignment (N : Node_Id);
-- If the right-hand side of an assignment is an aggregate, expand the
-- the components, and the aggregate cannot be handled as a whole by the
-- backend.
+ procedure Convert_Aggr_In_Object_Decl (N : Node_Id);
+ -- N is an N_Object_Declaration with an expression which must be an
+ -- N_Aggregate or N_Extension_Aggregate with Expansion_Delayed.
+ -- This procedure performs in-place aggregate assignment.
+
+ function Is_Delayed_Aggregate (N : Node_Id) return Boolean;
+ -- Returns True if N is an aggregate of some kind whose Expansion_Delayed
+ -- flag is set (see sinfo for meaning of flag).
+
function Static_Array_Aggregate (N : Node_Id) return Boolean;
-- N is an array aggregate that may have a component association with
-- an others clause and a range. If bounds are static and the expressions
DesigT : constant Entity_Id := Designated_Type (PtrT);
Special_Return : constant Boolean := For_Special_Return_Object (N);
+ procedure Build_Aggregate_In_Place (Temp : Entity_Id; Typ : Entity_Id);
+ -- If Exp is an aggregate to build in place, build the declaration of
+ -- Temp with Typ and with expression an uninitialized allocator for
+ -- Etype (Exp), then perform an in-place aggregate assignment of Exp
+ -- into the allocated memory.
+
+ ------------------------------
+ -- Build_Aggregate_In_Place --
+ ------------------------------
+
+ procedure Build_Aggregate_In_Place (Temp : Entity_Id; Typ : Entity_Id) is
+ Temp_Decl : constant Node_Id :=
+ Make_Object_Declaration (Loc,
+ Defining_Identifier => Temp,
+ Object_Definition => New_Occurrence_Of (Typ, Loc),
+ Expression =>
+ Make_Allocator (Loc,
+ Expression => New_Occurrence_Of (Etype (Exp), Loc)));
+
+ begin
+ -- Prevent default initialization of the allocator
+
+ Set_No_Initialization (Expression (Temp_Decl));
+
+ -- Copy the Comes_From_Source flag onto the allocator since logically
+ -- this allocator is a replacement of the original allocator. This is
+ -- for proper handling of restriction No_Implicit_Heap_Allocations.
+
+ Preserve_Comes_From_Source (Expression (Temp_Decl), N);
+
+ -- Insert declaration, assignment and build the allocation procedure
+
+ Insert_Action (N, Temp_Decl);
+ Convert_Aggr_In_Allocator (N, Exp, Temp);
+ Build_Allocate_Deallocate_Proc (Temp_Decl);
+ end Build_Aggregate_In_Place;
+
+ -- Local variables
+
Adj_Call : Node_Id;
Aggr_In_Place : Boolean;
Node : Node_Id;
if not Is_Interface (DesigT) then
if Aggr_In_Place then
- Temp_Decl :=
- Make_Object_Declaration (Loc,
- Defining_Identifier => Temp,
- Object_Definition => New_Occurrence_Of (PtrT, Loc),
- Expression =>
- Make_Allocator (Loc,
- Expression =>
- New_Occurrence_Of (Etype (Exp), Loc)));
-
- -- Copy the Comes_From_Source flag for the allocator we just
- -- built, since logically this allocator is a replacement of
- -- the original allocator node. This is for proper handling of
- -- restriction No_Implicit_Heap_Allocations.
-
- Preserve_Comes_From_Source
- (Expression (Temp_Decl), N);
-
- Set_No_Initialization (Expression (Temp_Decl));
- Insert_Action (N, Temp_Decl);
-
- Build_Allocate_Deallocate_Proc (Temp_Decl, True);
- Convert_Aggr_In_Allocator (N, Temp_Decl, Exp);
+ Build_Aggregate_In_Place (Temp, PtrT);
else
Node := Relocate_Node (N);
Expression => Node);
Insert_Action (N, Temp_Decl);
- Build_Allocate_Deallocate_Proc (Temp_Decl, True);
+ Build_Allocate_Deallocate_Proc (Temp_Decl);
end if;
-- Ada 2005 (AI-251): Handle allocators whose designated type is an
-- Declare the object using the previous type declaration
if Aggr_In_Place then
- Temp_Decl :=
- Make_Object_Declaration (Loc,
- Defining_Identifier => Temp,
- Object_Definition => New_Occurrence_Of (Def_Id, Loc),
- Expression =>
- Make_Allocator (Loc,
- New_Occurrence_Of (Etype (Exp), Loc)));
-
- -- Copy the Comes_From_Source flag for the allocator we just
- -- built, since logically this allocator is a replacement of
- -- the original allocator node. This is for proper handling
- -- of restriction No_Implicit_Heap_Allocations.
-
- Set_Comes_From_Source
- (Expression (Temp_Decl), Comes_From_Source (N));
-
- Set_No_Initialization (Expression (Temp_Decl));
- Insert_Action (N, Temp_Decl);
-
- Build_Allocate_Deallocate_Proc (Temp_Decl, True);
- Convert_Aggr_In_Allocator (N, Temp_Decl, Exp);
+ Build_Aggregate_In_Place (Temp, Def_Id);
else
Node := Relocate_Node (N);
Expression => Node);
Insert_Action (N, Temp_Decl);
- Build_Allocate_Deallocate_Proc (Temp_Decl, True);
+ Build_Allocate_Deallocate_Proc (Temp_Decl);
end if;
-- Generate an additional object containing the address of the
or else (Modify_Tree_For_C and then Nkind (Exp) = N_Aggregate)
then
Temp := Make_Temporary (Loc, 'P', N);
- Temp_Decl :=
- Make_Object_Declaration (Loc,
- Defining_Identifier => Temp,
- Object_Definition => New_Occurrence_Of (PtrT, Loc),
- Expression =>
- Make_Allocator (Loc,
- Expression => New_Occurrence_Of (Etype (Exp), Loc)));
-
- -- Copy the Comes_From_Source flag for the allocator we just built,
- -- since logically this allocator is a replacement of the original
- -- allocator node. This is for proper handling of restriction
- -- No_Implicit_Heap_Allocations.
-
- Set_Comes_From_Source
- (Expression (Temp_Decl), Comes_From_Source (N));
-
- Set_No_Initialization (Expression (Temp_Decl));
- Insert_Action (N, Temp_Decl);
-
- Build_Allocate_Deallocate_Proc (Temp_Decl, True);
- Convert_Aggr_In_Allocator (N, Temp_Decl, Exp);
-
+ Build_Aggregate_In_Place (Temp, PtrT);
Rewrite (N, New_Occurrence_Of (Temp, Loc));
Analyze_And_Resolve (N, PtrT);
end if;
else
- Build_Allocate_Deallocate_Proc (N, True);
+ Build_Allocate_Deallocate_Proc (N);
-- For an access-to-unconstrained-packed-array type, build an
-- expression with a constrained subtype in order for the code
end if;
end To_Ityp;
- -- Local Declarations
+ -- Local variables
Opnd_Typ : Entity_Id;
Slice_Rng : Node_Id;
-- the context requires it.
elsif No_Initialization (N) then
- Build_Allocate_Deallocate_Proc (N, True);
+ Build_Allocate_Deallocate_Proc (N);
-- If the allocator is for a type which requires initialization, and
-- there is no initial value (i.e. operand is a subtype indication
Expression => Relocate_Node (N));
Insert_Action (N, Temp_Decl, Suppress => All_Checks);
- Build_Allocate_Deallocate_Proc (Temp_Decl, True);
+ Build_Allocate_Deallocate_Proc (Temp_Decl);
-- Generate:
-- Temp.all := ...
Expression => Relocate_Node (N));
Insert_Action (N, Temp_Decl, Suppress => All_Checks);
- Build_Allocate_Deallocate_Proc (Temp_Decl, True);
+ Build_Allocate_Deallocate_Proc (Temp_Decl);
-- If the designated type is a task type or contains tasks,
-- create a specific block to activate the created tasks.
-- No initialization required
else
- Build_Allocate_Deallocate_Proc (N, True);
+ Build_Allocate_Deallocate_Proc (N);
end if;
end if;
end if;
-- Build_Allocate_Deallocate_Proc --
------------------------------------
- procedure Build_Allocate_Deallocate_Proc
- (N : Node_Id;
- Is_Allocate : Boolean)
- is
+ procedure Build_Allocate_Deallocate_Proc (N : Node_Id) is
+ Is_Allocate : constant Boolean := Nkind (N) /= N_Free_Statement;
+
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.
-- Start of processing for Build_Allocate_Deallocate_Proc
begin
- -- Obtain the attributes of the allocation / deallocation
-
- if Nkind (N) = N_Free_Statement then
- Expr := Expression (N);
- Ptr_Typ := Base_Type (Etype (Expr));
- Proc_To_Call := Procedure_To_Call (N);
+ -- Obtain the attributes of the allocation
- else
+ if Is_Allocate then
if Nkind (N) = N_Object_Declaration then
Expr := Expression (N);
else
and then Nkind (Parent (Entity (Expr))) = N_Object_Declaration
and then Nkind (Expression (Parent (Entity (Expr)))) = N_Allocator
then
- Build_Allocate_Deallocate_Proc (Parent (Entity (Expr)), True);
+ Build_Allocate_Deallocate_Proc (Parent (Entity (Expr)));
return;
end if;
Ptr_Typ := Base_Type (Etype (Expr));
Proc_To_Call := Procedure_To_Call (Expr);
+
+ -- Obtain the attributes of the deallocation
+
+ else
+ Expr := Expression (N);
+ Ptr_Typ := Base_Type (Etype (Expr));
+ Proc_To_Call := Procedure_To_Call (N);
end if;
Pool_Id := Associated_Storage_Pool (Ptr_Typ);
Size_Id : constant Entity_Id := Make_Temporary (Loc, 'S');
Actuals : List_Id;
- Alloc_Nod : Node_Id := Empty;
Alloc_Expr : Node_Id := Empty;
Fin_Addr_Id : Entity_Id;
Fin_Coll_Act : Node_Id;
-- node for later processing and calculation of alignment.
if Is_Allocate then
-
- if Nkind (Expr) = N_Allocator then
- Alloc_Nod := Expr;
-
- -- When Expr is an object declaration we have to examine its
- -- expression.
-
- elsif Nkind (Expr) = N_Object_Declaration
- and then Nkind (Expression (Expr)) = N_Allocator
- then
- Alloc_Nod := Expression (Expr);
-
- -- Otherwise, we raise an error because we should have found one
-
- else
- raise Program_Error;
- end if;
-
-- Extract the qualified expression if there is one from the
-- allocator.
- if Nkind (Expression (Alloc_Nod)) = N_Qualified_Expression then
- Alloc_Expr := Expression (Alloc_Nod);
+ if Nkind (Expression (Expr)) = N_Qualified_Expression then
+ Alloc_Expr := Expression (Expr);
end if;
end if;