Daily bump.
[official-gcc.git] / gcc / ada / exp_aggr.adb
blob93317e891484fb6d4975228430c2221f199b5155
1 ------------------------------------------------------------------------------
2 -- --
3 -- GNAT COMPILER COMPONENTS --
4 -- --
5 -- E X P _ A G G R --
6 -- --
7 -- B o d y --
8 -- --
9 -- $Revision: 1.2 $
10 -- --
11 -- Copyright (C) 1992-2001 Free Software Foundation, Inc. --
12 -- --
13 -- GNAT is free software; you can redistribute it and/or modify it under --
14 -- terms of the GNU General Public License as published by the Free Soft- --
15 -- ware Foundation; either version 2, or (at your option) any later ver- --
16 -- sion. GNAT is distributed in the hope that it will be useful, but WITH- --
17 -- OUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY --
18 -- or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License --
19 -- for more details. You should have received a copy of the GNU General --
20 -- Public License distributed with GNAT; see file COPYING. If not, write --
21 -- to the Free Software Foundation, 59 Temple Place - Suite 330, Boston, --
22 -- MA 02111-1307, USA. --
23 -- --
24 -- GNAT was originally developed by the GNAT team at New York University. --
25 -- Extensive contributions were provided by Ada Core Technologies Inc. --
26 -- --
27 ------------------------------------------------------------------------------
29 with Atree; use Atree;
30 with Checks; use Checks;
31 with Einfo; use Einfo;
32 with Elists; use Elists;
33 with Expander; use Expander;
34 with Exp_Util; use Exp_Util;
35 with Exp_Ch3; use Exp_Ch3;
36 with Exp_Ch7; use Exp_Ch7;
37 with Freeze; use Freeze;
38 with Hostparm; use Hostparm;
39 with Itypes; use Itypes;
40 with Nmake; use Nmake;
41 with Nlists; use Nlists;
42 with Restrict; use Restrict;
43 with Rtsfind; use Rtsfind;
44 with Sem; use Sem;
45 with Sem_Ch3; use Sem_Ch3;
46 with Sem_Eval; use Sem_Eval;
47 with Sem_Res; use Sem_Res;
48 with Sem_Util; use Sem_Util;
49 with Sinfo; use Sinfo;
50 with Snames; use Snames;
51 with Stand; use Stand;
52 with Tbuild; use Tbuild;
53 with Uintp; use Uintp;
55 package body Exp_Aggr is
57 type Case_Bounds is record
58 Choice_Lo : Node_Id;
59 Choice_Hi : Node_Id;
60 Choice_Node : Node_Id;
61 end record;
63 type Case_Table_Type is array (Nat range <>) of Case_Bounds;
64 -- Table type used by Check_Case_Choices procedure
66 procedure Sort_Case_Table (Case_Table : in out Case_Table_Type);
67 -- Sort the Case Table using the Lower Bound of each Choice as the key.
68 -- A simple insertion sort is used since the number of choices in a case
69 -- statement of variant part will usually be small and probably in near
70 -- sorted order.
72 ------------------------------------------------------
73 -- Local subprograms for Record Aggregate Expansion --
74 ------------------------------------------------------
76 procedure Expand_Record_Aggregate
77 (N : Node_Id;
78 Orig_Tag : Node_Id := Empty;
79 Parent_Expr : Node_Id := Empty);
80 -- This is the top level procedure for record aggregate expansion.
81 -- Expansion for record aggregates needs expand aggregates for tagged
82 -- record types. Specifically Expand_Record_Aggregate adds the Tag
83 -- field in front of the Component_Association list that was created
84 -- during resolution by Resolve_Record_Aggregate.
86 -- N is the record aggregate node.
87 -- Orig_Tag is the value of the Tag that has to be provided for this
88 -- specific aggregate. It carries the tag corresponding to the type
89 -- of the outermost aggregate during the recursive expansion
90 -- Parent_Expr is the ancestor part of the original extension
91 -- aggregate
93 procedure Convert_To_Assignments (N : Node_Id; Typ : Entity_Id);
94 -- N is an N_Aggregate of a N_Extension_Aggregate. Typ is the type of
95 -- the aggregate. Transform the given aggregate into a sequence of
96 -- assignments component per component.
98 function Build_Record_Aggr_Code
99 (N : Node_Id;
100 Typ : Entity_Id;
101 Target : Node_Id;
102 Flist : Node_Id := Empty;
103 Obj : Entity_Id := Empty)
104 return List_Id;
105 -- N is an N_Aggregate or a N_Extension_Aggregate. Typ is the type
106 -- of the aggregate. Target is an expression containing the
107 -- location on which the component by component assignments will
108 -- take place. Returns the list of assignments plus all other
109 -- adjustments needed for tagged and controlled types. Flist is an
110 -- expression representing the finalization list on which to
111 -- attach the controlled components if any. Obj is present in the
112 -- object declaration and dynamic allocation cases, it contains
113 -- an entity that allows to know if the value being created needs to be
114 -- attached to the final list in case of pragma finalize_Storage_Only.
116 -----------------------------------------------------
117 -- Local subprograms for array aggregate expansion --
118 -----------------------------------------------------
120 procedure Expand_Array_Aggregate (N : Node_Id);
121 -- This is the top-level routine to perform array aggregate expansion.
122 -- N is the N_Aggregate node to be expanded.
124 function Backend_Processing_Possible (N : Node_Id) return Boolean;
125 -- This function checks if array aggregate N can be processed directly
126 -- by Gigi. If this is the case True is returned.
128 function Build_Array_Aggr_Code
129 (N : Node_Id;
130 Index : Node_Id;
131 Into : Node_Id;
132 Scalar_Comp : Boolean;
133 Indices : List_Id := No_List;
134 Flist : Node_Id := Empty)
135 return List_Id;
136 -- This recursive routine returns a list of statements containing the
137 -- loops and assignments that are needed for the expansion of the array
138 -- aggregate N.
140 -- N is the (sub-)aggregate node to be expanded into code.
142 -- Index is the index node corresponding to the array sub-aggregate N.
144 -- Into is the target expression into which we are copying the aggregate.
146 -- Scalar_Comp is True if the component type of the aggregate is scalar.
148 -- Indices is the current list of expressions used to index the
149 -- object we are writing into.
151 -- Flist is an expression representing the finalization list on which
152 -- to attach the controlled components if any.
154 function Number_Of_Choices (N : Node_Id) return Nat;
155 -- Returns the number of discrete choices (not including the others choice
156 -- if present) contained in (sub-)aggregate N.
158 function Late_Expansion
159 (N : Node_Id;
160 Typ : Entity_Id;
161 Target : Node_Id;
162 Flist : Node_Id := Empty;
163 Obj : Entity_Id := Empty)
164 return List_Id;
165 -- N is a nested (record or array) aggregate that has been marked
166 -- with 'Delay_Expansion'. Typ is the expected type of the
167 -- aggregate and Target is a (duplicable) expression that will
168 -- hold the result of the aggregate expansion. Flist is the
169 -- finalization list to be used to attach controlled
170 -- components. 'Obj' when non empty, carries the original object
171 -- being initialized in order to know if it needs to be attached
172 -- to the previous parameter which may not be the case when
173 -- Finalize_Storage_Only is set. Basically this procedure is used
174 -- to implement top-down expansions of nested aggregates. This is
175 -- necessary for avoiding temporaries at each level as well as for
176 -- propagating the right internal finalization list.
178 function Make_OK_Assignment_Statement
179 (Sloc : Source_Ptr;
180 Name : Node_Id;
181 Expression : Node_Id)
182 return Node_Id;
183 -- This is like Make_Assignment_Statement, except that Assignment_OK
184 -- is set in the left operand. All assignments built by this unit
185 -- use this routine. This is needed to deal with assignments to
186 -- initialized constants that are done in place.
188 function Safe_Slice_Assignment
189 (N : Node_Id;
190 Typ : Entity_Id)
191 return Boolean;
192 -- If a slice assignment has an aggregate with a single others_choice,
193 -- the assignment can be done in place even if bounds are not static,
194 -- by converting it into a loop over the discrete range of the slice.
196 ---------------------------------
197 -- Backend_Processing_Possible --
198 ---------------------------------
200 -- Backend processing by Gigi/gcc is possible only if all the following
201 -- conditions are met:
203 -- 1. N is fully positional
205 -- 2. N is not a bit-packed array aggregate;
207 -- 3. The size of N's array type must be known at compile time. Note
208 -- that this implies that the component size is also known
210 -- 4. The array type of N does not follow the Fortran layout convention
211 -- or if it does it must be 1 dimensional.
213 -- 5. The array component type is tagged, which may necessitate
214 -- reassignment of proper tags.
216 function Backend_Processing_Possible (N : Node_Id) return Boolean is
217 Typ : constant Entity_Id := Etype (N);
218 -- Typ is the correct constrained array subtype of the aggregate.
220 function Static_Check (N : Node_Id; Index : Node_Id) return Boolean;
221 -- Recursively checks that N is fully positional, returns true if so.
223 ------------------
224 -- Static_Check --
225 ------------------
227 function Static_Check (N : Node_Id; Index : Node_Id) return Boolean is
228 Expr : Node_Id;
230 begin
231 -- Check for component associations
233 if Present (Component_Associations (N)) then
234 return False;
235 end if;
237 -- Recurse to check subaggregates, which may appear in qualified
238 -- expressions. If delayed, the front-end will have to expand.
240 Expr := First (Expressions (N));
242 while Present (Expr) loop
244 if Is_Delayed_Aggregate (Expr) then
245 return False;
246 end if;
248 if Present (Next_Index (Index))
249 and then not Static_Check (Expr, Next_Index (Index))
250 then
251 return False;
252 end if;
254 Next (Expr);
255 end loop;
257 return True;
258 end Static_Check;
260 -- Start of processing for Backend_Processing_Possible
262 begin
263 -- Checks 2 (array must not be bit packed)
265 if Is_Bit_Packed_Array (Typ) then
266 return False;
267 end if;
269 -- Checks 4 (array must not be multi-dimensional Fortran case)
271 if Convention (Typ) = Convention_Fortran
272 and then Number_Dimensions (Typ) > 1
273 then
274 return False;
275 end if;
277 -- Checks 3 (size of array must be known at compile time)
279 if not Size_Known_At_Compile_Time (Typ) then
280 return False;
281 end if;
283 -- Checks 1 (aggregate must be fully positional)
285 if not Static_Check (N, First_Index (Typ)) then
286 return False;
287 end if;
289 -- Checks 5 (if the component type is tagged, then we may need
290 -- to do tag adjustments; perhaps this should be refined to
291 -- check for any component associations that actually
292 -- need tag adjustment, along the lines of the test that's
293 -- done in Has_Delayed_Nested_Aggregate_Or_Tagged_Comps
294 -- for record aggregates with tagged components, but not
295 -- clear whether it's worthwhile ???; in the case of the
296 -- JVM, object tags are handled implicitly)
298 if Is_Tagged_Type (Component_Type (Typ)) and then not Java_VM then
299 return False;
300 end if;
302 -- Backend processing is possible
304 Set_Compile_Time_Known_Aggregate (N, True);
305 Set_Size_Known_At_Compile_Time (Etype (N), True);
306 return True;
307 end Backend_Processing_Possible;
309 ---------------------------
310 -- Build_Array_Aggr_Code --
311 ---------------------------
313 -- The code that we generate from a one dimensional aggregate is
315 -- 1. If the sub-aggregate contains discrete choices we
317 -- (a) Sort the discrete choices
319 -- (b) Otherwise for each discrete choice that specifies a range we
320 -- emit a loop. If a range specifies a maximum of three values, or
321 -- we are dealing with an expression we emit a sequence of
322 -- assignments instead of a loop.
324 -- (c) Generate the remaining loops to cover the others choice if any.
326 -- 2. If the aggregate contains positional elements we
328 -- (a) translate the positional elements in a series of assignments.
330 -- (b) Generate a final loop to cover the others choice if any.
331 -- Note that this final loop has to be a while loop since the case
333 -- L : Integer := Integer'Last;
334 -- H : Integer := Integer'Last;
335 -- A : array (L .. H) := (1, others =>0);
337 -- cannot be handled by a for loop. Thus for the following
339 -- array (L .. H) := (.. positional elements.., others =>E);
341 -- we always generate something like:
343 -- I : Index_Type := Index_Of_Last_Positional_Element;
344 -- while I < H loop
345 -- I := Index_Base'Succ (I)
346 -- Tmp (I) := E;
347 -- end loop;
349 function Build_Array_Aggr_Code
350 (N : Node_Id;
351 Index : Node_Id;
352 Into : Node_Id;
353 Scalar_Comp : Boolean;
354 Indices : List_Id := No_List;
355 Flist : Node_Id := Empty)
356 return List_Id
358 Loc : constant Source_Ptr := Sloc (N);
359 Index_Base : constant Entity_Id := Base_Type (Etype (Index));
360 Index_Base_L : constant Node_Id := Type_Low_Bound (Index_Base);
361 Index_Base_H : constant Node_Id := Type_High_Bound (Index_Base);
363 function Add (Val : Int; To : Node_Id) return Node_Id;
364 -- Returns an expression where Val is added to expression To,
365 -- unless To+Val is provably out of To's base type range.
366 -- To must be an already analyzed expression.
368 function Empty_Range (L, H : Node_Id) return Boolean;
369 -- Returns True if the range defined by L .. H is certainly empty.
371 function Equal (L, H : Node_Id) return Boolean;
372 -- Returns True if L = H for sure.
374 function Index_Base_Name return Node_Id;
375 -- Returns a new reference to the index type name.
377 function Gen_Assign (Ind : Node_Id; Expr : Node_Id) return List_Id;
378 -- Ind must be a side-effect free expression.
379 -- If the input aggregate N to Build_Loop contains no sub-aggregates,
380 -- This routine returns the assignment statement
382 -- Into (Indices, Ind) := Expr;
384 -- Otherwise we call Build_Code recursively.
386 function Gen_Loop (L, H : Node_Id; Expr : Node_Id) return List_Id;
387 -- Nodes L and H must be side-effect free expressions.
388 -- If the input aggregate N to Build_Loop contains no sub-aggregates,
389 -- This routine returns the for loop statement
391 -- for J in Index_Base'(L) .. Index_Base'(H) loop
392 -- Into (Indices, J) := Expr;
393 -- end loop;
395 -- Otherwise we call Build_Code recursively.
396 -- As an optimization if the loop covers 3 or less scalar elements we
397 -- generate a sequence of assignments.
399 function Gen_While (L, H : Node_Id; Expr : Node_Id) return List_Id;
400 -- Nodes L and H must be side-effect free expressions.
401 -- If the input aggregate N to Build_Loop contains no sub-aggregates,
402 -- This routine returns the while loop statement
404 -- I : Index_Base := L;
405 -- while I < H loop
406 -- I := Index_Base'Succ (I);
407 -- Into (Indices, I) := Expr;
408 -- end loop;
410 -- Otherwise we call Build_Code recursively.
412 function Local_Compile_Time_Known_Value (E : Node_Id) return Boolean;
413 function Local_Expr_Value (E : Node_Id) return Uint;
414 -- These two Local routines are used to replace the corresponding ones
415 -- in sem_eval because while processing the bounds of an aggregate with
416 -- discrete choices whose index type is an enumeration, we build static
417 -- expressions not recognized by Compile_Time_Known_Value as such since
418 -- they have not yet been analyzed and resolved. All the expressions in
419 -- question are things like Index_Base_Name'Val (Const) which we can
420 -- easily recognize as being constant.
422 ---------
423 -- Add --
424 ---------
426 function Add (Val : Int; To : Node_Id) return Node_Id is
427 Expr_Pos : Node_Id;
428 Expr : Node_Id;
429 To_Pos : Node_Id;
431 U_To : Uint;
432 U_Val : Uint := UI_From_Int (Val);
434 begin
435 -- Note: do not try to optimize the case of Val = 0, because
436 -- we need to build a new node with the proper Sloc value anyway.
438 -- First test if we can do constant folding
440 if Local_Compile_Time_Known_Value (To) then
441 U_To := Local_Expr_Value (To) + Val;
443 -- Determine if our constant is outside the range of the index.
444 -- If so return an Empty node. This empty node will be caught
445 -- by Empty_Range below.
447 if Compile_Time_Known_Value (Index_Base_L)
448 and then U_To < Expr_Value (Index_Base_L)
449 then
450 return Empty;
452 elsif Compile_Time_Known_Value (Index_Base_H)
453 and then U_To > Expr_Value (Index_Base_H)
454 then
455 return Empty;
456 end if;
458 Expr_Pos := Make_Integer_Literal (Loc, U_To);
459 Set_Is_Static_Expression (Expr_Pos);
461 if not Is_Enumeration_Type (Index_Base) then
462 Expr := Expr_Pos;
464 -- If we are dealing with enumeration return
465 -- Index_Base'Val (Expr_Pos)
467 else
468 Expr :=
469 Make_Attribute_Reference
470 (Loc,
471 Prefix => Index_Base_Name,
472 Attribute_Name => Name_Val,
473 Expressions => New_List (Expr_Pos));
474 end if;
476 return Expr;
477 end if;
479 -- If we are here no constant folding possible
481 if not Is_Enumeration_Type (Index_Base) then
482 Expr :=
483 Make_Op_Add (Loc,
484 Left_Opnd => Duplicate_Subexpr (To),
485 Right_Opnd => Make_Integer_Literal (Loc, U_Val));
487 -- If we are dealing with enumeration return
488 -- Index_Base'Val (Index_Base'Pos (To) + Val)
490 else
491 To_Pos :=
492 Make_Attribute_Reference
493 (Loc,
494 Prefix => Index_Base_Name,
495 Attribute_Name => Name_Pos,
496 Expressions => New_List (Duplicate_Subexpr (To)));
498 Expr_Pos :=
499 Make_Op_Add (Loc,
500 Left_Opnd => To_Pos,
501 Right_Opnd => Make_Integer_Literal (Loc, U_Val));
503 Expr :=
504 Make_Attribute_Reference
505 (Loc,
506 Prefix => Index_Base_Name,
507 Attribute_Name => Name_Val,
508 Expressions => New_List (Expr_Pos));
509 end if;
511 return Expr;
512 end Add;
514 -----------------
515 -- Empty_Range --
516 -----------------
518 function Empty_Range (L, H : Node_Id) return Boolean is
519 Is_Empty : Boolean := False;
520 Low : Node_Id;
521 High : Node_Id;
523 begin
524 -- First check if L or H were already detected as overflowing the
525 -- index base range type by function Add above. If this is so Add
526 -- returns the empty node.
528 if No (L) or else No (H) then
529 return True;
530 end if;
532 for J in 1 .. 3 loop
533 case J is
535 -- L > H range is empty
537 when 1 =>
538 Low := L;
539 High := H;
541 -- B_L > H range must be empty
543 when 2 =>
544 Low := Index_Base_L;
545 High := H;
547 -- L > B_H range must be empty
549 when 3 =>
550 Low := L;
551 High := Index_Base_H;
552 end case;
554 if Local_Compile_Time_Known_Value (Low)
555 and then Local_Compile_Time_Known_Value (High)
556 then
557 Is_Empty :=
558 UI_Gt (Local_Expr_Value (Low), Local_Expr_Value (High));
559 end if;
561 exit when Is_Empty;
562 end loop;
564 return Is_Empty;
565 end Empty_Range;
567 -----------
568 -- Equal --
569 -----------
571 function Equal (L, H : Node_Id) return Boolean is
572 begin
573 if L = H then
574 return True;
576 elsif Local_Compile_Time_Known_Value (L)
577 and then Local_Compile_Time_Known_Value (H)
578 then
579 return UI_Eq (Local_Expr_Value (L), Local_Expr_Value (H));
580 end if;
582 return False;
583 end Equal;
585 ----------------
586 -- Gen_Assign --
587 ----------------
589 function Gen_Assign (Ind : Node_Id; Expr : Node_Id) return List_Id is
590 L : List_Id := New_List;
591 F : Entity_Id;
592 A : Node_Id;
594 New_Indices : List_Id;
595 Indexed_Comp : Node_Id;
596 Expr_Q : Node_Id;
597 Comp_Type : Entity_Id := Empty;
599 function Add_Loop_Actions (Lis : List_Id) return List_Id;
600 -- Collect insert_actions generated in the construction of a
601 -- loop, and prepend them to the sequence of assignments to
602 -- complete the eventual body of the loop.
604 ----------------------
605 -- Add_Loop_Actions --
606 ----------------------
608 function Add_Loop_Actions (Lis : List_Id) return List_Id is
609 Res : List_Id;
611 begin
612 if Nkind (Parent (Expr)) = N_Component_Association
613 and then Present (Loop_Actions (Parent (Expr)))
614 then
615 Append_List (Lis, Loop_Actions (Parent (Expr)));
616 Res := Loop_Actions (Parent (Expr));
617 Set_Loop_Actions (Parent (Expr), No_List);
618 return Res;
620 else
621 return Lis;
622 end if;
623 end Add_Loop_Actions;
625 -- Start of processing for Gen_Assign
627 begin
628 if No (Indices) then
629 New_Indices := New_List;
630 else
631 New_Indices := New_Copy_List_Tree (Indices);
632 end if;
634 Append_To (New_Indices, Ind);
636 if Present (Flist) then
637 F := New_Copy_Tree (Flist);
639 elsif Present (Etype (N)) and then Controlled_Type (Etype (N)) then
640 if Is_Entity_Name (Into)
641 and then Present (Scope (Entity (Into)))
642 then
643 F := Find_Final_List (Scope (Entity (Into)));
645 else
646 F := Find_Final_List (Current_Scope);
647 end if;
648 else
649 F := 0;
650 end if;
652 if Present (Next_Index (Index)) then
653 return
654 Add_Loop_Actions (
655 Build_Array_Aggr_Code
656 (Expr, Next_Index (Index),
657 Into, Scalar_Comp, New_Indices, F));
658 end if;
660 -- If we get here then we are at a bottom-level (sub-)aggregate
662 Indexed_Comp := Checks_Off (
663 Make_Indexed_Component (Loc,
664 Prefix => New_Copy_Tree (Into),
665 Expressions => New_Indices));
667 Set_Assignment_OK (Indexed_Comp);
669 if Nkind (Expr) = N_Qualified_Expression then
670 Expr_Q := Expression (Expr);
671 else
672 Expr_Q := Expr;
673 end if;
675 if Present (Etype (N))
676 and then Etype (N) /= Any_Composite
677 then
678 Comp_Type := Component_Type (Etype (N));
680 elsif Present (Next (First (New_Indices))) then
682 -- this is a multidimensional array. Recover the component
683 -- type from the outermost aggregate, because subaggregates
684 -- do not have an assigned type.
686 declare
687 P : Node_Id := Parent (Expr);
689 begin
690 while Present (P) loop
692 if Nkind (P) = N_Aggregate
693 and then Present (Etype (P))
694 then
695 Comp_Type := Component_Type (Etype (P));
696 exit;
698 else
699 P := Parent (P);
700 end if;
701 end loop;
702 end;
703 end if;
705 if (Nkind (Expr_Q) = N_Aggregate
706 or else Nkind (Expr_Q) = N_Extension_Aggregate)
707 then
709 -- At this stage the Expression may not have been
710 -- analyzed yet because the array aggregate code has not
711 -- been updated to use the Expansion_Delayed flag and
712 -- avoid analysis altogether to solve the same problem
713 -- (see Resolve_Aggr_Expr) so let's do the analysis of
714 -- non-array aggregates now in order to get the value of
715 -- Expansion_Delayed flag for the inner aggregate ???
717 if Present (Comp_Type) and then not Is_Array_Type (Comp_Type) then
718 Analyze_And_Resolve (Expr_Q, Comp_Type);
719 end if;
721 if Is_Delayed_Aggregate (Expr_Q) then
722 return
723 Add_Loop_Actions (
724 Late_Expansion (Expr_Q, Etype (Expr_Q), Indexed_Comp, F));
725 end if;
726 end if;
728 -- Now generate the assignment with no associated controlled
729 -- actions since the target of the assignment may not have
730 -- been initialized, it is not possible to Finalize it as
731 -- expected by normal controlled assignment. The rest of the
732 -- controlled actions are done manually with the proper
733 -- finalization list coming from the context.
735 A :=
736 Make_OK_Assignment_Statement (Loc,
737 Name => Indexed_Comp,
738 Expression => New_Copy_Tree (Expr));
740 if Present (Comp_Type) and then Controlled_Type (Comp_Type) then
741 Set_No_Ctrl_Actions (A);
742 end if;
744 Append_To (L, A);
746 -- Adjust the tag if tagged (because of possible view
747 -- conversions), unless compiling for the Java VM
748 -- where tags are implicit.
750 if Present (Comp_Type)
751 and then Is_Tagged_Type (Comp_Type)
752 and then not Java_VM
753 then
754 A :=
755 Make_OK_Assignment_Statement (Loc,
756 Name =>
757 Make_Selected_Component (Loc,
758 Prefix => New_Copy_Tree (Indexed_Comp),
759 Selector_Name =>
760 New_Reference_To (Tag_Component (Comp_Type), Loc)),
762 Expression =>
763 Unchecked_Convert_To (RTE (RE_Tag),
764 New_Reference_To (
765 Access_Disp_Table (Comp_Type), Loc)));
767 Append_To (L, A);
768 end if;
770 -- Adjust and Attach the component to the proper final list
771 -- which can be the controller of the outer record object or
772 -- the final list associated with the scope
774 if Present (Comp_Type) and then Controlled_Type (Comp_Type) then
775 Append_List_To (L,
776 Make_Adjust_Call (
777 Ref => New_Copy_Tree (Indexed_Comp),
778 Typ => Comp_Type,
779 Flist_Ref => F,
780 With_Attach => Make_Integer_Literal (Loc, 1)));
781 end if;
783 return Add_Loop_Actions (L);
784 end Gen_Assign;
786 --------------
787 -- Gen_Loop --
788 --------------
790 function Gen_Loop (L, H : Node_Id; Expr : Node_Id) return List_Id is
791 L_I : Node_Id;
793 L_Range : Node_Id;
794 -- Index_Base'(L) .. Index_Base'(H)
796 L_Iteration_Scheme : Node_Id;
797 -- L_I in Index_Base'(L) .. Index_Base'(H)
799 L_Body : List_Id;
800 -- The statements to execute in the loop
802 S : List_Id := New_List;
803 -- list of statement
805 Tcopy : Node_Id;
806 -- Copy of expression tree, used for checking purposes
808 begin
809 -- If loop bounds define an empty range return the null statement
811 if Empty_Range (L, H) then
812 Append_To (S, Make_Null_Statement (Loc));
814 -- The expression must be type-checked even though no component
815 -- of the aggregate will have this value. This is done only for
816 -- actual components of the array, not for subaggregates. Do the
817 -- check on a copy, because the expression may be shared among
818 -- several choices, some of which might be non-null.
820 if Present (Etype (N))
821 and then Is_Array_Type (Etype (N))
822 and then No (Next_Index (Index))
823 then
824 Expander_Mode_Save_And_Set (False);
825 Tcopy := New_Copy_Tree (Expr);
826 Set_Parent (Tcopy, N);
827 Analyze_And_Resolve (Tcopy, Component_Type (Etype (N)));
828 Expander_Mode_Restore;
829 end if;
831 return S;
833 -- If loop bounds are the same then generate an assignment
835 elsif Equal (L, H) then
836 return Gen_Assign (New_Copy_Tree (L), Expr);
838 -- If H - L <= 2 then generate a sequence of assignments
839 -- when we are processing the bottom most aggregate and it contains
840 -- scalar components.
842 elsif No (Next_Index (Index))
843 and then Scalar_Comp
844 and then Local_Compile_Time_Known_Value (L)
845 and then Local_Compile_Time_Known_Value (H)
846 and then Local_Expr_Value (H) - Local_Expr_Value (L) <= 2
847 then
848 Append_List_To (S, Gen_Assign (New_Copy_Tree (L), Expr));
849 Append_List_To (S, Gen_Assign (Add (1, To => L), Expr));
851 if Local_Expr_Value (H) - Local_Expr_Value (L) = 2 then
852 Append_List_To (S, Gen_Assign (Add (2, To => L), Expr));
853 end if;
855 return S;
856 end if;
858 -- Otherwise construct the loop, starting with the loop index L_I
860 L_I := Make_Defining_Identifier (Loc, New_Internal_Name ('I'));
862 -- Construct "L .. H"
864 L_Range :=
865 Make_Range
866 (Loc,
867 Low_Bound => Make_Qualified_Expression
868 (Loc,
869 Subtype_Mark => Index_Base_Name,
870 Expression => L),
871 High_Bound => Make_Qualified_Expression
872 (Loc,
873 Subtype_Mark => Index_Base_Name,
874 Expression => H));
876 -- Construct "for L_I in Index_Base range L .. H"
878 L_Iteration_Scheme :=
879 Make_Iteration_Scheme
880 (Loc,
881 Loop_Parameter_Specification =>
882 Make_Loop_Parameter_Specification
883 (Loc,
884 Defining_Identifier => L_I,
885 Discrete_Subtype_Definition => L_Range));
887 -- Construct the statements to execute in the loop body
889 L_Body := Gen_Assign (New_Reference_To (L_I, Loc), Expr);
891 -- Construct the final loop
893 Append_To (S, Make_Implicit_Loop_Statement
894 (Node => N,
895 Identifier => Empty,
896 Iteration_Scheme => L_Iteration_Scheme,
897 Statements => L_Body));
899 return S;
900 end Gen_Loop;
902 ---------------
903 -- Gen_While --
904 ---------------
906 -- The code built is
908 -- W_I : Index_Base := L;
909 -- while W_I < H loop
910 -- W_I := Index_Base'Succ (W);
911 -- L_Body;
912 -- end loop;
914 function Gen_While (L, H : Node_Id; Expr : Node_Id) return List_Id is
916 W_I : Node_Id;
918 W_Decl : Node_Id;
919 -- W_I : Base_Type := L;
921 W_Iteration_Scheme : Node_Id;
922 -- while W_I < H
924 W_Index_Succ : Node_Id;
925 -- Index_Base'Succ (I)
927 W_Increment : Node_Id;
928 -- W_I := Index_Base'Succ (W)
930 W_Body : List_Id := New_List;
931 -- The statements to execute in the loop
933 S : List_Id := New_List;
934 -- list of statement
936 begin
937 -- If loop bounds define an empty range or are equal return null
939 if Empty_Range (L, H) or else Equal (L, H) then
940 Append_To (S, Make_Null_Statement (Loc));
941 return S;
942 end if;
944 -- Build the decl of W_I
946 W_I := Make_Defining_Identifier (Loc, New_Internal_Name ('I'));
947 W_Decl :=
948 Make_Object_Declaration
949 (Loc,
950 Defining_Identifier => W_I,
951 Object_Definition => Index_Base_Name,
952 Expression => L);
954 -- Theoretically we should do a New_Copy_Tree (L) here, but we know
955 -- that in this particular case L is a fresh Expr generated by
956 -- Add which we are the only ones to use.
958 Append_To (S, W_Decl);
960 -- construct " while W_I < H"
962 W_Iteration_Scheme :=
963 Make_Iteration_Scheme
964 (Loc,
965 Condition => Make_Op_Lt
966 (Loc,
967 Left_Opnd => New_Reference_To (W_I, Loc),
968 Right_Opnd => New_Copy_Tree (H)));
970 -- Construct the statements to execute in the loop body
972 W_Index_Succ :=
973 Make_Attribute_Reference
974 (Loc,
975 Prefix => Index_Base_Name,
976 Attribute_Name => Name_Succ,
977 Expressions => New_List (New_Reference_To (W_I, Loc)));
979 W_Increment :=
980 Make_OK_Assignment_Statement
981 (Loc,
982 Name => New_Reference_To (W_I, Loc),
983 Expression => W_Index_Succ);
985 Append_To (W_Body, W_Increment);
986 Append_List_To (W_Body,
987 Gen_Assign (New_Reference_To (W_I, Loc), Expr));
989 -- Construct the final loop
991 Append_To (S, Make_Implicit_Loop_Statement
992 (Node => N,
993 Identifier => Empty,
994 Iteration_Scheme => W_Iteration_Scheme,
995 Statements => W_Body));
997 return S;
998 end Gen_While;
1000 ---------------------
1001 -- Index_Base_Name --
1002 ---------------------
1004 function Index_Base_Name return Node_Id is
1005 begin
1006 return New_Reference_To (Index_Base, Sloc (N));
1007 end Index_Base_Name;
1009 ------------------------------------
1010 -- Local_Compile_Time_Known_Value --
1011 ------------------------------------
1013 function Local_Compile_Time_Known_Value (E : Node_Id) return Boolean is
1014 begin
1015 return Compile_Time_Known_Value (E)
1016 or else
1017 (Nkind (E) = N_Attribute_Reference
1018 and then Attribute_Name (E) = Name_Val
1019 and then Compile_Time_Known_Value (First (Expressions (E))));
1020 end Local_Compile_Time_Known_Value;
1022 ----------------------
1023 -- Local_Expr_Value --
1024 ----------------------
1026 function Local_Expr_Value (E : Node_Id) return Uint is
1027 begin
1028 if Compile_Time_Known_Value (E) then
1029 return Expr_Value (E);
1030 else
1031 return Expr_Value (First (Expressions (E)));
1032 end if;
1033 end Local_Expr_Value;
1035 -- Build_Array_Aggr_Code Variables
1037 Assoc : Node_Id;
1038 Choice : Node_Id;
1039 Expr : Node_Id;
1041 Others_Expr : Node_Id := Empty;
1043 Aggr_L : constant Node_Id := Low_Bound (Aggregate_Bounds (N));
1044 Aggr_H : constant Node_Id := High_Bound (Aggregate_Bounds (N));
1045 -- The aggregate bounds of this specific sub-aggregate. Note that if
1046 -- the code generated by Build_Array_Aggr_Code is executed then these
1047 -- bounds are OK. Otherwise a Constraint_Error would have been raised.
1049 Aggr_Low : constant Node_Id := Duplicate_Subexpr (Aggr_L);
1050 Aggr_High : constant Node_Id := Duplicate_Subexpr (Aggr_H);
1051 -- After Duplicate_Subexpr these are side-effect free.
1053 Low : Node_Id;
1054 High : Node_Id;
1056 Nb_Choices : Nat := 0;
1057 Table : Case_Table_Type (1 .. Number_Of_Choices (N));
1058 -- Used to sort all the different choice values
1060 Nb_Elements : Int;
1061 -- Number of elements in the positional aggregate
1063 New_Code : List_Id := New_List;
1065 -- Start of processing for Build_Array_Aggr_Code
1067 begin
1068 -- STEP 1: Process component associations
1070 if No (Expressions (N)) then
1072 -- STEP 1 (a): Sort the discrete choices
1074 Assoc := First (Component_Associations (N));
1075 while Present (Assoc) loop
1077 Choice := First (Choices (Assoc));
1078 while Present (Choice) loop
1080 if Nkind (Choice) = N_Others_Choice then
1081 Others_Expr := Expression (Assoc);
1082 exit;
1083 end if;
1085 Get_Index_Bounds (Choice, Low, High);
1087 Nb_Choices := Nb_Choices + 1;
1088 Table (Nb_Choices) := (Choice_Lo => Low,
1089 Choice_Hi => High,
1090 Choice_Node => Expression (Assoc));
1092 Next (Choice);
1093 end loop;
1095 Next (Assoc);
1096 end loop;
1098 -- If there is more than one set of choices these must be static
1099 -- and we can therefore sort them. Remember that Nb_Choices does not
1100 -- account for an others choice.
1102 if Nb_Choices > 1 then
1103 Sort_Case_Table (Table);
1104 end if;
1106 -- STEP 1 (b): take care of the whole set of discrete choices.
1108 for J in 1 .. Nb_Choices loop
1109 Low := Table (J).Choice_Lo;
1110 High := Table (J).Choice_Hi;
1111 Expr := Table (J).Choice_Node;
1113 Append_List (Gen_Loop (Low, High, Expr), To => New_Code);
1114 end loop;
1116 -- STEP 1 (c): generate the remaining loops to cover others choice
1117 -- We don't need to generate loops over empty gaps, but if there is
1118 -- a single empty range we must analyze the expression for semantics
1120 if Present (Others_Expr) then
1121 declare
1122 First : Boolean := True;
1124 begin
1125 for J in 0 .. Nb_Choices loop
1127 if J = 0 then
1128 Low := Aggr_Low;
1129 else
1130 Low := Add (1, To => Table (J).Choice_Hi);
1131 end if;
1133 if J = Nb_Choices then
1134 High := Aggr_High;
1135 else
1136 High := Add (-1, To => Table (J + 1).Choice_Lo);
1137 end if;
1139 -- If this is an expansion within an init_proc, make
1140 -- sure that discriminant references are replaced by
1141 -- the corresponding discriminal.
1143 if Inside_Init_Proc then
1144 if Is_Entity_Name (Low)
1145 and then Ekind (Entity (Low)) = E_Discriminant
1146 then
1147 Set_Entity (Low, Discriminal (Entity (Low)));
1148 end if;
1150 if Is_Entity_Name (High)
1151 and then Ekind (Entity (High)) = E_Discriminant
1152 then
1153 Set_Entity (High, Discriminal (Entity (High)));
1154 end if;
1155 end if;
1157 if First
1158 or else not Empty_Range (Low, High)
1159 then
1160 First := False;
1161 Append_List
1162 (Gen_Loop (Low, High, Others_Expr), To => New_Code);
1163 end if;
1164 end loop;
1165 end;
1166 end if;
1168 -- STEP 2: Process positional components
1170 else
1171 -- STEP 2 (a): Generate the assignments for each positional element
1172 -- Note that here we have to use Aggr_L rather than Aggr_Low because
1173 -- Aggr_L is analyzed and Add wants an analyzed expression.
1175 Expr := First (Expressions (N));
1176 Nb_Elements := -1;
1178 while Present (Expr) loop
1179 Nb_Elements := Nb_Elements + 1;
1180 Append_List (Gen_Assign (Add (Nb_Elements, To => Aggr_L), Expr),
1181 To => New_Code);
1182 Next (Expr);
1183 end loop;
1185 -- STEP 2 (b): Generate final loop if an others choice is present
1186 -- Here Nb_Elements gives the offset of the last positional element.
1188 if Present (Component_Associations (N)) then
1189 Assoc := Last (Component_Associations (N));
1190 Expr := Expression (Assoc);
1192 Append_List (Gen_While (Add (Nb_Elements, To => Aggr_L),
1193 Aggr_High,
1194 Expr),
1195 To => New_Code);
1196 end if;
1197 end if;
1199 return New_Code;
1200 end Build_Array_Aggr_Code;
1202 ----------------------------
1203 -- Build_Record_Aggr_Code --
1204 ----------------------------
1206 function Build_Record_Aggr_Code
1207 (N : Node_Id;
1208 Typ : Entity_Id;
1209 Target : Node_Id;
1210 Flist : Node_Id := Empty;
1211 Obj : Entity_Id := Empty)
1212 return List_Id
1214 Loc : constant Source_Ptr := Sloc (N);
1215 L : constant List_Id := New_List;
1216 Start_L : constant List_Id := New_List;
1217 N_Typ : constant Entity_Id := Etype (N);
1219 Comp : Node_Id;
1220 Instr : Node_Id;
1221 Ref : Node_Id;
1222 F : Node_Id;
1223 Comp_Type : Entity_Id;
1224 Selector : Entity_Id;
1225 Comp_Expr : Node_Id;
1226 Comp_Kind : Node_Kind;
1227 Expr_Q : Node_Id;
1229 Internal_Final_List : Node_Id;
1231 -- If this is an internal aggregate, the External_Final_List is an
1232 -- expression for the controller record of the enclosing type.
1233 -- If the current aggregate has several controlled components, this
1234 -- expression will appear in several calls to attach to the finali-
1235 -- zation list, and it must not be shared.
1237 External_Final_List : Node_Id;
1238 Ancestor_Is_Expression : Boolean := False;
1239 Ancestor_Is_Subtype_Mark : Boolean := False;
1241 Init_Typ : Entity_Id := Empty;
1242 Attach : Node_Id;
1244 function Get_Constraint_Association (T : Entity_Id) return Node_Id;
1245 -- Returns the first discriminant association in the constraint
1246 -- associated with T, if any, otherwise returns Empty.
1248 function Ancestor_Discriminant_Value (Disc : Entity_Id) return Node_Id;
1249 -- Returns the value that the given discriminant of an ancestor
1250 -- type should receive (in the absence of a conflict with the
1251 -- value provided by an ancestor part of an extension aggregate).
1253 procedure Check_Ancestor_Discriminants (Anc_Typ : Entity_Id);
1254 -- Check that each of the discriminant values defined by the
1255 -- ancestor part of an extension aggregate match the corresponding
1256 -- values provided by either an association of the aggregate or
1257 -- by the constraint imposed by a parent type (RM95-4.3.2(8)).
1259 function Init_Controller
1260 (Target : Node_Id;
1261 Typ : Entity_Id;
1262 F : Node_Id;
1263 Attach : Node_Id;
1264 Init_Pr : Boolean)
1265 return List_Id;
1266 -- returns the list of statements necessary to initialize the internal
1267 -- controller of the (possible) ancestor typ into target and attach
1268 -- it to finalization list F. Init_Pr conditions the call to the
1269 -- init_proc since it may already be done due to ancestor initialization
1271 ---------------------------------
1272 -- Ancestor_Discriminant_Value --
1273 ---------------------------------
1275 function Ancestor_Discriminant_Value (Disc : Entity_Id) return Node_Id is
1276 Assoc : Node_Id;
1277 Assoc_Elmt : Elmt_Id;
1278 Aggr_Comp : Entity_Id;
1279 Corresp_Disc : Entity_Id;
1280 Current_Typ : Entity_Id := Base_Type (Typ);
1281 Parent_Typ : Entity_Id;
1282 Parent_Disc : Entity_Id;
1283 Save_Assoc : Node_Id := Empty;
1285 begin
1286 -- First check any discriminant associations to see if
1287 -- any of them provide a value for the discriminant.
1289 if Present (Discriminant_Specifications (Parent (Current_Typ))) then
1290 Assoc := First (Component_Associations (N));
1291 while Present (Assoc) loop
1292 Aggr_Comp := Entity (First (Choices (Assoc)));
1294 if Ekind (Aggr_Comp) = E_Discriminant then
1295 Save_Assoc := Expression (Assoc);
1297 Corresp_Disc := Corresponding_Discriminant (Aggr_Comp);
1298 while Present (Corresp_Disc) loop
1299 -- If found a corresponding discriminant then return
1300 -- the value given in the aggregate. (Note: this is
1301 -- not correct in the presence of side effects. ???)
1303 if Disc = Corresp_Disc then
1304 return Duplicate_Subexpr (Expression (Assoc));
1305 end if;
1306 Corresp_Disc :=
1307 Corresponding_Discriminant (Corresp_Disc);
1308 end loop;
1309 end if;
1311 Next (Assoc);
1312 end loop;
1313 end if;
1315 -- No match found in aggregate, so chain up parent types to find
1316 -- a constraint that defines the value of the discriminant.
1318 Parent_Typ := Etype (Current_Typ);
1319 while Current_Typ /= Parent_Typ loop
1320 if Has_Discriminants (Parent_Typ) then
1321 Parent_Disc := First_Discriminant (Parent_Typ);
1323 -- We either get the association from the subtype indication
1324 -- of the type definition itself, or from the discriminant
1325 -- constraint associated with the type entity (which is
1326 -- preferable, but it's not always present ???)
1328 if Is_Empty_Elmt_List (
1329 Discriminant_Constraint (Current_Typ))
1330 then
1331 Assoc := Get_Constraint_Association (Current_Typ);
1332 Assoc_Elmt := No_Elmt;
1333 else
1334 Assoc_Elmt :=
1335 First_Elmt (Discriminant_Constraint (Current_Typ));
1336 Assoc := Node (Assoc_Elmt);
1337 end if;
1339 -- Traverse the discriminants of the parent type looking
1340 -- for one that corresponds.
1342 while Present (Parent_Disc) and then Present (Assoc) loop
1343 Corresp_Disc := Parent_Disc;
1344 while Present (Corresp_Disc)
1345 and then Disc /= Corresp_Disc
1346 loop
1347 Corresp_Disc :=
1348 Corresponding_Discriminant (Corresp_Disc);
1349 end loop;
1351 if Disc = Corresp_Disc then
1352 if Nkind (Assoc) = N_Discriminant_Association then
1353 Assoc := Expression (Assoc);
1354 end if;
1356 -- If the located association directly denotes
1357 -- a discriminant, then use the value of a saved
1358 -- association of the aggregate. This is a kludge
1359 -- to handle certain cases involving multiple
1360 -- discriminants mapped to a single discriminant
1361 -- of a descendant. It's not clear how to locate the
1362 -- appropriate discriminant value for such cases. ???
1364 if Is_Entity_Name (Assoc)
1365 and then Ekind (Entity (Assoc)) = E_Discriminant
1366 then
1367 Assoc := Save_Assoc;
1368 end if;
1370 return Duplicate_Subexpr (Assoc);
1371 end if;
1373 Next_Discriminant (Parent_Disc);
1375 if No (Assoc_Elmt) then
1376 Next (Assoc);
1377 else
1378 Next_Elmt (Assoc_Elmt);
1379 if Present (Assoc_Elmt) then
1380 Assoc := Node (Assoc_Elmt);
1381 else
1382 Assoc := Empty;
1383 end if;
1384 end if;
1385 end loop;
1386 end if;
1388 Current_Typ := Parent_Typ;
1389 Parent_Typ := Etype (Current_Typ);
1390 end loop;
1392 -- In some cases there's no ancestor value to locate (such as
1393 -- when an ancestor part given by an expression defines the
1394 -- discriminant value).
1396 return Empty;
1397 end Ancestor_Discriminant_Value;
1399 ----------------------------------
1400 -- Check_Ancestor_Discriminants --
1401 ----------------------------------
1403 procedure Check_Ancestor_Discriminants (Anc_Typ : Entity_Id) is
1404 Discr : Entity_Id := First_Discriminant (Base_Type (Anc_Typ));
1405 Disc_Value : Node_Id;
1406 Cond : Node_Id;
1408 begin
1409 while Present (Discr) loop
1410 Disc_Value := Ancestor_Discriminant_Value (Discr);
1412 if Present (Disc_Value) then
1413 Cond := Make_Op_Ne (Loc,
1414 Left_Opnd =>
1415 Make_Selected_Component (Loc,
1416 Prefix => New_Copy_Tree (Target),
1417 Selector_Name => New_Occurrence_Of (Discr, Loc)),
1418 Right_Opnd => Disc_Value);
1420 Append_To (L, Make_Raise_Constraint_Error (Loc,
1421 Condition => Cond));
1422 end if;
1424 Next_Discriminant (Discr);
1425 end loop;
1426 end Check_Ancestor_Discriminants;
1428 --------------------------------
1429 -- Get_Constraint_Association --
1430 --------------------------------
1432 function Get_Constraint_Association (T : Entity_Id) return Node_Id is
1433 Typ_Def : constant Node_Id := Type_Definition (Parent (T));
1434 Indic : constant Node_Id := Subtype_Indication (Typ_Def);
1436 begin
1437 -- ??? Also need to cover case of a type mark denoting a subtype
1438 -- with constraint.
1440 if Nkind (Indic) = N_Subtype_Indication
1441 and then Present (Constraint (Indic))
1442 then
1443 return First (Constraints (Constraint (Indic)));
1444 end if;
1446 return Empty;
1447 end Get_Constraint_Association;
1449 ---------------------
1450 -- Init_controller --
1451 ---------------------
1453 function Init_Controller
1454 (Target : Node_Id;
1455 Typ : Entity_Id;
1456 F : Node_Id;
1457 Attach : Node_Id;
1458 Init_Pr : Boolean)
1459 return List_Id
1461 Ref : Node_Id;
1462 L : List_Id := New_List;
1464 begin
1465 -- _init_proc (target._controller);
1466 -- initialize (target._controller);
1467 -- Attach_to_Final_List (target._controller, F);
1469 Ref := Make_Selected_Component (Loc,
1470 Prefix => Convert_To (Typ, New_Copy_Tree (Target)),
1471 Selector_Name => Make_Identifier (Loc, Name_uController));
1472 Set_Assignment_OK (Ref);
1474 if Init_Pr then
1475 Append_List_To (L,
1476 Build_Initialization_Call (Loc,
1477 Id_Ref => Ref,
1478 Typ => RTE (RE_Record_Controller),
1479 In_Init_Proc => Within_Init_Proc));
1480 end if;
1482 Append_To (L,
1483 Make_Procedure_Call_Statement (Loc,
1484 Name =>
1485 New_Reference_To (Find_Prim_Op (RTE (RE_Record_Controller),
1486 Name_Initialize), Loc),
1487 Parameter_Associations => New_List (New_Copy_Tree (Ref))));
1489 Append_To (L,
1490 Make_Attach_Call (
1491 Obj_Ref => New_Copy_Tree (Ref),
1492 Flist_Ref => F,
1493 With_Attach => Attach));
1494 return L;
1495 end Init_Controller;
1497 -- Start of processing for Build_Record_Aggr_Code
1499 begin
1501 -- Deal with the ancestor part of extension aggregates
1502 -- or with the discriminants of the root type
1504 if Nkind (N) = N_Extension_Aggregate then
1505 declare
1506 A : constant Node_Id := Ancestor_Part (N);
1508 begin
1510 -- If the ancestor part is a subtype mark "T", we generate
1511 -- _init_proc (T(tmp)); if T is constrained and
1512 -- _init_proc (S(tmp)); where S applies an appropriate
1513 -- constraint if T is unconstrained
1515 if Is_Entity_Name (A) and then Is_Type (Entity (A)) then
1517 Ancestor_Is_Subtype_Mark := True;
1519 if Is_Constrained (Entity (A)) then
1520 Init_Typ := Entity (A);
1522 -- For an ancestor part given by an unconstrained type
1523 -- mark, create a subtype constrained by appropriate
1524 -- corresponding discriminant values coming from either
1525 -- associations of the aggregate or a constraint on
1526 -- a parent type. The subtype will be used to generate
1527 -- the correct default value for the ancestor part.
1529 elsif Has_Discriminants (Entity (A)) then
1530 declare
1531 Anc_Typ : Entity_Id := Entity (A);
1532 Discrim : Entity_Id := First_Discriminant (Anc_Typ);
1533 Anc_Constr : List_Id := New_List;
1534 Disc_Value : Node_Id;
1535 New_Indic : Node_Id;
1536 Subt_Decl : Node_Id;
1537 begin
1538 while Present (Discrim) loop
1539 Disc_Value := Ancestor_Discriminant_Value (Discrim);
1540 Append_To (Anc_Constr, Disc_Value);
1541 Next_Discriminant (Discrim);
1542 end loop;
1544 New_Indic :=
1545 Make_Subtype_Indication (Loc,
1546 Subtype_Mark => New_Occurrence_Of (Anc_Typ, Loc),
1547 Constraint =>
1548 Make_Index_Or_Discriminant_Constraint (Loc,
1549 Constraints => Anc_Constr));
1551 Init_Typ := Create_Itype (Ekind (Anc_Typ), N);
1553 Subt_Decl :=
1554 Make_Subtype_Declaration (Loc,
1555 Defining_Identifier => Init_Typ,
1556 Subtype_Indication => New_Indic);
1558 -- Itypes must be analyzed with checks off
1560 Analyze (Subt_Decl, Suppress => All_Checks);
1561 end;
1562 end if;
1564 Ref := Convert_To (Init_Typ, New_Copy_Tree (Target));
1565 Set_Assignment_OK (Ref);
1567 Append_List_To (Start_L,
1568 Build_Initialization_Call (Loc,
1569 Id_Ref => Ref,
1570 Typ => Init_Typ,
1571 In_Init_Proc => Within_Init_Proc));
1573 if Is_Constrained (Entity (A))
1574 and then Has_Discriminants (Entity (A))
1575 then
1576 Check_Ancestor_Discriminants (Entity (A));
1577 end if;
1579 -- If the ancestor part is an expression "E", we generate
1580 -- T(tmp) := E;
1582 else
1583 Ancestor_Is_Expression := True;
1584 Init_Typ := Etype (A);
1586 -- Assign the tag before doing the assignment to make sure
1587 -- that the dispatching call in the subsequent deep_adjust
1588 -- works properly (unless Java_VM, where tags are implicit).
1590 if not Java_VM then
1591 Instr :=
1592 Make_OK_Assignment_Statement (Loc,
1593 Name =>
1594 Make_Selected_Component (Loc,
1595 Prefix => New_Copy_Tree (Target),
1596 Selector_Name => New_Reference_To (
1597 Tag_Component (Base_Type (Typ)), Loc)),
1599 Expression =>
1600 Unchecked_Convert_To (RTE (RE_Tag),
1601 New_Reference_To (
1602 Access_Disp_Table (Base_Type (Typ)), Loc)));
1604 Set_Assignment_OK (Name (Instr));
1605 Append_To (L, Instr);
1606 end if;
1608 -- If the ancestor part is an aggregate, force its full
1609 -- expansion, which was delayed.
1611 if Nkind (A) = N_Qualified_Expression
1612 and then (Nkind (Expression (A)) = N_Aggregate
1613 or else
1614 Nkind (Expression (A)) = N_Extension_Aggregate)
1615 then
1616 Set_Analyzed (A, False);
1617 Set_Analyzed (Expression (A), False);
1618 end if;
1620 Ref := Convert_To (Init_Typ, New_Copy_Tree (Target));
1621 Set_Assignment_OK (Ref);
1622 Append_To (L,
1623 Make_Unsuppress_Block (Loc,
1624 Name_Discriminant_Check,
1625 New_List (
1626 Make_OK_Assignment_Statement (Loc,
1627 Name => Ref,
1628 Expression => A))));
1630 if Has_Discriminants (Init_Typ) then
1631 Check_Ancestor_Discriminants (Init_Typ);
1632 end if;
1633 end if;
1634 end;
1636 else
1637 -- Generate the discriminant expressions, component by component.
1638 -- If the base type is an unchecked union, the discriminants are
1639 -- unknown to the back-end and absent from a value of the type, so
1640 -- assignments for them are not emitted.
1642 if Has_Discriminants (Typ)
1643 and then not Is_Unchecked_Union (Base_Type (Typ))
1644 then
1646 -- ??? The discriminants of the object not inherited in the type
1647 -- of the object should be initialized here
1649 null;
1651 -- Generate discriminant init values
1653 declare
1654 Discriminant : Entity_Id;
1655 Discriminant_Value : Node_Id;
1657 begin
1658 Discriminant := First_Girder_Discriminant (Typ);
1660 while Present (Discriminant) loop
1662 Comp_Expr :=
1663 Make_Selected_Component (Loc,
1664 Prefix => New_Copy_Tree (Target),
1665 Selector_Name => New_Occurrence_Of (Discriminant, Loc));
1667 Discriminant_Value :=
1668 Get_Discriminant_Value (
1669 Discriminant,
1670 N_Typ,
1671 Discriminant_Constraint (N_Typ));
1673 Instr :=
1674 Make_OK_Assignment_Statement (Loc,
1675 Name => Comp_Expr,
1676 Expression => New_Copy_Tree (Discriminant_Value));
1678 Set_No_Ctrl_Actions (Instr);
1679 Append_To (L, Instr);
1681 Next_Girder_Discriminant (Discriminant);
1682 end loop;
1683 end;
1684 end if;
1685 end if;
1687 -- Generate the assignments, component by component
1689 -- tmp.comp1 := Expr1_From_Aggr;
1690 -- tmp.comp2 := Expr2_From_Aggr;
1691 -- ....
1693 Comp := First (Component_Associations (N));
1694 while Present (Comp) loop
1695 Selector := Entity (First (Choices (Comp)));
1697 if Ekind (Selector) /= E_Discriminant
1698 or else Nkind (N) = N_Extension_Aggregate
1699 then
1700 Comp_Type := Etype (Selector);
1701 Comp_Kind := Nkind (Expression (Comp));
1702 Comp_Expr :=
1703 Make_Selected_Component (Loc,
1704 Prefix => New_Copy_Tree (Target),
1705 Selector_Name => New_Occurrence_Of (Selector, Loc));
1707 if Nkind (Expression (Comp)) = N_Qualified_Expression then
1708 Expr_Q := Expression (Expression (Comp));
1709 else
1710 Expr_Q := Expression (Comp);
1711 end if;
1713 -- The controller is the one of the parent type defining
1714 -- the component (in case of inherited components).
1716 if Controlled_Type (Comp_Type) then
1717 Internal_Final_List :=
1718 Make_Selected_Component (Loc,
1719 Prefix => Convert_To (
1720 Scope (Original_Record_Component (Selector)),
1721 New_Copy_Tree (Target)),
1722 Selector_Name =>
1723 Make_Identifier (Loc, Name_uController));
1724 Internal_Final_List :=
1725 Make_Selected_Component (Loc,
1726 Prefix => Internal_Final_List,
1727 Selector_Name => Make_Identifier (Loc, Name_F));
1729 -- The internal final list can be part of a constant object
1731 Set_Assignment_OK (Internal_Final_List);
1732 else
1733 Internal_Final_List := Empty;
1734 end if;
1736 if Is_Delayed_Aggregate (Expr_Q) then
1737 Append_List_To (L,
1738 Late_Expansion (Expr_Q, Comp_Type, Comp_Expr,
1739 Internal_Final_List));
1740 else
1741 Instr :=
1742 Make_OK_Assignment_Statement (Loc,
1743 Name => Comp_Expr,
1744 Expression => Expression (Comp));
1746 Set_No_Ctrl_Actions (Instr);
1747 Append_To (L, Instr);
1749 -- Adjust the tag if tagged (because of possible view
1750 -- conversions), unless compiling for the Java VM
1751 -- where tags are implicit.
1753 -- tmp.comp._tag := comp_typ'tag;
1755 if Is_Tagged_Type (Comp_Type) and then not Java_VM then
1756 Instr :=
1757 Make_OK_Assignment_Statement (Loc,
1758 Name =>
1759 Make_Selected_Component (Loc,
1760 Prefix => New_Copy_Tree (Comp_Expr),
1761 Selector_Name =>
1762 New_Reference_To (Tag_Component (Comp_Type), Loc)),
1764 Expression =>
1765 Unchecked_Convert_To (RTE (RE_Tag),
1766 New_Reference_To (
1767 Access_Disp_Table (Comp_Type), Loc)));
1769 Append_To (L, Instr);
1770 end if;
1772 -- Adjust and Attach the component to the proper controller
1773 -- Adjust (tmp.comp);
1774 -- Attach_To_Final_List (tmp.comp,
1775 -- comp_typ (tmp)._record_controller.f)
1777 if Controlled_Type (Comp_Type) then
1778 Append_List_To (L,
1779 Make_Adjust_Call (
1780 Ref => New_Copy_Tree (Comp_Expr),
1781 Typ => Comp_Type,
1782 Flist_Ref => Internal_Final_List,
1783 With_Attach => Make_Integer_Literal (Loc, 1)));
1784 end if;
1785 end if;
1786 end if;
1788 Next (Comp);
1789 end loop;
1791 -- If the type is tagged, the tag needs to be initialized (unless
1792 -- compiling for the Java VM where tags are implicit). It is done
1793 -- late in the initialization process because in some cases, we call
1794 -- the init_proc of an ancestor which will not leave out the right tag
1796 if Ancestor_Is_Expression then
1797 null;
1799 elsif Is_Tagged_Type (Typ) and then not Java_VM then
1800 Instr :=
1801 Make_OK_Assignment_Statement (Loc,
1802 Name =>
1803 Make_Selected_Component (Loc,
1804 Prefix => New_Copy_Tree (Target),
1805 Selector_Name =>
1806 New_Reference_To (Tag_Component (Base_Type (Typ)), Loc)),
1808 Expression =>
1809 Unchecked_Convert_To (RTE (RE_Tag),
1810 New_Reference_To (Access_Disp_Table (Base_Type (Typ)), Loc)));
1812 Append_To (L, Instr);
1813 end if;
1815 -- Now deal with the various controlled type data structure
1816 -- initializations
1818 if Present (Obj)
1819 and then Finalize_Storage_Only (Typ)
1820 and then (Is_Library_Level_Entity (Obj)
1821 or else Entity (Constant_Value (RTE (RE_Garbage_Collected)))
1822 = Standard_True)
1823 then
1824 Attach := Make_Integer_Literal (Loc, 0);
1826 elsif Nkind (Parent (N)) = N_Qualified_Expression
1827 and then Nkind (Parent (Parent (N))) = N_Allocator
1828 then
1829 Attach := Make_Integer_Literal (Loc, 2);
1831 else
1832 Attach := Make_Integer_Literal (Loc, 1);
1833 end if;
1835 -- Determine the external finalization list. It is either the
1836 -- finalization list of the outer-scope or the one coming from
1837 -- an outer aggregate. When the target is not a temporary, the
1838 -- proper scope is the scope of the target rather than the
1839 -- potentially transient current scope.
1841 if Controlled_Type (Typ) then
1842 if Present (Flist) then
1843 External_Final_List := New_Copy_Tree (Flist);
1845 elsif Is_Entity_Name (Target)
1846 and then Present (Scope (Entity (Target)))
1847 then
1848 External_Final_List := Find_Final_List (Scope (Entity (Target)));
1850 else
1851 External_Final_List := Find_Final_List (Current_Scope);
1852 end if;
1854 else
1855 External_Final_List := Empty;
1856 end if;
1858 -- initialize and attach the outer object in the is_controlled
1859 -- case
1861 if Is_Controlled (Typ) then
1862 if Ancestor_Is_Subtype_Mark then
1863 Ref := Convert_To (Init_Typ, New_Copy_Tree (Target));
1864 Set_Assignment_OK (Ref);
1865 Append_To (L,
1866 Make_Procedure_Call_Statement (Loc,
1867 Name => New_Reference_To (
1868 Find_Prim_Op (Init_Typ, Name_Initialize), Loc),
1869 Parameter_Associations => New_List (New_Copy_Tree (Ref))));
1870 end if;
1872 -- ??? when the ancestor part is an expression, the global
1873 -- object is already attached at the wrong level. It should
1874 -- be detached and re-attached. We have a design problem here.
1876 if Ancestor_Is_Expression
1877 and then Has_Controlled_Component (Init_Typ)
1878 then
1879 null;
1881 elsif Has_Controlled_Component (Typ) then
1882 F := Make_Selected_Component (Loc,
1883 Prefix => New_Copy_Tree (Target),
1884 Selector_Name => Make_Identifier (Loc, Name_uController));
1885 F := Make_Selected_Component (Loc,
1886 Prefix => F,
1887 Selector_Name => Make_Identifier (Loc, Name_F));
1889 Ref := New_Copy_Tree (Target);
1890 Set_Assignment_OK (Ref);
1892 Append_To (L,
1893 Make_Attach_Call (
1894 Obj_Ref => Ref,
1895 Flist_Ref => F,
1896 With_Attach => Make_Integer_Literal (Loc, 1)));
1898 else -- is_Controlled (Typ) and not Has_Controlled_Component (Typ)
1899 Ref := New_Copy_Tree (Target);
1900 Set_Assignment_OK (Ref);
1901 Append_To (Start_L,
1902 Make_Attach_Call (
1903 Obj_Ref => Ref,
1904 Flist_Ref => New_Copy_Tree (External_Final_List),
1905 With_Attach => Attach));
1906 end if;
1907 end if;
1909 -- in the Has_Controlled component case, all the intermediate
1910 -- controllers must be initialized
1912 if Has_Controlled_Component (Typ) then
1913 declare
1914 Inner_Typ : Entity_Id;
1915 Outer_Typ : Entity_Id;
1916 At_Root : Boolean;
1918 begin
1920 Outer_Typ := Base_Type (Typ);
1922 -- find outer type with a controller
1924 while Outer_Typ /= Init_Typ
1925 and then not Has_New_Controlled_Component (Outer_Typ)
1926 loop
1927 Outer_Typ := Etype (Outer_Typ);
1928 end loop;
1930 -- attach it to the outer record controller to the
1931 -- external final list
1933 if Outer_Typ = Init_Typ then
1934 Append_List_To (Start_L,
1935 Init_Controller (
1936 Target => Target,
1937 Typ => Outer_Typ,
1938 F => External_Final_List,
1939 Attach => Attach,
1940 Init_Pr => Ancestor_Is_Expression));
1941 At_Root := True;
1942 Inner_Typ := Init_Typ;
1944 else
1945 Append_List_To (Start_L,
1946 Init_Controller (
1947 Target => Target,
1948 Typ => Outer_Typ,
1949 F => External_Final_List,
1950 Attach => Attach,
1951 Init_Pr => True));
1953 Inner_Typ := Etype (Outer_Typ);
1954 At_Root :=
1955 not Is_Tagged_Type (Typ) or else Inner_Typ = Outer_Typ;
1956 end if;
1958 -- Initialize the internal controllers for tagged types with
1959 -- more than one controller.
1961 while not At_Root and then Inner_Typ /= Init_Typ loop
1962 if Has_New_Controlled_Component (Inner_Typ) then
1963 F :=
1964 Make_Selected_Component (Loc,
1965 Prefix => Convert_To (Outer_Typ, New_Copy_Tree (Target)),
1966 Selector_Name =>
1967 Make_Identifier (Loc, Name_uController));
1968 F := Make_Selected_Component (Loc,
1969 Prefix => F,
1970 Selector_Name => Make_Identifier (Loc, Name_F));
1971 Append_List_To (Start_L,
1972 Init_Controller (
1973 Target => Target,
1974 Typ => Inner_Typ,
1975 F => F,
1976 Attach => Make_Integer_Literal (Loc, 1),
1977 Init_Pr => True));
1978 Outer_Typ := Inner_Typ;
1979 end if;
1981 -- Stop at the root
1983 At_Root := Inner_Typ = Etype (Inner_Typ);
1984 Inner_Typ := Etype (Inner_Typ);
1985 end loop;
1987 -- if not done yet attach the controller of the ancestor part
1989 if Outer_Typ /= Init_Typ
1990 and then Inner_Typ = Init_Typ
1991 and then Has_Controlled_Component (Init_Typ)
1992 then
1993 F :=
1994 Make_Selected_Component (Loc,
1995 Prefix => Convert_To (Outer_Typ, New_Copy_Tree (Target)),
1996 Selector_Name => Make_Identifier (Loc, Name_uController));
1997 F := Make_Selected_Component (Loc,
1998 Prefix => F,
1999 Selector_Name => Make_Identifier (Loc, Name_F));
2001 Attach := Make_Integer_Literal (Loc, 1);
2002 Append_List_To (Start_L,
2003 Init_Controller (
2004 Target => Target,
2005 Typ => Init_Typ,
2006 F => F,
2007 Attach => Attach,
2008 Init_Pr => Ancestor_Is_Expression));
2009 end if;
2010 end;
2011 end if;
2013 Append_List_To (Start_L, L);
2014 return Start_L;
2015 end Build_Record_Aggr_Code;
2017 -------------------------------
2018 -- Convert_Aggr_In_Allocator --
2019 -------------------------------
2021 procedure Convert_Aggr_In_Allocator (Decl, Aggr : Node_Id) is
2022 Loc : constant Source_Ptr := Sloc (Aggr);
2023 Typ : constant Entity_Id := Etype (Aggr);
2024 Temp : constant Entity_Id := Defining_Identifier (Decl);
2025 Occ : constant Node_Id := Unchecked_Convert_To (Typ,
2026 Make_Explicit_Dereference (Loc, New_Reference_To (Temp, Loc)));
2028 Access_Type : constant Entity_Id := Etype (Temp);
2030 begin
2031 Insert_Actions_After (Decl,
2032 Late_Expansion (Aggr, Typ, Occ,
2033 Find_Final_List (Access_Type),
2034 Associated_Final_Chain (Base_Type (Access_Type))));
2035 end Convert_Aggr_In_Allocator;
2037 --------------------------------
2038 -- Convert_Aggr_In_Assignment --
2039 --------------------------------
2041 procedure Convert_Aggr_In_Assignment (N : Node_Id) is
2042 Aggr : Node_Id := Expression (N);
2043 Typ : constant Entity_Id := Etype (Aggr);
2044 Occ : constant Node_Id := New_Copy_Tree (Name (N));
2046 begin
2047 if Nkind (Aggr) = N_Qualified_Expression then
2048 Aggr := Expression (Aggr);
2049 end if;
2051 Insert_Actions_After (N,
2052 Late_Expansion (Aggr, Typ, Occ,
2053 Find_Final_List (Typ, New_Copy_Tree (Occ))));
2054 end Convert_Aggr_In_Assignment;
2056 ---------------------------------
2057 -- Convert_Aggr_In_Object_Decl --
2058 ---------------------------------
2060 procedure Convert_Aggr_In_Object_Decl (N : Node_Id) is
2061 Obj : constant Entity_Id := Defining_Identifier (N);
2062 Aggr : Node_Id := Expression (N);
2063 Loc : constant Source_Ptr := Sloc (Aggr);
2064 Typ : constant Entity_Id := Etype (Aggr);
2065 Occ : constant Node_Id := New_Occurrence_Of (Obj, Loc);
2067 begin
2068 Set_Assignment_OK (Occ);
2070 if Nkind (Aggr) = N_Qualified_Expression then
2071 Aggr := Expression (Aggr);
2072 end if;
2074 Insert_Actions_After (N, Late_Expansion (Aggr, Typ, Occ, Obj => Obj));
2075 Set_No_Initialization (N);
2076 end Convert_Aggr_In_Object_Decl;
2078 ----------------------------
2079 -- Convert_To_Assignments --
2080 ----------------------------
2082 procedure Convert_To_Assignments (N : Node_Id; Typ : Entity_Id) is
2083 Loc : constant Source_Ptr := Sloc (N);
2084 Temp : Entity_Id;
2086 Instr : Node_Id;
2087 Target_Expr : Node_Id;
2088 Parent_Kind : Node_Kind;
2089 Unc_Decl : Boolean := False;
2090 Parent_Node : Node_Id;
2092 begin
2094 Parent_Node := Parent (N);
2095 Parent_Kind := Nkind (Parent_Node);
2097 if Parent_Kind = N_Qualified_Expression then
2099 -- Check if we are in a unconstrained declaration because in this
2100 -- case the current delayed expansion mechanism doesn't work when
2101 -- the declared object size depend on the initializing expr.
2103 begin
2104 Parent_Node := Parent (Parent_Node);
2105 Parent_Kind := Nkind (Parent_Node);
2106 if Parent_Kind = N_Object_Declaration then
2107 Unc_Decl :=
2108 not Is_Entity_Name (Object_Definition (Parent_Node))
2109 or else Has_Discriminants (
2110 Entity (Object_Definition (Parent_Node)))
2111 or else Is_Class_Wide_Type (
2112 Entity (Object_Definition (Parent_Node)));
2113 end if;
2114 end;
2115 end if;
2117 -- Just set the Delay flag in the following cases where the
2118 -- transformation will be done top down from above
2119 -- - internal aggregate (transformed when expanding the parent)
2120 -- - allocators (see Convert_Aggr_In_Allocator)
2121 -- - object decl (see Convert_Aggr_In_Object_Decl)
2122 -- - safe assignments (see Convert_Aggr_Assignments)
2123 -- so far only the assignments in the init_procs are taken
2124 -- into account
2126 if Parent_Kind = N_Aggregate
2127 or else Parent_Kind = N_Extension_Aggregate
2128 or else Parent_Kind = N_Component_Association
2129 or else Parent_Kind = N_Allocator
2130 or else (Parent_Kind = N_Object_Declaration and then not Unc_Decl)
2131 or else (Parent_Kind = N_Assignment_Statement
2132 and then Inside_Init_Proc)
2133 then
2134 Set_Expansion_Delayed (N);
2135 return;
2136 end if;
2138 if Requires_Transient_Scope (Typ) then
2139 Establish_Transient_Scope (N, Sec_Stack =>
2140 Is_Controlled (Typ) or else Has_Controlled_Component (Typ));
2141 end if;
2143 -- Create the temporary
2145 Temp := Make_Defining_Identifier (Loc, New_Internal_Name ('A'));
2147 Instr :=
2148 Make_Object_Declaration (Loc,
2149 Defining_Identifier => Temp,
2150 Object_Definition => New_Occurrence_Of (Typ, Loc));
2152 Set_No_Initialization (Instr);
2153 Insert_Action (N, Instr);
2154 Target_Expr := New_Occurrence_Of (Temp, Loc);
2156 Insert_Actions (N, Build_Record_Aggr_Code (N, Typ, Target_Expr));
2157 Rewrite (N, New_Occurrence_Of (Temp, Loc));
2158 Analyze_And_Resolve (N, Typ);
2159 end Convert_To_Assignments;
2161 ----------------------------
2162 -- Expand_Array_Aggregate --
2163 ----------------------------
2165 -- Array aggregate expansion proceeds as follows:
2167 -- 1. If requested we generate code to perform all the array aggregate
2168 -- bound checks, specifically
2170 -- (a) Check that the index range defined by aggregate bounds is
2171 -- compatible with corresponding index subtype.
2173 -- (b) If an others choice is present check that no aggregate
2174 -- index is outside the bounds of the index constraint.
2176 -- (c) For multidimensional arrays make sure that all subaggregates
2177 -- corresponding to the same dimension have the same bounds.
2179 -- 2. Check if the aggregate can be statically processed. If this is the
2180 -- case pass it as is to Gigi. Note that a necessary condition for
2181 -- static processing is that the aggregate be fully positional.
2183 -- 3. If in place aggregate expansion is possible (i.e. no need to create
2184 -- a temporary) then mark the aggregate as such and return. Otherwise
2185 -- create a new temporary and generate the appropriate initialization
2186 -- code.
2188 procedure Expand_Array_Aggregate (N : Node_Id) is
2189 Loc : constant Source_Ptr := Sloc (N);
2191 Typ : constant Entity_Id := Etype (N);
2192 Ctyp : constant Entity_Id := Component_Type (Typ);
2193 -- Typ is the correct constrained array subtype of the aggregate and
2194 -- Ctyp is the corresponding component type.
2196 Aggr_Dimension : constant Pos := Number_Dimensions (Typ);
2197 -- Number of aggregate index dimensions.
2199 Aggr_Low : array (1 .. Aggr_Dimension) of Node_Id;
2200 Aggr_High : array (1 .. Aggr_Dimension) of Node_Id;
2201 -- Low and High bounds of the constraint for each aggregate index.
2203 Aggr_Index_Typ : array (1 .. Aggr_Dimension) of Entity_Id;
2204 -- The type of each index.
2206 Maybe_In_Place_OK : Boolean;
2207 -- If the type is neither controlled nor packed and the aggregate
2208 -- is the expression in an assignment, assignment in place may be
2209 -- possible, provided other conditions are met on the LHS.
2211 Others_Present : array (1 .. Aggr_Dimension) of Boolean
2212 := (others => False);
2213 -- If Others_Present (I) is True, then there is an others choice
2214 -- in one of the sub-aggregates of N at dimension I.
2216 procedure Build_Constrained_Type (Positional : Boolean);
2217 -- If the subtype is not static or unconstrained, build a constrained
2218 -- type using the computable sizes of the aggregate and its sub-
2219 -- aggregates.
2221 procedure Check_Bounds (Aggr_Bounds : Node_Id; Index_Bounds : Node_Id);
2222 -- Checks that the bounds of Aggr_Bounds are within the bounds defined
2223 -- by Index_Bounds.
2225 procedure Check_Same_Aggr_Bounds (Sub_Aggr : Node_Id; Dim : Pos);
2226 -- Checks that in a multi-dimensional array aggregate all subaggregates
2227 -- corresponding to the same dimension have the same bounds.
2228 -- Sub_Aggr is an array sub-aggregate. Dim is the dimension
2229 -- corresponding to the sub-aggregate.
2231 procedure Compute_Others_Present (Sub_Aggr : Node_Id; Dim : Pos);
2232 -- Computes the values of array Others_Present. Sub_Aggr is the
2233 -- array sub-aggregate we start the computation from. Dim is the
2234 -- dimension corresponding to the sub-aggregate.
2236 procedure Convert_To_Positional (N : Node_Id);
2237 -- If possible, convert named notation to positional notation. This
2238 -- conversion is possible only in some static cases. If the conversion
2239 -- is possible, then N is rewritten with the analyzed converted
2240 -- aggregate.
2242 function Has_Address_Clause (D : Node_Id) return Boolean;
2243 -- If the aggregate is the expression in an object declaration, it
2244 -- cannot be expanded in place. This function does a lookahead in the
2245 -- current declarative part to find an address clause for the object
2246 -- being declared.
2248 function In_Place_Assign_OK return Boolean;
2249 -- Simple predicate to determine whether an aggregate assignment can
2250 -- be done in place, because none of the new values can depend on the
2251 -- components of the target of the assignment.
2253 procedure Others_Check (Sub_Aggr : Node_Id; Dim : Pos);
2254 -- Checks that if an others choice is present in any sub-aggregate no
2255 -- aggregate index is outside the bounds of the index constraint.
2256 -- Sub_Aggr is an array sub-aggregate. Dim is the dimension
2257 -- corresponding to the sub-aggregate.
2259 ----------------------------
2260 -- Build_Constrained_Type --
2261 ----------------------------
2263 procedure Build_Constrained_Type (Positional : Boolean) is
2264 Loc : constant Source_Ptr := Sloc (N);
2265 Agg_Type : Entity_Id;
2266 Comp : Node_Id;
2267 Decl : Node_Id;
2268 Typ : constant Entity_Id := Etype (N);
2269 Indices : List_Id := New_List;
2270 Num : Int;
2271 Sub_Agg : Node_Id;
2273 begin
2274 Agg_Type :=
2275 Make_Defining_Identifier (
2276 Loc, New_Internal_Name ('A'));
2278 -- If the aggregate is purely positional, all its subaggregates
2279 -- have the same size. We collect the dimensions from the first
2280 -- subaggregate at each level.
2282 if Positional then
2283 Sub_Agg := N;
2285 for D in 1 .. Number_Dimensions (Typ) loop
2286 Comp := First (Expressions (Sub_Agg));
2288 Sub_Agg := Comp;
2289 Num := 0;
2291 while Present (Comp) loop
2292 Num := Num + 1;
2293 Next (Comp);
2294 end loop;
2296 Append (
2297 Make_Range (Loc,
2298 Low_Bound => Make_Integer_Literal (Loc, 1),
2299 High_Bound =>
2300 Make_Integer_Literal (Loc, Num)),
2301 Indices);
2302 end loop;
2304 else
2306 -- We know the aggregate type is unconstrained and the
2307 -- aggregate is not processable by the back end, therefore
2308 -- not necessarily positional. Retrieve the bounds of each
2309 -- dimension as computed earlier.
2311 for D in 1 .. Number_Dimensions (Typ) loop
2312 Append (
2313 Make_Range (Loc,
2314 Low_Bound => Aggr_Low (D),
2315 High_Bound => Aggr_High (D)),
2316 Indices);
2317 end loop;
2318 end if;
2320 Decl :=
2321 Make_Full_Type_Declaration (Loc,
2322 Defining_Identifier => Agg_Type,
2323 Type_Definition =>
2324 Make_Constrained_Array_Definition (Loc,
2325 Discrete_Subtype_Definitions => Indices,
2326 Subtype_Indication =>
2327 New_Occurrence_Of (Component_Type (Typ), Loc)));
2329 Insert_Action (N, Decl);
2330 Analyze (Decl);
2331 Set_Etype (N, Agg_Type);
2332 Set_Is_Itype (Agg_Type);
2333 Freeze_Itype (Agg_Type, N);
2334 end Build_Constrained_Type;
2336 ------------------
2337 -- Check_Bounds --
2338 ------------------
2340 procedure Check_Bounds (Aggr_Bounds : Node_Id; Index_Bounds : Node_Id) is
2341 Aggr_Lo : Node_Id;
2342 Aggr_Hi : Node_Id;
2344 Ind_Lo : Node_Id;
2345 Ind_Hi : Node_Id;
2347 Cond : Node_Id := Empty;
2349 begin
2350 Get_Index_Bounds (Aggr_Bounds, Aggr_Lo, Aggr_Hi);
2351 Get_Index_Bounds (Index_Bounds, Ind_Lo, Ind_Hi);
2353 -- Generate the following test:
2355 -- [constraint_error when
2356 -- Aggr_Lo <= Aggr_Hi and then
2357 -- (Aggr_Lo < Ind_Lo or else Aggr_Hi > Ind_Hi)]
2359 -- As an optimization try to see if some tests are trivially vacuos
2360 -- because we are comparing an expression against itself.
2362 if Aggr_Lo = Ind_Lo and then Aggr_Hi = Ind_Hi then
2363 Cond := Empty;
2365 elsif Aggr_Hi = Ind_Hi then
2366 Cond :=
2367 Make_Op_Lt (Loc,
2368 Left_Opnd => Duplicate_Subexpr (Aggr_Lo),
2369 Right_Opnd => Duplicate_Subexpr (Ind_Lo));
2371 elsif Aggr_Lo = Ind_Lo then
2372 Cond :=
2373 Make_Op_Gt (Loc,
2374 Left_Opnd => Duplicate_Subexpr (Aggr_Hi),
2375 Right_Opnd => Duplicate_Subexpr (Ind_Hi));
2377 else
2378 Cond :=
2379 Make_Or_Else (Loc,
2380 Left_Opnd =>
2381 Make_Op_Lt (Loc,
2382 Left_Opnd => Duplicate_Subexpr (Aggr_Lo),
2383 Right_Opnd => Duplicate_Subexpr (Ind_Lo)),
2385 Right_Opnd =>
2386 Make_Op_Gt (Loc,
2387 Left_Opnd => Duplicate_Subexpr (Aggr_Hi),
2388 Right_Opnd => Duplicate_Subexpr (Ind_Hi)));
2389 end if;
2391 if Present (Cond) then
2392 Cond :=
2393 Make_And_Then (Loc,
2394 Left_Opnd =>
2395 Make_Op_Le (Loc,
2396 Left_Opnd => Duplicate_Subexpr (Aggr_Lo),
2397 Right_Opnd => Duplicate_Subexpr (Aggr_Hi)),
2399 Right_Opnd => Cond);
2401 Set_Analyzed (Left_Opnd (Left_Opnd (Cond)), False);
2402 Set_Analyzed (Right_Opnd (Left_Opnd (Cond)), False);
2403 Insert_Action (N,
2404 Make_Raise_Constraint_Error (Loc, Condition => Cond));
2405 end if;
2406 end Check_Bounds;
2408 ----------------------------
2409 -- Check_Same_Aggr_Bounds --
2410 ----------------------------
2412 procedure Check_Same_Aggr_Bounds (Sub_Aggr : Node_Id; Dim : Pos) is
2413 Sub_Lo : constant Node_Id := Low_Bound (Aggregate_Bounds (Sub_Aggr));
2414 Sub_Hi : constant Node_Id := High_Bound (Aggregate_Bounds (Sub_Aggr));
2415 -- The bounds of this specific sub-aggregate.
2417 Aggr_Lo : constant Node_Id := Aggr_Low (Dim);
2418 Aggr_Hi : constant Node_Id := Aggr_High (Dim);
2419 -- The bounds of the aggregate for this dimension
2421 Ind_Typ : constant Entity_Id := Aggr_Index_Typ (Dim);
2422 -- The index type for this dimension.
2424 Cond : Node_Id := Empty;
2426 Assoc : Node_Id;
2427 Expr : Node_Id;
2429 begin
2430 -- If index checks are on generate the test
2432 -- [constraint_error when
2433 -- Aggr_Lo /= Sub_Lo or else Aggr_Hi /= Sub_Hi]
2435 -- As an optimization try to see if some tests are trivially vacuos
2436 -- because we are comparing an expression against itself. Also for
2437 -- the first dimension the test is trivially vacuous because there
2438 -- is just one aggregate for dimension 1.
2440 if Index_Checks_Suppressed (Ind_Typ) then
2441 Cond := Empty;
2443 elsif Dim = 1
2444 or else (Aggr_Lo = Sub_Lo and then Aggr_Hi = Sub_Hi)
2445 then
2446 Cond := Empty;
2448 elsif Aggr_Hi = Sub_Hi then
2449 Cond :=
2450 Make_Op_Ne (Loc,
2451 Left_Opnd => Duplicate_Subexpr (Aggr_Lo),
2452 Right_Opnd => Duplicate_Subexpr (Sub_Lo));
2454 elsif Aggr_Lo = Sub_Lo then
2455 Cond :=
2456 Make_Op_Ne (Loc,
2457 Left_Opnd => Duplicate_Subexpr (Aggr_Hi),
2458 Right_Opnd => Duplicate_Subexpr (Sub_Hi));
2460 else
2461 Cond :=
2462 Make_Or_Else (Loc,
2463 Left_Opnd =>
2464 Make_Op_Ne (Loc,
2465 Left_Opnd => Duplicate_Subexpr (Aggr_Lo),
2466 Right_Opnd => Duplicate_Subexpr (Sub_Lo)),
2468 Right_Opnd =>
2469 Make_Op_Ne (Loc,
2470 Left_Opnd => Duplicate_Subexpr (Aggr_Hi),
2471 Right_Opnd => Duplicate_Subexpr (Sub_Hi)));
2472 end if;
2474 if Present (Cond) then
2475 Insert_Action (N,
2476 Make_Raise_Constraint_Error (Loc, Condition => Cond));
2477 end if;
2479 -- Now look inside the sub-aggregate to see if there is more work
2481 if Dim < Aggr_Dimension then
2483 -- Process positional components
2485 if Present (Expressions (Sub_Aggr)) then
2486 Expr := First (Expressions (Sub_Aggr));
2487 while Present (Expr) loop
2488 Check_Same_Aggr_Bounds (Expr, Dim + 1);
2489 Next (Expr);
2490 end loop;
2491 end if;
2493 -- Process component associations
2495 if Present (Component_Associations (Sub_Aggr)) then
2496 Assoc := First (Component_Associations (Sub_Aggr));
2497 while Present (Assoc) loop
2498 Expr := Expression (Assoc);
2499 Check_Same_Aggr_Bounds (Expr, Dim + 1);
2500 Next (Assoc);
2501 end loop;
2502 end if;
2503 end if;
2504 end Check_Same_Aggr_Bounds;
2506 ----------------------------
2507 -- Compute_Others_Present --
2508 ----------------------------
2510 procedure Compute_Others_Present (Sub_Aggr : Node_Id; Dim : Pos) is
2511 Assoc : Node_Id;
2512 Expr : Node_Id;
2514 begin
2515 if Present (Component_Associations (Sub_Aggr)) then
2516 Assoc := Last (Component_Associations (Sub_Aggr));
2517 if Nkind (First (Choices (Assoc))) = N_Others_Choice then
2518 Others_Present (Dim) := True;
2519 end if;
2520 end if;
2522 -- Now look inside the sub-aggregate to see if there is more work
2524 if Dim < Aggr_Dimension then
2526 -- Process positional components
2528 if Present (Expressions (Sub_Aggr)) then
2529 Expr := First (Expressions (Sub_Aggr));
2530 while Present (Expr) loop
2531 Compute_Others_Present (Expr, Dim + 1);
2532 Next (Expr);
2533 end loop;
2534 end if;
2536 -- Process component associations
2538 if Present (Component_Associations (Sub_Aggr)) then
2539 Assoc := First (Component_Associations (Sub_Aggr));
2540 while Present (Assoc) loop
2541 Expr := Expression (Assoc);
2542 Compute_Others_Present (Expr, Dim + 1);
2543 Next (Assoc);
2544 end loop;
2545 end if;
2546 end if;
2547 end Compute_Others_Present;
2549 ---------------------------
2550 -- Convert_To_Positional --
2551 ---------------------------
2553 procedure Convert_To_Positional (N : Node_Id) is
2554 Typ : constant Entity_Id := Etype (N);
2555 Ndim : constant Pos := Number_Dimensions (Typ);
2556 Xtyp : constant Entity_Id := Etype (First_Index (Typ));
2557 Blo : constant Node_Id :=
2558 Type_Low_Bound (Etype (First_Index (Base_Type (Typ))));
2559 Lo : constant Node_Id := Type_Low_Bound (Xtyp);
2560 Hi : constant Node_Id := Type_High_Bound (Xtyp);
2561 Lov : Uint;
2562 Hiv : Uint;
2564 Max_Aggr_Size : constant := 500;
2565 -- Maximum size of aggregate produced by converting positional to
2566 -- named notation. This avoids running away with attempts to
2567 -- convert huge aggregates.
2569 Max_Others_Replicate : constant := 5;
2570 -- This constant defines the maximum expansion of an others clause
2571 -- into a list of values. This applies when converting a named
2572 -- aggregate to positional form for processing by the back end.
2573 -- If a given others clause generates more than five values, the
2574 -- aggregate is retained as named, since the loop is more compact.
2575 -- However, this constant is completely overridden if restriction
2576 -- No_Elaboration_Code is active, since in this case, the loop
2577 -- would not be allowed anyway. Similarly No_Implicit_Loops causes
2578 -- this parameter to be ignored.
2580 begin
2581 -- For now, we only handle the one dimensional case and aggregates
2582 -- that are not part of a component_association
2584 if Ndim > 1 or else Nkind (Parent (N)) = N_Aggregate
2585 or else Nkind (Parent (N)) = N_Component_Association
2586 then
2587 return;
2588 end if;
2590 -- If already positional, nothing to do!
2592 if No (Component_Associations (N)) then
2593 return;
2594 end if;
2596 -- Bounds need to be known at compile time
2598 if not Compile_Time_Known_Value (Lo)
2599 or else not Compile_Time_Known_Value (Hi)
2600 then
2601 return;
2602 end if;
2604 -- Do not attempt to convert bit packed arrays, since they cannot
2605 -- be handled by the backend in any case.
2607 if Is_Bit_Packed_Array (Typ) then
2608 return;
2609 end if;
2611 -- Do not convert to positional if controlled components are
2612 -- involved since these require special processing
2614 if Has_Controlled_Component (Typ) then
2615 return;
2616 end if;
2618 -- Get bounds and check reasonable size (positive, not too large)
2619 -- Also only handle bounds starting at the base type low bound for
2620 -- now since the compiler isn't able to handle different low bounds
2621 -- yet
2623 Lov := Expr_Value (Lo);
2624 Hiv := Expr_Value (Hi);
2626 if Hiv < Lov
2627 or else (Hiv - Lov > Max_Aggr_Size)
2628 or else not Compile_Time_Known_Value (Blo)
2629 or else (Lov /= Expr_Value (Blo))
2630 then
2631 return;
2632 end if;
2634 -- Bounds must be in integer range (for array Vals below)
2636 if not UI_Is_In_Int_Range (Lov)
2637 or else
2638 not UI_Is_In_Int_Range (Hiv)
2639 then
2640 return;
2641 end if;
2643 -- Determine if set of alternatives is suitable for conversion
2644 -- and build an array containing the values in sequence.
2646 declare
2647 Vals : array (UI_To_Int (Lov) .. UI_To_Int (Hiv))
2648 of Node_Id := (others => Empty);
2649 -- The values in the aggregate sorted appropriately
2651 Vlist : List_Id;
2652 -- Same data as Vals in list form
2654 Rep_Count : Nat;
2655 -- Used to validate Max_Others_Replicate limit
2657 Elmt : Node_Id;
2658 Num : Int := UI_To_Int (Lov);
2659 Choice : Node_Id;
2660 Lo, Hi : Node_Id;
2662 begin
2663 if Present (Expressions (N)) then
2664 Elmt := First (Expressions (N));
2665 while Present (Elmt) loop
2666 Vals (Num) := Relocate_Node (Elmt);
2667 Num := Num + 1;
2668 Next (Elmt);
2669 end loop;
2670 end if;
2672 Elmt := First (Component_Associations (N));
2673 Component_Loop : while Present (Elmt) loop
2675 Choice := First (Choices (Elmt));
2676 Choice_Loop : while Present (Choice) loop
2678 -- If we have an others choice, fill in the missing elements
2679 -- subject to the limit established by Max_Others_Replicate.
2681 if Nkind (Choice) = N_Others_Choice then
2682 Rep_Count := 0;
2684 for J in Vals'Range loop
2685 if No (Vals (J)) then
2686 Vals (J) := New_Copy_Tree (Expression (Elmt));
2687 Rep_Count := Rep_Count + 1;
2689 if Rep_Count > Max_Others_Replicate
2690 and then not Restrictions (No_Elaboration_Code)
2691 and then not Restrictions (No_Implicit_Loops)
2692 then
2693 return;
2694 end if;
2695 end if;
2696 end loop;
2698 exit Component_Loop;
2700 -- Case of a subtype mark
2702 elsif (Nkind (Choice) = N_Identifier
2703 and then Is_Type (Entity (Choice)))
2704 then
2705 Lo := Type_Low_Bound (Etype (Choice));
2706 Hi := Type_High_Bound (Etype (Choice));
2708 -- Case of subtype indication
2710 elsif Nkind (Choice) = N_Subtype_Indication then
2711 Lo := Low_Bound (Range_Expression (Constraint (Choice)));
2712 Hi := High_Bound (Range_Expression (Constraint (Choice)));
2714 -- Case of a range
2716 elsif Nkind (Choice) = N_Range then
2717 Lo := Low_Bound (Choice);
2718 Hi := High_Bound (Choice);
2720 -- Normal subexpression case
2722 else pragma Assert (Nkind (Choice) in N_Subexpr);
2723 if not Compile_Time_Known_Value (Choice) then
2724 return;
2726 else
2727 Vals (UI_To_Int (Expr_Value (Choice))) :=
2728 New_Copy_Tree (Expression (Elmt));
2729 goto Continue;
2730 end if;
2731 end if;
2733 -- Range cases merge with Lo,Hi said
2735 if not Compile_Time_Known_Value (Lo)
2736 or else
2737 not Compile_Time_Known_Value (Hi)
2738 then
2739 return;
2740 else
2741 for J in UI_To_Int (Expr_Value (Lo)) ..
2742 UI_To_Int (Expr_Value (Hi))
2743 loop
2744 Vals (J) := New_Copy_Tree (Expression (Elmt));
2745 end loop;
2746 end if;
2748 <<Continue>>
2749 Next (Choice);
2750 end loop Choice_Loop;
2752 Next (Elmt);
2753 end loop Component_Loop;
2755 -- If we get here the conversion is possible
2757 Vlist := New_List;
2758 for J in Vals'Range loop
2759 Append (Vals (J), Vlist);
2760 end loop;
2762 Rewrite (N, Make_Aggregate (Loc, Expressions => Vlist));
2763 Analyze_And_Resolve (N, Typ);
2764 end;
2765 end Convert_To_Positional;
2767 -------------------------
2768 -- Has_Address_Clause --
2769 -------------------------
2771 function Has_Address_Clause (D : Node_Id) return Boolean is
2772 Id : Entity_Id := Defining_Identifier (D);
2773 Decl : Node_Id := Next (D);
2775 begin
2776 while Present (Decl) loop
2778 if Nkind (Decl) = N_At_Clause
2779 and then Chars (Identifier (Decl)) = Chars (Id)
2780 then
2781 return True;
2783 elsif Nkind (Decl) = N_Attribute_Definition_Clause
2784 and then Chars (Decl) = Name_Address
2785 and then Chars (Name (Decl)) = Chars (Id)
2786 then
2787 return True;
2788 end if;
2790 Next (Decl);
2791 end loop;
2793 return False;
2794 end Has_Address_Clause;
2796 ------------------------
2797 -- In_Place_Assign_OK --
2798 ------------------------
2800 function In_Place_Assign_OK return Boolean is
2801 Aggr_In : Node_Id;
2802 Aggr_Lo : Node_Id;
2803 Aggr_Hi : Node_Id;
2804 Obj_In : Node_Id;
2805 Obj_Lo : Node_Id;
2806 Obj_Hi : Node_Id;
2808 function Safe_Aggregate (Aggr : Node_Id) return Boolean;
2809 -- Check recursively that each component of a (sub)aggregate does
2810 -- not depend on the variable being assigned to.
2812 function Safe_Component (Expr : Node_Id) return Boolean;
2813 -- Verify that an expression cannot depend on the variable being
2814 -- assigned to. Room for improvement here (but less than before).
2816 --------------------
2817 -- Safe_Aggregate --
2818 --------------------
2820 function Safe_Aggregate (Aggr : Node_Id) return Boolean is
2821 Expr : Node_Id;
2823 begin
2824 if Present (Expressions (Aggr)) then
2825 Expr := First (Expressions (Aggr));
2827 while Present (Expr) loop
2828 if Nkind (Expr) = N_Aggregate then
2829 if not Safe_Aggregate (Expr) then
2830 return False;
2831 end if;
2833 elsif not Safe_Component (Expr) then
2834 return False;
2835 end if;
2837 Next (Expr);
2838 end loop;
2839 end if;
2841 if Present (Component_Associations (Aggr)) then
2842 Expr := First (Component_Associations (Aggr));
2844 while Present (Expr) loop
2845 if Nkind (Expression (Expr)) = N_Aggregate then
2846 if not Safe_Aggregate (Expression (Expr)) then
2847 return False;
2848 end if;
2850 elsif not Safe_Component (Expression (Expr)) then
2851 return False;
2852 end if;
2854 Next (Expr);
2855 end loop;
2856 end if;
2858 return True;
2859 end Safe_Aggregate;
2861 --------------------
2862 -- Safe_Component --
2863 --------------------
2865 function Safe_Component (Expr : Node_Id) return Boolean is
2866 Comp : Node_Id := Expr;
2868 function Check_Component (Comp : Node_Id) return Boolean;
2869 -- Do the recursive traversal, after copy.
2871 function Check_Component (Comp : Node_Id) return Boolean is
2872 begin
2873 if Is_Overloaded (Comp) then
2874 return False;
2875 end if;
2877 return Compile_Time_Known_Value (Comp)
2879 or else (Is_Entity_Name (Comp)
2880 and then Present (Entity (Comp))
2881 and then No (Renamed_Object (Entity (Comp))))
2883 or else (Nkind (Comp) = N_Attribute_Reference
2884 and then Check_Component (Prefix (Comp)))
2886 or else (Nkind (Comp) in N_Binary_Op
2887 and then Check_Component (Left_Opnd (Comp))
2888 and then Check_Component (Right_Opnd (Comp)))
2890 or else (Nkind (Comp) in N_Unary_Op
2891 and then Check_Component (Right_Opnd (Comp)))
2893 or else (Nkind (Comp) = N_Selected_Component
2894 and then Check_Component (Prefix (Comp)));
2895 end Check_Component;
2897 -- Start of processing for Safe_Component
2899 begin
2900 -- If the component appears in an association that may
2901 -- correspond to more than one element, it is not analyzed
2902 -- before the expansion into assignments, to avoid side effects.
2903 -- We analyze, but do not resolve the copy, to obtain sufficient
2904 -- entity information for the checks that follow. If component is
2905 -- overloaded we assume an unsafe function call.
2907 if not Analyzed (Comp) then
2908 if Is_Overloaded (Expr) then
2909 return False;
2910 end if;
2912 Comp := New_Copy_Tree (Expr);
2913 Analyze (Comp);
2914 end if;
2916 return Check_Component (Comp);
2917 end Safe_Component;
2919 -- Start of processing for In_Place_Assign_OK
2921 begin
2922 if Present (Component_Associations (N)) then
2924 -- On assignment, sliding can take place, so we cannot do the
2925 -- assignment in place unless the bounds of the aggregate are
2926 -- statically equal to those of the target.
2928 -- If the aggregate is given by an others choice, the bounds
2929 -- are derived from the left-hand side, and the assignment is
2930 -- safe if the expression is.
2932 if No (Expressions (N))
2933 and then Nkind
2934 (First (Choices (First (Component_Associations (N)))))
2935 = N_Others_Choice
2936 then
2937 return
2938 Safe_Component
2939 (Expression (First (Component_Associations (N))));
2940 end if;
2942 Aggr_In := First_Index (Etype (N));
2943 Obj_In := First_Index (Etype (Name (Parent (N))));
2945 while Present (Aggr_In) loop
2946 Get_Index_Bounds (Aggr_In, Aggr_Lo, Aggr_Hi);
2947 Get_Index_Bounds (Obj_In, Obj_Lo, Obj_Hi);
2949 if not Compile_Time_Known_Value (Aggr_Lo)
2950 or else not Compile_Time_Known_Value (Aggr_Hi)
2951 or else not Compile_Time_Known_Value (Obj_Lo)
2952 or else not Compile_Time_Known_Value (Obj_Hi)
2953 or else Expr_Value (Aggr_Lo) /= Expr_Value (Obj_Lo)
2954 or else Expr_Value (Aggr_Hi) /= Expr_Value (Obj_Hi)
2955 then
2956 return False;
2957 end if;
2959 Next_Index (Aggr_In);
2960 Next_Index (Obj_In);
2961 end loop;
2962 end if;
2964 -- Now check the component values themselves.
2966 return Safe_Aggregate (N);
2967 end In_Place_Assign_OK;
2969 ------------------
2970 -- Others_Check --
2971 ------------------
2973 procedure Others_Check (Sub_Aggr : Node_Id; Dim : Pos) is
2974 Aggr_Lo : constant Node_Id := Aggr_Low (Dim);
2975 Aggr_Hi : constant Node_Id := Aggr_High (Dim);
2976 -- The bounds of the aggregate for this dimension.
2978 Ind_Typ : constant Entity_Id := Aggr_Index_Typ (Dim);
2979 -- The index type for this dimension.
2981 Need_To_Check : Boolean := False;
2983 Choices_Lo : Node_Id := Empty;
2984 Choices_Hi : Node_Id := Empty;
2985 -- The lowest and highest discrete choices for a named sub-aggregate
2987 Nb_Choices : Int := -1;
2988 -- The number of discrete non-others choices in this sub-aggregate
2990 Nb_Elements : Uint := Uint_0;
2991 -- The number of elements in a positional aggregate
2993 Cond : Node_Id := Empty;
2995 Assoc : Node_Id;
2996 Choice : Node_Id;
2997 Expr : Node_Id;
2999 begin
3000 -- Check if we have an others choice. If we do make sure that this
3001 -- sub-aggregate contains at least one element in addition to the
3002 -- others choice.
3004 if Range_Checks_Suppressed (Ind_Typ) then
3005 Need_To_Check := False;
3007 elsif Present (Expressions (Sub_Aggr))
3008 and then Present (Component_Associations (Sub_Aggr))
3009 then
3010 Need_To_Check := True;
3012 elsif Present (Component_Associations (Sub_Aggr)) then
3013 Assoc := Last (Component_Associations (Sub_Aggr));
3015 if Nkind (First (Choices (Assoc))) /= N_Others_Choice then
3016 Need_To_Check := False;
3018 else
3019 -- Count the number of discrete choices. Start with -1
3020 -- because the others choice does not count.
3022 Nb_Choices := -1;
3023 Assoc := First (Component_Associations (Sub_Aggr));
3024 while Present (Assoc) loop
3025 Choice := First (Choices (Assoc));
3026 while Present (Choice) loop
3027 Nb_Choices := Nb_Choices + 1;
3028 Next (Choice);
3029 end loop;
3031 Next (Assoc);
3032 end loop;
3034 -- If there is only an others choice nothing to do
3036 Need_To_Check := (Nb_Choices > 0);
3037 end if;
3039 else
3040 Need_To_Check := False;
3041 end if;
3043 -- If we are dealing with a positional sub-aggregate with an
3044 -- others choice, compute the number or positional elements.
3046 if Need_To_Check and then Present (Expressions (Sub_Aggr)) then
3047 Expr := First (Expressions (Sub_Aggr));
3048 Nb_Elements := Uint_0;
3049 while Present (Expr) loop
3050 Nb_Elements := Nb_Elements + 1;
3051 Next (Expr);
3052 end loop;
3054 -- If the aggregate contains discrete choices and an others choice
3055 -- compute the smallest and largest discrete choice values.
3057 elsif Need_To_Check then
3058 Compute_Choices_Lo_And_Choices_Hi : declare
3059 Table : Case_Table_Type (1 .. Nb_Choices);
3060 -- Used to sort all the different choice values
3062 I : Pos := 1;
3063 Low : Node_Id;
3064 High : Node_Id;
3066 begin
3067 Assoc := First (Component_Associations (Sub_Aggr));
3068 while Present (Assoc) loop
3069 Choice := First (Choices (Assoc));
3070 while Present (Choice) loop
3071 if Nkind (Choice) = N_Others_Choice then
3072 exit;
3073 end if;
3075 Get_Index_Bounds (Choice, Low, High);
3076 Table (I).Choice_Lo := Low;
3077 Table (I).Choice_Hi := High;
3079 I := I + 1;
3080 Next (Choice);
3081 end loop;
3083 Next (Assoc);
3084 end loop;
3086 -- Sort the discrete choices
3088 Sort_Case_Table (Table);
3090 Choices_Lo := Table (1).Choice_Lo;
3091 Choices_Hi := Table (Nb_Choices).Choice_Hi;
3092 end Compute_Choices_Lo_And_Choices_Hi;
3093 end if;
3095 -- If no others choice in this sub-aggregate, or the aggregate
3096 -- comprises only an others choice, nothing to do.
3098 if not Need_To_Check then
3099 Cond := Empty;
3101 -- If we are dealing with an aggregate containing an others
3102 -- choice and positional components, we generate the following test:
3104 -- if Ind_Typ'Pos (Aggr_Lo) + (Nb_Elements - 1) >
3105 -- Ind_Typ'Pos (Aggr_Hi)
3106 -- then
3107 -- raise Constraint_Error;
3108 -- end if;
3110 elsif Nb_Elements > Uint_0 then
3111 Cond :=
3112 Make_Op_Gt (Loc,
3113 Left_Opnd =>
3114 Make_Op_Add (Loc,
3115 Left_Opnd =>
3116 Make_Attribute_Reference (Loc,
3117 Prefix => New_Reference_To (Ind_Typ, Loc),
3118 Attribute_Name => Name_Pos,
3119 Expressions =>
3120 New_List (Duplicate_Subexpr (Aggr_Lo))),
3121 Right_Opnd => Make_Integer_Literal (Loc, Nb_Elements - 1)),
3123 Right_Opnd =>
3124 Make_Attribute_Reference (Loc,
3125 Prefix => New_Reference_To (Ind_Typ, Loc),
3126 Attribute_Name => Name_Pos,
3127 Expressions => New_List (Duplicate_Subexpr (Aggr_Hi))));
3129 -- If we are dealing with an aggregate containing an others
3130 -- choice and discrete choices we generate the following test:
3132 -- [constraint_error when
3133 -- Choices_Lo < Aggr_Lo or else Choices_Hi > Aggr_Hi];
3135 else
3136 Cond :=
3137 Make_Or_Else (Loc,
3138 Left_Opnd =>
3139 Make_Op_Lt (Loc,
3140 Left_Opnd => Duplicate_Subexpr (Choices_Lo),
3141 Right_Opnd => Duplicate_Subexpr (Aggr_Lo)),
3143 Right_Opnd =>
3144 Make_Op_Gt (Loc,
3145 Left_Opnd => Duplicate_Subexpr (Choices_Hi),
3146 Right_Opnd => Duplicate_Subexpr (Aggr_Hi)));
3147 end if;
3149 if Present (Cond) then
3150 Insert_Action (N,
3151 Make_Raise_Constraint_Error (Loc, Condition => Cond));
3152 end if;
3154 -- Now look inside the sub-aggregate to see if there is more work
3156 if Dim < Aggr_Dimension then
3158 -- Process positional components
3160 if Present (Expressions (Sub_Aggr)) then
3161 Expr := First (Expressions (Sub_Aggr));
3162 while Present (Expr) loop
3163 Others_Check (Expr, Dim + 1);
3164 Next (Expr);
3165 end loop;
3166 end if;
3168 -- Process component associations
3170 if Present (Component_Associations (Sub_Aggr)) then
3171 Assoc := First (Component_Associations (Sub_Aggr));
3172 while Present (Assoc) loop
3173 Expr := Expression (Assoc);
3174 Others_Check (Expr, Dim + 1);
3175 Next (Assoc);
3176 end loop;
3177 end if;
3178 end if;
3179 end Others_Check;
3181 -- Remaining Expand_Array_Aggregate variables
3183 Tmp : Entity_Id;
3184 -- Holds the temporary aggregate value.
3186 Tmp_Decl : Node_Id;
3187 -- Holds the declaration of Tmp.
3189 Aggr_Code : List_Id;
3190 Parent_Node : Node_Id;
3191 Parent_Kind : Node_Kind;
3193 -- Start of processing for Expand_Array_Aggregate
3195 begin
3196 -- Do not touch the special aggregates of attributes used for Asm calls
3198 if Is_RTE (Ctyp, RE_Asm_Input_Operand)
3199 or else Is_RTE (Ctyp, RE_Asm_Output_Operand)
3200 then
3201 return;
3202 end if;
3204 -- If during semantic analysis it has been determined that aggregate N
3205 -- will raise Constraint_Error at run-time, then the aggregate node
3206 -- has been replaced with an N_Raise_Constraint_Error node and we
3207 -- should never get here.
3209 pragma Assert (not Raises_Constraint_Error (N));
3211 -- STEP 1: Check (a)
3213 Index_Compatibility_Check : declare
3214 Aggr_Index_Range : Node_Id := First_Index (Typ);
3215 -- The current aggregate index range
3217 Index_Constraint : Node_Id := First_Index (Etype (Typ));
3218 -- The corresponding index constraint against which we have to
3219 -- check the above aggregate index range.
3221 begin
3222 Compute_Others_Present (N, 1);
3224 for J in 1 .. Aggr_Dimension loop
3225 -- There is no need to emit a check if an others choice is
3226 -- present for this array aggregate dimension since in this
3227 -- case one of N's sub-aggregates has taken its bounds from the
3228 -- context and these bounds must have been checked already. In
3229 -- addition all sub-aggregates corresponding to the same
3230 -- dimension must all have the same bounds (checked in (c) below).
3232 if not Range_Checks_Suppressed (Etype (Index_Constraint))
3233 and then not Others_Present (J)
3234 then
3235 -- We don't use Checks.Apply_Range_Check here because it
3236 -- emits a spurious check. Namely it checks that the range
3237 -- defined by the aggregate bounds is non empty. But we know
3238 -- this already if we get here.
3240 Check_Bounds (Aggr_Index_Range, Index_Constraint);
3241 end if;
3243 -- Save the low and high bounds of the aggregate index as well
3244 -- as the index type for later use in checks (b) and (c) below.
3246 Aggr_Low (J) := Low_Bound (Aggr_Index_Range);
3247 Aggr_High (J) := High_Bound (Aggr_Index_Range);
3249 Aggr_Index_Typ (J) := Etype (Index_Constraint);
3251 Next_Index (Aggr_Index_Range);
3252 Next_Index (Index_Constraint);
3253 end loop;
3254 end Index_Compatibility_Check;
3256 -- STEP 1: Check (b)
3258 Others_Check (N, 1);
3260 -- STEP 1: Check (c)
3262 if Aggr_Dimension > 1 then
3263 Check_Same_Aggr_Bounds (N, 1);
3264 end if;
3266 -- STEP 2.
3268 -- First try to convert to positional form. If the result is not
3269 -- an aggregate any more, then we are done with the analysis (it
3270 -- it could be a string literal or an identifier for a temporary
3271 -- variable following this call). If result is an analyzed aggregate
3272 -- the transformation was also successful and we are done as well.
3274 Convert_To_Positional (N);
3276 if Nkind (N) /= N_Aggregate then
3277 return;
3279 elsif Analyzed (N)
3280 and then N /= Original_Node (N)
3281 then
3282 return;
3283 end if;
3285 if Backend_Processing_Possible (N) then
3287 -- If the aggregate is static but the constraints are not, build
3288 -- a static subtype for the aggregate, so that Gigi can place it
3289 -- in static memory. Perform an unchecked_conversion to the non-
3290 -- static type imposed by the context.
3292 declare
3293 Itype : constant Entity_Id := Etype (N);
3294 Index : Node_Id;
3295 Needs_Type : Boolean := False;
3297 begin
3298 Index := First_Index (Itype);
3300 while Present (Index) loop
3301 if not Is_Static_Subtype (Etype (Index)) then
3302 Needs_Type := True;
3303 exit;
3304 else
3305 Next_Index (Index);
3306 end if;
3307 end loop;
3309 if Needs_Type then
3310 Build_Constrained_Type (Positional => True);
3311 Rewrite (N, Unchecked_Convert_To (Itype, N));
3312 Analyze (N);
3313 end if;
3314 end;
3316 return;
3317 end if;
3319 -- Delay expansion for nested aggregates it will be taken care of
3320 -- when the parent aggregate is expanded
3322 Parent_Node := Parent (N);
3323 Parent_Kind := Nkind (Parent_Node);
3325 if Parent_Kind = N_Qualified_Expression then
3326 Parent_Node := Parent (Parent_Node);
3327 Parent_Kind := Nkind (Parent_Node);
3328 end if;
3330 if Parent_Kind = N_Aggregate
3331 or else Parent_Kind = N_Extension_Aggregate
3332 or else Parent_Kind = N_Component_Association
3333 or else (Parent_Kind = N_Object_Declaration
3334 and then Controlled_Type (Typ))
3335 or else (Parent_Kind = N_Assignment_Statement
3336 and then Inside_Init_Proc)
3337 then
3338 Set_Expansion_Delayed (N);
3339 return;
3340 end if;
3342 -- STEP 3.
3344 -- Look if in place aggregate expansion is possible
3346 -- For object declarations we build the aggregate in place, unless
3347 -- the array is bit-packed or the component is controlled.
3349 -- For assignments we do the assignment in place if all the component
3350 -- associations have compile-time known values. For other cases we
3351 -- create a temporary. The analysis for safety of on-line assignment
3352 -- is delicate, i.e. we don't know how to do it fully yet ???
3354 if Requires_Transient_Scope (Typ) then
3355 Establish_Transient_Scope
3356 (N, Sec_Stack => Has_Controlled_Component (Typ));
3357 end if;
3359 Maybe_In_Place_OK :=
3360 Comes_From_Source (N)
3361 and then Nkind (Parent (N)) = N_Assignment_Statement
3362 and then not Is_Bit_Packed_Array (Typ)
3363 and then not Has_Controlled_Component (Typ)
3364 and then In_Place_Assign_OK;
3366 if Comes_From_Source (Parent (N))
3367 and then Nkind (Parent (N)) = N_Object_Declaration
3368 and then N = Expression (Parent (N))
3369 and then not Is_Bit_Packed_Array (Typ)
3370 and then not Has_Controlled_Component (Typ)
3371 and then not Has_Address_Clause (Parent (N))
3372 then
3374 Tmp := Defining_Identifier (Parent (N));
3375 Set_No_Initialization (Parent (N));
3376 Set_Expression (Parent (N), Empty);
3378 -- Set the type of the entity, for use in the analysis of the
3379 -- subsequent indexed assignments. If the nominal type is not
3380 -- constrained, build a subtype from the known bounds of the
3381 -- aggregate. If the declaration has a subtype mark, use it,
3382 -- otherwise use the itype of the aggregate.
3384 if not Is_Constrained (Typ) then
3385 Build_Constrained_Type (Positional => False);
3386 elsif Is_Entity_Name (Object_Definition (Parent (N)))
3387 and then Is_Constrained (Entity (Object_Definition (Parent (N))))
3388 then
3389 Set_Etype (Tmp, Entity (Object_Definition (Parent (N))));
3390 else
3391 Set_Size_Known_At_Compile_Time (Typ, False);
3392 Set_Etype (Tmp, Typ);
3393 end if;
3395 elsif Maybe_In_Place_OK
3396 and then Is_Entity_Name (Name (Parent (N)))
3397 then
3398 Tmp := Entity (Name (Parent (N)));
3400 if Etype (Tmp) /= Etype (N) then
3401 Apply_Length_Check (N, Etype (Tmp));
3402 end if;
3404 elsif Maybe_In_Place_OK
3405 and then Nkind (Name (Parent (N))) = N_Slice
3406 and then Safe_Slice_Assignment (N, Typ)
3407 then
3408 -- Safe_Slice_Assignment rewrites assignment as a loop.
3410 return;
3412 else
3413 Tmp := Make_Defining_Identifier (Loc, New_Internal_Name ('A'));
3414 Tmp_Decl :=
3415 Make_Object_Declaration
3416 (Loc,
3417 Defining_Identifier => Tmp,
3418 Object_Definition => New_Occurrence_Of (Typ, Loc));
3419 Set_No_Initialization (Tmp_Decl, True);
3421 -- If we are within a loop, the temporary will be pushed on the
3422 -- stack at each iteration. If the aggregate is the expression for
3423 -- an allocator, it will be immediately copied to the heap and can
3424 -- be reclaimed at once. We create a transient scope around the
3425 -- aggregate for this purpose.
3427 if Ekind (Current_Scope) = E_Loop
3428 and then Nkind (Parent (Parent (N))) = N_Allocator
3429 then
3430 Establish_Transient_Scope (N, False);
3431 end if;
3433 Insert_Action (N, Tmp_Decl);
3434 end if;
3436 -- Construct and insert the aggregate code. We can safely suppress
3437 -- index checks because this code is guaranteed not to raise CE
3438 -- on index checks. However we should *not* suppress all checks.
3440 Aggr_Code :=
3441 Build_Array_Aggr_Code (N,
3442 Index => First_Index (Typ),
3443 Into => New_Reference_To (Tmp, Loc),
3444 Scalar_Comp => Is_Scalar_Type (Ctyp));
3446 if Comes_From_Source (Tmp) then
3447 Insert_Actions_After (Parent (N), Aggr_Code);
3449 else
3450 Insert_Actions (N, Aggr_Code);
3451 end if;
3453 if Nkind (Parent (N)) = N_Assignment_Statement
3454 and then Is_Entity_Name (Name (Parent (N)))
3455 and then Tmp = Entity (Name (Parent (N)))
3456 then
3457 Rewrite (Parent (N), Make_Null_Statement (Loc));
3458 Analyze (N);
3460 elsif Nkind (Parent (N)) /= N_Object_Declaration
3461 or else Tmp /= Defining_Identifier (Parent (N))
3462 then
3463 Rewrite (N, New_Occurrence_Of (Tmp, Loc));
3464 Analyze_And_Resolve (N, Typ);
3465 end if;
3466 end Expand_Array_Aggregate;
3468 ------------------------
3469 -- Expand_N_Aggregate --
3470 ------------------------
3472 procedure Expand_N_Aggregate (N : Node_Id) is
3473 begin
3474 if Is_Record_Type (Etype (N)) then
3475 Expand_Record_Aggregate (N);
3476 else
3477 Expand_Array_Aggregate (N);
3478 end if;
3479 end Expand_N_Aggregate;
3481 ----------------------------------
3482 -- Expand_N_Extension_Aggregate --
3483 ----------------------------------
3485 -- If the ancestor part is an expression, add a component association for
3486 -- the parent field. If the type of the ancestor part is not the direct
3487 -- parent of the expected type, build recursively the needed ancestors.
3488 -- If the ancestor part is a subtype_mark, replace aggregate with a decla-
3489 -- ration for a temporary of the expected type, followed by individual
3490 -- assignments to the given components.
3492 procedure Expand_N_Extension_Aggregate (N : Node_Id) is
3493 Loc : constant Source_Ptr := Sloc (N);
3494 A : constant Node_Id := Ancestor_Part (N);
3495 Typ : constant Entity_Id := Etype (N);
3497 begin
3498 -- If the ancestor is a subtype mark, an init_proc must be called
3499 -- on the resulting object which thus has to be materialized in
3500 -- the front-end
3502 if Is_Entity_Name (A) and then Is_Type (Entity (A)) then
3503 Convert_To_Assignments (N, Typ);
3505 -- The extension aggregate is transformed into a record aggregate
3506 -- of the following form (c1 and c2 are inherited components)
3508 -- (Exp with c3 => a, c4 => b)
3509 -- ==> (c1 => Exp.c1, c2 => Exp.c2, c1 => a, c2 => b)
3511 else
3512 Set_Etype (N, Typ);
3514 -- No tag is needed in the case of Java_VM
3516 if Java_VM then
3517 Expand_Record_Aggregate (N,
3518 Parent_Expr => A);
3519 else
3520 Expand_Record_Aggregate (N,
3521 Orig_Tag => New_Occurrence_Of (Access_Disp_Table (Typ), Loc),
3522 Parent_Expr => A);
3523 end if;
3524 end if;
3525 end Expand_N_Extension_Aggregate;
3527 -----------------------------
3528 -- Expand_Record_Aggregate --
3529 -----------------------------
3531 procedure Expand_Record_Aggregate
3532 (N : Node_Id;
3533 Orig_Tag : Node_Id := Empty;
3534 Parent_Expr : Node_Id := Empty)
3536 Loc : constant Source_Ptr := Sloc (N);
3537 Comps : constant List_Id := Component_Associations (N);
3538 Typ : constant Entity_Id := Etype (N);
3539 Base_Typ : constant Entity_Id := Base_Type (Typ);
3541 function Has_Delayed_Nested_Aggregate_Or_Tagged_Comps return Boolean;
3542 -- Checks the presence of a nested aggregate which needs Late_Expansion
3543 -- or the presence of tagged components which may need tag adjustment.
3545 --------------------------------------------------
3546 -- Has_Delayed_Nested_Aggregate_Or_Tagged_Comps --
3547 --------------------------------------------------
3549 function Has_Delayed_Nested_Aggregate_Or_Tagged_Comps return Boolean is
3550 C : Node_Id;
3551 Expr_Q : Node_Id;
3553 begin
3554 if No (Comps) then
3555 return False;
3556 end if;
3558 C := First (Comps);
3559 while Present (C) loop
3561 if Nkind (Expression (C)) = N_Qualified_Expression then
3562 Expr_Q := Expression (Expression (C));
3563 else
3564 Expr_Q := Expression (C);
3565 end if;
3567 -- Return true if the aggregate has any associations for
3568 -- tagged components that may require tag adjustment.
3569 -- These are cases where the source expression may have
3570 -- a tag that could differ from the component tag (e.g.,
3571 -- can occur for type conversions and formal parameters).
3572 -- (Tag adjustment is not needed if Java_VM because object
3573 -- tags are implicit in the JVM.)
3575 if Is_Tagged_Type (Etype (Expr_Q))
3576 and then (Nkind (Expr_Q) = N_Type_Conversion
3577 or else (Is_Entity_Name (Expr_Q)
3578 and then Ekind (Entity (Expr_Q)) in Formal_Kind))
3579 and then not Java_VM
3580 then
3581 return True;
3582 end if;
3584 if Is_Delayed_Aggregate (Expr_Q) then
3585 return True;
3586 end if;
3588 Next (C);
3589 end loop;
3591 return False;
3592 end Has_Delayed_Nested_Aggregate_Or_Tagged_Comps;
3594 -- Remaining Expand_Record_Aggregate variables
3596 Tag_Value : Node_Id;
3597 Comp : Entity_Id;
3598 New_Comp : Node_Id;
3600 -- Start of processing for Expand_Record_Aggregate
3602 begin
3603 -- Gigi doesn't handle properly temporaries of variable size
3604 -- so we generate it in the front-end
3606 if not Size_Known_At_Compile_Time (Typ) then
3607 Convert_To_Assignments (N, Typ);
3609 -- Temporaries for controlled aggregates need to be attached to a
3610 -- final chain in order to be properly finalized, so it has to
3611 -- be created in the front-end
3613 elsif Is_Controlled (Typ)
3614 or else Has_Controlled_Component (Base_Type (Typ))
3615 then
3616 Convert_To_Assignments (N, Typ);
3618 elsif Has_Delayed_Nested_Aggregate_Or_Tagged_Comps then
3619 Convert_To_Assignments (N, Typ);
3621 -- If an ancestor is private, some components are not inherited and
3622 -- we cannot expand into a record aggregate
3624 elsif Has_Private_Ancestor (Typ) then
3625 Convert_To_Assignments (N, Typ);
3627 -- ??? The following was done to compile fxacc00.ads in the ACVCs. Gigi
3628 -- is not able to handle the aggregate for Late_Request.
3630 elsif Is_Tagged_Type (Typ) and then Has_Discriminants (Typ) then
3631 Convert_To_Assignments (N, Typ);
3633 -- In all other cases we generate a proper aggregate that
3634 -- can be handled by gigi.
3636 else
3637 if not Has_Discriminants (Typ) then
3639 -- This bizarre if/elsif is to avoid a compiler crash ???
3641 null;
3643 elsif Is_Derived_Type (Typ) then
3645 -- Non-girder discriminants are replaced with girder discriminants
3647 declare
3648 First_Comp : Node_Id;
3649 Discriminant : Entity_Id;
3651 begin
3652 -- Remove all the discriminants
3654 First_Comp := First (Component_Associations (N));
3656 while Present (First_Comp) loop
3657 Comp := First_Comp;
3658 Next (First_Comp);
3660 if Ekind (Entity (First (Choices (Comp)))) =
3661 E_Discriminant
3662 then
3663 Remove (Comp);
3664 end if;
3665 end loop;
3667 -- Insert girder discriminant associations
3668 -- in the correct order
3670 First_Comp := Empty;
3671 Discriminant := First_Girder_Discriminant (Typ);
3672 while Present (Discriminant) loop
3673 New_Comp :=
3674 Make_Component_Association (Loc,
3675 Choices =>
3676 New_List (New_Occurrence_Of (Discriminant, Loc)),
3678 Expression =>
3679 New_Copy_Tree (
3680 Get_Discriminant_Value (
3681 Discriminant,
3682 Typ,
3683 Discriminant_Constraint (Typ))));
3685 if No (First_Comp) then
3686 Prepend_To (Component_Associations (N), New_Comp);
3687 else
3688 Insert_After (First_Comp, New_Comp);
3689 end if;
3691 First_Comp := New_Comp;
3692 Next_Girder_Discriminant (Discriminant);
3693 end loop;
3694 end;
3695 end if;
3697 if Is_Tagged_Type (Typ) then
3699 -- The tagged case, _parent and _tag component must be created.
3701 -- Reset null_present unconditionally. tagged records always have
3702 -- at least one field (the tag or the parent)
3704 Set_Null_Record_Present (N, False);
3706 -- When the current aggregate comes from the expansion of an
3707 -- extension aggregate, the parent expr is replaced by an
3708 -- aggregate formed by selected components of this expr
3710 if Present (Parent_Expr)
3711 and then Is_Empty_List (Comps)
3712 then
3713 Comp := First_Entity (Typ);
3714 while Present (Comp) loop
3716 -- Skip all entities that aren't discriminants or components
3718 if Ekind (Comp) /= E_Discriminant
3719 and then Ekind (Comp) /= E_Component
3720 then
3721 null;
3723 -- Skip all expander-generated components
3725 elsif
3726 not Comes_From_Source (Original_Record_Component (Comp))
3727 then
3728 null;
3730 else
3731 New_Comp :=
3732 Make_Selected_Component (Loc,
3733 Prefix =>
3734 Unchecked_Convert_To (Typ,
3735 Duplicate_Subexpr (Parent_Expr, True)),
3737 Selector_Name => New_Occurrence_Of (Comp, Loc));
3739 Append_To (Comps,
3740 Make_Component_Association (Loc,
3741 Choices =>
3742 New_List (New_Occurrence_Of (Comp, Loc)),
3743 Expression =>
3744 New_Comp));
3746 Analyze_And_Resolve (New_Comp, Etype (Comp));
3747 end if;
3749 Next_Entity (Comp);
3750 end loop;
3751 end if;
3753 -- Compute the value for the Tag now, if the type is a root it
3754 -- will be included in the aggregate right away, otherwise it will
3755 -- be propagated to the parent aggregate
3757 if Present (Orig_Tag) then
3758 Tag_Value := Orig_Tag;
3759 elsif Java_VM then
3760 Tag_Value := Empty;
3761 else
3762 Tag_Value := New_Occurrence_Of (Access_Disp_Table (Typ), Loc);
3763 end if;
3765 -- For a derived type, an aggregate for the parent is formed with
3766 -- all the inherited components.
3768 if Is_Derived_Type (Typ) then
3770 declare
3771 First_Comp : Node_Id;
3772 Parent_Comps : List_Id;
3773 Parent_Aggr : Node_Id;
3774 Parent_Name : Node_Id;
3776 begin
3777 -- Remove the inherited component association from the
3778 -- aggregate and store them in the parent aggregate
3780 First_Comp := First (Component_Associations (N));
3781 Parent_Comps := New_List;
3783 while Present (First_Comp)
3784 and then Scope (Original_Record_Component (
3785 Entity (First (Choices (First_Comp))))) /= Base_Typ
3786 loop
3787 Comp := First_Comp;
3788 Next (First_Comp);
3789 Remove (Comp);
3790 Append (Comp, Parent_Comps);
3791 end loop;
3793 Parent_Aggr := Make_Aggregate (Loc,
3794 Component_Associations => Parent_Comps);
3795 Set_Etype (Parent_Aggr, Etype (Base_Type (Typ)));
3797 -- Find the _parent component
3799 Comp := First_Component (Typ);
3800 while Chars (Comp) /= Name_uParent loop
3801 Comp := Next_Component (Comp);
3802 end loop;
3804 Parent_Name := New_Occurrence_Of (Comp, Loc);
3806 -- Insert the parent aggregate
3808 Prepend_To (Component_Associations (N),
3809 Make_Component_Association (Loc,
3810 Choices => New_List (Parent_Name),
3811 Expression => Parent_Aggr));
3813 -- Expand recursively the parent propagating the right Tag
3815 Expand_Record_Aggregate (
3816 Parent_Aggr, Tag_Value, Parent_Expr);
3817 end;
3819 -- For a root type, the tag component is added (unless compiling
3820 -- for the Java VM, where tags are implicit).
3822 elsif not Java_VM then
3823 declare
3824 Tag_Name : constant Node_Id :=
3825 New_Occurrence_Of (Tag_Component (Typ), Loc);
3826 Typ_Tag : constant Entity_Id := RTE (RE_Tag);
3827 Conv_Node : constant Node_Id :=
3828 Unchecked_Convert_To (Typ_Tag, Tag_Value);
3830 begin
3831 Set_Etype (Conv_Node, Typ_Tag);
3832 Prepend_To (Component_Associations (N),
3833 Make_Component_Association (Loc,
3834 Choices => New_List (Tag_Name),
3835 Expression => Conv_Node));
3836 end;
3837 end if;
3838 end if;
3839 end if;
3840 end Expand_Record_Aggregate;
3842 --------------------------
3843 -- Is_Delayed_Aggregate --
3844 --------------------------
3846 function Is_Delayed_Aggregate (N : Node_Id) return Boolean is
3847 Node : Node_Id := N;
3848 Kind : Node_Kind := Nkind (Node);
3849 begin
3850 if Kind = N_Qualified_Expression then
3851 Node := Expression (Node);
3852 Kind := Nkind (Node);
3853 end if;
3855 if Kind /= N_Aggregate and then Kind /= N_Extension_Aggregate then
3856 return False;
3857 else
3858 return Expansion_Delayed (Node);
3859 end if;
3860 end Is_Delayed_Aggregate;
3862 --------------------
3863 -- Late_Expansion --
3864 --------------------
3866 function Late_Expansion
3867 (N : Node_Id;
3868 Typ : Entity_Id;
3869 Target : Node_Id;
3870 Flist : Node_Id := Empty;
3871 Obj : Entity_Id := Empty)
3873 return List_Id is
3875 begin
3876 if Is_Record_Type (Etype (N)) then
3877 return Build_Record_Aggr_Code (N, Typ, Target, Flist, Obj);
3878 else
3879 return
3880 Build_Array_Aggr_Code
3882 First_Index (Typ),
3883 Target,
3884 Is_Scalar_Type (Component_Type (Typ)),
3885 No_List,
3886 Flist);
3887 end if;
3888 end Late_Expansion;
3890 ----------------------------------
3891 -- Make_OK_Assignment_Statement --
3892 ----------------------------------
3894 function Make_OK_Assignment_Statement
3895 (Sloc : Source_Ptr;
3896 Name : Node_Id;
3897 Expression : Node_Id)
3898 return Node_Id
3900 begin
3901 Set_Assignment_OK (Name);
3902 return Make_Assignment_Statement (Sloc, Name, Expression);
3903 end Make_OK_Assignment_Statement;
3905 -----------------------
3906 -- Number_Of_Choices --
3907 -----------------------
3909 function Number_Of_Choices (N : Node_Id) return Nat is
3910 Assoc : Node_Id;
3911 Choice : Node_Id;
3913 Nb_Choices : Nat := 0;
3915 begin
3916 if Present (Expressions (N)) then
3917 return 0;
3918 end if;
3920 Assoc := First (Component_Associations (N));
3921 while Present (Assoc) loop
3923 Choice := First (Choices (Assoc));
3924 while Present (Choice) loop
3926 if Nkind (Choice) /= N_Others_Choice then
3927 Nb_Choices := Nb_Choices + 1;
3928 end if;
3930 Next (Choice);
3931 end loop;
3933 Next (Assoc);
3934 end loop;
3936 return Nb_Choices;
3937 end Number_Of_Choices;
3939 ---------------------------
3940 -- Safe_Slice_Assignment --
3941 ---------------------------
3943 function Safe_Slice_Assignment
3944 (N : Node_Id;
3945 Typ : Entity_Id)
3946 return Boolean
3948 Loc : constant Source_Ptr := Sloc (Parent (N));
3949 Pref : constant Node_Id := Prefix (Name (Parent (N)));
3950 Range_Node : constant Node_Id := Discrete_Range (Name (Parent (N)));
3951 Expr : Node_Id;
3952 L_I : Entity_Id;
3953 L_Iter : Node_Id;
3954 L_Body : Node_Id;
3955 Stat : Node_Id;
3957 begin
3958 -- Generate: For J in Range loop Pref (I) := Expr; end loop;
3960 if Comes_From_Source (N)
3961 and then No (Expressions (N))
3962 and then Nkind (First (Choices (First (Component_Associations (N)))))
3963 = N_Others_Choice
3964 then
3965 Expr :=
3966 Expression (First (Component_Associations (N)));
3967 L_I := Make_Defining_Identifier (Loc, New_Internal_Name ('I'));
3969 L_Iter :=
3970 Make_Iteration_Scheme (Loc,
3971 Loop_Parameter_Specification =>
3972 Make_Loop_Parameter_Specification
3973 (Loc,
3974 Defining_Identifier => L_I,
3975 Discrete_Subtype_Definition => Relocate_Node (Range_Node)));
3977 L_Body :=
3978 Make_Assignment_Statement (Loc,
3979 Name =>
3980 Make_Indexed_Component (Loc,
3981 Prefix => Relocate_Node (Pref),
3982 Expressions => New_List (New_Occurrence_Of (L_I, Loc))),
3983 Expression => Relocate_Node (Expr));
3985 -- Construct the final loop
3987 Stat :=
3988 Make_Implicit_Loop_Statement
3989 (Node => Parent (N),
3990 Identifier => Empty,
3991 Iteration_Scheme => L_Iter,
3992 Statements => New_List (L_Body));
3994 Rewrite (Parent (N), Stat);
3995 Analyze (Parent (N));
3996 return True;
3998 else
3999 return False;
4000 end if;
4001 end Safe_Slice_Assignment;
4003 ---------------------
4004 -- Sort_Case_Table --
4005 ---------------------
4007 procedure Sort_Case_Table (Case_Table : in out Case_Table_Type) is
4008 L : Int := Case_Table'First;
4009 U : Int := Case_Table'Last;
4010 K : Int;
4011 J : Int;
4012 T : Case_Bounds;
4014 begin
4015 K := L;
4017 while K /= U loop
4018 T := Case_Table (K + 1);
4019 J := K + 1;
4021 while J /= L
4022 and then Expr_Value (Case_Table (J - 1).Choice_Lo) >
4023 Expr_Value (T.Choice_Lo)
4024 loop
4025 Case_Table (J) := Case_Table (J - 1);
4026 J := J - 1;
4027 end loop;
4029 Case_Table (J) := T;
4030 K := K + 1;
4031 end loop;
4032 end Sort_Case_Table;
4034 end Exp_Aggr;