Siz_Exp : Node_Id := Empty;
Count_Type : Entity_Id;
+ Is_Indexed_Aggregate : Boolean := False;
+
function Aggregate_Size return Int;
-- Compute number of entries in aggregate, including choices
-- that cover a range or subtype, as well as iterated constructs.
("\this will result in infinite recursion??", Parent (N));
end if;
+ -- Determine whether this is an indexed aggregate (see RM 4.3.5(25/5)).
+
+ if Present (New_Indexed_Subp) then
+ if not Present (Add_Unnamed_Subp) then
+ Is_Indexed_Aggregate := True;
+
+ else
+ declare
+ Comp_Assns : constant List_Id := Component_Associations (N);
+ Comp_Assn : Node_Id;
+
+ begin
+ if Present (Comp_Assns)
+ and then not Is_Empty_List (Comp_Assns)
+ then
+ Comp_Assn := First (Comp_Assns);
+
+ if Nkind (Comp_Assn) = N_Component_Association
+ or else
+ (Nkind (Comp_Assn) = N_Iterated_Component_Association
+ and then Present (Defining_Identifier (Comp_Assn)))
+ then
+ Is_Indexed_Aggregate := True;
+ end if;
+ end if;
+ end;
+ end if;
+ end if;
+
---------------------------
-- Positional aggregate --
---------------------------
Next (Comp);
end loop;
end;
- end if;
-- Indexed aggregates are handled below. Unnamed aggregates
-- such as sets may include iterated component associations.
- if No (New_Indexed_Subp) then
+ elsif not Is_Indexed_Aggregate then
Comp := First (Component_Associations (N));
while Present (Comp) loop
if Nkind (Comp) = N_Iterated_Component_Association then
-- Indexed_Aggregate --
-----------------------
- -- For an indexed aggregate there must be an Assigned_Indexeed
+ -- For an indexed aggregate there must be an Assigned_Indexed
-- subprogram. Note that unlike array aggregates, a container
-- aggregate must be fully positional or fully indexed. In the
-- first case the expansion has already taken place.
-- TBA: the keys for an indexed aggregate must provide a dense
-- range with no repetitions.
- if Present (Assign_Indexed_Subp)
+ if Is_Indexed_Aggregate
and then Present (Component_Associations (N))
+ and then not Is_Empty_List (Component_Associations (N))
then
declare
Insert : constant Entity_Id := Entity (Assign_Indexed_Subp);
Comp : Node_Id;
Index : Node_Id;
- Pos : Int := 0;
Stat : Node_Id;
Key : Node_Id;
end Expand_Range_Component;
begin
+ pragma Assert (not Present (Expressions (N)));
+
if Siz > 0 then
-- Modify the call to the constructor to allocate the
Index)));
end if;
- if Present (Expressions (N)) then
- Comp := First (Expressions (N));
-
- while Present (Comp) loop
-
- -- Compute index position for successive components
- -- in the list of expressions, and use the indexed
- -- assignment procedure for each.
-
- Index := Make_Op_Add (Loc,
- Left_Opnd => Type_Low_Bound (Index_Type),
- Right_Opnd => Make_Integer_Literal (Loc, Pos));
-
- Stat := Make_Procedure_Call_Statement (Loc,
- Name => New_Occurrence_Of (Insert, Loc),
- Parameter_Associations =>
- New_List (New_Occurrence_Of (Temp, Loc),
- Index,
- New_Copy_Tree (Comp)));
-
- Pos := Pos + 1;
-
- Append (Stat, Aggr_Code);
- Next (Comp);
- end loop;
- end if;
-
- if Present (Component_Associations (N)) then
- Comp := First (Component_Associations (N));
-
- -- The choice may be a static value, or a range with
- -- static bounds.
+ Comp := First (Component_Associations (N));
- while Present (Comp) loop
- if Nkind (Comp) = N_Component_Association then
- Key := First (Choices (Comp));
- while Present (Key) loop
+ -- The choice may be a static value, or a range with
+ -- static bounds.
- -- If the expression is a box, the corresponding
- -- component (s) is left uninitialized.
+ while Present (Comp) loop
+ if Nkind (Comp) = N_Component_Association then
+ Key := First (Choices (Comp));
+ while Present (Key) loop
- if Box_Present (Comp) then
- goto Next_Key;
+ -- If the expression is a box, the corresponding
+ -- component (s) is left uninitialized.
- elsif Nkind (Key) = N_Range then
+ if Box_Present (Comp) then
+ goto Next_Key;
- -- Create loop for tne specified range,
- -- with copies of the expression.
+ elsif Nkind (Key) = N_Range then
- Stat :=
- Expand_Range_Component (Key, Expression (Comp));
+ -- Create loop for tne specified range,
+ -- with copies of the expression.
- else
- Stat := Make_Procedure_Call_Statement (Loc,
- Name => New_Occurrence_Of
- (Entity (Assign_Indexed_Subp), Loc),
- Parameter_Associations =>
- New_List (New_Occurrence_Of (Temp, Loc),
- New_Copy_Tree (Key),
- New_Copy_Tree (Expression (Comp))));
- end if;
+ Stat :=
+ Expand_Range_Component (Key, Expression (Comp));
- Append (Stat, Aggr_Code);
+ else
+ Stat := Make_Procedure_Call_Statement (Loc,
+ Name => New_Occurrence_Of
+ (Entity (Assign_Indexed_Subp), Loc),
+ Parameter_Associations =>
+ New_List (New_Occurrence_Of (Temp, Loc),
+ New_Copy_Tree (Key),
+ New_Copy_Tree (Expression (Comp))));
+ end if;
- <<Next_Key>>
- Next (Key);
- end loop;
+ Append (Stat, Aggr_Code);
- else
- -- Iterated component association. Discard
- -- positional insertion procedure.
+ <<Next_Key>>
+ Next (Key);
+ end loop;
- if No (Iterator_Specification (Comp)) then
- Add_Named_Subp := Assign_Indexed_Subp;
- Add_Unnamed_Subp := Empty;
- end if;
+ else
+ -- Iterated component association. Discard
+ -- positional insertion procedure.
- Expand_Iterated_Component (Comp);
+ if No (Iterator_Specification (Comp)) then
+ Add_Named_Subp := Assign_Indexed_Subp;
+ Add_Unnamed_Subp := Empty;
end if;
- Next (Comp);
- end loop;
- end if;
+ Expand_Iterated_Component (Comp);
+ end if;
+
+ Next (Comp);
+ end loop;
end;
end if;