PR rtl-optimization/79386
[official-gcc.git] / gcc / ada / exp_aggr.adb
blob6a0b0d53244f81bd89ff9cb03ec58cdc74232a56
1 ------------------------------------------------------------------------------
2 -- --
3 -- GNAT COMPILER COMPONENTS --
4 -- --
5 -- E X P _ A G G R --
6 -- --
7 -- B o d y --
8 -- --
9 -- Copyright (C) 1992-2016, Free Software Foundation, Inc. --
10 -- --
11 -- GNAT is free software; you can redistribute it and/or modify it under --
12 -- terms of the GNU General Public License as published by the Free Soft- --
13 -- ware Foundation; either version 3, or (at your option) any later ver- --
14 -- sion. GNAT is distributed in the hope that it will be useful, but WITH- --
15 -- OUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY --
16 -- or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License --
17 -- for more details. You should have received a copy of the GNU General --
18 -- Public License distributed with GNAT; see file COPYING3. If not, go to --
19 -- http://www.gnu.org/licenses for a complete copy of the license. --
20 -- --
21 -- GNAT was originally developed by the GNAT team at New York University. --
22 -- Extensive contributions were provided by Ada Core Technologies Inc. --
23 -- --
24 ------------------------------------------------------------------------------
26 with Atree; use Atree;
27 with Checks; use Checks;
28 with Debug; use Debug;
29 with Einfo; use Einfo;
30 with Elists; use Elists;
31 with Errout; use Errout;
32 with Expander; use Expander;
33 with Exp_Util; use Exp_Util;
34 with Exp_Ch3; use Exp_Ch3;
35 with Exp_Ch6; use Exp_Ch6;
36 with Exp_Ch7; use Exp_Ch7;
37 with Exp_Ch9; use Exp_Ch9;
38 with Exp_Disp; use Exp_Disp;
39 with Exp_Tss; use Exp_Tss;
40 with Fname; use Fname;
41 with Freeze; use Freeze;
42 with Itypes; use Itypes;
43 with Lib; use Lib;
44 with Namet; use Namet;
45 with Nmake; use Nmake;
46 with Nlists; use Nlists;
47 with Opt; use Opt;
48 with Restrict; use Restrict;
49 with Rident; use Rident;
50 with Rtsfind; use Rtsfind;
51 with Ttypes; use Ttypes;
52 with Sem; use Sem;
53 with Sem_Aggr; use Sem_Aggr;
54 with Sem_Aux; use Sem_Aux;
55 with Sem_Ch3; use Sem_Ch3;
56 with Sem_Eval; use Sem_Eval;
57 with Sem_Res; use Sem_Res;
58 with Sem_Util; use Sem_Util;
59 with Sinfo; use Sinfo;
60 with Snames; use Snames;
61 with Stand; use Stand;
62 with Stringt; use Stringt;
63 with Targparm; use Targparm;
64 with Tbuild; use Tbuild;
65 with Uintp; use Uintp;
67 package body Exp_Aggr is
69 type Case_Bounds is record
70 Choice_Lo : Node_Id;
71 Choice_Hi : Node_Id;
72 Choice_Node : Node_Id;
73 end record;
75 type Case_Table_Type is array (Nat range <>) of Case_Bounds;
76 -- Table type used by Check_Case_Choices procedure
78 procedure Collect_Initialization_Statements
79 (Obj : Entity_Id;
80 N : Node_Id;
81 Node_After : Node_Id);
82 -- If Obj is not frozen, collect actions inserted after N until, but not
83 -- including, Node_After, for initialization of Obj, and move them to an
84 -- expression with actions, which becomes the Initialization_Statements for
85 -- Obj.
87 procedure Expand_Delta_Array_Aggregate (N : Node_Id; Deltas : List_Id);
88 procedure Expand_Delta_Record_Aggregate (N : Node_Id; Deltas : List_Id);
90 function Has_Default_Init_Comps (N : Node_Id) return Boolean;
91 -- N is an aggregate (record or array). Checks the presence of default
92 -- initialization (<>) in any component (Ada 2005: AI-287).
94 function In_Object_Declaration (N : Node_Id) return Boolean;
95 -- Return True if N is part of an object declaration, False otherwise
97 function Is_Static_Dispatch_Table_Aggregate (N : Node_Id) return Boolean;
98 -- Returns true if N is an aggregate used to initialize the components
99 -- of a statically allocated dispatch table.
101 function Late_Expansion
102 (N : Node_Id;
103 Typ : Entity_Id;
104 Target : Node_Id) return List_Id;
105 -- This routine implements top-down expansion of nested aggregates. In
106 -- doing so, it avoids the generation of temporaries at each level. N is
107 -- a nested record or array aggregate with the Expansion_Delayed flag.
108 -- Typ is the expected type of the aggregate. Target is a (duplicatable)
109 -- expression that will hold the result of the aggregate expansion.
111 function Make_OK_Assignment_Statement
112 (Sloc : Source_Ptr;
113 Name : Node_Id;
114 Expression : Node_Id) return Node_Id;
115 -- This is like Make_Assignment_Statement, except that Assignment_OK
116 -- is set in the left operand. All assignments built by this unit use
117 -- this routine. This is needed to deal with assignments to initialized
118 -- constants that are done in place.
120 function Must_Slide
121 (Obj_Type : Entity_Id;
122 Typ : Entity_Id) return Boolean;
123 -- A static array aggregate in an object declaration can in most cases be
124 -- expanded in place. The one exception is when the aggregate is given
125 -- with component associations that specify different bounds from those of
126 -- the type definition in the object declaration. In this pathological
127 -- case the aggregate must slide, and we must introduce an intermediate
128 -- temporary to hold it.
130 -- The same holds in an assignment to one-dimensional array of arrays,
131 -- when a component may be given with bounds that differ from those of the
132 -- component type.
134 function Number_Of_Choices (N : Node_Id) return Nat;
135 -- Returns the number of discrete choices (not including the others choice
136 -- if present) contained in (sub-)aggregate N.
138 procedure Process_Transient_Component
139 (Loc : Source_Ptr;
140 Comp_Typ : Entity_Id;
141 Init_Expr : Node_Id;
142 Fin_Call : out Node_Id;
143 Hook_Clear : out Node_Id;
144 Aggr : Node_Id := Empty;
145 Stmts : List_Id := No_List);
146 -- Subsidiary to the expansion of array and record aggregates. Generate
147 -- part of the necessary code to finalize a transient component. Comp_Typ
148 -- is the component type. Init_Expr is the initialization expression of the
149 -- component which is always a function call. Fin_Call is the finalization
150 -- call used to clean up the transient function result. Hook_Clear is the
151 -- hook reset statement. Aggr and Stmts both control the placement of the
152 -- generated code. Aggr is the related aggregate. If present, all code is
153 -- inserted prior to Aggr using Insert_Action. Stmts is the initialization
154 -- statements of the component. If present, all code is added to Stmts.
156 procedure Process_Transient_Component_Completion
157 (Loc : Source_Ptr;
158 Aggr : Node_Id;
159 Fin_Call : Node_Id;
160 Hook_Clear : Node_Id;
161 Stmts : List_Id);
162 -- Subsidiary to the expansion of array and record aggregates. Generate
163 -- part of the necessary code to finalize a transient component. Aggr is
164 -- the related aggregate. Fin_Clear is the finalization call used to clean
165 -- up the transient component. Hook_Clear is the hook reset statment. Stmts
166 -- is the initialization statement list for the component. All generated
167 -- code is added to Stmts.
169 procedure Sort_Case_Table (Case_Table : in out Case_Table_Type);
170 -- Sort the Case Table using the Lower Bound of each Choice as the key.
171 -- A simple insertion sort is used since the number of choices in a case
172 -- statement of variant part will usually be small and probably in near
173 -- sorted order.
175 ------------------------------------------------------
176 -- Local subprograms for Record Aggregate Expansion --
177 ------------------------------------------------------
179 function Build_Record_Aggr_Code
180 (N : Node_Id;
181 Typ : Entity_Id;
182 Lhs : Node_Id) return List_Id;
183 -- N is an N_Aggregate or an N_Extension_Aggregate. Typ is the type of the
184 -- aggregate. Target is an expression containing the location on which the
185 -- component by component assignments will take place. Returns the list of
186 -- assignments plus all other adjustments needed for tagged and controlled
187 -- types.
189 procedure Convert_To_Assignments (N : Node_Id; Typ : Entity_Id);
190 -- N is an N_Aggregate or an N_Extension_Aggregate. Typ is the type of the
191 -- aggregate (which can only be a record type, this procedure is only used
192 -- for record types). Transform the given aggregate into a sequence of
193 -- assignments performed component by component.
195 procedure Expand_Record_Aggregate
196 (N : Node_Id;
197 Orig_Tag : Node_Id := Empty;
198 Parent_Expr : Node_Id := Empty);
199 -- This is the top level procedure for record aggregate expansion.
200 -- Expansion for record aggregates needs expand aggregates for tagged
201 -- record types. Specifically Expand_Record_Aggregate adds the Tag
202 -- field in front of the Component_Association list that was created
203 -- during resolution by Resolve_Record_Aggregate.
205 -- N is the record aggregate node.
206 -- Orig_Tag is the value of the Tag that has to be provided for this
207 -- specific aggregate. It carries the tag corresponding to the type
208 -- of the outermost aggregate during the recursive expansion
209 -- Parent_Expr is the ancestor part of the original extension
210 -- aggregate
212 function Has_Mutable_Components (Typ : Entity_Id) return Boolean;
213 -- Return true if one of the components is of a discriminated type with
214 -- defaults. An aggregate for a type with mutable components must be
215 -- expanded into individual assignments.
217 procedure Initialize_Discriminants (N : Node_Id; Typ : Entity_Id);
218 -- If the type of the aggregate is a type extension with renamed discrimi-
219 -- nants, we must initialize the hidden discriminants of the parent.
220 -- Otherwise, the target object must not be initialized. The discriminants
221 -- are initialized by calling the initialization procedure for the type.
222 -- This is incorrect if the initialization of other components has any
223 -- side effects. We restrict this call to the case where the parent type
224 -- has a variant part, because this is the only case where the hidden
225 -- discriminants are accessed, namely when calling discriminant checking
226 -- functions of the parent type, and when applying a stream attribute to
227 -- an object of the derived type.
229 -----------------------------------------------------
230 -- Local Subprograms for Array Aggregate Expansion --
231 -----------------------------------------------------
233 function Aggr_Size_OK (N : Node_Id; Typ : Entity_Id) return Boolean;
234 -- Very large static aggregates present problems to the back-end, and are
235 -- transformed into assignments and loops. This function verifies that the
236 -- total number of components of an aggregate is acceptable for rewriting
237 -- into a purely positional static form. Aggr_Size_OK must be called before
238 -- calling Flatten.
240 -- This function also detects and warns about one-component aggregates that
241 -- appear in a non-static context. Even if the component value is static,
242 -- such an aggregate must be expanded into an assignment.
244 function Backend_Processing_Possible (N : Node_Id) return Boolean;
245 -- This function checks if array aggregate N can be processed directly
246 -- by the backend. If this is the case, True is returned.
248 function Build_Array_Aggr_Code
249 (N : Node_Id;
250 Ctype : Entity_Id;
251 Index : Node_Id;
252 Into : Node_Id;
253 Scalar_Comp : Boolean;
254 Indexes : List_Id := No_List) return List_Id;
255 -- This recursive routine returns a list of statements containing the
256 -- loops and assignments that are needed for the expansion of the array
257 -- aggregate N.
259 -- N is the (sub-)aggregate node to be expanded into code. This node has
260 -- been fully analyzed, and its Etype is properly set.
262 -- Index is the index node corresponding to the array subaggregate N
264 -- Into is the target expression into which we are copying the aggregate.
265 -- Note that this node may not have been analyzed yet, and so the Etype
266 -- field may not be set.
268 -- Scalar_Comp is True if the component type of the aggregate is scalar
270 -- Indexes is the current list of expressions used to index the object we
271 -- are writing into.
273 procedure Convert_Array_Aggr_In_Allocator
274 (Decl : Node_Id;
275 Aggr : Node_Id;
276 Target : Node_Id);
277 -- If the aggregate appears within an allocator and can be expanded in
278 -- place, this routine generates the individual assignments to components
279 -- of the designated object. This is an optimization over the general
280 -- case, where a temporary is first created on the stack and then used to
281 -- construct the allocated object on the heap.
283 procedure Convert_To_Positional
284 (N : Node_Id;
285 Max_Others_Replicate : Nat := 5;
286 Handle_Bit_Packed : Boolean := False);
287 -- If possible, convert named notation to positional notation. This
288 -- conversion is possible only in some static cases. If the conversion is
289 -- possible, then N is rewritten with the analyzed converted aggregate.
290 -- The parameter Max_Others_Replicate controls the maximum number of
291 -- values corresponding to an others choice that will be converted to
292 -- positional notation (the default of 5 is the normal limit, and reflects
293 -- the fact that normally the loop is better than a lot of separate
294 -- assignments). Note that this limit gets overridden in any case if
295 -- either of the restrictions No_Elaboration_Code or No_Implicit_Loops is
296 -- set. The parameter Handle_Bit_Packed is usually set False (since we do
297 -- not expect the back end to handle bit packed arrays, so the normal case
298 -- of conversion is pointless), but in the special case of a call from
299 -- Packed_Array_Aggregate_Handled, we set this parameter to True, since
300 -- these are cases we handle in there.
302 -- It would seem useful to have a higher default for Max_Others_Replicate,
303 -- but aggregates in the compiler make this impossible: the compiler
304 -- bootstrap fails if Max_Others_Replicate is greater than 25. This
305 -- is unexpected ???
307 procedure Expand_Array_Aggregate (N : Node_Id);
308 -- This is the top-level routine to perform array aggregate expansion.
309 -- N is the N_Aggregate node to be expanded.
311 function Is_Two_Dim_Packed_Array (Typ : Entity_Id) return Boolean;
312 -- For two-dimensional packed aggregates with constant bounds and constant
313 -- components, it is preferable to pack the inner aggregates because the
314 -- whole matrix can then be presented to the back-end as a one-dimensional
315 -- list of literals. This is much more efficient than expanding into single
316 -- component assignments. This function determines if the type Typ is for
317 -- an array that is suitable for this optimization: it returns True if Typ
318 -- is a two dimensional bit packed array with component size 1, 2, or 4.
320 function Packed_Array_Aggregate_Handled (N : Node_Id) return Boolean;
321 -- Given an array aggregate, this function handles the case of a packed
322 -- array aggregate with all constant values, where the aggregate can be
323 -- evaluated at compile time. If this is possible, then N is rewritten
324 -- to be its proper compile time value with all the components properly
325 -- assembled. The expression is analyzed and resolved and True is returned.
326 -- If this transformation is not possible, N is unchanged and False is
327 -- returned.
329 function Two_Dim_Packed_Array_Handled (N : Node_Id) return Boolean;
330 -- If the type of the aggregate is a two-dimensional bit_packed array
331 -- it may be transformed into an array of bytes with constant values,
332 -- and presented to the back-end as a static value. The function returns
333 -- false if this transformation cannot be performed. THis is similar to,
334 -- and reuses part of the machinery in Packed_Array_Aggregate_Handled.
336 ------------------
337 -- Aggr_Size_OK --
338 ------------------
340 function Aggr_Size_OK (N : Node_Id; Typ : Entity_Id) return Boolean is
341 Lo : Node_Id;
342 Hi : Node_Id;
343 Indx : Node_Id;
344 Siz : Int;
345 Lov : Uint;
346 Hiv : Uint;
348 Max_Aggr_Size : Nat;
349 -- Determines the maximum size of an array aggregate produced by
350 -- converting named to positional notation (e.g. from others clauses).
351 -- This avoids running away with attempts to convert huge aggregates,
352 -- which hit memory limits in the backend.
354 function Component_Count (T : Entity_Id) return Nat;
355 -- The limit is applied to the total number of components that the
356 -- aggregate will have, which is the number of static expressions
357 -- that will appear in the flattened array. This requires a recursive
358 -- computation of the number of scalar components of the structure.
360 ---------------------
361 -- Component_Count --
362 ---------------------
364 function Component_Count (T : Entity_Id) return Nat is
365 Res : Nat := 0;
366 Comp : Entity_Id;
368 begin
369 if Is_Scalar_Type (T) then
370 return 1;
372 elsif Is_Record_Type (T) then
373 Comp := First_Component (T);
374 while Present (Comp) loop
375 Res := Res + Component_Count (Etype (Comp));
376 Next_Component (Comp);
377 end loop;
379 return Res;
381 elsif Is_Array_Type (T) then
382 declare
383 Lo : constant Node_Id :=
384 Type_Low_Bound (Etype (First_Index (T)));
385 Hi : constant Node_Id :=
386 Type_High_Bound (Etype (First_Index (T)));
388 Siz : constant Nat := Component_Count (Component_Type (T));
390 begin
391 -- Check for superflat arrays, i.e. arrays with such bounds
392 -- as 4 .. 2, to insure that this function never returns a
393 -- meaningless negative value.
395 if not Compile_Time_Known_Value (Lo)
396 or else not Compile_Time_Known_Value (Hi)
397 or else Expr_Value (Hi) < Expr_Value (Lo)
398 then
399 return 0;
401 else
402 return
403 Siz * UI_To_Int (Expr_Value (Hi) - Expr_Value (Lo) + 1);
404 end if;
405 end;
407 else
408 -- Can only be a null for an access type
410 return 1;
411 end if;
412 end Component_Count;
414 -- Start of processing for Aggr_Size_OK
416 begin
417 -- The normal aggregate limit is 50000, but we increase this limit to
418 -- 2**24 (about 16 million) if Restrictions (No_Elaboration_Code) or
419 -- Restrictions (No_Implicit_Loops) is specified, since in either case
420 -- we are at risk of declaring the program illegal because of this
421 -- limit. We also increase the limit when Static_Elaboration_Desired,
422 -- given that this means that objects are intended to be placed in data
423 -- memory.
425 -- We also increase the limit if the aggregate is for a packed two-
426 -- dimensional array, because if components are static it is much more
427 -- efficient to construct a one-dimensional equivalent array with static
428 -- components.
430 -- Conversely, we decrease the maximum size if none of the above
431 -- requirements apply, and if the aggregate has a single component
432 -- association, which will be more efficient if implemented with a loop.
434 -- Finally, we use a small limit in CodePeer mode where we favor loops
435 -- instead of thousands of single assignments (from large aggregates).
437 Max_Aggr_Size := 50000;
439 if CodePeer_Mode then
440 Max_Aggr_Size := 100;
442 elsif Restriction_Active (No_Elaboration_Code)
443 or else Restriction_Active (No_Implicit_Loops)
444 or else Is_Two_Dim_Packed_Array (Typ)
445 or else (Ekind (Current_Scope) = E_Package
446 and then Static_Elaboration_Desired (Current_Scope))
447 then
448 Max_Aggr_Size := 2 ** 24;
450 elsif No (Expressions (N))
451 and then No (Next (First (Component_Associations (N))))
452 then
453 Max_Aggr_Size := 5000;
454 end if;
456 Siz := Component_Count (Component_Type (Typ));
458 Indx := First_Index (Typ);
459 while Present (Indx) loop
460 Lo := Type_Low_Bound (Etype (Indx));
461 Hi := Type_High_Bound (Etype (Indx));
463 -- Bounds need to be known at compile time
465 if not Compile_Time_Known_Value (Lo)
466 or else not Compile_Time_Known_Value (Hi)
467 then
468 return False;
469 end if;
471 Lov := Expr_Value (Lo);
472 Hiv := Expr_Value (Hi);
474 -- A flat array is always safe
476 if Hiv < Lov then
477 return True;
478 end if;
480 -- One-component aggregates are suspicious, and if the context type
481 -- is an object declaration with non-static bounds it will trip gcc;
482 -- such an aggregate must be expanded into a single assignment.
484 if Hiv = Lov and then Nkind (Parent (N)) = N_Object_Declaration then
485 declare
486 Index_Type : constant Entity_Id :=
487 Etype
488 (First_Index (Etype (Defining_Identifier (Parent (N)))));
489 Indx : Node_Id;
491 begin
492 if not Compile_Time_Known_Value (Type_Low_Bound (Index_Type))
493 or else not Compile_Time_Known_Value
494 (Type_High_Bound (Index_Type))
495 then
496 if Present (Component_Associations (N)) then
497 Indx :=
498 First
499 (Choice_List (First (Component_Associations (N))));
501 if Is_Entity_Name (Indx)
502 and then not Is_Type (Entity (Indx))
503 then
504 Error_Msg_N
505 ("single component aggregate in "
506 & "non-static context??", Indx);
507 Error_Msg_N ("\maybe subtype name was meant??", Indx);
508 end if;
509 end if;
511 return False;
512 end if;
513 end;
514 end if;
516 declare
517 Rng : constant Uint := Hiv - Lov + 1;
519 begin
520 -- Check if size is too large
522 if not UI_Is_In_Int_Range (Rng) then
523 return False;
524 end if;
526 Siz := Siz * UI_To_Int (Rng);
527 end;
529 if Siz <= 0
530 or else Siz > Max_Aggr_Size
531 then
532 return False;
533 end if;
535 -- Bounds must be in integer range, for later array construction
537 if not UI_Is_In_Int_Range (Lov)
538 or else
539 not UI_Is_In_Int_Range (Hiv)
540 then
541 return False;
542 end if;
544 Next_Index (Indx);
545 end loop;
547 return True;
548 end Aggr_Size_OK;
550 ---------------------------------
551 -- Backend_Processing_Possible --
552 ---------------------------------
554 -- Backend processing by Gigi/gcc is possible only if all the following
555 -- conditions are met:
557 -- 1. N is fully positional
559 -- 2. N is not a bit-packed array aggregate;
561 -- 3. The size of N's array type must be known at compile time. Note
562 -- that this implies that the component size is also known
564 -- 4. The array type of N does not follow the Fortran layout convention
565 -- or if it does it must be 1 dimensional.
567 -- 5. The array component type may not be tagged (which could necessitate
568 -- reassignment of proper tags).
570 -- 6. The array component type must not have unaligned bit components
572 -- 7. None of the components of the aggregate may be bit unaligned
573 -- components.
575 -- 8. There cannot be delayed components, since we do not know enough
576 -- at this stage to know if back end processing is possible.
578 -- 9. There cannot be any discriminated record components, since the
579 -- back end cannot handle this complex case.
581 -- 10. No controlled actions need to be generated for components
583 -- 11. When generating C code, N must be part of a N_Object_Declaration
585 -- 12. When generating C code, N must not include function calls
587 function Backend_Processing_Possible (N : Node_Id) return Boolean is
588 Typ : constant Entity_Id := Etype (N);
589 -- Typ is the correct constrained array subtype of the aggregate
591 function Component_Check (N : Node_Id; Index : Node_Id) return Boolean;
592 -- This routine checks components of aggregate N, enforcing checks
593 -- 1, 7, 8, 9, 11, and 12. In the multidimensional case, these checks
594 -- are performed on subaggregates. The Index value is the current index
595 -- being checked in the multidimensional case.
597 ---------------------
598 -- Component_Check --
599 ---------------------
601 function Component_Check (N : Node_Id; Index : Node_Id) return Boolean is
602 function Ultimate_Original_Expression (N : Node_Id) return Node_Id;
603 -- Given a type conversion or an unchecked type conversion N, return
604 -- its innermost original expression.
606 ----------------------------------
607 -- Ultimate_Original_Expression --
608 ----------------------------------
610 function Ultimate_Original_Expression (N : Node_Id) return Node_Id is
611 Expr : Node_Id := Original_Node (N);
613 begin
614 while Nkind_In (Expr, N_Type_Conversion,
615 N_Unchecked_Type_Conversion)
616 loop
617 Expr := Original_Node (Expression (Expr));
618 end loop;
620 return Expr;
621 end Ultimate_Original_Expression;
623 -- Local variables
625 Expr : Node_Id;
627 -- Start of processing for Component_Check
629 begin
630 -- Checks 1: (no component associations)
632 if Present (Component_Associations (N)) then
633 return False;
634 end if;
636 -- Checks 11: (part of an object declaration)
638 if Modify_Tree_For_C
639 and then Nkind (Parent (N)) /= N_Object_Declaration
640 and then
641 (Nkind (Parent (N)) /= N_Qualified_Expression
642 or else Nkind (Parent (Parent (N))) /= N_Object_Declaration)
643 then
644 return False;
645 end if;
647 -- Checks on components
649 -- Recurse to check subaggregates, which may appear in qualified
650 -- expressions. If delayed, the front-end will have to expand.
651 -- If the component is a discriminated record, treat as non-static,
652 -- as the back-end cannot handle this properly.
654 Expr := First (Expressions (N));
655 while Present (Expr) loop
657 -- Checks 8: (no delayed components)
659 if Is_Delayed_Aggregate (Expr) then
660 return False;
661 end if;
663 -- Checks 9: (no discriminated records)
665 if Present (Etype (Expr))
666 and then Is_Record_Type (Etype (Expr))
667 and then Has_Discriminants (Etype (Expr))
668 then
669 return False;
670 end if;
672 -- Checks 7. Component must not be bit aligned component
674 if Possible_Bit_Aligned_Component (Expr) then
675 return False;
676 end if;
678 -- Checks 12: (no function call)
680 if Modify_Tree_For_C
681 and then
682 Nkind (Ultimate_Original_Expression (Expr)) = N_Function_Call
683 then
684 return False;
685 end if;
687 -- Recursion to following indexes for multiple dimension case
689 if Present (Next_Index (Index))
690 and then not Component_Check (Expr, Next_Index (Index))
691 then
692 return False;
693 end if;
695 -- All checks for that component finished, on to next
697 Next (Expr);
698 end loop;
700 return True;
701 end Component_Check;
703 -- Start of processing for Backend_Processing_Possible
705 begin
706 -- Checks 2 (array not bit packed) and 10 (no controlled actions)
708 if Is_Bit_Packed_Array (Typ) or else Needs_Finalization (Typ) then
709 return False;
710 end if;
712 -- If component is limited, aggregate must be expanded because each
713 -- component assignment must be built in place.
715 if Is_Limited_View (Component_Type (Typ)) then
716 return False;
717 end if;
719 -- Checks 4 (array must not be multidimensional Fortran case)
721 if Convention (Typ) = Convention_Fortran
722 and then Number_Dimensions (Typ) > 1
723 then
724 return False;
725 end if;
727 -- Checks 3 (size of array must be known at compile time)
729 if not Size_Known_At_Compile_Time (Typ) then
730 return False;
731 end if;
733 -- Checks on components
735 if not Component_Check (N, First_Index (Typ)) then
736 return False;
737 end if;
739 -- Checks 5 (if the component type is tagged, then we may need to do
740 -- tag adjustments. Perhaps this should be refined to check for any
741 -- component associations that actually need tag adjustment, similar
742 -- to the test in Component_Not_OK_For_Backend for record aggregates
743 -- with tagged components, but not clear whether it's worthwhile ???;
744 -- in the case of virtual machines (no Tagged_Type_Expansion), object
745 -- tags are handled implicitly).
747 if Is_Tagged_Type (Component_Type (Typ))
748 and then Tagged_Type_Expansion
749 then
750 return False;
751 end if;
753 -- Checks 6 (component type must not have bit aligned components)
755 if Type_May_Have_Bit_Aligned_Components (Component_Type (Typ)) then
756 return False;
757 end if;
759 -- Backend processing is possible
761 Set_Size_Known_At_Compile_Time (Etype (N), True);
762 return True;
763 end Backend_Processing_Possible;
765 ---------------------------
766 -- Build_Array_Aggr_Code --
767 ---------------------------
769 -- The code that we generate from a one dimensional aggregate is
771 -- 1. If the subaggregate contains discrete choices we
773 -- (a) Sort the discrete choices
775 -- (b) Otherwise for each discrete choice that specifies a range we
776 -- emit a loop. If a range specifies a maximum of three values, or
777 -- we are dealing with an expression we emit a sequence of
778 -- assignments instead of a loop.
780 -- (c) Generate the remaining loops to cover the others choice if any
782 -- 2. If the aggregate contains positional elements we
784 -- (a) translate the positional elements in a series of assignments
786 -- (b) Generate a final loop to cover the others choice if any.
787 -- Note that this final loop has to be a while loop since the case
789 -- L : Integer := Integer'Last;
790 -- H : Integer := Integer'Last;
791 -- A : array (L .. H) := (1, others =>0);
793 -- cannot be handled by a for loop. Thus for the following
795 -- array (L .. H) := (.. positional elements.., others =>E);
797 -- we always generate something like:
799 -- J : Index_Type := Index_Of_Last_Positional_Element;
800 -- while J < H loop
801 -- J := Index_Base'Succ (J)
802 -- Tmp (J) := E;
803 -- end loop;
805 function Build_Array_Aggr_Code
806 (N : Node_Id;
807 Ctype : Entity_Id;
808 Index : Node_Id;
809 Into : Node_Id;
810 Scalar_Comp : Boolean;
811 Indexes : List_Id := No_List) return List_Id
813 Loc : constant Source_Ptr := Sloc (N);
814 Index_Base : constant Entity_Id := Base_Type (Etype (Index));
815 Index_Base_L : constant Node_Id := Type_Low_Bound (Index_Base);
816 Index_Base_H : constant Node_Id := Type_High_Bound (Index_Base);
818 function Add (Val : Int; To : Node_Id) return Node_Id;
819 -- Returns an expression where Val is added to expression To, unless
820 -- To+Val is provably out of To's base type range. To must be an
821 -- already analyzed expression.
823 function Empty_Range (L, H : Node_Id) return Boolean;
824 -- Returns True if the range defined by L .. H is certainly empty
826 function Equal (L, H : Node_Id) return Boolean;
827 -- Returns True if L = H for sure
829 function Index_Base_Name return Node_Id;
830 -- Returns a new reference to the index type name
832 function Gen_Assign
833 (Ind : Node_Id;
834 Expr : Node_Id;
835 In_Loop : Boolean := False) return List_Id;
836 -- Ind must be a side-effect-free expression. If the input aggregate N
837 -- to Build_Loop contains no subaggregates, then this function returns
838 -- the assignment statement:
840 -- Into (Indexes, Ind) := Expr;
842 -- Otherwise we call Build_Code recursively. Flag In_Loop should be set
843 -- when the assignment appears within a generated loop.
845 -- Ada 2005 (AI-287): In case of default initialized component, Expr
846 -- is empty and we generate a call to the corresponding IP subprogram.
848 function Gen_Loop (L, H : Node_Id; Expr : Node_Id) return List_Id;
849 -- Nodes L and H must be side-effect-free expressions. If the input
850 -- aggregate N to Build_Loop contains no subaggregates, this routine
851 -- returns the for loop statement:
853 -- for J in Index_Base'(L) .. Index_Base'(H) loop
854 -- Into (Indexes, J) := Expr;
855 -- end loop;
857 -- Otherwise we call Build_Code recursively. As an optimization if the
858 -- loop covers 3 or fewer scalar elements we generate a sequence of
859 -- assignments.
860 -- If the component association that generates the loop comes from an
861 -- Iterated_Component_Association, the loop parameter has the name of
862 -- the corresponding parameter in the original construct.
864 function Gen_While (L, H : Node_Id; Expr : Node_Id) return List_Id;
865 -- Nodes L and H must be side-effect-free expressions. If the input
866 -- aggregate N to Build_Loop contains no subaggregates, this routine
867 -- returns the while loop statement:
869 -- J : Index_Base := L;
870 -- while J < H loop
871 -- J := Index_Base'Succ (J);
872 -- Into (Indexes, J) := Expr;
873 -- end loop;
875 -- Otherwise we call Build_Code recursively
877 function Get_Assoc_Expr (Assoc : Node_Id) return Node_Id;
878 -- For an association with a box, use value given by aspect
879 -- Default_Component_Value of array type if specified, else use
880 -- value given by aspect Default_Value for component type itself
881 -- if specified, else return Empty.
883 function Local_Compile_Time_Known_Value (E : Node_Id) return Boolean;
884 function Local_Expr_Value (E : Node_Id) return Uint;
885 -- These two Local routines are used to replace the corresponding ones
886 -- in sem_eval because while processing the bounds of an aggregate with
887 -- discrete choices whose index type is an enumeration, we build static
888 -- expressions not recognized by Compile_Time_Known_Value as such since
889 -- they have not yet been analyzed and resolved. All the expressions in
890 -- question are things like Index_Base_Name'Val (Const) which we can
891 -- easily recognize as being constant.
893 ---------
894 -- Add --
895 ---------
897 function Add (Val : Int; To : Node_Id) return Node_Id is
898 Expr_Pos : Node_Id;
899 Expr : Node_Id;
900 To_Pos : Node_Id;
901 U_To : Uint;
902 U_Val : constant Uint := UI_From_Int (Val);
904 begin
905 -- Note: do not try to optimize the case of Val = 0, because
906 -- we need to build a new node with the proper Sloc value anyway.
908 -- First test if we can do constant folding
910 if Local_Compile_Time_Known_Value (To) then
911 U_To := Local_Expr_Value (To) + Val;
913 -- Determine if our constant is outside the range of the index.
914 -- If so return an Empty node. This empty node will be caught
915 -- by Empty_Range below.
917 if Compile_Time_Known_Value (Index_Base_L)
918 and then U_To < Expr_Value (Index_Base_L)
919 then
920 return Empty;
922 elsif Compile_Time_Known_Value (Index_Base_H)
923 and then U_To > Expr_Value (Index_Base_H)
924 then
925 return Empty;
926 end if;
928 Expr_Pos := Make_Integer_Literal (Loc, U_To);
929 Set_Is_Static_Expression (Expr_Pos);
931 if not Is_Enumeration_Type (Index_Base) then
932 Expr := Expr_Pos;
934 -- If we are dealing with enumeration return
935 -- Index_Base'Val (Expr_Pos)
937 else
938 Expr :=
939 Make_Attribute_Reference
940 (Loc,
941 Prefix => Index_Base_Name,
942 Attribute_Name => Name_Val,
943 Expressions => New_List (Expr_Pos));
944 end if;
946 return Expr;
947 end if;
949 -- If we are here no constant folding possible
951 if not Is_Enumeration_Type (Index_Base) then
952 Expr :=
953 Make_Op_Add (Loc,
954 Left_Opnd => Duplicate_Subexpr (To),
955 Right_Opnd => Make_Integer_Literal (Loc, U_Val));
957 -- If we are dealing with enumeration return
958 -- Index_Base'Val (Index_Base'Pos (To) + Val)
960 else
961 To_Pos :=
962 Make_Attribute_Reference
963 (Loc,
964 Prefix => Index_Base_Name,
965 Attribute_Name => Name_Pos,
966 Expressions => New_List (Duplicate_Subexpr (To)));
968 Expr_Pos :=
969 Make_Op_Add (Loc,
970 Left_Opnd => To_Pos,
971 Right_Opnd => Make_Integer_Literal (Loc, U_Val));
973 Expr :=
974 Make_Attribute_Reference
975 (Loc,
976 Prefix => Index_Base_Name,
977 Attribute_Name => Name_Val,
978 Expressions => New_List (Expr_Pos));
979 end if;
981 return Expr;
982 end Add;
984 -----------------
985 -- Empty_Range --
986 -----------------
988 function Empty_Range (L, H : Node_Id) return Boolean is
989 Is_Empty : Boolean := False;
990 Low : Node_Id;
991 High : Node_Id;
993 begin
994 -- First check if L or H were already detected as overflowing the
995 -- index base range type by function Add above. If this is so Add
996 -- returns the empty node.
998 if No (L) or else No (H) then
999 return True;
1000 end if;
1002 for J in 1 .. 3 loop
1003 case J is
1005 -- L > H range is empty
1007 when 1 =>
1008 Low := L;
1009 High := H;
1011 -- B_L > H range must be empty
1013 when 2 =>
1014 Low := Index_Base_L;
1015 High := H;
1017 -- L > B_H range must be empty
1019 when 3 =>
1020 Low := L;
1021 High := Index_Base_H;
1022 end case;
1024 if Local_Compile_Time_Known_Value (Low)
1025 and then
1026 Local_Compile_Time_Known_Value (High)
1027 then
1028 Is_Empty :=
1029 UI_Gt (Local_Expr_Value (Low), Local_Expr_Value (High));
1030 end if;
1032 exit when Is_Empty;
1033 end loop;
1035 return Is_Empty;
1036 end Empty_Range;
1038 -----------
1039 -- Equal --
1040 -----------
1042 function Equal (L, H : Node_Id) return Boolean is
1043 begin
1044 if L = H then
1045 return True;
1047 elsif Local_Compile_Time_Known_Value (L)
1048 and then
1049 Local_Compile_Time_Known_Value (H)
1050 then
1051 return UI_Eq (Local_Expr_Value (L), Local_Expr_Value (H));
1052 end if;
1054 return False;
1055 end Equal;
1057 ----------------
1058 -- Gen_Assign --
1059 ----------------
1061 function Gen_Assign
1062 (Ind : Node_Id;
1063 Expr : Node_Id;
1064 In_Loop : Boolean := False) return List_Id
1066 function Add_Loop_Actions (Lis : List_Id) return List_Id;
1067 -- Collect insert_actions generated in the construction of a loop,
1068 -- and prepend them to the sequence of assignments to complete the
1069 -- eventual body of the loop.
1071 procedure Initialize_Array_Component
1072 (Arr_Comp : Node_Id;
1073 Comp_Typ : Node_Id;
1074 Init_Expr : Node_Id;
1075 Stmts : List_Id);
1076 -- Perform the initialization of array component Arr_Comp with
1077 -- expected type Comp_Typ. Init_Expr denotes the initialization
1078 -- expression of the array component. All generated code is added
1079 -- to list Stmts.
1081 procedure Initialize_Ctrl_Array_Component
1082 (Arr_Comp : Node_Id;
1083 Comp_Typ : Entity_Id;
1084 Init_Expr : Node_Id;
1085 Stmts : List_Id);
1086 -- Perform the initialization of array component Arr_Comp when its
1087 -- expected type Comp_Typ needs finalization actions. Init_Expr is
1088 -- the initialization expression of the array component. All hook-
1089 -- related declarations are inserted prior to aggregate N. Remaining
1090 -- code is added to list Stmts.
1092 ----------------------
1093 -- Add_Loop_Actions --
1094 ----------------------
1096 function Add_Loop_Actions (Lis : List_Id) return List_Id is
1097 Res : List_Id;
1099 begin
1100 -- Ada 2005 (AI-287): Do nothing else in case of default
1101 -- initialized component.
1103 if No (Expr) then
1104 return Lis;
1106 elsif Nkind (Parent (Expr)) = N_Component_Association
1107 and then Present (Loop_Actions (Parent (Expr)))
1108 then
1109 Append_List (Lis, Loop_Actions (Parent (Expr)));
1110 Res := Loop_Actions (Parent (Expr));
1111 Set_Loop_Actions (Parent (Expr), No_List);
1112 return Res;
1114 else
1115 return Lis;
1116 end if;
1117 end Add_Loop_Actions;
1119 --------------------------------
1120 -- Initialize_Array_Component --
1121 --------------------------------
1123 procedure Initialize_Array_Component
1124 (Arr_Comp : Node_Id;
1125 Comp_Typ : Node_Id;
1126 Init_Expr : Node_Id;
1127 Stmts : List_Id)
1129 Exceptions_OK : constant Boolean :=
1130 not Restriction_Active
1131 (No_Exception_Propagation);
1133 Finalization_OK : constant Boolean :=
1134 Present (Comp_Typ)
1135 and then Needs_Finalization (Comp_Typ);
1137 Full_Typ : constant Entity_Id := Underlying_Type (Comp_Typ);
1138 Adj_Call : Node_Id;
1139 Blk_Stmts : List_Id;
1140 Init_Stmt : Node_Id;
1142 begin
1143 -- Protect the initialization statements from aborts. Generate:
1145 -- Abort_Defer;
1147 if Finalization_OK and Abort_Allowed then
1148 if Exceptions_OK then
1149 Blk_Stmts := New_List;
1150 else
1151 Blk_Stmts := Stmts;
1152 end if;
1154 Append_To (Blk_Stmts, Build_Runtime_Call (Loc, RE_Abort_Defer));
1156 -- Otherwise aborts are not allowed. All generated code is added
1157 -- directly to the input list.
1159 else
1160 Blk_Stmts := Stmts;
1161 end if;
1163 -- Initialize the array element. Generate:
1165 -- Arr_Comp := Init_Expr;
1167 -- Note that the initialization expression is replicated because
1168 -- it has to be reevaluated within a generated loop.
1170 Init_Stmt :=
1171 Make_OK_Assignment_Statement (Loc,
1172 Name => New_Copy_Tree (Arr_Comp),
1173 Expression => New_Copy_Tree (Init_Expr));
1174 Set_No_Ctrl_Actions (Init_Stmt);
1176 -- If this is an aggregate for an array of arrays, each
1177 -- subaggregate will be expanded as well, and even with
1178 -- No_Ctrl_Actions the assignments of inner components will
1179 -- require attachment in their assignments to temporaries. These
1180 -- temporaries must be finalized for each subaggregate. Generate:
1182 -- begin
1183 -- Arr_Comp := Init_Expr;
1184 -- end;
1186 if Finalization_OK and then Is_Array_Type (Comp_Typ) then
1187 Init_Stmt :=
1188 Make_Block_Statement (Loc,
1189 Handled_Statement_Sequence =>
1190 Make_Handled_Sequence_Of_Statements (Loc,
1191 Statements => New_List (Init_Stmt)));
1192 end if;
1194 Append_To (Blk_Stmts, Init_Stmt);
1196 -- Adjust the tag due to a possible view conversion. Generate:
1198 -- Arr_Comp._tag := Full_TypP;
1200 if Tagged_Type_Expansion
1201 and then Present (Comp_Typ)
1202 and then Is_Tagged_Type (Comp_Typ)
1203 then
1204 Append_To (Blk_Stmts,
1205 Make_OK_Assignment_Statement (Loc,
1206 Name =>
1207 Make_Selected_Component (Loc,
1208 Prefix => New_Copy_Tree (Arr_Comp),
1209 Selector_Name =>
1210 New_Occurrence_Of
1211 (First_Tag_Component (Full_Typ), Loc)),
1213 Expression =>
1214 Unchecked_Convert_To (RTE (RE_Tag),
1215 New_Occurrence_Of
1216 (Node (First_Elmt (Access_Disp_Table (Full_Typ))),
1217 Loc))));
1218 end if;
1220 -- Adjust the array component. Controlled subaggregates are not
1221 -- considered because each of their individual elements will
1222 -- receive an adjustment of its own. Generate:
1224 -- [Deep_]Adjust (Arr_Comp);
1226 if Finalization_OK
1227 and then not Is_Limited_Type (Comp_Typ)
1228 and then not
1229 (Is_Array_Type (Comp_Typ)
1230 and then Is_Controlled (Component_Type (Comp_Typ))
1231 and then Nkind (Expr) = N_Aggregate)
1232 then
1233 Adj_Call :=
1234 Make_Adjust_Call
1235 (Obj_Ref => New_Copy_Tree (Arr_Comp),
1236 Typ => Comp_Typ);
1238 -- Guard against a missing [Deep_]Adjust when the component
1239 -- type was not frozen properly.
1241 if Present (Adj_Call) then
1242 Append_To (Blk_Stmts, Adj_Call);
1243 end if;
1244 end if;
1246 -- Complete the protection of the initialization statements
1248 if Finalization_OK and Abort_Allowed then
1250 -- Wrap the initialization statements in a block to catch a
1251 -- potential exception. Generate:
1253 -- begin
1254 -- Abort_Defer;
1255 -- Arr_Comp := Init_Expr;
1256 -- Arr_Comp._tag := Full_TypP;
1257 -- [Deep_]Adjust (Arr_Comp);
1258 -- at end
1259 -- Abort_Undefer_Direct;
1260 -- end;
1262 if Exceptions_OK then
1263 Append_To (Stmts,
1264 Build_Abort_Undefer_Block (Loc,
1265 Stmts => Blk_Stmts,
1266 Context => N));
1268 -- Otherwise exceptions are not propagated. Generate:
1270 -- Abort_Defer;
1271 -- Arr_Comp := Init_Expr;
1272 -- Arr_Comp._tag := Full_TypP;
1273 -- [Deep_]Adjust (Arr_Comp);
1274 -- Abort_Undefer;
1276 else
1277 Append_To (Blk_Stmts,
1278 Build_Runtime_Call (Loc, RE_Abort_Undefer));
1279 end if;
1280 end if;
1281 end Initialize_Array_Component;
1283 -------------------------------------
1284 -- Initialize_Ctrl_Array_Component --
1285 -------------------------------------
1287 procedure Initialize_Ctrl_Array_Component
1288 (Arr_Comp : Node_Id;
1289 Comp_Typ : Entity_Id;
1290 Init_Expr : Node_Id;
1291 Stmts : List_Id)
1293 Act_Aggr : Node_Id;
1294 Act_Stmts : List_Id;
1295 Expr : Node_Id;
1296 Fin_Call : Node_Id;
1297 Hook_Clear : Node_Id;
1299 In_Place_Expansion : Boolean;
1300 -- Flag set when a nonlimited controlled function call requires
1301 -- in-place expansion.
1303 begin
1304 -- Duplicate the initialization expression in case the context is
1305 -- a multi choice list or an "others" choice which plugs various
1306 -- holes in the aggregate. As a result the expression is no longer
1307 -- shared between the various components and is reevaluated for
1308 -- each such component.
1310 Expr := New_Copy_Tree (Init_Expr);
1311 Set_Parent (Expr, Parent (Init_Expr));
1313 -- Perform a preliminary analysis and resolution to determine what
1314 -- the initialization expression denotes. An unanalyzed function
1315 -- call may appear as an identifier or an indexed component.
1317 if Nkind_In (Expr, N_Function_Call,
1318 N_Identifier,
1319 N_Indexed_Component)
1320 and then not Analyzed (Expr)
1321 then
1322 Preanalyze_And_Resolve (Expr, Comp_Typ);
1323 end if;
1325 In_Place_Expansion :=
1326 Nkind (Expr) = N_Function_Call
1327 and then not Is_Limited_Type (Comp_Typ);
1329 -- The initialization expression is a controlled function call.
1330 -- Perform in-place removal of side effects to avoid creating a
1331 -- transient scope, which leads to premature finalization.
1333 -- This in-place expansion is not performed for limited transient
1334 -- objects because the initialization is already done in-place.
1336 if In_Place_Expansion then
1338 -- Suppress the removal of side effects by general analysis
1339 -- because this behavior is emulated here. This avoids the
1340 -- generation of a transient scope, which leads to out-of-order
1341 -- adjustment and finalization.
1343 Set_No_Side_Effect_Removal (Expr);
1345 -- When the transient component initialization is related to a
1346 -- range or an "others", keep all generated statements within
1347 -- the enclosing loop. This way the controlled function call
1348 -- will be evaluated at each iteration, and its result will be
1349 -- finalized at the end of each iteration.
1351 if In_Loop then
1352 Act_Aggr := Empty;
1353 Act_Stmts := Stmts;
1355 -- Otherwise this is a single component initialization. Hook-
1356 -- related statements are inserted prior to the aggregate.
1358 else
1359 Act_Aggr := N;
1360 Act_Stmts := No_List;
1361 end if;
1363 -- Install all hook-related declarations and prepare the clean
1364 -- up statements.
1366 Process_Transient_Component
1367 (Loc => Loc,
1368 Comp_Typ => Comp_Typ,
1369 Init_Expr => Expr,
1370 Fin_Call => Fin_Call,
1371 Hook_Clear => Hook_Clear,
1372 Aggr => Act_Aggr,
1373 Stmts => Act_Stmts);
1374 end if;
1376 -- Use the noncontrolled component initialization circuitry to
1377 -- assign the result of the function call to the array element.
1378 -- This also performs subaggregate wrapping, tag adjustment, and
1379 -- [deep] adjustment of the array element.
1381 Initialize_Array_Component
1382 (Arr_Comp => Arr_Comp,
1383 Comp_Typ => Comp_Typ,
1384 Init_Expr => Expr,
1385 Stmts => Stmts);
1387 -- At this point the array element is fully initialized. Complete
1388 -- the processing of the controlled array component by finalizing
1389 -- the transient function result.
1391 if In_Place_Expansion then
1392 Process_Transient_Component_Completion
1393 (Loc => Loc,
1394 Aggr => N,
1395 Fin_Call => Fin_Call,
1396 Hook_Clear => Hook_Clear,
1397 Stmts => Stmts);
1398 end if;
1399 end Initialize_Ctrl_Array_Component;
1401 -- Local variables
1403 Stmts : constant List_Id := New_List;
1405 Comp_Typ : Entity_Id := Empty;
1406 Expr_Q : Node_Id;
1407 Indexed_Comp : Node_Id;
1408 Init_Call : Node_Id;
1409 New_Indexes : List_Id;
1411 -- Start of processing for Gen_Assign
1413 begin
1414 if No (Indexes) then
1415 New_Indexes := New_List;
1416 else
1417 New_Indexes := New_Copy_List_Tree (Indexes);
1418 end if;
1420 Append_To (New_Indexes, Ind);
1422 if Present (Next_Index (Index)) then
1423 return
1424 Add_Loop_Actions (
1425 Build_Array_Aggr_Code
1426 (N => Expr,
1427 Ctype => Ctype,
1428 Index => Next_Index (Index),
1429 Into => Into,
1430 Scalar_Comp => Scalar_Comp,
1431 Indexes => New_Indexes));
1432 end if;
1434 -- If we get here then we are at a bottom-level (sub-)aggregate
1436 Indexed_Comp :=
1437 Checks_Off
1438 (Make_Indexed_Component (Loc,
1439 Prefix => New_Copy_Tree (Into),
1440 Expressions => New_Indexes));
1442 Set_Assignment_OK (Indexed_Comp);
1444 -- Ada 2005 (AI-287): In case of default initialized component, Expr
1445 -- is not present (and therefore we also initialize Expr_Q to empty).
1447 if No (Expr) then
1448 Expr_Q := Empty;
1449 elsif Nkind (Expr) = N_Qualified_Expression then
1450 Expr_Q := Expression (Expr);
1451 else
1452 Expr_Q := Expr;
1453 end if;
1455 if Present (Etype (N)) and then Etype (N) /= Any_Composite then
1456 Comp_Typ := Component_Type (Etype (N));
1457 pragma Assert (Comp_Typ = Ctype); -- AI-287
1459 elsif Present (Next (First (New_Indexes))) then
1461 -- Ada 2005 (AI-287): Do nothing in case of default initialized
1462 -- component because we have received the component type in
1463 -- the formal parameter Ctype.
1465 -- ??? Some assert pragmas have been added to check if this new
1466 -- formal can be used to replace this code in all cases.
1468 if Present (Expr) then
1470 -- This is a multidimensional array. Recover the component type
1471 -- from the outermost aggregate, because subaggregates do not
1472 -- have an assigned type.
1474 declare
1475 P : Node_Id;
1477 begin
1478 P := Parent (Expr);
1479 while Present (P) loop
1480 if Nkind (P) = N_Aggregate
1481 and then Present (Etype (P))
1482 then
1483 Comp_Typ := Component_Type (Etype (P));
1484 exit;
1486 else
1487 P := Parent (P);
1488 end if;
1489 end loop;
1491 pragma Assert (Comp_Typ = Ctype); -- AI-287
1492 end;
1493 end if;
1494 end if;
1496 -- Ada 2005 (AI-287): We only analyze the expression in case of non-
1497 -- default initialized components (otherwise Expr_Q is not present).
1499 if Present (Expr_Q)
1500 and then Nkind_In (Expr_Q, N_Aggregate, N_Extension_Aggregate)
1501 then
1502 -- At this stage the Expression may not have been analyzed yet
1503 -- because the array aggregate code has not been updated to use
1504 -- the Expansion_Delayed flag and avoid analysis altogether to
1505 -- solve the same problem (see Resolve_Aggr_Expr). So let us do
1506 -- the analysis of non-array aggregates now in order to get the
1507 -- value of Expansion_Delayed flag for the inner aggregate ???
1509 if Present (Comp_Typ) and then not Is_Array_Type (Comp_Typ) then
1510 Analyze_And_Resolve (Expr_Q, Comp_Typ);
1511 end if;
1513 if Is_Delayed_Aggregate (Expr_Q) then
1515 -- This is either a subaggregate of a multidimensional array,
1516 -- or a component of an array type whose component type is
1517 -- also an array. In the latter case, the expression may have
1518 -- component associations that provide different bounds from
1519 -- those of the component type, and sliding must occur. Instead
1520 -- of decomposing the current aggregate assignment, force the
1521 -- reanalysis of the assignment, so that a temporary will be
1522 -- generated in the usual fashion, and sliding will take place.
1524 if Nkind (Parent (N)) = N_Assignment_Statement
1525 and then Is_Array_Type (Comp_Typ)
1526 and then Present (Component_Associations (Expr_Q))
1527 and then Must_Slide (Comp_Typ, Etype (Expr_Q))
1528 then
1529 Set_Expansion_Delayed (Expr_Q, False);
1530 Set_Analyzed (Expr_Q, False);
1532 else
1533 return
1534 Add_Loop_Actions (
1535 Late_Expansion (Expr_Q, Etype (Expr_Q), Indexed_Comp));
1536 end if;
1537 end if;
1538 end if;
1540 if Present (Expr) then
1542 -- Handle an initialization expression of a controlled type in
1543 -- case it denotes a function call. In general such a scenario
1544 -- will produce a transient scope, but this will lead to wrong
1545 -- order of initialization, adjustment, and finalization in the
1546 -- context of aggregates.
1548 -- Target (1) := Ctrl_Func_Call;
1550 -- begin -- scope
1551 -- Trans_Obj : ... := Ctrl_Func_Call; -- object
1552 -- Target (1) := Trans_Obj;
1553 -- Finalize (Trans_Obj);
1554 -- end;
1555 -- Target (1)._tag := ...;
1556 -- Adjust (Target (1));
1558 -- In the example above, the call to Finalize occurs too early
1559 -- and as a result it may leave the array component in a bad
1560 -- state. Finalization of the transient object should really
1561 -- happen after adjustment.
1563 -- To avoid this scenario, perform in-place side-effect removal
1564 -- of the function call. This eliminates the transient property
1565 -- of the function result and ensures correct order of actions.
1567 -- Res : ... := Ctrl_Func_Call;
1568 -- Target (1) := Res;
1569 -- Target (1)._tag := ...;
1570 -- Adjust (Target (1));
1571 -- Finalize (Res);
1573 if Present (Comp_Typ)
1574 and then Needs_Finalization (Comp_Typ)
1575 and then Nkind (Expr) /= N_Aggregate
1576 then
1577 Initialize_Ctrl_Array_Component
1578 (Arr_Comp => Indexed_Comp,
1579 Comp_Typ => Comp_Typ,
1580 Init_Expr => Expr,
1581 Stmts => Stmts);
1583 -- Otherwise perform simple component initialization
1585 else
1586 Initialize_Array_Component
1587 (Arr_Comp => Indexed_Comp,
1588 Comp_Typ => Comp_Typ,
1589 Init_Expr => Expr,
1590 Stmts => Stmts);
1591 end if;
1593 -- Ada 2005 (AI-287): In case of default initialized component, call
1594 -- the initialization subprogram associated with the component type.
1595 -- If the component type is an access type, add an explicit null
1596 -- assignment, because for the back-end there is an initialization
1597 -- present for the whole aggregate, and no default initialization
1598 -- will take place.
1600 -- In addition, if the component type is controlled, we must call
1601 -- its Initialize procedure explicitly, because there is no explicit
1602 -- object creation that will invoke it otherwise.
1604 else
1605 if Present (Base_Init_Proc (Base_Type (Ctype)))
1606 or else Has_Task (Base_Type (Ctype))
1607 then
1608 Append_List_To (Stmts,
1609 Build_Initialization_Call (Loc,
1610 Id_Ref => Indexed_Comp,
1611 Typ => Ctype,
1612 With_Default_Init => True));
1614 -- If the component type has invariants, add an invariant
1615 -- check after the component is default-initialized. It will
1616 -- be analyzed and resolved before the code for initialization
1617 -- of other components.
1619 if Has_Invariants (Ctype) then
1620 Set_Etype (Indexed_Comp, Ctype);
1621 Append_To (Stmts, Make_Invariant_Call (Indexed_Comp));
1622 end if;
1624 elsif Is_Access_Type (Ctype) then
1625 Append_To (Stmts,
1626 Make_Assignment_Statement (Loc,
1627 Name => New_Copy_Tree (Indexed_Comp),
1628 Expression => Make_Null (Loc)));
1629 end if;
1631 if Needs_Finalization (Ctype) then
1632 Init_Call :=
1633 Make_Init_Call
1634 (Obj_Ref => New_Copy_Tree (Indexed_Comp),
1635 Typ => Ctype);
1637 -- Guard against a missing [Deep_]Initialize when the component
1638 -- type was not properly frozen.
1640 if Present (Init_Call) then
1641 Append_To (Stmts, Init_Call);
1642 end if;
1643 end if;
1644 end if;
1646 return Add_Loop_Actions (Stmts);
1647 end Gen_Assign;
1649 --------------
1650 -- Gen_Loop --
1651 --------------
1653 function Gen_Loop (L, H : Node_Id; Expr : Node_Id) return List_Id is
1654 Is_Iterated_Component : constant Boolean :=
1655 Nkind (Parent (Expr)) = N_Iterated_Component_Association;
1657 L_J : Node_Id;
1659 L_L : Node_Id;
1660 -- Index_Base'(L)
1662 L_H : Node_Id;
1663 -- Index_Base'(H)
1665 L_Range : Node_Id;
1666 -- Index_Base'(L) .. Index_Base'(H)
1668 L_Iteration_Scheme : Node_Id;
1669 -- L_J in Index_Base'(L) .. Index_Base'(H)
1671 L_Body : List_Id;
1672 -- The statements to execute in the loop
1674 S : constant List_Id := New_List;
1675 -- List of statements
1677 Tcopy : Node_Id;
1678 -- Copy of expression tree, used for checking purposes
1680 begin
1681 -- If loop bounds define an empty range return the null statement
1683 if Empty_Range (L, H) then
1684 Append_To (S, Make_Null_Statement (Loc));
1686 -- Ada 2005 (AI-287): Nothing else need to be done in case of
1687 -- default initialized component.
1689 if No (Expr) then
1690 null;
1692 else
1693 -- The expression must be type-checked even though no component
1694 -- of the aggregate will have this value. This is done only for
1695 -- actual components of the array, not for subaggregates. Do
1696 -- the check on a copy, because the expression may be shared
1697 -- among several choices, some of which might be non-null.
1699 if Present (Etype (N))
1700 and then Is_Array_Type (Etype (N))
1701 and then No (Next_Index (Index))
1702 then
1703 Expander_Mode_Save_And_Set (False);
1704 Tcopy := New_Copy_Tree (Expr);
1705 Set_Parent (Tcopy, N);
1706 Analyze_And_Resolve (Tcopy, Component_Type (Etype (N)));
1707 Expander_Mode_Restore;
1708 end if;
1709 end if;
1711 return S;
1713 -- If loop bounds are the same then generate an assignment, unless
1714 -- the parent construct is an Iterated_Component_Association.
1716 elsif Equal (L, H) and then not Is_Iterated_Component then
1717 return Gen_Assign (New_Copy_Tree (L), Expr);
1719 -- If H - L <= 2 then generate a sequence of assignments when we are
1720 -- processing the bottom most aggregate and it contains scalar
1721 -- components.
1723 elsif No (Next_Index (Index))
1724 and then Scalar_Comp
1725 and then Local_Compile_Time_Known_Value (L)
1726 and then Local_Compile_Time_Known_Value (H)
1727 and then Local_Expr_Value (H) - Local_Expr_Value (L) <= 2
1728 and then not Is_Iterated_Component
1729 then
1730 Append_List_To (S, Gen_Assign (New_Copy_Tree (L), Expr));
1731 Append_List_To (S, Gen_Assign (Add (1, To => L), Expr));
1733 if Local_Expr_Value (H) - Local_Expr_Value (L) = 2 then
1734 Append_List_To (S, Gen_Assign (Add (2, To => L), Expr));
1735 end if;
1737 return S;
1738 end if;
1740 -- Otherwise construct the loop, starting with the loop index L_J
1742 if Is_Iterated_Component then
1743 L_J :=
1744 Make_Defining_Identifier (Loc,
1745 Chars => (Chars (Defining_Identifier (Parent (Expr)))));
1747 else
1748 L_J := Make_Temporary (Loc, 'J', L);
1749 end if;
1751 -- Construct "L .. H" in Index_Base. We use a qualified expression
1752 -- for the bound to convert to the index base, but we don't need
1753 -- to do that if we already have the base type at hand.
1755 if Etype (L) = Index_Base then
1756 L_L := L;
1757 else
1758 L_L :=
1759 Make_Qualified_Expression (Loc,
1760 Subtype_Mark => Index_Base_Name,
1761 Expression => New_Copy_Tree (L));
1762 end if;
1764 if Etype (H) = Index_Base then
1765 L_H := H;
1766 else
1767 L_H :=
1768 Make_Qualified_Expression (Loc,
1769 Subtype_Mark => Index_Base_Name,
1770 Expression => New_Copy_Tree (H));
1771 end if;
1773 L_Range :=
1774 Make_Range (Loc,
1775 Low_Bound => L_L,
1776 High_Bound => L_H);
1778 -- Construct "for L_J in Index_Base range L .. H"
1780 L_Iteration_Scheme :=
1781 Make_Iteration_Scheme
1782 (Loc,
1783 Loop_Parameter_Specification =>
1784 Make_Loop_Parameter_Specification
1785 (Loc,
1786 Defining_Identifier => L_J,
1787 Discrete_Subtype_Definition => L_Range));
1789 -- Construct the statements to execute in the loop body
1791 L_Body :=
1792 Gen_Assign (New_Occurrence_Of (L_J, Loc), Expr, In_Loop => True);
1794 -- Construct the final loop
1796 Append_To (S,
1797 Make_Implicit_Loop_Statement
1798 (Node => N,
1799 Identifier => Empty,
1800 Iteration_Scheme => L_Iteration_Scheme,
1801 Statements => L_Body));
1803 -- A small optimization: if the aggregate is initialized with a box
1804 -- and the component type has no initialization procedure, remove the
1805 -- useless empty loop.
1807 if Nkind (First (S)) = N_Loop_Statement
1808 and then Is_Empty_List (Statements (First (S)))
1809 then
1810 return New_List (Make_Null_Statement (Loc));
1811 else
1812 return S;
1813 end if;
1814 end Gen_Loop;
1816 ---------------
1817 -- Gen_While --
1818 ---------------
1820 -- The code built is
1822 -- W_J : Index_Base := L;
1823 -- while W_J < H loop
1824 -- W_J := Index_Base'Succ (W);
1825 -- L_Body;
1826 -- end loop;
1828 function Gen_While (L, H : Node_Id; Expr : Node_Id) return List_Id is
1829 W_J : Node_Id;
1831 W_Decl : Node_Id;
1832 -- W_J : Base_Type := L;
1834 W_Iteration_Scheme : Node_Id;
1835 -- while W_J < H
1837 W_Index_Succ : Node_Id;
1838 -- Index_Base'Succ (J)
1840 W_Increment : Node_Id;
1841 -- W_J := Index_Base'Succ (W)
1843 W_Body : constant List_Id := New_List;
1844 -- The statements to execute in the loop
1846 S : constant List_Id := New_List;
1847 -- list of statement
1849 begin
1850 -- If loop bounds define an empty range or are equal return null
1852 if Empty_Range (L, H) or else Equal (L, H) then
1853 Append_To (S, Make_Null_Statement (Loc));
1854 return S;
1855 end if;
1857 -- Build the decl of W_J
1859 W_J := Make_Temporary (Loc, 'J', L);
1860 W_Decl :=
1861 Make_Object_Declaration
1862 (Loc,
1863 Defining_Identifier => W_J,
1864 Object_Definition => Index_Base_Name,
1865 Expression => L);
1867 -- Theoretically we should do a New_Copy_Tree (L) here, but we know
1868 -- that in this particular case L is a fresh Expr generated by
1869 -- Add which we are the only ones to use.
1871 Append_To (S, W_Decl);
1873 -- Construct " while W_J < H"
1875 W_Iteration_Scheme :=
1876 Make_Iteration_Scheme
1877 (Loc,
1878 Condition => Make_Op_Lt
1879 (Loc,
1880 Left_Opnd => New_Occurrence_Of (W_J, Loc),
1881 Right_Opnd => New_Copy_Tree (H)));
1883 -- Construct the statements to execute in the loop body
1885 W_Index_Succ :=
1886 Make_Attribute_Reference
1887 (Loc,
1888 Prefix => Index_Base_Name,
1889 Attribute_Name => Name_Succ,
1890 Expressions => New_List (New_Occurrence_Of (W_J, Loc)));
1892 W_Increment :=
1893 Make_OK_Assignment_Statement
1894 (Loc,
1895 Name => New_Occurrence_Of (W_J, Loc),
1896 Expression => W_Index_Succ);
1898 Append_To (W_Body, W_Increment);
1900 Append_List_To (W_Body,
1901 Gen_Assign (New_Occurrence_Of (W_J, Loc), Expr, In_Loop => True));
1903 -- Construct the final loop
1905 Append_To (S,
1906 Make_Implicit_Loop_Statement
1907 (Node => N,
1908 Identifier => Empty,
1909 Iteration_Scheme => W_Iteration_Scheme,
1910 Statements => W_Body));
1912 return S;
1913 end Gen_While;
1915 --------------------
1916 -- Get_Assoc_Expr --
1917 --------------------
1919 function Get_Assoc_Expr (Assoc : Node_Id) return Node_Id is
1920 Typ : constant Entity_Id := Base_Type (Etype (N));
1922 begin
1923 if Box_Present (Assoc) then
1924 if Is_Scalar_Type (Ctype) then
1925 if Present (Default_Aspect_Component_Value (Typ)) then
1926 return Default_Aspect_Component_Value (Typ);
1927 elsif Present (Default_Aspect_Value (Ctype)) then
1928 return Default_Aspect_Value (Ctype);
1929 else
1930 return Empty;
1931 end if;
1933 else
1934 return Empty;
1935 end if;
1937 else
1938 return Expression (Assoc);
1939 end if;
1940 end Get_Assoc_Expr;
1942 ---------------------
1943 -- Index_Base_Name --
1944 ---------------------
1946 function Index_Base_Name return Node_Id is
1947 begin
1948 return New_Occurrence_Of (Index_Base, Sloc (N));
1949 end Index_Base_Name;
1951 ------------------------------------
1952 -- Local_Compile_Time_Known_Value --
1953 ------------------------------------
1955 function Local_Compile_Time_Known_Value (E : Node_Id) return Boolean is
1956 begin
1957 return Compile_Time_Known_Value (E)
1958 or else
1959 (Nkind (E) = N_Attribute_Reference
1960 and then Attribute_Name (E) = Name_Val
1961 and then Compile_Time_Known_Value (First (Expressions (E))));
1962 end Local_Compile_Time_Known_Value;
1964 ----------------------
1965 -- Local_Expr_Value --
1966 ----------------------
1968 function Local_Expr_Value (E : Node_Id) return Uint is
1969 begin
1970 if Compile_Time_Known_Value (E) then
1971 return Expr_Value (E);
1972 else
1973 return Expr_Value (First (Expressions (E)));
1974 end if;
1975 end Local_Expr_Value;
1977 -- Local variables
1979 New_Code : constant List_Id := New_List;
1981 Aggr_L : constant Node_Id := Low_Bound (Aggregate_Bounds (N));
1982 Aggr_H : constant Node_Id := High_Bound (Aggregate_Bounds (N));
1983 -- The aggregate bounds of this specific subaggregate. Note that if the
1984 -- code generated by Build_Array_Aggr_Code is executed then these bounds
1985 -- are OK. Otherwise a Constraint_Error would have been raised.
1987 Aggr_Low : constant Node_Id := Duplicate_Subexpr_No_Checks (Aggr_L);
1988 Aggr_High : constant Node_Id := Duplicate_Subexpr_No_Checks (Aggr_H);
1989 -- After Duplicate_Subexpr these are side-effect free
1991 Assoc : Node_Id;
1992 Choice : Node_Id;
1993 Expr : Node_Id;
1994 High : Node_Id;
1995 Low : Node_Id;
1996 Typ : Entity_Id;
1998 Nb_Choices : Nat := 0;
1999 Table : Case_Table_Type (1 .. Number_Of_Choices (N));
2000 -- Used to sort all the different choice values
2002 Nb_Elements : Int;
2003 -- Number of elements in the positional aggregate
2005 Others_Assoc : Node_Id := Empty;
2007 -- Start of processing for Build_Array_Aggr_Code
2009 begin
2010 -- First before we start, a special case. if we have a bit packed
2011 -- array represented as a modular type, then clear the value to
2012 -- zero first, to ensure that unused bits are properly cleared.
2014 Typ := Etype (N);
2016 if Present (Typ)
2017 and then Is_Bit_Packed_Array (Typ)
2018 and then Is_Modular_Integer_Type (Packed_Array_Impl_Type (Typ))
2019 then
2020 Append_To (New_Code,
2021 Make_Assignment_Statement (Loc,
2022 Name => New_Copy_Tree (Into),
2023 Expression =>
2024 Unchecked_Convert_To (Typ,
2025 Make_Integer_Literal (Loc, Uint_0))));
2026 end if;
2028 -- If the component type contains tasks, we need to build a Master
2029 -- entity in the current scope, because it will be needed if build-
2030 -- in-place functions are called in the expanded code.
2032 if Nkind (Parent (N)) = N_Object_Declaration and then Has_Task (Typ) then
2033 Build_Master_Entity (Defining_Identifier (Parent (N)));
2034 end if;
2036 -- STEP 1: Process component associations
2038 -- For those associations that may generate a loop, initialize
2039 -- Loop_Actions to collect inserted actions that may be crated.
2041 -- Skip this if no component associations
2043 if No (Expressions (N)) then
2045 -- STEP 1 (a): Sort the discrete choices
2047 Assoc := First (Component_Associations (N));
2048 while Present (Assoc) loop
2049 Choice := First (Choice_List (Assoc));
2050 while Present (Choice) loop
2051 if Nkind (Choice) = N_Others_Choice then
2052 Set_Loop_Actions (Assoc, New_List);
2053 Others_Assoc := Assoc;
2054 exit;
2055 end if;
2057 Get_Index_Bounds (Choice, Low, High);
2059 if Low /= High then
2060 Set_Loop_Actions (Assoc, New_List);
2061 end if;
2063 Nb_Choices := Nb_Choices + 1;
2065 Table (Nb_Choices) :=
2066 (Choice_Lo => Low,
2067 Choice_Hi => High,
2068 Choice_Node => Get_Assoc_Expr (Assoc));
2070 Next (Choice);
2071 end loop;
2073 Next (Assoc);
2074 end loop;
2076 -- If there is more than one set of choices these must be static
2077 -- and we can therefore sort them. Remember that Nb_Choices does not
2078 -- account for an others choice.
2080 if Nb_Choices > 1 then
2081 Sort_Case_Table (Table);
2082 end if;
2084 -- STEP 1 (b): take care of the whole set of discrete choices
2086 for J in 1 .. Nb_Choices loop
2087 Low := Table (J).Choice_Lo;
2088 High := Table (J).Choice_Hi;
2089 Expr := Table (J).Choice_Node;
2090 Append_List (Gen_Loop (Low, High, Expr), To => New_Code);
2091 end loop;
2093 -- STEP 1 (c): generate the remaining loops to cover others choice
2094 -- We don't need to generate loops over empty gaps, but if there is
2095 -- a single empty range we must analyze the expression for semantics
2097 if Present (Others_Assoc) then
2098 declare
2099 First : Boolean := True;
2101 begin
2102 for J in 0 .. Nb_Choices loop
2103 if J = 0 then
2104 Low := Aggr_Low;
2105 else
2106 Low := Add (1, To => Table (J).Choice_Hi);
2107 end if;
2109 if J = Nb_Choices then
2110 High := Aggr_High;
2111 else
2112 High := Add (-1, To => Table (J + 1).Choice_Lo);
2113 end if;
2115 -- If this is an expansion within an init proc, make
2116 -- sure that discriminant references are replaced by
2117 -- the corresponding discriminal.
2119 if Inside_Init_Proc then
2120 if Is_Entity_Name (Low)
2121 and then Ekind (Entity (Low)) = E_Discriminant
2122 then
2123 Set_Entity (Low, Discriminal (Entity (Low)));
2124 end if;
2126 if Is_Entity_Name (High)
2127 and then Ekind (Entity (High)) = E_Discriminant
2128 then
2129 Set_Entity (High, Discriminal (Entity (High)));
2130 end if;
2131 end if;
2133 if First
2134 or else not Empty_Range (Low, High)
2135 then
2136 First := False;
2137 Append_List
2138 (Gen_Loop (Low, High,
2139 Get_Assoc_Expr (Others_Assoc)), To => New_Code);
2140 end if;
2141 end loop;
2142 end;
2143 end if;
2145 -- STEP 2: Process positional components
2147 else
2148 -- STEP 2 (a): Generate the assignments for each positional element
2149 -- Note that here we have to use Aggr_L rather than Aggr_Low because
2150 -- Aggr_L is analyzed and Add wants an analyzed expression.
2152 Expr := First (Expressions (N));
2153 Nb_Elements := -1;
2154 while Present (Expr) loop
2155 Nb_Elements := Nb_Elements + 1;
2156 Append_List (Gen_Assign (Add (Nb_Elements, To => Aggr_L), Expr),
2157 To => New_Code);
2158 Next (Expr);
2159 end loop;
2161 -- STEP 2 (b): Generate final loop if an others choice is present
2162 -- Here Nb_Elements gives the offset of the last positional element.
2164 if Present (Component_Associations (N)) then
2165 Assoc := Last (Component_Associations (N));
2167 -- Ada 2005 (AI-287)
2169 Append_List (Gen_While (Add (Nb_Elements, To => Aggr_L),
2170 Aggr_High,
2171 Get_Assoc_Expr (Assoc)), -- AI-287
2172 To => New_Code);
2173 end if;
2174 end if;
2176 return New_Code;
2177 end Build_Array_Aggr_Code;
2179 ----------------------------
2180 -- Build_Record_Aggr_Code --
2181 ----------------------------
2183 function Build_Record_Aggr_Code
2184 (N : Node_Id;
2185 Typ : Entity_Id;
2186 Lhs : Node_Id) return List_Id
2188 Loc : constant Source_Ptr := Sloc (N);
2189 L : constant List_Id := New_List;
2190 N_Typ : constant Entity_Id := Etype (N);
2192 Comp : Node_Id;
2193 Instr : Node_Id;
2194 Ref : Node_Id;
2195 Target : Entity_Id;
2196 Comp_Type : Entity_Id;
2197 Selector : Entity_Id;
2198 Comp_Expr : Node_Id;
2199 Expr_Q : Node_Id;
2201 -- If this is an internal aggregate, the External_Final_List is an
2202 -- expression for the controller record of the enclosing type.
2204 -- If the current aggregate has several controlled components, this
2205 -- expression will appear in several calls to attach to the finali-
2206 -- zation list, and it must not be shared.
2208 Ancestor_Is_Expression : Boolean := False;
2209 Ancestor_Is_Subtype_Mark : Boolean := False;
2211 Init_Typ : Entity_Id := Empty;
2213 Finalization_Done : Boolean := False;
2214 -- True if Generate_Finalization_Actions has already been called; calls
2215 -- after the first do nothing.
2217 function Ancestor_Discriminant_Value (Disc : Entity_Id) return Node_Id;
2218 -- Returns the value that the given discriminant of an ancestor type
2219 -- should receive (in the absence of a conflict with the value provided
2220 -- by an ancestor part of an extension aggregate).
2222 procedure Check_Ancestor_Discriminants (Anc_Typ : Entity_Id);
2223 -- Check that each of the discriminant values defined by the ancestor
2224 -- part of an extension aggregate match the corresponding values
2225 -- provided by either an association of the aggregate or by the
2226 -- constraint imposed by a parent type (RM95-4.3.2(8)).
2228 function Compatible_Int_Bounds
2229 (Agg_Bounds : Node_Id;
2230 Typ_Bounds : Node_Id) return Boolean;
2231 -- Return true if Agg_Bounds are equal or within Typ_Bounds. It is
2232 -- assumed that both bounds are integer ranges.
2234 procedure Generate_Finalization_Actions;
2235 -- Deal with the various controlled type data structure initializations
2236 -- (but only if it hasn't been done already).
2238 function Get_Constraint_Association (T : Entity_Id) return Node_Id;
2239 -- Returns the first discriminant association in the constraint
2240 -- associated with T, if any, otherwise returns Empty.
2242 function Get_Explicit_Discriminant_Value (D : Entity_Id) return Node_Id;
2243 -- If the ancestor part is an unconstrained type and further ancestors
2244 -- do not provide discriminants for it, check aggregate components for
2245 -- values of the discriminants.
2247 procedure Init_Hidden_Discriminants (Typ : Entity_Id; List : List_Id);
2248 -- If Typ is derived, and constrains discriminants of the parent type,
2249 -- these discriminants are not components of the aggregate, and must be
2250 -- initialized. The assignments are appended to List. The same is done
2251 -- if Typ derives fron an already constrained subtype of a discriminated
2252 -- parent type.
2254 procedure Init_Stored_Discriminants;
2255 -- If the type is derived and has inherited discriminants, generate
2256 -- explicit assignments for each, using the store constraint of the
2257 -- type. Note that both visible and stored discriminants must be
2258 -- initialized in case the derived type has some renamed and some
2259 -- constrained discriminants.
2261 procedure Init_Visible_Discriminants;
2262 -- If type has discriminants, retrieve their values from aggregate,
2263 -- and generate explicit assignments for each. This does not include
2264 -- discriminants inherited from ancestor, which are handled above.
2265 -- The type of the aggregate is a subtype created ealier using the
2266 -- given values of the discriminant components of the aggregate.
2268 procedure Initialize_Ctrl_Record_Component
2269 (Rec_Comp : Node_Id;
2270 Comp_Typ : Entity_Id;
2271 Init_Expr : Node_Id;
2272 Stmts : List_Id);
2273 -- Perform the initialization of controlled record component Rec_Comp.
2274 -- Comp_Typ is the component type. Init_Expr is the initialization
2275 -- expression for the record component. Hook-related declarations are
2276 -- inserted prior to aggregate N using Insert_Action. All remaining
2277 -- generated code is added to list Stmts.
2279 procedure Initialize_Record_Component
2280 (Rec_Comp : Node_Id;
2281 Comp_Typ : Entity_Id;
2282 Init_Expr : Node_Id;
2283 Stmts : List_Id);
2284 -- Perform the initialization of record component Rec_Comp. Comp_Typ
2285 -- is the component type. Init_Expr is the initialization expression
2286 -- of the record component. All generated code is added to list Stmts.
2288 function Is_Int_Range_Bounds (Bounds : Node_Id) return Boolean;
2289 -- Check whether Bounds is a range node and its lower and higher bounds
2290 -- are integers literals.
2292 function Replace_Type (Expr : Node_Id) return Traverse_Result;
2293 -- If the aggregate contains a self-reference, traverse each expression
2294 -- to replace a possible self-reference with a reference to the proper
2295 -- component of the target of the assignment.
2297 function Rewrite_Discriminant (Expr : Node_Id) return Traverse_Result;
2298 -- If default expression of a component mentions a discriminant of the
2299 -- type, it must be rewritten as the discriminant of the target object.
2301 ---------------------------------
2302 -- Ancestor_Discriminant_Value --
2303 ---------------------------------
2305 function Ancestor_Discriminant_Value (Disc : Entity_Id) return Node_Id is
2306 Assoc : Node_Id;
2307 Assoc_Elmt : Elmt_Id;
2308 Aggr_Comp : Entity_Id;
2309 Corresp_Disc : Entity_Id;
2310 Current_Typ : Entity_Id := Base_Type (Typ);
2311 Parent_Typ : Entity_Id;
2312 Parent_Disc : Entity_Id;
2313 Save_Assoc : Node_Id := Empty;
2315 begin
2316 -- First check any discriminant associations to see if any of them
2317 -- provide a value for the discriminant.
2319 if Present (Discriminant_Specifications (Parent (Current_Typ))) then
2320 Assoc := First (Component_Associations (N));
2321 while Present (Assoc) loop
2322 Aggr_Comp := Entity (First (Choices (Assoc)));
2324 if Ekind (Aggr_Comp) = E_Discriminant then
2325 Save_Assoc := Expression (Assoc);
2327 Corresp_Disc := Corresponding_Discriminant (Aggr_Comp);
2328 while Present (Corresp_Disc) loop
2330 -- If found a corresponding discriminant then return the
2331 -- value given in the aggregate. (Note: this is not
2332 -- correct in the presence of side effects. ???)
2334 if Disc = Corresp_Disc then
2335 return Duplicate_Subexpr (Expression (Assoc));
2336 end if;
2338 Corresp_Disc := Corresponding_Discriminant (Corresp_Disc);
2339 end loop;
2340 end if;
2342 Next (Assoc);
2343 end loop;
2344 end if;
2346 -- No match found in aggregate, so chain up parent types to find
2347 -- a constraint that defines the value of the discriminant.
2349 Parent_Typ := Etype (Current_Typ);
2350 while Current_Typ /= Parent_Typ loop
2351 if Has_Discriminants (Parent_Typ)
2352 and then not Has_Unknown_Discriminants (Parent_Typ)
2353 then
2354 Parent_Disc := First_Discriminant (Parent_Typ);
2356 -- We either get the association from the subtype indication
2357 -- of the type definition itself, or from the discriminant
2358 -- constraint associated with the type entity (which is
2359 -- preferable, but it's not always present ???)
2361 if Is_Empty_Elmt_List (Discriminant_Constraint (Current_Typ))
2362 then
2363 Assoc := Get_Constraint_Association (Current_Typ);
2364 Assoc_Elmt := No_Elmt;
2365 else
2366 Assoc_Elmt :=
2367 First_Elmt (Discriminant_Constraint (Current_Typ));
2368 Assoc := Node (Assoc_Elmt);
2369 end if;
2371 -- Traverse the discriminants of the parent type looking
2372 -- for one that corresponds.
2374 while Present (Parent_Disc) and then Present (Assoc) loop
2375 Corresp_Disc := Parent_Disc;
2376 while Present (Corresp_Disc)
2377 and then Disc /= Corresp_Disc
2378 loop
2379 Corresp_Disc := Corresponding_Discriminant (Corresp_Disc);
2380 end loop;
2382 if Disc = Corresp_Disc then
2383 if Nkind (Assoc) = N_Discriminant_Association then
2384 Assoc := Expression (Assoc);
2385 end if;
2387 -- If the located association directly denotes
2388 -- a discriminant, then use the value of a saved
2389 -- association of the aggregate. This is an approach
2390 -- used to handle certain cases involving multiple
2391 -- discriminants mapped to a single discriminant of
2392 -- a descendant. It's not clear how to locate the
2393 -- appropriate discriminant value for such cases. ???
2395 if Is_Entity_Name (Assoc)
2396 and then Ekind (Entity (Assoc)) = E_Discriminant
2397 then
2398 Assoc := Save_Assoc;
2399 end if;
2401 return Duplicate_Subexpr (Assoc);
2402 end if;
2404 Next_Discriminant (Parent_Disc);
2406 if No (Assoc_Elmt) then
2407 Next (Assoc);
2409 else
2410 Next_Elmt (Assoc_Elmt);
2412 if Present (Assoc_Elmt) then
2413 Assoc := Node (Assoc_Elmt);
2414 else
2415 Assoc := Empty;
2416 end if;
2417 end if;
2418 end loop;
2419 end if;
2421 Current_Typ := Parent_Typ;
2422 Parent_Typ := Etype (Current_Typ);
2423 end loop;
2425 -- In some cases there's no ancestor value to locate (such as
2426 -- when an ancestor part given by an expression defines the
2427 -- discriminant value).
2429 return Empty;
2430 end Ancestor_Discriminant_Value;
2432 ----------------------------------
2433 -- Check_Ancestor_Discriminants --
2434 ----------------------------------
2436 procedure Check_Ancestor_Discriminants (Anc_Typ : Entity_Id) is
2437 Discr : Entity_Id;
2438 Disc_Value : Node_Id;
2439 Cond : Node_Id;
2441 begin
2442 Discr := First_Discriminant (Base_Type (Anc_Typ));
2443 while Present (Discr) loop
2444 Disc_Value := Ancestor_Discriminant_Value (Discr);
2446 if Present (Disc_Value) then
2447 Cond := Make_Op_Ne (Loc,
2448 Left_Opnd =>
2449 Make_Selected_Component (Loc,
2450 Prefix => New_Copy_Tree (Target),
2451 Selector_Name => New_Occurrence_Of (Discr, Loc)),
2452 Right_Opnd => Disc_Value);
2454 Append_To (L,
2455 Make_Raise_Constraint_Error (Loc,
2456 Condition => Cond,
2457 Reason => CE_Discriminant_Check_Failed));
2458 end if;
2460 Next_Discriminant (Discr);
2461 end loop;
2462 end Check_Ancestor_Discriminants;
2464 ---------------------------
2465 -- Compatible_Int_Bounds --
2466 ---------------------------
2468 function Compatible_Int_Bounds
2469 (Agg_Bounds : Node_Id;
2470 Typ_Bounds : Node_Id) return Boolean
2472 Agg_Lo : constant Uint := Intval (Low_Bound (Agg_Bounds));
2473 Agg_Hi : constant Uint := Intval (High_Bound (Agg_Bounds));
2474 Typ_Lo : constant Uint := Intval (Low_Bound (Typ_Bounds));
2475 Typ_Hi : constant Uint := Intval (High_Bound (Typ_Bounds));
2476 begin
2477 return Typ_Lo <= Agg_Lo and then Agg_Hi <= Typ_Hi;
2478 end Compatible_Int_Bounds;
2480 -----------------------------------
2481 -- Generate_Finalization_Actions --
2482 -----------------------------------
2484 procedure Generate_Finalization_Actions is
2485 begin
2486 -- Do the work only the first time this is called
2488 if Finalization_Done then
2489 return;
2490 end if;
2492 Finalization_Done := True;
2494 -- Determine the external finalization list. It is either the
2495 -- finalization list of the outer scope or the one coming from an
2496 -- outer aggregate. When the target is not a temporary, the proper
2497 -- scope is the scope of the target rather than the potentially
2498 -- transient current scope.
2500 if Is_Controlled (Typ) and then Ancestor_Is_Subtype_Mark then
2501 Ref := Convert_To (Init_Typ, New_Copy_Tree (Target));
2502 Set_Assignment_OK (Ref);
2504 Append_To (L,
2505 Make_Procedure_Call_Statement (Loc,
2506 Name =>
2507 New_Occurrence_Of
2508 (Find_Prim_Op (Init_Typ, Name_Initialize), Loc),
2509 Parameter_Associations => New_List (New_Copy_Tree (Ref))));
2510 end if;
2511 end Generate_Finalization_Actions;
2513 --------------------------------
2514 -- Get_Constraint_Association --
2515 --------------------------------
2517 function Get_Constraint_Association (T : Entity_Id) return Node_Id is
2518 Indic : Node_Id;
2519 Typ : Entity_Id;
2521 begin
2522 Typ := T;
2524 -- If type is private, get constraint from full view. This was
2525 -- previously done in an instance context, but is needed whenever
2526 -- the ancestor part has a discriminant, possibly inherited through
2527 -- multiple derivations.
2529 if Is_Private_Type (Typ) and then Present (Full_View (Typ)) then
2530 Typ := Full_View (Typ);
2531 end if;
2533 Indic := Subtype_Indication (Type_Definition (Parent (Typ)));
2535 -- Verify that the subtype indication carries a constraint
2537 if Nkind (Indic) = N_Subtype_Indication
2538 and then Present (Constraint (Indic))
2539 then
2540 return First (Constraints (Constraint (Indic)));
2541 end if;
2543 return Empty;
2544 end Get_Constraint_Association;
2546 -------------------------------------
2547 -- Get_Explicit_Discriminant_Value --
2548 -------------------------------------
2550 function Get_Explicit_Discriminant_Value
2551 (D : Entity_Id) return Node_Id
2553 Assoc : Node_Id;
2554 Choice : Node_Id;
2555 Val : Node_Id;
2557 begin
2558 -- The aggregate has been normalized and all associations have a
2559 -- single choice.
2561 Assoc := First (Component_Associations (N));
2562 while Present (Assoc) loop
2563 Choice := First (Choices (Assoc));
2565 if Chars (Choice) = Chars (D) then
2566 Val := Expression (Assoc);
2567 Remove (Assoc);
2568 return Val;
2569 end if;
2571 Next (Assoc);
2572 end loop;
2574 return Empty;
2575 end Get_Explicit_Discriminant_Value;
2577 -------------------------------
2578 -- Init_Hidden_Discriminants --
2579 -------------------------------
2581 procedure Init_Hidden_Discriminants (Typ : Entity_Id; List : List_Id) is
2582 function Is_Completely_Hidden_Discriminant
2583 (Discr : Entity_Id) return Boolean;
2584 -- Determine whether Discr is a completely hidden discriminant of
2585 -- type Typ.
2587 ---------------------------------------
2588 -- Is_Completely_Hidden_Discriminant --
2589 ---------------------------------------
2591 function Is_Completely_Hidden_Discriminant
2592 (Discr : Entity_Id) return Boolean
2594 Item : Entity_Id;
2596 begin
2597 -- Use First/Next_Entity as First/Next_Discriminant do not yield
2598 -- completely hidden discriminants.
2600 Item := First_Entity (Typ);
2601 while Present (Item) loop
2602 if Ekind (Item) = E_Discriminant
2603 and then Is_Completely_Hidden (Item)
2604 and then Chars (Original_Record_Component (Item)) =
2605 Chars (Discr)
2606 then
2607 return True;
2608 end if;
2610 Next_Entity (Item);
2611 end loop;
2613 return False;
2614 end Is_Completely_Hidden_Discriminant;
2616 -- Local variables
2618 Base_Typ : Entity_Id;
2619 Discr : Entity_Id;
2620 Discr_Constr : Elmt_Id;
2621 Discr_Init : Node_Id;
2622 Discr_Val : Node_Id;
2623 In_Aggr_Type : Boolean;
2624 Par_Typ : Entity_Id;
2626 -- Start of processing for Init_Hidden_Discriminants
2628 begin
2629 -- The constraints on the hidden discriminants, if present, are kept
2630 -- in the Stored_Constraint list of the type itself, or in that of
2631 -- the base type. If not in the constraints of the aggregate itself,
2632 -- we examine ancestors to find discriminants that are not renamed
2633 -- by other discriminants but constrained explicitly.
2635 In_Aggr_Type := True;
2637 Base_Typ := Base_Type (Typ);
2638 while Is_Derived_Type (Base_Typ)
2639 and then
2640 (Present (Stored_Constraint (Base_Typ))
2641 or else
2642 (In_Aggr_Type and then Present (Stored_Constraint (Typ))))
2643 loop
2644 Par_Typ := Etype (Base_Typ);
2646 if not Has_Discriminants (Par_Typ) then
2647 return;
2648 end if;
2650 Discr := First_Discriminant (Par_Typ);
2652 -- We know that one of the stored-constraint lists is present
2654 if Present (Stored_Constraint (Base_Typ)) then
2655 Discr_Constr := First_Elmt (Stored_Constraint (Base_Typ));
2657 -- For private extension, stored constraint may be on full view
2659 elsif Is_Private_Type (Base_Typ)
2660 and then Present (Full_View (Base_Typ))
2661 and then Present (Stored_Constraint (Full_View (Base_Typ)))
2662 then
2663 Discr_Constr :=
2664 First_Elmt (Stored_Constraint (Full_View (Base_Typ)));
2666 else
2667 Discr_Constr := First_Elmt (Stored_Constraint (Typ));
2668 end if;
2670 while Present (Discr) and then Present (Discr_Constr) loop
2671 Discr_Val := Node (Discr_Constr);
2673 -- The parent discriminant is renamed in the derived type,
2674 -- nothing to initialize.
2676 -- type Deriv_Typ (Discr : ...)
2677 -- is new Parent_Typ (Discr => Discr);
2679 if Is_Entity_Name (Discr_Val)
2680 and then Ekind (Entity (Discr_Val)) = E_Discriminant
2681 then
2682 null;
2684 -- When the parent discriminant is constrained at the type
2685 -- extension level, it does not appear in the derived type.
2687 -- type Deriv_Typ (Discr : ...)
2688 -- is new Parent_Typ (Discr => Discr,
2689 -- Hidden_Discr => Expression);
2691 elsif Is_Completely_Hidden_Discriminant (Discr) then
2692 null;
2694 -- Otherwise initialize the discriminant
2696 else
2697 Discr_Init :=
2698 Make_OK_Assignment_Statement (Loc,
2699 Name =>
2700 Make_Selected_Component (Loc,
2701 Prefix => New_Copy_Tree (Target),
2702 Selector_Name => New_Occurrence_Of (Discr, Loc)),
2703 Expression => New_Copy_Tree (Discr_Val));
2705 Set_No_Ctrl_Actions (Discr_Init);
2706 Append_To (List, Discr_Init);
2707 end if;
2709 Next_Elmt (Discr_Constr);
2710 Next_Discriminant (Discr);
2711 end loop;
2713 In_Aggr_Type := False;
2714 Base_Typ := Base_Type (Par_Typ);
2715 end loop;
2716 end Init_Hidden_Discriminants;
2718 --------------------------------
2719 -- Init_Visible_Discriminants --
2720 --------------------------------
2722 procedure Init_Visible_Discriminants is
2723 Discriminant : Entity_Id;
2724 Discriminant_Value : Node_Id;
2726 begin
2727 Discriminant := First_Discriminant (Typ);
2728 while Present (Discriminant) loop
2729 Comp_Expr :=
2730 Make_Selected_Component (Loc,
2731 Prefix => New_Copy_Tree (Target),
2732 Selector_Name => New_Occurrence_Of (Discriminant, Loc));
2734 Discriminant_Value :=
2735 Get_Discriminant_Value
2736 (Discriminant, Typ, Discriminant_Constraint (N_Typ));
2738 Instr :=
2739 Make_OK_Assignment_Statement (Loc,
2740 Name => Comp_Expr,
2741 Expression => New_Copy_Tree (Discriminant_Value));
2743 Set_No_Ctrl_Actions (Instr);
2744 Append_To (L, Instr);
2746 Next_Discriminant (Discriminant);
2747 end loop;
2748 end Init_Visible_Discriminants;
2750 -------------------------------
2751 -- Init_Stored_Discriminants --
2752 -------------------------------
2754 procedure Init_Stored_Discriminants is
2755 Discriminant : Entity_Id;
2756 Discriminant_Value : Node_Id;
2758 begin
2759 Discriminant := First_Stored_Discriminant (Typ);
2760 while Present (Discriminant) loop
2761 Comp_Expr :=
2762 Make_Selected_Component (Loc,
2763 Prefix => New_Copy_Tree (Target),
2764 Selector_Name => New_Occurrence_Of (Discriminant, Loc));
2766 Discriminant_Value :=
2767 Get_Discriminant_Value
2768 (Discriminant, N_Typ, Discriminant_Constraint (N_Typ));
2770 Instr :=
2771 Make_OK_Assignment_Statement (Loc,
2772 Name => Comp_Expr,
2773 Expression => New_Copy_Tree (Discriminant_Value));
2775 Set_No_Ctrl_Actions (Instr);
2776 Append_To (L, Instr);
2778 Next_Stored_Discriminant (Discriminant);
2779 end loop;
2780 end Init_Stored_Discriminants;
2782 --------------------------------------
2783 -- Initialize_Ctrl_Record_Component --
2784 --------------------------------------
2786 procedure Initialize_Ctrl_Record_Component
2787 (Rec_Comp : Node_Id;
2788 Comp_Typ : Entity_Id;
2789 Init_Expr : Node_Id;
2790 Stmts : List_Id)
2792 Fin_Call : Node_Id;
2793 Hook_Clear : Node_Id;
2795 In_Place_Expansion : Boolean;
2796 -- Flag set when a nonlimited controlled function call requires
2797 -- in-place expansion.
2799 begin
2800 -- Perform a preliminary analysis and resolution to determine what
2801 -- the initialization expression denotes. Unanalyzed function calls
2802 -- may appear as identifiers or indexed components.
2804 if Nkind_In (Init_Expr, N_Function_Call,
2805 N_Identifier,
2806 N_Indexed_Component)
2807 and then not Analyzed (Init_Expr)
2808 then
2809 Preanalyze_And_Resolve (Init_Expr, Comp_Typ);
2810 end if;
2812 In_Place_Expansion :=
2813 Nkind (Init_Expr) = N_Function_Call
2814 and then not Is_Limited_Type (Comp_Typ);
2816 -- The initialization expression is a controlled function call.
2817 -- Perform in-place removal of side effects to avoid creating a
2818 -- transient scope.
2820 -- This in-place expansion is not performed for limited transient
2821 -- objects because the initialization is already done in place.
2823 if In_Place_Expansion then
2825 -- Suppress the removal of side effects by general analysis
2826 -- because this behavior is emulated here. This avoids the
2827 -- generation of a transient scope, which leads to out-of-order
2828 -- adjustment and finalization.
2830 Set_No_Side_Effect_Removal (Init_Expr);
2832 -- Install all hook-related declarations and prepare the clean up
2833 -- statements.
2835 Process_Transient_Component
2836 (Loc => Loc,
2837 Comp_Typ => Comp_Typ,
2838 Init_Expr => Init_Expr,
2839 Fin_Call => Fin_Call,
2840 Hook_Clear => Hook_Clear,
2841 Aggr => N);
2842 end if;
2844 -- Use the noncontrolled component initialization circuitry to
2845 -- assign the result of the function call to the record component.
2846 -- This also performs tag adjustment and [deep] adjustment of the
2847 -- record component.
2849 Initialize_Record_Component
2850 (Rec_Comp => Rec_Comp,
2851 Comp_Typ => Comp_Typ,
2852 Init_Expr => Init_Expr,
2853 Stmts => Stmts);
2855 -- At this point the record component is fully initialized. Complete
2856 -- the processing of the controlled record component by finalizing
2857 -- the transient function result.
2859 if In_Place_Expansion then
2860 Process_Transient_Component_Completion
2861 (Loc => Loc,
2862 Aggr => N,
2863 Fin_Call => Fin_Call,
2864 Hook_Clear => Hook_Clear,
2865 Stmts => Stmts);
2866 end if;
2867 end Initialize_Ctrl_Record_Component;
2869 ---------------------------------
2870 -- Initialize_Record_Component --
2871 ---------------------------------
2873 procedure Initialize_Record_Component
2874 (Rec_Comp : Node_Id;
2875 Comp_Typ : Entity_Id;
2876 Init_Expr : Node_Id;
2877 Stmts : List_Id)
2879 Exceptions_OK : constant Boolean :=
2880 not Restriction_Active (No_Exception_Propagation);
2882 Finalization_OK : constant Boolean := Needs_Finalization (Comp_Typ);
2884 Full_Typ : constant Entity_Id := Underlying_Type (Comp_Typ);
2885 Adj_Call : Node_Id;
2886 Blk_Stmts : List_Id;
2887 Init_Stmt : Node_Id;
2889 begin
2890 -- Protect the initialization statements from aborts. Generate:
2892 -- Abort_Defer;
2894 if Finalization_OK and Abort_Allowed then
2895 if Exceptions_OK then
2896 Blk_Stmts := New_List;
2897 else
2898 Blk_Stmts := Stmts;
2899 end if;
2901 Append_To (Blk_Stmts, Build_Runtime_Call (Loc, RE_Abort_Defer));
2903 -- Otherwise aborts are not allowed. All generated code is added
2904 -- directly to the input list.
2906 else
2907 Blk_Stmts := Stmts;
2908 end if;
2910 -- Initialize the record component. Generate:
2912 -- Rec_Comp := Init_Expr;
2914 -- Note that the initialization expression is NOT replicated because
2915 -- only a single component may be initialized by it.
2917 Init_Stmt :=
2918 Make_OK_Assignment_Statement (Loc,
2919 Name => New_Copy_Tree (Rec_Comp),
2920 Expression => Init_Expr);
2921 Set_No_Ctrl_Actions (Init_Stmt);
2923 Append_To (Blk_Stmts, Init_Stmt);
2925 -- Adjust the tag due to a possible view conversion. Generate:
2927 -- Rec_Comp._tag := Full_TypeP;
2929 if Tagged_Type_Expansion and then Is_Tagged_Type (Comp_Typ) then
2930 Append_To (Blk_Stmts,
2931 Make_OK_Assignment_Statement (Loc,
2932 Name =>
2933 Make_Selected_Component (Loc,
2934 Prefix => New_Copy_Tree (Rec_Comp),
2935 Selector_Name =>
2936 New_Occurrence_Of
2937 (First_Tag_Component (Full_Typ), Loc)),
2939 Expression =>
2940 Unchecked_Convert_To (RTE (RE_Tag),
2941 New_Occurrence_Of
2942 (Node (First_Elmt (Access_Disp_Table (Full_Typ))),
2943 Loc))));
2944 end if;
2946 -- Adjust the component. Generate:
2948 -- [Deep_]Adjust (Rec_Comp);
2950 if Finalization_OK and then not Is_Limited_Type (Comp_Typ) then
2951 Adj_Call :=
2952 Make_Adjust_Call
2953 (Obj_Ref => New_Copy_Tree (Rec_Comp),
2954 Typ => Comp_Typ);
2956 -- Guard against a missing [Deep_]Adjust when the component type
2957 -- was not properly frozen.
2959 if Present (Adj_Call) then
2960 Append_To (Blk_Stmts, Adj_Call);
2961 end if;
2962 end if;
2964 -- Complete the protection of the initialization statements
2966 if Finalization_OK and Abort_Allowed then
2968 -- Wrap the initialization statements in a block to catch a
2969 -- potential exception. Generate:
2971 -- begin
2972 -- Abort_Defer;
2973 -- Rec_Comp := Init_Expr;
2974 -- Rec_Comp._tag := Full_TypP;
2975 -- [Deep_]Adjust (Rec_Comp);
2976 -- at end
2977 -- Abort_Undefer_Direct;
2978 -- end;
2980 if Exceptions_OK then
2981 Append_To (Stmts,
2982 Build_Abort_Undefer_Block (Loc,
2983 Stmts => Blk_Stmts,
2984 Context => N));
2986 -- Otherwise exceptions are not propagated. Generate:
2988 -- Abort_Defer;
2989 -- Rec_Comp := Init_Expr;
2990 -- Rec_Comp._tag := Full_TypP;
2991 -- [Deep_]Adjust (Rec_Comp);
2992 -- Abort_Undefer;
2994 else
2995 Append_To (Blk_Stmts,
2996 Build_Runtime_Call (Loc, RE_Abort_Undefer));
2997 end if;
2998 end if;
2999 end Initialize_Record_Component;
3001 -------------------------
3002 -- Is_Int_Range_Bounds --
3003 -------------------------
3005 function Is_Int_Range_Bounds (Bounds : Node_Id) return Boolean is
3006 begin
3007 return Nkind (Bounds) = N_Range
3008 and then Nkind (Low_Bound (Bounds)) = N_Integer_Literal
3009 and then Nkind (High_Bound (Bounds)) = N_Integer_Literal;
3010 end Is_Int_Range_Bounds;
3012 ------------------
3013 -- Replace_Type --
3014 ------------------
3016 function Replace_Type (Expr : Node_Id) return Traverse_Result is
3017 begin
3018 -- Note regarding the Root_Type test below: Aggregate components for
3019 -- self-referential types include attribute references to the current
3020 -- instance, of the form: Typ'access, etc.. These references are
3021 -- rewritten as references to the target of the aggregate: the
3022 -- left-hand side of an assignment, the entity in a declaration,
3023 -- or a temporary. Without this test, we would improperly extended
3024 -- this rewriting to attribute references whose prefix was not the
3025 -- type of the aggregate.
3027 if Nkind (Expr) = N_Attribute_Reference
3028 and then Is_Entity_Name (Prefix (Expr))
3029 and then Is_Type (Entity (Prefix (Expr)))
3030 and then Root_Type (Etype (N)) = Root_Type (Entity (Prefix (Expr)))
3031 then
3032 if Is_Entity_Name (Lhs) then
3033 Rewrite (Prefix (Expr),
3034 New_Occurrence_Of (Entity (Lhs), Loc));
3036 elsif Nkind (Lhs) = N_Selected_Component then
3037 Rewrite (Expr,
3038 Make_Attribute_Reference (Loc,
3039 Attribute_Name => Name_Unrestricted_Access,
3040 Prefix => New_Copy_Tree (Lhs)));
3041 Set_Analyzed (Parent (Expr), False);
3043 else
3044 Rewrite (Expr,
3045 Make_Attribute_Reference (Loc,
3046 Attribute_Name => Name_Unrestricted_Access,
3047 Prefix => New_Copy_Tree (Lhs)));
3048 Set_Analyzed (Parent (Expr), False);
3049 end if;
3050 end if;
3052 return OK;
3053 end Replace_Type;
3055 --------------------------
3056 -- Rewrite_Discriminant --
3057 --------------------------
3059 function Rewrite_Discriminant (Expr : Node_Id) return Traverse_Result is
3060 begin
3061 if Is_Entity_Name (Expr)
3062 and then Present (Entity (Expr))
3063 and then Ekind (Entity (Expr)) = E_In_Parameter
3064 and then Present (Discriminal_Link (Entity (Expr)))
3065 and then Scope (Discriminal_Link (Entity (Expr))) =
3066 Base_Type (Etype (N))
3067 then
3068 Rewrite (Expr,
3069 Make_Selected_Component (Loc,
3070 Prefix => New_Copy_Tree (Lhs),
3071 Selector_Name => Make_Identifier (Loc, Chars (Expr))));
3072 end if;
3074 return OK;
3075 end Rewrite_Discriminant;
3077 procedure Replace_Discriminants is
3078 new Traverse_Proc (Rewrite_Discriminant);
3080 procedure Replace_Self_Reference is
3081 new Traverse_Proc (Replace_Type);
3083 -- Start of processing for Build_Record_Aggr_Code
3085 begin
3086 if Has_Self_Reference (N) then
3087 Replace_Self_Reference (N);
3088 end if;
3090 -- If the target of the aggregate is class-wide, we must convert it
3091 -- to the actual type of the aggregate, so that the proper components
3092 -- are visible. We know already that the types are compatible.
3094 if Present (Etype (Lhs))
3095 and then Is_Class_Wide_Type (Etype (Lhs))
3096 then
3097 Target := Unchecked_Convert_To (Typ, Lhs);
3098 else
3099 Target := Lhs;
3100 end if;
3102 -- Deal with the ancestor part of extension aggregates or with the
3103 -- discriminants of the root type.
3105 if Nkind (N) = N_Extension_Aggregate then
3106 declare
3107 Ancestor : constant Node_Id := Ancestor_Part (N);
3108 Adj_Call : Node_Id;
3109 Assign : List_Id;
3111 begin
3112 -- If the ancestor part is a subtype mark "T", we generate
3114 -- init-proc (T (tmp)); if T is constrained and
3115 -- init-proc (S (tmp)); where S applies an appropriate
3116 -- constraint if T is unconstrained
3118 if Is_Entity_Name (Ancestor)
3119 and then Is_Type (Entity (Ancestor))
3120 then
3121 Ancestor_Is_Subtype_Mark := True;
3123 if Is_Constrained (Entity (Ancestor)) then
3124 Init_Typ := Entity (Ancestor);
3126 -- For an ancestor part given by an unconstrained type mark,
3127 -- create a subtype constrained by appropriate corresponding
3128 -- discriminant values coming from either associations of the
3129 -- aggregate or a constraint on a parent type. The subtype will
3130 -- be used to generate the correct default value for the
3131 -- ancestor part.
3133 elsif Has_Discriminants (Entity (Ancestor)) then
3134 declare
3135 Anc_Typ : constant Entity_Id := Entity (Ancestor);
3136 Anc_Constr : constant List_Id := New_List;
3137 Discrim : Entity_Id;
3138 Disc_Value : Node_Id;
3139 New_Indic : Node_Id;
3140 Subt_Decl : Node_Id;
3142 begin
3143 Discrim := First_Discriminant (Anc_Typ);
3144 while Present (Discrim) loop
3145 Disc_Value := Ancestor_Discriminant_Value (Discrim);
3147 -- If no usable discriminant in ancestors, check
3148 -- whether aggregate has an explicit value for it.
3150 if No (Disc_Value) then
3151 Disc_Value :=
3152 Get_Explicit_Discriminant_Value (Discrim);
3153 end if;
3155 Append_To (Anc_Constr, Disc_Value);
3156 Next_Discriminant (Discrim);
3157 end loop;
3159 New_Indic :=
3160 Make_Subtype_Indication (Loc,
3161 Subtype_Mark => New_Occurrence_Of (Anc_Typ, Loc),
3162 Constraint =>
3163 Make_Index_Or_Discriminant_Constraint (Loc,
3164 Constraints => Anc_Constr));
3166 Init_Typ := Create_Itype (Ekind (Anc_Typ), N);
3168 Subt_Decl :=
3169 Make_Subtype_Declaration (Loc,
3170 Defining_Identifier => Init_Typ,
3171 Subtype_Indication => New_Indic);
3173 -- Itypes must be analyzed with checks off Declaration
3174 -- must have a parent for proper handling of subsidiary
3175 -- actions.
3177 Set_Parent (Subt_Decl, N);
3178 Analyze (Subt_Decl, Suppress => All_Checks);
3179 end;
3180 end if;
3182 Ref := Convert_To (Init_Typ, New_Copy_Tree (Target));
3183 Set_Assignment_OK (Ref);
3185 if not Is_Interface (Init_Typ) then
3186 Append_List_To (L,
3187 Build_Initialization_Call (Loc,
3188 Id_Ref => Ref,
3189 Typ => Init_Typ,
3190 In_Init_Proc => Within_Init_Proc,
3191 With_Default_Init => Has_Default_Init_Comps (N)
3192 or else
3193 Has_Task (Base_Type (Init_Typ))));
3195 if Is_Constrained (Entity (Ancestor))
3196 and then Has_Discriminants (Entity (Ancestor))
3197 then
3198 Check_Ancestor_Discriminants (Entity (Ancestor));
3199 end if;
3200 end if;
3202 -- Handle calls to C++ constructors
3204 elsif Is_CPP_Constructor_Call (Ancestor) then
3205 Init_Typ := Etype (Ancestor);
3206 Ref := Convert_To (Init_Typ, New_Copy_Tree (Target));
3207 Set_Assignment_OK (Ref);
3209 Append_List_To (L,
3210 Build_Initialization_Call (Loc,
3211 Id_Ref => Ref,
3212 Typ => Init_Typ,
3213 In_Init_Proc => Within_Init_Proc,
3214 With_Default_Init => Has_Default_Init_Comps (N),
3215 Constructor_Ref => Ancestor));
3217 -- Ada 2005 (AI-287): If the ancestor part is an aggregate of
3218 -- limited type, a recursive call expands the ancestor. Note that
3219 -- in the limited case, the ancestor part must be either a
3220 -- function call (possibly qualified, or wrapped in an unchecked
3221 -- conversion) or aggregate (definitely qualified).
3223 -- The ancestor part can also be a function call (that may be
3224 -- transformed into an explicit dereference) or a qualification
3225 -- of one such.
3227 elsif Is_Limited_Type (Etype (Ancestor))
3228 and then Nkind_In (Unqualify (Ancestor), N_Aggregate,
3229 N_Extension_Aggregate)
3230 then
3231 Ancestor_Is_Expression := True;
3233 -- Set up finalization data for enclosing record, because
3234 -- controlled subcomponents of the ancestor part will be
3235 -- attached to it.
3237 Generate_Finalization_Actions;
3239 Append_List_To (L,
3240 Build_Record_Aggr_Code
3241 (N => Unqualify (Ancestor),
3242 Typ => Etype (Unqualify (Ancestor)),
3243 Lhs => Target));
3245 -- If the ancestor part is an expression "E", we generate
3247 -- T (tmp) := E;
3249 -- In Ada 2005, this includes the case of a (possibly qualified)
3250 -- limited function call. The assignment will turn into a
3251 -- build-in-place function call (for further details, see
3252 -- Make_Build_In_Place_Call_In_Assignment).
3254 else
3255 Ancestor_Is_Expression := True;
3256 Init_Typ := Etype (Ancestor);
3258 -- If the ancestor part is an aggregate, force its full
3259 -- expansion, which was delayed.
3261 if Nkind_In (Unqualify (Ancestor), N_Aggregate,
3262 N_Extension_Aggregate)
3263 then
3264 Set_Analyzed (Ancestor, False);
3265 Set_Analyzed (Expression (Ancestor), False);
3266 end if;
3268 Ref := Convert_To (Init_Typ, New_Copy_Tree (Target));
3269 Set_Assignment_OK (Ref);
3271 -- Make the assignment without usual controlled actions, since
3272 -- we only want to Adjust afterwards, but not to Finalize
3273 -- beforehand. Add manual Adjust when necessary.
3275 Assign := New_List (
3276 Make_OK_Assignment_Statement (Loc,
3277 Name => Ref,
3278 Expression => Ancestor));
3279 Set_No_Ctrl_Actions (First (Assign));
3281 -- Assign the tag now to make sure that the dispatching call in
3282 -- the subsequent deep_adjust works properly (unless
3283 -- Tagged_Type_Expansion where tags are implicit).
3285 if Tagged_Type_Expansion then
3286 Instr :=
3287 Make_OK_Assignment_Statement (Loc,
3288 Name =>
3289 Make_Selected_Component (Loc,
3290 Prefix => New_Copy_Tree (Target),
3291 Selector_Name =>
3292 New_Occurrence_Of
3293 (First_Tag_Component (Base_Type (Typ)), Loc)),
3295 Expression =>
3296 Unchecked_Convert_To (RTE (RE_Tag),
3297 New_Occurrence_Of
3298 (Node (First_Elmt
3299 (Access_Disp_Table (Base_Type (Typ)))),
3300 Loc)));
3302 Set_Assignment_OK (Name (Instr));
3303 Append_To (Assign, Instr);
3305 -- Ada 2005 (AI-251): If tagged type has progenitors we must
3306 -- also initialize tags of the secondary dispatch tables.
3308 if Has_Interfaces (Base_Type (Typ)) then
3309 Init_Secondary_Tags
3310 (Typ => Base_Type (Typ),
3311 Target => Target,
3312 Stmts_List => Assign);
3313 end if;
3314 end if;
3316 -- Call Adjust manually
3318 if Needs_Finalization (Etype (Ancestor))
3319 and then not Is_Limited_Type (Etype (Ancestor))
3320 then
3321 Adj_Call :=
3322 Make_Adjust_Call
3323 (Obj_Ref => New_Copy_Tree (Ref),
3324 Typ => Etype (Ancestor));
3326 -- Guard against a missing [Deep_]Adjust when the ancestor
3327 -- type was not properly frozen.
3329 if Present (Adj_Call) then
3330 Append_To (Assign, Adj_Call);
3331 end if;
3332 end if;
3334 Append_To (L,
3335 Make_Unsuppress_Block (Loc, Name_Discriminant_Check, Assign));
3337 if Has_Discriminants (Init_Typ) then
3338 Check_Ancestor_Discriminants (Init_Typ);
3339 end if;
3340 end if;
3341 end;
3343 -- Generate assignments of hidden discriminants. If the base type is
3344 -- an unchecked union, the discriminants are unknown to the back-end
3345 -- and absent from a value of the type, so assignments for them are
3346 -- not emitted.
3348 if Has_Discriminants (Typ)
3349 and then not Is_Unchecked_Union (Base_Type (Typ))
3350 then
3351 Init_Hidden_Discriminants (Typ, L);
3352 end if;
3354 -- Normal case (not an extension aggregate)
3356 else
3357 -- Generate the discriminant expressions, component by component.
3358 -- If the base type is an unchecked union, the discriminants are
3359 -- unknown to the back-end and absent from a value of the type, so
3360 -- assignments for them are not emitted.
3362 if Has_Discriminants (Typ)
3363 and then not Is_Unchecked_Union (Base_Type (Typ))
3364 then
3365 Init_Hidden_Discriminants (Typ, L);
3367 -- Generate discriminant init values for the visible discriminants
3369 Init_Visible_Discriminants;
3371 if Is_Derived_Type (N_Typ) then
3372 Init_Stored_Discriminants;
3373 end if;
3374 end if;
3375 end if;
3377 -- For CPP types we generate an implicit call to the C++ default
3378 -- constructor to ensure the proper initialization of the _Tag
3379 -- component.
3381 if Is_CPP_Class (Root_Type (Typ)) and then CPP_Num_Prims (Typ) > 0 then
3382 Invoke_Constructor : declare
3383 CPP_Parent : constant Entity_Id := Enclosing_CPP_Parent (Typ);
3385 procedure Invoke_IC_Proc (T : Entity_Id);
3386 -- Recursive routine used to climb to parents. Required because
3387 -- parents must be initialized before descendants to ensure
3388 -- propagation of inherited C++ slots.
3390 --------------------
3391 -- Invoke_IC_Proc --
3392 --------------------
3394 procedure Invoke_IC_Proc (T : Entity_Id) is
3395 begin
3396 -- Avoid generating extra calls. Initialization required
3397 -- only for types defined from the level of derivation of
3398 -- type of the constructor and the type of the aggregate.
3400 if T = CPP_Parent then
3401 return;
3402 end if;
3404 Invoke_IC_Proc (Etype (T));
3406 -- Generate call to the IC routine
3408 if Present (CPP_Init_Proc (T)) then
3409 Append_To (L,
3410 Make_Procedure_Call_Statement (Loc,
3411 Name => New_Occurrence_Of (CPP_Init_Proc (T), Loc)));
3412 end if;
3413 end Invoke_IC_Proc;
3415 -- Start of processing for Invoke_Constructor
3417 begin
3418 -- Implicit invocation of the C++ constructor
3420 if Nkind (N) = N_Aggregate then
3421 Append_To (L,
3422 Make_Procedure_Call_Statement (Loc,
3423 Name =>
3424 New_Occurrence_Of (Base_Init_Proc (CPP_Parent), Loc),
3425 Parameter_Associations => New_List (
3426 Unchecked_Convert_To (CPP_Parent,
3427 New_Copy_Tree (Lhs)))));
3428 end if;
3430 Invoke_IC_Proc (Typ);
3431 end Invoke_Constructor;
3432 end if;
3434 -- Generate the assignments, component by component
3436 -- tmp.comp1 := Expr1_From_Aggr;
3437 -- tmp.comp2 := Expr2_From_Aggr;
3438 -- ....
3440 Comp := First (Component_Associations (N));
3441 while Present (Comp) loop
3442 Selector := Entity (First (Choices (Comp)));
3444 -- C++ constructors
3446 if Is_CPP_Constructor_Call (Expression (Comp)) then
3447 Append_List_To (L,
3448 Build_Initialization_Call (Loc,
3449 Id_Ref =>
3450 Make_Selected_Component (Loc,
3451 Prefix => New_Copy_Tree (Target),
3452 Selector_Name => New_Occurrence_Of (Selector, Loc)),
3453 Typ => Etype (Selector),
3454 Enclos_Type => Typ,
3455 With_Default_Init => True,
3456 Constructor_Ref => Expression (Comp)));
3458 -- Ada 2005 (AI-287): For each default-initialized component generate
3459 -- a call to the corresponding IP subprogram if available.
3461 elsif Box_Present (Comp)
3462 and then Has_Non_Null_Base_Init_Proc (Etype (Selector))
3463 then
3464 if Ekind (Selector) /= E_Discriminant then
3465 Generate_Finalization_Actions;
3466 end if;
3468 -- Ada 2005 (AI-287): If the component type has tasks then
3469 -- generate the activation chain and master entities (except
3470 -- in case of an allocator because in that case these entities
3471 -- are generated by Build_Task_Allocate_Block_With_Init_Stmts).
3473 declare
3474 Ctype : constant Entity_Id := Etype (Selector);
3475 Inside_Allocator : Boolean := False;
3476 P : Node_Id := Parent (N);
3478 begin
3479 if Is_Task_Type (Ctype) or else Has_Task (Ctype) then
3480 while Present (P) loop
3481 if Nkind (P) = N_Allocator then
3482 Inside_Allocator := True;
3483 exit;
3484 end if;
3486 P := Parent (P);
3487 end loop;
3489 if not Inside_Init_Proc and not Inside_Allocator then
3490 Build_Activation_Chain_Entity (N);
3491 end if;
3492 end if;
3493 end;
3495 Append_List_To (L,
3496 Build_Initialization_Call (Loc,
3497 Id_Ref => Make_Selected_Component (Loc,
3498 Prefix => New_Copy_Tree (Target),
3499 Selector_Name =>
3500 New_Occurrence_Of (Selector, Loc)),
3501 Typ => Etype (Selector),
3502 Enclos_Type => Typ,
3503 With_Default_Init => True));
3505 -- Prepare for component assignment
3507 elsif Ekind (Selector) /= E_Discriminant
3508 or else Nkind (N) = N_Extension_Aggregate
3509 then
3510 -- All the discriminants have now been assigned
3512 -- This is now a good moment to initialize and attach all the
3513 -- controllers. Their position may depend on the discriminants.
3515 if Ekind (Selector) /= E_Discriminant then
3516 Generate_Finalization_Actions;
3517 end if;
3519 Comp_Type := Underlying_Type (Etype (Selector));
3520 Comp_Expr :=
3521 Make_Selected_Component (Loc,
3522 Prefix => New_Copy_Tree (Target),
3523 Selector_Name => New_Occurrence_Of (Selector, Loc));
3525 if Nkind (Expression (Comp)) = N_Qualified_Expression then
3526 Expr_Q := Expression (Expression (Comp));
3527 else
3528 Expr_Q := Expression (Comp);
3529 end if;
3531 -- Now either create the assignment or generate the code for the
3532 -- inner aggregate top-down.
3534 if Is_Delayed_Aggregate (Expr_Q) then
3536 -- We have the following case of aggregate nesting inside
3537 -- an object declaration:
3539 -- type Arr_Typ is array (Integer range <>) of ...;
3541 -- type Rec_Typ (...) is record
3542 -- Obj_Arr_Typ : Arr_Typ (A .. B);
3543 -- end record;
3545 -- Obj_Rec_Typ : Rec_Typ := (...,
3546 -- Obj_Arr_Typ => (X => (...), Y => (...)));
3548 -- The length of the ranges of the aggregate and Obj_Add_Typ
3549 -- are equal (B - A = Y - X), but they do not coincide (X /=
3550 -- A and B /= Y). This case requires array sliding which is
3551 -- performed in the following manner:
3553 -- subtype Arr_Sub is Arr_Typ (X .. Y);
3554 -- Temp : Arr_Sub;
3555 -- Temp (X) := (...);
3556 -- ...
3557 -- Temp (Y) := (...);
3558 -- Obj_Rec_Typ.Obj_Arr_Typ := Temp;
3560 if Ekind (Comp_Type) = E_Array_Subtype
3561 and then Is_Int_Range_Bounds (Aggregate_Bounds (Expr_Q))
3562 and then Is_Int_Range_Bounds (First_Index (Comp_Type))
3563 and then not
3564 Compatible_Int_Bounds
3565 (Agg_Bounds => Aggregate_Bounds (Expr_Q),
3566 Typ_Bounds => First_Index (Comp_Type))
3567 then
3568 -- Create the array subtype with bounds equal to those of
3569 -- the corresponding aggregate.
3571 declare
3572 SubE : constant Entity_Id := Make_Temporary (Loc, 'T');
3574 SubD : constant Node_Id :=
3575 Make_Subtype_Declaration (Loc,
3576 Defining_Identifier => SubE,
3577 Subtype_Indication =>
3578 Make_Subtype_Indication (Loc,
3579 Subtype_Mark =>
3580 New_Occurrence_Of (Etype (Comp_Type), Loc),
3581 Constraint =>
3582 Make_Index_Or_Discriminant_Constraint
3583 (Loc,
3584 Constraints => New_List (
3585 New_Copy_Tree
3586 (Aggregate_Bounds (Expr_Q))))));
3588 -- Create a temporary array of the above subtype which
3589 -- will be used to capture the aggregate assignments.
3591 TmpE : constant Entity_Id := Make_Temporary (Loc, 'A', N);
3593 TmpD : constant Node_Id :=
3594 Make_Object_Declaration (Loc,
3595 Defining_Identifier => TmpE,
3596 Object_Definition => New_Occurrence_Of (SubE, Loc));
3598 begin
3599 Set_No_Initialization (TmpD);
3600 Append_To (L, SubD);
3601 Append_To (L, TmpD);
3603 -- Expand aggregate into assignments to the temp array
3605 Append_List_To (L,
3606 Late_Expansion (Expr_Q, Comp_Type,
3607 New_Occurrence_Of (TmpE, Loc)));
3609 -- Slide
3611 Append_To (L,
3612 Make_Assignment_Statement (Loc,
3613 Name => New_Copy_Tree (Comp_Expr),
3614 Expression => New_Occurrence_Of (TmpE, Loc)));
3615 end;
3617 -- Normal case (sliding not required)
3619 else
3620 Append_List_To (L,
3621 Late_Expansion (Expr_Q, Comp_Type, Comp_Expr));
3622 end if;
3624 -- Expr_Q is not delayed aggregate
3626 else
3627 if Has_Discriminants (Typ) then
3628 Replace_Discriminants (Expr_Q);
3630 -- If the component is an array type that depends on
3631 -- discriminants, and the expression is a single Others
3632 -- clause, create an explicit subtype for it because the
3633 -- backend has troubles recovering the actual bounds.
3635 if Nkind (Expr_Q) = N_Aggregate
3636 and then Is_Array_Type (Comp_Type)
3637 and then Present (Component_Associations (Expr_Q))
3638 then
3639 declare
3640 Assoc : constant Node_Id :=
3641 First (Component_Associations (Expr_Q));
3642 Decl : Node_Id;
3644 begin
3645 if Nkind (First (Choices (Assoc))) = N_Others_Choice
3646 then
3647 Decl :=
3648 Build_Actual_Subtype_Of_Component
3649 (Comp_Type, Comp_Expr);
3651 -- If the component type does not in fact depend on
3652 -- discriminants, the subtype declaration is empty.
3654 if Present (Decl) then
3655 Append_To (L, Decl);
3656 Set_Etype (Comp_Expr, Defining_Entity (Decl));
3657 end if;
3658 end if;
3659 end;
3660 end if;
3661 end if;
3663 if Modify_Tree_For_C
3664 and then Nkind (Expr_Q) = N_Aggregate
3665 and then Is_Array_Type (Etype (Expr_Q))
3666 and then Present (First_Index (Etype (Expr_Q)))
3667 then
3668 declare
3669 Expr_Q_Type : constant Node_Id := Etype (Expr_Q);
3670 begin
3671 Append_List_To (L,
3672 Build_Array_Aggr_Code
3673 (N => Expr_Q,
3674 Ctype => Component_Type (Expr_Q_Type),
3675 Index => First_Index (Expr_Q_Type),
3676 Into => Comp_Expr,
3677 Scalar_Comp =>
3678 Is_Scalar_Type (Component_Type (Expr_Q_Type))));
3679 end;
3681 else
3682 -- Handle an initialization expression of a controlled type
3683 -- in case it denotes a function call. In general such a
3684 -- scenario will produce a transient scope, but this will
3685 -- lead to wrong order of initialization, adjustment, and
3686 -- finalization in the context of aggregates.
3688 -- Target.Comp := Ctrl_Func_Call;
3690 -- begin -- scope
3691 -- Trans_Obj : ... := Ctrl_Func_Call; -- object
3692 -- Target.Comp := Trans_Obj;
3693 -- Finalize (Trans_Obj);
3694 -- end
3695 -- Target.Comp._tag := ...;
3696 -- Adjust (Target.Comp);
3698 -- In the example above, the call to Finalize occurs too
3699 -- early and as a result it may leave the record component
3700 -- in a bad state. Finalization of the transient object
3701 -- should really happen after adjustment.
3703 -- To avoid this scenario, perform in-place side-effect
3704 -- removal of the function call. This eliminates the
3705 -- transient property of the function result and ensures
3706 -- correct order of actions.
3708 -- Res : ... := Ctrl_Func_Call;
3709 -- Target.Comp := Res;
3710 -- Target.Comp._tag := ...;
3711 -- Adjust (Target.Comp);
3712 -- Finalize (Res);
3714 if Needs_Finalization (Comp_Type)
3715 and then Nkind (Expr_Q) /= N_Aggregate
3716 then
3717 Initialize_Ctrl_Record_Component
3718 (Rec_Comp => Comp_Expr,
3719 Comp_Typ => Etype (Selector),
3720 Init_Expr => Expr_Q,
3721 Stmts => L);
3723 -- Otherwise perform single component initialization
3725 else
3726 Initialize_Record_Component
3727 (Rec_Comp => Comp_Expr,
3728 Comp_Typ => Etype (Selector),
3729 Init_Expr => Expr_Q,
3730 Stmts => L);
3731 end if;
3732 end if;
3733 end if;
3735 -- comment would be good here ???
3737 elsif Ekind (Selector) = E_Discriminant
3738 and then Nkind (N) /= N_Extension_Aggregate
3739 and then Nkind (Parent (N)) = N_Component_Association
3740 and then Is_Constrained (Typ)
3741 then
3742 -- We must check that the discriminant value imposed by the
3743 -- context is the same as the value given in the subaggregate,
3744 -- because after the expansion into assignments there is no
3745 -- record on which to perform a regular discriminant check.
3747 declare
3748 D_Val : Elmt_Id;
3749 Disc : Entity_Id;
3751 begin
3752 D_Val := First_Elmt (Discriminant_Constraint (Typ));
3753 Disc := First_Discriminant (Typ);
3754 while Chars (Disc) /= Chars (Selector) loop
3755 Next_Discriminant (Disc);
3756 Next_Elmt (D_Val);
3757 end loop;
3759 pragma Assert (Present (D_Val));
3761 -- This check cannot performed for components that are
3762 -- constrained by a current instance, because this is not a
3763 -- value that can be compared with the actual constraint.
3765 if Nkind (Node (D_Val)) /= N_Attribute_Reference
3766 or else not Is_Entity_Name (Prefix (Node (D_Val)))
3767 or else not Is_Type (Entity (Prefix (Node (D_Val))))
3768 then
3769 Append_To (L,
3770 Make_Raise_Constraint_Error (Loc,
3771 Condition =>
3772 Make_Op_Ne (Loc,
3773 Left_Opnd => New_Copy_Tree (Node (D_Val)),
3774 Right_Opnd => Expression (Comp)),
3775 Reason => CE_Discriminant_Check_Failed));
3777 else
3778 -- Find self-reference in previous discriminant assignment,
3779 -- and replace with proper expression.
3781 declare
3782 Ass : Node_Id;
3784 begin
3785 Ass := First (L);
3786 while Present (Ass) loop
3787 if Nkind (Ass) = N_Assignment_Statement
3788 and then Nkind (Name (Ass)) = N_Selected_Component
3789 and then Chars (Selector_Name (Name (Ass))) =
3790 Chars (Disc)
3791 then
3792 Set_Expression
3793 (Ass, New_Copy_Tree (Expression (Comp)));
3794 exit;
3795 end if;
3796 Next (Ass);
3797 end loop;
3798 end;
3799 end if;
3800 end;
3801 end if;
3803 Next (Comp);
3804 end loop;
3806 -- If the type is tagged, the tag needs to be initialized (unless we
3807 -- are in VM-mode where tags are implicit). It is done late in the
3808 -- initialization process because in some cases, we call the init
3809 -- proc of an ancestor which will not leave out the right tag.
3811 if Ancestor_Is_Expression then
3812 null;
3814 -- For CPP types we generated a call to the C++ default constructor
3815 -- before the components have been initialized to ensure the proper
3816 -- initialization of the _Tag component (see above).
3818 elsif Is_CPP_Class (Typ) then
3819 null;
3821 elsif Is_Tagged_Type (Typ) and then Tagged_Type_Expansion then
3822 Instr :=
3823 Make_OK_Assignment_Statement (Loc,
3824 Name =>
3825 Make_Selected_Component (Loc,
3826 Prefix => New_Copy_Tree (Target),
3827 Selector_Name =>
3828 New_Occurrence_Of
3829 (First_Tag_Component (Base_Type (Typ)), Loc)),
3831 Expression =>
3832 Unchecked_Convert_To (RTE (RE_Tag),
3833 New_Occurrence_Of
3834 (Node (First_Elmt (Access_Disp_Table (Base_Type (Typ)))),
3835 Loc)));
3837 Append_To (L, Instr);
3839 -- Ada 2005 (AI-251): If the tagged type has been derived from an
3840 -- abstract interfaces we must also initialize the tags of the
3841 -- secondary dispatch tables.
3843 if Has_Interfaces (Base_Type (Typ)) then
3844 Init_Secondary_Tags
3845 (Typ => Base_Type (Typ),
3846 Target => Target,
3847 Stmts_List => L);
3848 end if;
3849 end if;
3851 -- If the controllers have not been initialized yet (by lack of non-
3852 -- discriminant components), let's do it now.
3854 Generate_Finalization_Actions;
3856 return L;
3857 end Build_Record_Aggr_Code;
3859 ---------------------------------------
3860 -- Collect_Initialization_Statements --
3861 ---------------------------------------
3863 procedure Collect_Initialization_Statements
3864 (Obj : Entity_Id;
3865 N : Node_Id;
3866 Node_After : Node_Id)
3868 Loc : constant Source_Ptr := Sloc (N);
3869 Init_Actions : constant List_Id := New_List;
3870 Init_Node : Node_Id;
3871 Comp_Stmt : Node_Id;
3873 begin
3874 -- Nothing to do if Obj is already frozen, as in this case we known we
3875 -- won't need to move the initialization statements about later on.
3877 if Is_Frozen (Obj) then
3878 return;
3879 end if;
3881 Init_Node := N;
3882 while Next (Init_Node) /= Node_After loop
3883 Append_To (Init_Actions, Remove_Next (Init_Node));
3884 end loop;
3886 if not Is_Empty_List (Init_Actions) then
3887 Comp_Stmt := Make_Compound_Statement (Loc, Actions => Init_Actions);
3888 Insert_Action_After (Init_Node, Comp_Stmt);
3889 Set_Initialization_Statements (Obj, Comp_Stmt);
3890 end if;
3891 end Collect_Initialization_Statements;
3893 -------------------------------
3894 -- Convert_Aggr_In_Allocator --
3895 -------------------------------
3897 procedure Convert_Aggr_In_Allocator
3898 (Alloc : Node_Id;
3899 Decl : Node_Id;
3900 Aggr : Node_Id)
3902 Loc : constant Source_Ptr := Sloc (Aggr);
3903 Typ : constant Entity_Id := Etype (Aggr);
3904 Temp : constant Entity_Id := Defining_Identifier (Decl);
3906 Occ : constant Node_Id :=
3907 Unchecked_Convert_To (Typ,
3908 Make_Explicit_Dereference (Loc, New_Occurrence_Of (Temp, Loc)));
3910 begin
3911 if Is_Array_Type (Typ) then
3912 Convert_Array_Aggr_In_Allocator (Decl, Aggr, Occ);
3914 elsif Has_Default_Init_Comps (Aggr) then
3915 declare
3916 L : constant List_Id := New_List;
3917 Init_Stmts : List_Id;
3919 begin
3920 Init_Stmts := Late_Expansion (Aggr, Typ, Occ);
3922 if Has_Task (Typ) then
3923 Build_Task_Allocate_Block_With_Init_Stmts (L, Aggr, Init_Stmts);
3924 Insert_Actions (Alloc, L);
3925 else
3926 Insert_Actions (Alloc, Init_Stmts);
3927 end if;
3928 end;
3930 else
3931 Insert_Actions (Alloc, Late_Expansion (Aggr, Typ, Occ));
3932 end if;
3933 end Convert_Aggr_In_Allocator;
3935 --------------------------------
3936 -- Convert_Aggr_In_Assignment --
3937 --------------------------------
3939 procedure Convert_Aggr_In_Assignment (N : Node_Id) is
3940 Aggr : Node_Id := Expression (N);
3941 Typ : constant Entity_Id := Etype (Aggr);
3942 Occ : constant Node_Id := New_Copy_Tree (Name (N));
3944 begin
3945 if Nkind (Aggr) = N_Qualified_Expression then
3946 Aggr := Expression (Aggr);
3947 end if;
3949 Insert_Actions_After (N, Late_Expansion (Aggr, Typ, Occ));
3950 end Convert_Aggr_In_Assignment;
3952 ---------------------------------
3953 -- Convert_Aggr_In_Object_Decl --
3954 ---------------------------------
3956 procedure Convert_Aggr_In_Object_Decl (N : Node_Id) is
3957 Obj : constant Entity_Id := Defining_Identifier (N);
3958 Aggr : Node_Id := Expression (N);
3959 Loc : constant Source_Ptr := Sloc (Aggr);
3960 Typ : constant Entity_Id := Etype (Aggr);
3961 Occ : constant Node_Id := New_Occurrence_Of (Obj, Loc);
3963 function Discriminants_Ok return Boolean;
3964 -- If the object type is constrained, the discriminants in the
3965 -- aggregate must be checked against the discriminants of the subtype.
3966 -- This cannot be done using Apply_Discriminant_Checks because after
3967 -- expansion there is no aggregate left to check.
3969 ----------------------
3970 -- Discriminants_Ok --
3971 ----------------------
3973 function Discriminants_Ok return Boolean is
3974 Cond : Node_Id := Empty;
3975 Check : Node_Id;
3976 D : Entity_Id;
3977 Disc1 : Elmt_Id;
3978 Disc2 : Elmt_Id;
3979 Val1 : Node_Id;
3980 Val2 : Node_Id;
3982 begin
3983 D := First_Discriminant (Typ);
3984 Disc1 := First_Elmt (Discriminant_Constraint (Typ));
3985 Disc2 := First_Elmt (Discriminant_Constraint (Etype (Obj)));
3986 while Present (Disc1) and then Present (Disc2) loop
3987 Val1 := Node (Disc1);
3988 Val2 := Node (Disc2);
3990 if not Is_OK_Static_Expression (Val1)
3991 or else not Is_OK_Static_Expression (Val2)
3992 then
3993 Check := Make_Op_Ne (Loc,
3994 Left_Opnd => Duplicate_Subexpr (Val1),
3995 Right_Opnd => Duplicate_Subexpr (Val2));
3997 if No (Cond) then
3998 Cond := Check;
4000 else
4001 Cond := Make_Or_Else (Loc,
4002 Left_Opnd => Cond,
4003 Right_Opnd => Check);
4004 end if;
4006 elsif Expr_Value (Val1) /= Expr_Value (Val2) then
4007 Apply_Compile_Time_Constraint_Error (Aggr,
4008 Msg => "incorrect value for discriminant&??",
4009 Reason => CE_Discriminant_Check_Failed,
4010 Ent => D);
4011 return False;
4012 end if;
4014 Next_Discriminant (D);
4015 Next_Elmt (Disc1);
4016 Next_Elmt (Disc2);
4017 end loop;
4019 -- If any discriminant constraint is non-static, emit a check
4021 if Present (Cond) then
4022 Insert_Action (N,
4023 Make_Raise_Constraint_Error (Loc,
4024 Condition => Cond,
4025 Reason => CE_Discriminant_Check_Failed));
4026 end if;
4028 return True;
4029 end Discriminants_Ok;
4031 -- Start of processing for Convert_Aggr_In_Object_Decl
4033 begin
4034 Set_Assignment_OK (Occ);
4036 if Nkind (Aggr) = N_Qualified_Expression then
4037 Aggr := Expression (Aggr);
4038 end if;
4040 if Has_Discriminants (Typ)
4041 and then Typ /= Etype (Obj)
4042 and then Is_Constrained (Etype (Obj))
4043 and then not Discriminants_Ok
4044 then
4045 return;
4046 end if;
4048 -- If the context is an extended return statement, it has its own
4049 -- finalization machinery (i.e. works like a transient scope) and
4050 -- we do not want to create an additional one, because objects on
4051 -- the finalization list of the return must be moved to the caller's
4052 -- finalization list to complete the return.
4054 -- However, if the aggregate is limited, it is built in place, and the
4055 -- controlled components are not assigned to intermediate temporaries
4056 -- so there is no need for a transient scope in this case either.
4058 if Requires_Transient_Scope (Typ)
4059 and then Ekind (Current_Scope) /= E_Return_Statement
4060 and then not Is_Limited_Type (Typ)
4061 then
4062 Establish_Transient_Scope
4063 (Aggr,
4064 Sec_Stack =>
4065 Is_Controlled (Typ) or else Has_Controlled_Component (Typ));
4066 end if;
4068 declare
4069 Node_After : constant Node_Id := Next (N);
4070 begin
4071 Insert_Actions_After (N, Late_Expansion (Aggr, Typ, Occ));
4072 Collect_Initialization_Statements (Obj, N, Node_After);
4073 end;
4074 Set_No_Initialization (N);
4075 Initialize_Discriminants (N, Typ);
4076 end Convert_Aggr_In_Object_Decl;
4078 -------------------------------------
4079 -- Convert_Array_Aggr_In_Allocator --
4080 -------------------------------------
4082 procedure Convert_Array_Aggr_In_Allocator
4083 (Decl : Node_Id;
4084 Aggr : Node_Id;
4085 Target : Node_Id)
4087 Aggr_Code : List_Id;
4088 Typ : constant Entity_Id := Etype (Aggr);
4089 Ctyp : constant Entity_Id := Component_Type (Typ);
4091 begin
4092 -- The target is an explicit dereference of the allocated object.
4093 -- Generate component assignments to it, as for an aggregate that
4094 -- appears on the right-hand side of an assignment statement.
4096 Aggr_Code :=
4097 Build_Array_Aggr_Code (Aggr,
4098 Ctype => Ctyp,
4099 Index => First_Index (Typ),
4100 Into => Target,
4101 Scalar_Comp => Is_Scalar_Type (Ctyp));
4103 Insert_Actions_After (Decl, Aggr_Code);
4104 end Convert_Array_Aggr_In_Allocator;
4106 ----------------------------
4107 -- Convert_To_Assignments --
4108 ----------------------------
4110 procedure Convert_To_Assignments (N : Node_Id; Typ : Entity_Id) is
4111 Loc : constant Source_Ptr := Sloc (N);
4112 T : Entity_Id;
4113 Temp : Entity_Id;
4115 Aggr_Code : List_Id;
4116 Instr : Node_Id;
4117 Target_Expr : Node_Id;
4118 Parent_Kind : Node_Kind;
4119 Unc_Decl : Boolean := False;
4120 Parent_Node : Node_Id;
4122 begin
4123 pragma Assert (not Is_Static_Dispatch_Table_Aggregate (N));
4124 pragma Assert (Is_Record_Type (Typ));
4126 Parent_Node := Parent (N);
4127 Parent_Kind := Nkind (Parent_Node);
4129 if Parent_Kind = N_Qualified_Expression then
4131 -- Check if we are in a unconstrained declaration because in this
4132 -- case the current delayed expansion mechanism doesn't work when
4133 -- the declared object size depend on the initializing expr.
4135 Parent_Node := Parent (Parent_Node);
4136 Parent_Kind := Nkind (Parent_Node);
4138 if Parent_Kind = N_Object_Declaration then
4139 Unc_Decl :=
4140 not Is_Entity_Name (Object_Definition (Parent_Node))
4141 or else Has_Discriminants
4142 (Entity (Object_Definition (Parent_Node)))
4143 or else Is_Class_Wide_Type
4144 (Entity (Object_Definition (Parent_Node)));
4145 end if;
4146 end if;
4148 -- Just set the Delay flag in the cases where the transformation will be
4149 -- done top down from above.
4151 if False
4153 -- Internal aggregate (transformed when expanding the parent)
4155 or else Parent_Kind = N_Aggregate
4156 or else Parent_Kind = N_Extension_Aggregate
4157 or else Parent_Kind = N_Component_Association
4159 -- Allocator (see Convert_Aggr_In_Allocator)
4161 or else Parent_Kind = N_Allocator
4163 -- Object declaration (see Convert_Aggr_In_Object_Decl)
4165 or else (Parent_Kind = N_Object_Declaration and then not Unc_Decl)
4167 -- Safe assignment (see Convert_Aggr_Assignments). So far only the
4168 -- assignments in init procs are taken into account.
4170 or else (Parent_Kind = N_Assignment_Statement
4171 and then Inside_Init_Proc)
4173 -- (Ada 2005) An inherently limited type in a return statement, which
4174 -- will be handled in a build-in-place fashion, and may be rewritten
4175 -- as an extended return and have its own finalization machinery.
4176 -- In the case of a simple return, the aggregate needs to be delayed
4177 -- until the scope for the return statement has been created, so
4178 -- that any finalization chain will be associated with that scope.
4179 -- For extended returns, we delay expansion to avoid the creation
4180 -- of an unwanted transient scope that could result in premature
4181 -- finalization of the return object (which is built in place
4182 -- within the caller's scope).
4184 or else
4185 (Is_Limited_View (Typ)
4186 and then
4187 (Nkind (Parent (Parent_Node)) = N_Extended_Return_Statement
4188 or else Nkind (Parent_Node) = N_Simple_Return_Statement))
4189 then
4190 Set_Expansion_Delayed (N);
4191 return;
4192 end if;
4194 -- Otherwise, if a transient scope is required, create it now. If we
4195 -- are within an initialization procedure do not create such, because
4196 -- the target of the assignment must not be declared within a local
4197 -- block, and because cleanup will take place on return from the
4198 -- initialization procedure.
4200 -- Should the condition be more restrictive ???
4202 if Requires_Transient_Scope (Typ) and then not Inside_Init_Proc then
4203 Establish_Transient_Scope (N, Sec_Stack => Needs_Finalization (Typ));
4204 end if;
4206 -- If the aggregate is nonlimited, create a temporary. If it is limited
4207 -- and context is an assignment, this is a subaggregate for an enclosing
4208 -- aggregate being expanded. It must be built in place, so use target of
4209 -- the current assignment.
4211 if Is_Limited_Type (Typ)
4212 and then Nkind (Parent (N)) = N_Assignment_Statement
4213 then
4214 Target_Expr := New_Copy_Tree (Name (Parent (N)));
4215 Insert_Actions (Parent (N),
4216 Build_Record_Aggr_Code (N, Typ, Target_Expr));
4217 Rewrite (Parent (N), Make_Null_Statement (Loc));
4219 else
4220 Temp := Make_Temporary (Loc, 'A', N);
4222 -- If the type inherits unknown discriminants, use the view with
4223 -- known discriminants if available.
4225 if Has_Unknown_Discriminants (Typ)
4226 and then Present (Underlying_Record_View (Typ))
4227 then
4228 T := Underlying_Record_View (Typ);
4229 else
4230 T := Typ;
4231 end if;
4233 Instr :=
4234 Make_Object_Declaration (Loc,
4235 Defining_Identifier => Temp,
4236 Object_Definition => New_Occurrence_Of (T, Loc));
4238 Set_No_Initialization (Instr);
4239 Insert_Action (N, Instr);
4240 Initialize_Discriminants (Instr, T);
4242 Target_Expr := New_Occurrence_Of (Temp, Loc);
4243 Aggr_Code := Build_Record_Aggr_Code (N, T, Target_Expr);
4245 -- Save the last assignment statement associated with the aggregate
4246 -- when building a controlled object. This reference is utilized by
4247 -- the finalization machinery when marking an object as successfully
4248 -- initialized.
4250 if Needs_Finalization (T) then
4251 Set_Last_Aggregate_Assignment (Temp, Last (Aggr_Code));
4252 end if;
4254 Insert_Actions (N, Aggr_Code);
4255 Rewrite (N, New_Occurrence_Of (Temp, Loc));
4256 Analyze_And_Resolve (N, T);
4257 end if;
4258 end Convert_To_Assignments;
4260 ---------------------------
4261 -- Convert_To_Positional --
4262 ---------------------------
4264 procedure Convert_To_Positional
4265 (N : Node_Id;
4266 Max_Others_Replicate : Nat := 5;
4267 Handle_Bit_Packed : Boolean := False)
4269 Typ : constant Entity_Id := Etype (N);
4271 Static_Components : Boolean := True;
4273 procedure Check_Static_Components;
4274 -- Check whether all components of the aggregate are compile-time known
4275 -- values, and can be passed as is to the back-end without further
4276 -- expansion.
4277 -- An Iterated_component_Association is treated as non-static, but there
4278 -- are possibilities for optimization here.
4280 function Flatten
4281 (N : Node_Id;
4282 Ix : Node_Id;
4283 Ixb : Node_Id) return Boolean;
4284 -- Convert the aggregate into a purely positional form if possible. On
4285 -- entry the bounds of all dimensions are known to be static, and the
4286 -- total number of components is safe enough to expand.
4288 function Is_Flat (N : Node_Id; Dims : Int) return Boolean;
4289 -- Return True iff the array N is flat (which is not trivial in the case
4290 -- of multidimensional aggregates).
4292 -----------------------------
4293 -- Check_Static_Components --
4294 -----------------------------
4296 -- Could use some comments in this body ???
4298 procedure Check_Static_Components is
4299 Expr : Node_Id;
4301 begin
4302 Static_Components := True;
4304 if Nkind (N) = N_String_Literal then
4305 null;
4307 elsif Present (Expressions (N)) then
4308 Expr := First (Expressions (N));
4309 while Present (Expr) loop
4310 if Nkind (Expr) /= N_Aggregate
4311 or else not Compile_Time_Known_Aggregate (Expr)
4312 or else Expansion_Delayed (Expr)
4313 then
4314 Static_Components := False;
4315 exit;
4316 end if;
4318 Next (Expr);
4319 end loop;
4320 end if;
4322 if Nkind (N) = N_Aggregate
4323 and then Present (Component_Associations (N))
4324 then
4325 Expr := First (Component_Associations (N));
4326 while Present (Expr) loop
4327 if Nkind_In (Expression (Expr), N_Integer_Literal,
4328 N_Real_Literal)
4329 then
4330 null;
4332 elsif Is_Entity_Name (Expression (Expr))
4333 and then Present (Entity (Expression (Expr)))
4334 and then Ekind (Entity (Expression (Expr))) =
4335 E_Enumeration_Literal
4336 then
4337 null;
4339 elsif Nkind (Expression (Expr)) /= N_Aggregate
4340 or else not Compile_Time_Known_Aggregate (Expression (Expr))
4341 or else Expansion_Delayed (Expression (Expr))
4342 or else Nkind (Expr) = N_Iterated_Component_Association
4343 then
4344 Static_Components := False;
4345 exit;
4346 end if;
4348 Next (Expr);
4349 end loop;
4350 end if;
4351 end Check_Static_Components;
4353 -------------
4354 -- Flatten --
4355 -------------
4357 function Flatten
4358 (N : Node_Id;
4359 Ix : Node_Id;
4360 Ixb : Node_Id) return Boolean
4362 Loc : constant Source_Ptr := Sloc (N);
4363 Blo : constant Node_Id := Type_Low_Bound (Etype (Ixb));
4364 Lo : constant Node_Id := Type_Low_Bound (Etype (Ix));
4365 Hi : constant Node_Id := Type_High_Bound (Etype (Ix));
4366 Lov : Uint;
4367 Hiv : Uint;
4369 Others_Present : Boolean := False;
4371 begin
4372 if Nkind (Original_Node (N)) = N_String_Literal then
4373 return True;
4374 end if;
4376 if not Compile_Time_Known_Value (Lo)
4377 or else not Compile_Time_Known_Value (Hi)
4378 then
4379 return False;
4380 end if;
4382 Lov := Expr_Value (Lo);
4383 Hiv := Expr_Value (Hi);
4385 -- Check if there is an others choice
4387 if Present (Component_Associations (N)) then
4388 declare
4389 Assoc : Node_Id;
4390 Choice : Node_Id;
4392 begin
4393 Assoc := First (Component_Associations (N));
4394 while Present (Assoc) loop
4396 -- If this is a box association, flattening is in general
4397 -- not possible because at this point we cannot tell if the
4398 -- default is static or even exists.
4400 if Box_Present (Assoc) then
4401 return False;
4403 elsif Nkind (Assoc) = N_Iterated_Component_Association then
4404 return False;
4405 end if;
4407 Choice := First (Choice_List (Assoc));
4409 while Present (Choice) loop
4410 if Nkind (Choice) = N_Others_Choice then
4411 Others_Present := True;
4412 end if;
4414 Next (Choice);
4415 end loop;
4417 Next (Assoc);
4418 end loop;
4419 end;
4420 end if;
4422 -- If the low bound is not known at compile time and others is not
4423 -- present we can proceed since the bounds can be obtained from the
4424 -- aggregate.
4426 if Hiv < Lov
4427 or else (not Compile_Time_Known_Value (Blo) and then Others_Present)
4428 then
4429 return False;
4430 end if;
4432 -- Determine if set of alternatives is suitable for conversion and
4433 -- build an array containing the values in sequence.
4435 declare
4436 Vals : array (UI_To_Int (Lov) .. UI_To_Int (Hiv))
4437 of Node_Id := (others => Empty);
4438 -- The values in the aggregate sorted appropriately
4440 Vlist : List_Id;
4441 -- Same data as Vals in list form
4443 Rep_Count : Nat;
4444 -- Used to validate Max_Others_Replicate limit
4446 Elmt : Node_Id;
4447 Num : Int := UI_To_Int (Lov);
4448 Choice_Index : Int;
4449 Choice : Node_Id;
4450 Lo, Hi : Node_Id;
4452 begin
4453 if Present (Expressions (N)) then
4454 Elmt := First (Expressions (N));
4455 while Present (Elmt) loop
4456 if Nkind (Elmt) = N_Aggregate
4457 and then Present (Next_Index (Ix))
4458 and then
4459 not Flatten (Elmt, Next_Index (Ix), Next_Index (Ixb))
4460 then
4461 return False;
4462 end if;
4464 Vals (Num) := Relocate_Node (Elmt);
4465 Num := Num + 1;
4467 Next (Elmt);
4468 end loop;
4469 end if;
4471 if No (Component_Associations (N)) then
4472 return True;
4473 end if;
4475 Elmt := First (Component_Associations (N));
4477 if Nkind (Expression (Elmt)) = N_Aggregate then
4478 if Present (Next_Index (Ix))
4479 and then
4480 not Flatten
4481 (Expression (Elmt), Next_Index (Ix), Next_Index (Ixb))
4482 then
4483 return False;
4484 end if;
4485 end if;
4487 Component_Loop : while Present (Elmt) loop
4488 Choice := First (Choice_List (Elmt));
4489 Choice_Loop : while Present (Choice) loop
4491 -- If we have an others choice, fill in the missing elements
4492 -- subject to the limit established by Max_Others_Replicate.
4494 if Nkind (Choice) = N_Others_Choice then
4495 Rep_Count := 0;
4497 for J in Vals'Range loop
4498 if No (Vals (J)) then
4499 Vals (J) := New_Copy_Tree (Expression (Elmt));
4500 Rep_Count := Rep_Count + 1;
4502 -- Check for maximum others replication. Note that
4503 -- we skip this test if either of the restrictions
4504 -- No_Elaboration_Code or No_Implicit_Loops is
4505 -- active, if this is a preelaborable unit or
4506 -- a predefined unit, or if the unit must be
4507 -- placed in data memory. This also ensures that
4508 -- predefined units get the same level of constant
4509 -- folding in Ada 95 and Ada 2005, where their
4510 -- categorization has changed.
4512 declare
4513 P : constant Entity_Id :=
4514 Cunit_Entity (Current_Sem_Unit);
4516 begin
4517 -- Check if duplication OK and if so continue
4518 -- processing.
4520 if Restriction_Active (No_Elaboration_Code)
4521 or else Restriction_Active (No_Implicit_Loops)
4522 or else
4523 (Ekind (Current_Scope) = E_Package
4524 and then Static_Elaboration_Desired
4525 (Current_Scope))
4526 or else Is_Preelaborated (P)
4527 or else (Ekind (P) = E_Package_Body
4528 and then
4529 Is_Preelaborated (Spec_Entity (P)))
4530 or else
4531 Is_Predefined_File_Name
4532 (Unit_File_Name (Get_Source_Unit (P)))
4533 then
4534 null;
4536 -- If duplication not OK, then we return False
4537 -- if the replication count is too high
4539 elsif Rep_Count > Max_Others_Replicate then
4540 return False;
4542 -- Continue on if duplication not OK, but the
4543 -- replication count is not excessive.
4545 else
4546 null;
4547 end if;
4548 end;
4549 end if;
4550 end loop;
4552 exit Component_Loop;
4554 -- Case of a subtype mark, identifier or expanded name
4556 elsif Is_Entity_Name (Choice)
4557 and then Is_Type (Entity (Choice))
4558 then
4559 Lo := Type_Low_Bound (Etype (Choice));
4560 Hi := Type_High_Bound (Etype (Choice));
4562 -- Case of subtype indication
4564 elsif Nkind (Choice) = N_Subtype_Indication then
4565 Lo := Low_Bound (Range_Expression (Constraint (Choice)));
4566 Hi := High_Bound (Range_Expression (Constraint (Choice)));
4568 -- Case of a range
4570 elsif Nkind (Choice) = N_Range then
4571 Lo := Low_Bound (Choice);
4572 Hi := High_Bound (Choice);
4574 -- Normal subexpression case
4576 else pragma Assert (Nkind (Choice) in N_Subexpr);
4577 if not Compile_Time_Known_Value (Choice) then
4578 return False;
4580 else
4581 Choice_Index := UI_To_Int (Expr_Value (Choice));
4583 if Choice_Index in Vals'Range then
4584 Vals (Choice_Index) :=
4585 New_Copy_Tree (Expression (Elmt));
4586 goto Continue;
4588 -- Choice is statically out-of-range, will be
4589 -- rewritten to raise Constraint_Error.
4591 else
4592 return False;
4593 end if;
4594 end if;
4595 end if;
4597 -- Range cases merge with Lo,Hi set
4599 if not Compile_Time_Known_Value (Lo)
4600 or else
4601 not Compile_Time_Known_Value (Hi)
4602 then
4603 return False;
4605 else
4606 for J in UI_To_Int (Expr_Value (Lo)) ..
4607 UI_To_Int (Expr_Value (Hi))
4608 loop
4609 Vals (J) := New_Copy_Tree (Expression (Elmt));
4610 end loop;
4611 end if;
4613 <<Continue>>
4614 Next (Choice);
4615 end loop Choice_Loop;
4617 Next (Elmt);
4618 end loop Component_Loop;
4620 -- If we get here the conversion is possible
4622 Vlist := New_List;
4623 for J in Vals'Range loop
4624 Append (Vals (J), Vlist);
4625 end loop;
4627 Rewrite (N, Make_Aggregate (Loc, Expressions => Vlist));
4628 Set_Aggregate_Bounds (N, Aggregate_Bounds (Original_Node (N)));
4629 return True;
4630 end;
4631 end Flatten;
4633 -------------
4634 -- Is_Flat --
4635 -------------
4637 function Is_Flat (N : Node_Id; Dims : Int) return Boolean is
4638 Elmt : Node_Id;
4640 begin
4641 if Dims = 0 then
4642 return True;
4644 elsif Nkind (N) = N_Aggregate then
4645 if Present (Component_Associations (N)) then
4646 return False;
4648 else
4649 Elmt := First (Expressions (N));
4650 while Present (Elmt) loop
4651 if not Is_Flat (Elmt, Dims - 1) then
4652 return False;
4653 end if;
4655 Next (Elmt);
4656 end loop;
4658 return True;
4659 end if;
4660 else
4661 return True;
4662 end if;
4663 end Is_Flat;
4665 -- Start of processing for Convert_To_Positional
4667 begin
4668 -- Only convert to positional when generating C in case of an
4669 -- object declaration, this is the only case where aggregates are
4670 -- supported in C.
4672 if Modify_Tree_For_C and then not In_Object_Declaration (N) then
4673 return;
4674 end if;
4676 -- Ada 2005 (AI-287): Do not convert in case of default initialized
4677 -- components because in this case will need to call the corresponding
4678 -- IP procedure.
4680 if Has_Default_Init_Comps (N) then
4681 return;
4682 end if;
4684 if Is_Flat (N, Number_Dimensions (Typ)) then
4685 return;
4686 end if;
4688 if Is_Bit_Packed_Array (Typ) and then not Handle_Bit_Packed then
4689 return;
4690 end if;
4692 -- Do not convert to positional if controlled components are involved
4693 -- since these require special processing
4695 if Has_Controlled_Component (Typ) then
4696 return;
4697 end if;
4699 Check_Static_Components;
4701 -- If the size is known, or all the components are static, try to
4702 -- build a fully positional aggregate.
4704 -- The size of the type may not be known for an aggregate with
4705 -- discriminated array components, but if the components are static
4706 -- it is still possible to verify statically that the length is
4707 -- compatible with the upper bound of the type, and therefore it is
4708 -- worth flattening such aggregates as well.
4710 -- For now the back-end expands these aggregates into individual
4711 -- assignments to the target anyway, but it is conceivable that
4712 -- it will eventually be able to treat such aggregates statically???
4714 if Aggr_Size_OK (N, Typ)
4715 and then Flatten (N, First_Index (Typ), First_Index (Base_Type (Typ)))
4716 then
4717 if Static_Components then
4718 Set_Compile_Time_Known_Aggregate (N);
4719 Set_Expansion_Delayed (N, False);
4720 end if;
4722 Analyze_And_Resolve (N, Typ);
4723 end if;
4725 -- If Static_Elaboration_Desired has been specified, diagnose aggregates
4726 -- that will still require initialization code.
4728 if (Ekind (Current_Scope) = E_Package
4729 and then Static_Elaboration_Desired (Current_Scope))
4730 and then Nkind (Parent (N)) = N_Object_Declaration
4731 then
4732 declare
4733 Expr : Node_Id;
4735 begin
4736 if Nkind (N) = N_Aggregate and then Present (Expressions (N)) then
4737 Expr := First (Expressions (N));
4738 while Present (Expr) loop
4739 if Nkind_In (Expr, N_Integer_Literal, N_Real_Literal)
4740 or else
4741 (Is_Entity_Name (Expr)
4742 and then Ekind (Entity (Expr)) = E_Enumeration_Literal)
4743 then
4744 null;
4746 else
4747 Error_Msg_N
4748 ("non-static object requires elaboration code??", N);
4749 exit;
4750 end if;
4752 Next (Expr);
4753 end loop;
4755 if Present (Component_Associations (N)) then
4756 Error_Msg_N ("object requires elaboration code??", N);
4757 end if;
4758 end if;
4759 end;
4760 end if;
4761 end Convert_To_Positional;
4763 ----------------------------
4764 -- Expand_Array_Aggregate --
4765 ----------------------------
4767 -- Array aggregate expansion proceeds as follows:
4769 -- 1. If requested we generate code to perform all the array aggregate
4770 -- bound checks, specifically
4772 -- (a) Check that the index range defined by aggregate bounds is
4773 -- compatible with corresponding index subtype.
4775 -- (b) If an others choice is present check that no aggregate
4776 -- index is outside the bounds of the index constraint.
4778 -- (c) For multidimensional arrays make sure that all subaggregates
4779 -- corresponding to the same dimension have the same bounds.
4781 -- 2. Check for packed array aggregate which can be converted to a
4782 -- constant so that the aggregate disappears completely.
4784 -- 3. Check case of nested aggregate. Generally nested aggregates are
4785 -- handled during the processing of the parent aggregate.
4787 -- 4. Check if the aggregate can be statically processed. If this is the
4788 -- case pass it as is to Gigi. Note that a necessary condition for
4789 -- static processing is that the aggregate be fully positional.
4791 -- 5. If in place aggregate expansion is possible (i.e. no need to create
4792 -- a temporary) then mark the aggregate as such and return. Otherwise
4793 -- create a new temporary and generate the appropriate initialization
4794 -- code.
4796 procedure Expand_Array_Aggregate (N : Node_Id) is
4797 Loc : constant Source_Ptr := Sloc (N);
4799 Typ : constant Entity_Id := Etype (N);
4800 Ctyp : constant Entity_Id := Component_Type (Typ);
4801 -- Typ is the correct constrained array subtype of the aggregate
4802 -- Ctyp is the corresponding component type.
4804 Aggr_Dimension : constant Pos := Number_Dimensions (Typ);
4805 -- Number of aggregate index dimensions
4807 Aggr_Low : array (1 .. Aggr_Dimension) of Node_Id;
4808 Aggr_High : array (1 .. Aggr_Dimension) of Node_Id;
4809 -- Low and High bounds of the constraint for each aggregate index
4811 Aggr_Index_Typ : array (1 .. Aggr_Dimension) of Entity_Id;
4812 -- The type of each index
4814 In_Place_Assign_OK_For_Declaration : Boolean := False;
4815 -- True if we are to generate an in place assignment for a declaration
4817 Maybe_In_Place_OK : Boolean;
4818 -- If the type is neither controlled nor packed and the aggregate
4819 -- is the expression in an assignment, assignment in place may be
4820 -- possible, provided other conditions are met on the LHS.
4822 Others_Present : array (1 .. Aggr_Dimension) of Boolean :=
4823 (others => False);
4824 -- If Others_Present (J) is True, then there is an others choice in one
4825 -- of the subaggregates of N at dimension J.
4827 function Aggr_Assignment_OK_For_Backend (N : Node_Id) return Boolean;
4828 -- Returns true if an aggregate assignment can be done by the back end
4830 procedure Build_Constrained_Type (Positional : Boolean);
4831 -- If the subtype is not static or unconstrained, build a constrained
4832 -- type using the computable sizes of the aggregate and its sub-
4833 -- aggregates.
4835 procedure Check_Bounds (Aggr_Bounds : Node_Id; Index_Bounds : Node_Id);
4836 -- Checks that the bounds of Aggr_Bounds are within the bounds defined
4837 -- by Index_Bounds.
4839 procedure Check_Same_Aggr_Bounds (Sub_Aggr : Node_Id; Dim : Pos);
4840 -- Checks that in a multidimensional array aggregate all subaggregates
4841 -- corresponding to the same dimension have the same bounds. Sub_Aggr is
4842 -- an array subaggregate. Dim is the dimension corresponding to the
4843 -- subaggregate.
4845 procedure Compute_Others_Present (Sub_Aggr : Node_Id; Dim : Pos);
4846 -- Computes the values of array Others_Present. Sub_Aggr is the array
4847 -- subaggregate we start the computation from. Dim is the dimension
4848 -- corresponding to the subaggregate.
4850 function In_Place_Assign_OK return Boolean;
4851 -- Simple predicate to determine whether an aggregate assignment can
4852 -- be done in place, because none of the new values can depend on the
4853 -- components of the target of the assignment.
4855 procedure Others_Check (Sub_Aggr : Node_Id; Dim : Pos);
4856 -- Checks that if an others choice is present in any subaggregate, no
4857 -- aggregate index is outside the bounds of the index constraint.
4858 -- Sub_Aggr is an array subaggregate. Dim is the dimension corresponding
4859 -- to the subaggregate.
4861 function Safe_Left_Hand_Side (N : Node_Id) return Boolean;
4862 -- In addition to Maybe_In_Place_OK, in order for an aggregate to be
4863 -- built directly into the target of the assignment it must be free
4864 -- of side effects.
4866 ------------------------------------
4867 -- Aggr_Assignment_OK_For_Backend --
4868 ------------------------------------
4870 -- Backend processing by Gigi/gcc is possible only if all the following
4871 -- conditions are met:
4873 -- 1. N consists of a single OTHERS choice, possibly recursively
4875 -- 2. The array type is not packed
4877 -- 3. The array type has no atomic components
4879 -- 4. The array type has no null ranges (the purpose of this is to
4880 -- avoid a bogus warning for an out-of-range value).
4882 -- 5. The component type is discrete
4884 -- 6. The component size is Storage_Unit or the value is of the form
4885 -- M * (1 + A**1 + A**2 + .. A**(K-1)) where A = 2**(Storage_Unit)
4886 -- and M in 1 .. A-1. This can also be viewed as K occurrences of
4887 -- the 8-bit value M, concatenated together.
4889 -- The ultimate goal is to generate a call to a fast memset routine
4890 -- specifically optimized for the target.
4892 function Aggr_Assignment_OK_For_Backend (N : Node_Id) return Boolean is
4893 Ctyp : Entity_Id;
4894 Index : Entity_Id;
4895 Expr : Node_Id := N;
4896 Low : Node_Id;
4897 High : Node_Id;
4898 Remainder : Uint;
4899 Value : Uint;
4900 Nunits : Nat;
4902 begin
4903 -- Recurse as far as possible to find the innermost component type
4905 Ctyp := Etype (N);
4906 while Is_Array_Type (Ctyp) loop
4907 if Nkind (Expr) /= N_Aggregate
4908 or else not Is_Others_Aggregate (Expr)
4909 then
4910 return False;
4911 end if;
4913 if Present (Packed_Array_Impl_Type (Ctyp)) then
4914 return False;
4915 end if;
4917 if Has_Atomic_Components (Ctyp) then
4918 return False;
4919 end if;
4921 Index := First_Index (Ctyp);
4922 while Present (Index) loop
4923 Get_Index_Bounds (Index, Low, High);
4925 if Is_Null_Range (Low, High) then
4926 return False;
4927 end if;
4929 Next_Index (Index);
4930 end loop;
4932 Expr := Expression (First (Component_Associations (Expr)));
4934 for J in 1 .. Number_Dimensions (Ctyp) - 1 loop
4935 if Nkind (Expr) /= N_Aggregate
4936 or else not Is_Others_Aggregate (Expr)
4937 then
4938 return False;
4939 end if;
4941 Expr := Expression (First (Component_Associations (Expr)));
4942 end loop;
4944 Ctyp := Component_Type (Ctyp);
4946 if Is_Atomic_Or_VFA (Ctyp) then
4947 return False;
4948 end if;
4949 end loop;
4951 -- An Iterated_Component_Association involves a loop (in most cases)
4952 -- and is never static.
4954 if Nkind (Parent (Expr)) = N_Iterated_Component_Association then
4955 return False;
4956 end if;
4958 if not Is_Discrete_Type (Ctyp) then
4959 return False;
4960 end if;
4962 -- The expression needs to be analyzed if True is returned
4964 Analyze_And_Resolve (Expr, Ctyp);
4966 -- The back end uses the Esize as the precision of the type
4968 Nunits := UI_To_Int (Esize (Ctyp)) / System_Storage_Unit;
4970 if Nunits = 1 then
4971 return True;
4972 end if;
4974 if not Compile_Time_Known_Value (Expr) then
4975 return False;
4976 end if;
4978 Value := Expr_Value (Expr);
4980 if Has_Biased_Representation (Ctyp) then
4981 Value := Value - Expr_Value (Type_Low_Bound (Ctyp));
4982 end if;
4984 -- Values 0 and -1 immediately satisfy the last check
4986 if Value = Uint_0 or else Value = Uint_Minus_1 then
4987 return True;
4988 end if;
4990 -- We need to work with an unsigned value
4992 if Value < 0 then
4993 Value := Value + 2**(System_Storage_Unit * Nunits);
4994 end if;
4996 Remainder := Value rem 2**System_Storage_Unit;
4998 for J in 1 .. Nunits - 1 loop
4999 Value := Value / 2**System_Storage_Unit;
5001 if Value rem 2**System_Storage_Unit /= Remainder then
5002 return False;
5003 end if;
5004 end loop;
5006 return True;
5007 end Aggr_Assignment_OK_For_Backend;
5009 ----------------------------
5010 -- Build_Constrained_Type --
5011 ----------------------------
5013 procedure Build_Constrained_Type (Positional : Boolean) is
5014 Loc : constant Source_Ptr := Sloc (N);
5015 Agg_Type : constant Entity_Id := Make_Temporary (Loc, 'A');
5016 Comp : Node_Id;
5017 Decl : Node_Id;
5018 Typ : constant Entity_Id := Etype (N);
5019 Indexes : constant List_Id := New_List;
5020 Num : Nat;
5021 Sub_Agg : Node_Id;
5023 begin
5024 -- If the aggregate is purely positional, all its subaggregates
5025 -- have the same size. We collect the dimensions from the first
5026 -- subaggregate at each level.
5028 if Positional then
5029 Sub_Agg := N;
5031 for D in 1 .. Number_Dimensions (Typ) loop
5032 Sub_Agg := First (Expressions (Sub_Agg));
5034 Comp := Sub_Agg;
5035 Num := 0;
5036 while Present (Comp) loop
5037 Num := Num + 1;
5038 Next (Comp);
5039 end loop;
5041 Append_To (Indexes,
5042 Make_Range (Loc,
5043 Low_Bound => Make_Integer_Literal (Loc, 1),
5044 High_Bound => Make_Integer_Literal (Loc, Num)));
5045 end loop;
5047 else
5048 -- We know the aggregate type is unconstrained and the aggregate
5049 -- is not processable by the back end, therefore not necessarily
5050 -- positional. Retrieve each dimension bounds (computed earlier).
5052 for D in 1 .. Number_Dimensions (Typ) loop
5053 Append_To (Indexes,
5054 Make_Range (Loc,
5055 Low_Bound => Aggr_Low (D),
5056 High_Bound => Aggr_High (D)));
5057 end loop;
5058 end if;
5060 Decl :=
5061 Make_Full_Type_Declaration (Loc,
5062 Defining_Identifier => Agg_Type,
5063 Type_Definition =>
5064 Make_Constrained_Array_Definition (Loc,
5065 Discrete_Subtype_Definitions => Indexes,
5066 Component_Definition =>
5067 Make_Component_Definition (Loc,
5068 Aliased_Present => False,
5069 Subtype_Indication =>
5070 New_Occurrence_Of (Component_Type (Typ), Loc))));
5072 Insert_Action (N, Decl);
5073 Analyze (Decl);
5074 Set_Etype (N, Agg_Type);
5075 Set_Is_Itype (Agg_Type);
5076 Freeze_Itype (Agg_Type, N);
5077 end Build_Constrained_Type;
5079 ------------------
5080 -- Check_Bounds --
5081 ------------------
5083 procedure Check_Bounds (Aggr_Bounds : Node_Id; Index_Bounds : Node_Id) is
5084 Aggr_Lo : Node_Id;
5085 Aggr_Hi : Node_Id;
5087 Ind_Lo : Node_Id;
5088 Ind_Hi : Node_Id;
5090 Cond : Node_Id := Empty;
5092 begin
5093 Get_Index_Bounds (Aggr_Bounds, Aggr_Lo, Aggr_Hi);
5094 Get_Index_Bounds (Index_Bounds, Ind_Lo, Ind_Hi);
5096 -- Generate the following test:
5098 -- [constraint_error when
5099 -- Aggr_Lo <= Aggr_Hi and then
5100 -- (Aggr_Lo < Ind_Lo or else Aggr_Hi > Ind_Hi)]
5102 -- As an optimization try to see if some tests are trivially vacuous
5103 -- because we are comparing an expression against itself.
5105 if Aggr_Lo = Ind_Lo and then Aggr_Hi = Ind_Hi then
5106 Cond := Empty;
5108 elsif Aggr_Hi = Ind_Hi then
5109 Cond :=
5110 Make_Op_Lt (Loc,
5111 Left_Opnd => Duplicate_Subexpr_Move_Checks (Aggr_Lo),
5112 Right_Opnd => Duplicate_Subexpr_Move_Checks (Ind_Lo));
5114 elsif Aggr_Lo = Ind_Lo then
5115 Cond :=
5116 Make_Op_Gt (Loc,
5117 Left_Opnd => Duplicate_Subexpr_Move_Checks (Aggr_Hi),
5118 Right_Opnd => Duplicate_Subexpr_Move_Checks (Ind_Hi));
5120 else
5121 Cond :=
5122 Make_Or_Else (Loc,
5123 Left_Opnd =>
5124 Make_Op_Lt (Loc,
5125 Left_Opnd => Duplicate_Subexpr_Move_Checks (Aggr_Lo),
5126 Right_Opnd => Duplicate_Subexpr_Move_Checks (Ind_Lo)),
5128 Right_Opnd =>
5129 Make_Op_Gt (Loc,
5130 Left_Opnd => Duplicate_Subexpr (Aggr_Hi),
5131 Right_Opnd => Duplicate_Subexpr (Ind_Hi)));
5132 end if;
5134 if Present (Cond) then
5135 Cond :=
5136 Make_And_Then (Loc,
5137 Left_Opnd =>
5138 Make_Op_Le (Loc,
5139 Left_Opnd => Duplicate_Subexpr_Move_Checks (Aggr_Lo),
5140 Right_Opnd => Duplicate_Subexpr_Move_Checks (Aggr_Hi)),
5142 Right_Opnd => Cond);
5144 Set_Analyzed (Left_Opnd (Left_Opnd (Cond)), False);
5145 Set_Analyzed (Right_Opnd (Left_Opnd (Cond)), False);
5146 Insert_Action (N,
5147 Make_Raise_Constraint_Error (Loc,
5148 Condition => Cond,
5149 Reason => CE_Range_Check_Failed));
5150 end if;
5151 end Check_Bounds;
5153 ----------------------------
5154 -- Check_Same_Aggr_Bounds --
5155 ----------------------------
5157 procedure Check_Same_Aggr_Bounds (Sub_Aggr : Node_Id; Dim : Pos) is
5158 Sub_Lo : constant Node_Id := Low_Bound (Aggregate_Bounds (Sub_Aggr));
5159 Sub_Hi : constant Node_Id := High_Bound (Aggregate_Bounds (Sub_Aggr));
5160 -- The bounds of this specific subaggregate
5162 Aggr_Lo : constant Node_Id := Aggr_Low (Dim);
5163 Aggr_Hi : constant Node_Id := Aggr_High (Dim);
5164 -- The bounds of the aggregate for this dimension
5166 Ind_Typ : constant Entity_Id := Aggr_Index_Typ (Dim);
5167 -- The index type for this dimension.xxx
5169 Cond : Node_Id := Empty;
5170 Assoc : Node_Id;
5171 Expr : Node_Id;
5173 begin
5174 -- If index checks are on generate the test
5176 -- [constraint_error when
5177 -- Aggr_Lo /= Sub_Lo or else Aggr_Hi /= Sub_Hi]
5179 -- As an optimization try to see if some tests are trivially vacuos
5180 -- because we are comparing an expression against itself. Also for
5181 -- the first dimension the test is trivially vacuous because there
5182 -- is just one aggregate for dimension 1.
5184 if Index_Checks_Suppressed (Ind_Typ) then
5185 Cond := Empty;
5187 elsif Dim = 1 or else (Aggr_Lo = Sub_Lo and then Aggr_Hi = Sub_Hi)
5188 then
5189 Cond := Empty;
5191 elsif Aggr_Hi = Sub_Hi then
5192 Cond :=
5193 Make_Op_Ne (Loc,
5194 Left_Opnd => Duplicate_Subexpr_Move_Checks (Aggr_Lo),
5195 Right_Opnd => Duplicate_Subexpr_Move_Checks (Sub_Lo));
5197 elsif Aggr_Lo = Sub_Lo then
5198 Cond :=
5199 Make_Op_Ne (Loc,
5200 Left_Opnd => Duplicate_Subexpr_Move_Checks (Aggr_Hi),
5201 Right_Opnd => Duplicate_Subexpr_Move_Checks (Sub_Hi));
5203 else
5204 Cond :=
5205 Make_Or_Else (Loc,
5206 Left_Opnd =>
5207 Make_Op_Ne (Loc,
5208 Left_Opnd => Duplicate_Subexpr_Move_Checks (Aggr_Lo),
5209 Right_Opnd => Duplicate_Subexpr_Move_Checks (Sub_Lo)),
5211 Right_Opnd =>
5212 Make_Op_Ne (Loc,
5213 Left_Opnd => Duplicate_Subexpr (Aggr_Hi),
5214 Right_Opnd => Duplicate_Subexpr (Sub_Hi)));
5215 end if;
5217 if Present (Cond) then
5218 Insert_Action (N,
5219 Make_Raise_Constraint_Error (Loc,
5220 Condition => Cond,
5221 Reason => CE_Length_Check_Failed));
5222 end if;
5224 -- Now look inside the subaggregate to see if there is more work
5226 if Dim < Aggr_Dimension then
5228 -- Process positional components
5230 if Present (Expressions (Sub_Aggr)) then
5231 Expr := First (Expressions (Sub_Aggr));
5232 while Present (Expr) loop
5233 Check_Same_Aggr_Bounds (Expr, Dim + 1);
5234 Next (Expr);
5235 end loop;
5236 end if;
5238 -- Process component associations
5240 if Present (Component_Associations (Sub_Aggr)) then
5241 Assoc := First (Component_Associations (Sub_Aggr));
5242 while Present (Assoc) loop
5243 Expr := Expression (Assoc);
5244 Check_Same_Aggr_Bounds (Expr, Dim + 1);
5245 Next (Assoc);
5246 end loop;
5247 end if;
5248 end if;
5249 end Check_Same_Aggr_Bounds;
5251 ----------------------------
5252 -- Compute_Others_Present --
5253 ----------------------------
5255 procedure Compute_Others_Present (Sub_Aggr : Node_Id; Dim : Pos) is
5256 Assoc : Node_Id;
5257 Expr : Node_Id;
5259 begin
5260 if Present (Component_Associations (Sub_Aggr)) then
5261 Assoc := Last (Component_Associations (Sub_Aggr));
5263 if Nkind (First (Choice_List (Assoc))) = N_Others_Choice then
5264 Others_Present (Dim) := True;
5265 end if;
5266 end if;
5268 -- Now look inside the subaggregate to see if there is more work
5270 if Dim < Aggr_Dimension then
5272 -- Process positional components
5274 if Present (Expressions (Sub_Aggr)) then
5275 Expr := First (Expressions (Sub_Aggr));
5276 while Present (Expr) loop
5277 Compute_Others_Present (Expr, Dim + 1);
5278 Next (Expr);
5279 end loop;
5280 end if;
5282 -- Process component associations
5284 if Present (Component_Associations (Sub_Aggr)) then
5285 Assoc := First (Component_Associations (Sub_Aggr));
5286 while Present (Assoc) loop
5287 Expr := Expression (Assoc);
5288 Compute_Others_Present (Expr, Dim + 1);
5289 Next (Assoc);
5290 end loop;
5291 end if;
5292 end if;
5293 end Compute_Others_Present;
5295 ------------------------
5296 -- In_Place_Assign_OK --
5297 ------------------------
5299 function In_Place_Assign_OK return Boolean is
5300 Aggr_In : Node_Id;
5301 Aggr_Lo : Node_Id;
5302 Aggr_Hi : Node_Id;
5303 Obj_In : Node_Id;
5304 Obj_Lo : Node_Id;
5305 Obj_Hi : Node_Id;
5307 function Safe_Aggregate (Aggr : Node_Id) return Boolean;
5308 -- Check recursively that each component of a (sub)aggregate does not
5309 -- depend on the variable being assigned to.
5311 function Safe_Component (Expr : Node_Id) return Boolean;
5312 -- Verify that an expression cannot depend on the variable being
5313 -- assigned to. Room for improvement here (but less than before).
5315 --------------------
5316 -- Safe_Aggregate --
5317 --------------------
5319 function Safe_Aggregate (Aggr : Node_Id) return Boolean is
5320 Expr : Node_Id;
5322 begin
5323 if Present (Expressions (Aggr)) then
5324 Expr := First (Expressions (Aggr));
5325 while Present (Expr) loop
5326 if Nkind (Expr) = N_Aggregate then
5327 if not Safe_Aggregate (Expr) then
5328 return False;
5329 end if;
5331 elsif not Safe_Component (Expr) then
5332 return False;
5333 end if;
5335 Next (Expr);
5336 end loop;
5337 end if;
5339 if Present (Component_Associations (Aggr)) then
5340 Expr := First (Component_Associations (Aggr));
5341 while Present (Expr) loop
5342 if Nkind (Expression (Expr)) = N_Aggregate then
5343 if not Safe_Aggregate (Expression (Expr)) then
5344 return False;
5345 end if;
5347 -- If association has a box, no way to determine yet
5348 -- whether default can be assigned in place.
5350 elsif Box_Present (Expr) then
5351 return False;
5353 elsif not Safe_Component (Expression (Expr)) then
5354 return False;
5355 end if;
5357 Next (Expr);
5358 end loop;
5359 end if;
5361 return True;
5362 end Safe_Aggregate;
5364 --------------------
5365 -- Safe_Component --
5366 --------------------
5368 function Safe_Component (Expr : Node_Id) return Boolean is
5369 Comp : Node_Id := Expr;
5371 function Check_Component (Comp : Node_Id) return Boolean;
5372 -- Do the recursive traversal, after copy
5374 ---------------------
5375 -- Check_Component --
5376 ---------------------
5378 function Check_Component (Comp : Node_Id) return Boolean is
5379 begin
5380 if Is_Overloaded (Comp) then
5381 return False;
5382 end if;
5384 return Compile_Time_Known_Value (Comp)
5386 or else (Is_Entity_Name (Comp)
5387 and then Present (Entity (Comp))
5388 and then No (Renamed_Object (Entity (Comp))))
5390 or else (Nkind (Comp) = N_Attribute_Reference
5391 and then Check_Component (Prefix (Comp)))
5393 or else (Nkind (Comp) in N_Binary_Op
5394 and then Check_Component (Left_Opnd (Comp))
5395 and then Check_Component (Right_Opnd (Comp)))
5397 or else (Nkind (Comp) in N_Unary_Op
5398 and then Check_Component (Right_Opnd (Comp)))
5400 or else (Nkind (Comp) = N_Selected_Component
5401 and then Check_Component (Prefix (Comp)))
5403 or else (Nkind (Comp) = N_Unchecked_Type_Conversion
5404 and then Check_Component (Expression (Comp)));
5405 end Check_Component;
5407 -- Start of processing for Safe_Component
5409 begin
5410 -- If the component appears in an association that may correspond
5411 -- to more than one element, it is not analyzed before expansion
5412 -- into assignments, to avoid side effects. We analyze, but do not
5413 -- resolve the copy, to obtain sufficient entity information for
5414 -- the checks that follow. If component is overloaded we assume
5415 -- an unsafe function call.
5417 if not Analyzed (Comp) then
5418 if Is_Overloaded (Expr) then
5419 return False;
5421 elsif Nkind (Expr) = N_Aggregate
5422 and then not Is_Others_Aggregate (Expr)
5423 then
5424 return False;
5426 elsif Nkind (Expr) = N_Allocator then
5428 -- For now, too complex to analyze
5430 return False;
5431 end if;
5433 Comp := New_Copy_Tree (Expr);
5434 Set_Parent (Comp, Parent (Expr));
5435 Analyze (Comp);
5436 end if;
5438 if Nkind (Comp) = N_Aggregate then
5439 return Safe_Aggregate (Comp);
5440 else
5441 return Check_Component (Comp);
5442 end if;
5443 end Safe_Component;
5445 -- Start of processing for In_Place_Assign_OK
5447 begin
5448 if Present (Component_Associations (N)) then
5450 -- On assignment, sliding can take place, so we cannot do the
5451 -- assignment in place unless the bounds of the aggregate are
5452 -- statically equal to those of the target.
5454 -- If the aggregate is given by an others choice, the bounds are
5455 -- derived from the left-hand side, and the assignment is safe if
5456 -- the expression is.
5458 if Is_Others_Aggregate (N) then
5459 return
5460 Safe_Component
5461 (Expression (First (Component_Associations (N))));
5462 end if;
5464 Aggr_In := First_Index (Etype (N));
5466 if Nkind (Parent (N)) = N_Assignment_Statement then
5467 Obj_In := First_Index (Etype (Name (Parent (N))));
5469 else
5470 -- Context is an allocator. Check bounds of aggregate against
5471 -- given type in qualified expression.
5473 pragma Assert (Nkind (Parent (Parent (N))) = N_Allocator);
5474 Obj_In :=
5475 First_Index (Etype (Entity (Subtype_Mark (Parent (N)))));
5476 end if;
5478 while Present (Aggr_In) loop
5479 Get_Index_Bounds (Aggr_In, Aggr_Lo, Aggr_Hi);
5480 Get_Index_Bounds (Obj_In, Obj_Lo, Obj_Hi);
5482 if not Compile_Time_Known_Value (Aggr_Lo)
5483 or else not Compile_Time_Known_Value (Aggr_Hi)
5484 or else not Compile_Time_Known_Value (Obj_Lo)
5485 or else not Compile_Time_Known_Value (Obj_Hi)
5486 or else Expr_Value (Aggr_Lo) /= Expr_Value (Obj_Lo)
5487 or else Expr_Value (Aggr_Hi) /= Expr_Value (Obj_Hi)
5488 then
5489 return False;
5490 end if;
5492 Next_Index (Aggr_In);
5493 Next_Index (Obj_In);
5494 end loop;
5495 end if;
5497 -- Now check the component values themselves
5499 return Safe_Aggregate (N);
5500 end In_Place_Assign_OK;
5502 ------------------
5503 -- Others_Check --
5504 ------------------
5506 procedure Others_Check (Sub_Aggr : Node_Id; Dim : Pos) is
5507 Aggr_Lo : constant Node_Id := Aggr_Low (Dim);
5508 Aggr_Hi : constant Node_Id := Aggr_High (Dim);
5509 -- The bounds of the aggregate for this dimension
5511 Ind_Typ : constant Entity_Id := Aggr_Index_Typ (Dim);
5512 -- The index type for this dimension
5514 Need_To_Check : Boolean := False;
5516 Choices_Lo : Node_Id := Empty;
5517 Choices_Hi : Node_Id := Empty;
5518 -- The lowest and highest discrete choices for a named subaggregate
5520 Nb_Choices : Int := -1;
5521 -- The number of discrete non-others choices in this subaggregate
5523 Nb_Elements : Uint := Uint_0;
5524 -- The number of elements in a positional aggregate
5526 Cond : Node_Id := Empty;
5528 Assoc : Node_Id;
5529 Choice : Node_Id;
5530 Expr : Node_Id;
5532 begin
5533 -- Check if we have an others choice. If we do make sure that this
5534 -- subaggregate contains at least one element in addition to the
5535 -- others choice.
5537 if Range_Checks_Suppressed (Ind_Typ) then
5538 Need_To_Check := False;
5540 elsif Present (Expressions (Sub_Aggr))
5541 and then Present (Component_Associations (Sub_Aggr))
5542 then
5543 Need_To_Check := True;
5545 elsif Present (Component_Associations (Sub_Aggr)) then
5546 Assoc := Last (Component_Associations (Sub_Aggr));
5548 if Nkind (First (Choice_List (Assoc))) /= N_Others_Choice then
5549 Need_To_Check := False;
5551 else
5552 -- Count the number of discrete choices. Start with -1 because
5553 -- the others choice does not count.
5555 -- Is there some reason we do not use List_Length here ???
5557 Nb_Choices := -1;
5558 Assoc := First (Component_Associations (Sub_Aggr));
5559 while Present (Assoc) loop
5560 Choice := First (Choice_List (Assoc));
5561 while Present (Choice) loop
5562 Nb_Choices := Nb_Choices + 1;
5563 Next (Choice);
5564 end loop;
5566 Next (Assoc);
5567 end loop;
5569 -- If there is only an others choice nothing to do
5571 Need_To_Check := (Nb_Choices > 0);
5572 end if;
5574 else
5575 Need_To_Check := False;
5576 end if;
5578 -- If we are dealing with a positional subaggregate with an others
5579 -- choice then compute the number or positional elements.
5581 if Need_To_Check and then Present (Expressions (Sub_Aggr)) then
5582 Expr := First (Expressions (Sub_Aggr));
5583 Nb_Elements := Uint_0;
5584 while Present (Expr) loop
5585 Nb_Elements := Nb_Elements + 1;
5586 Next (Expr);
5587 end loop;
5589 -- If the aggregate contains discrete choices and an others choice
5590 -- compute the smallest and largest discrete choice values.
5592 elsif Need_To_Check then
5593 Compute_Choices_Lo_And_Choices_Hi : declare
5595 Table : Case_Table_Type (1 .. Nb_Choices);
5596 -- Used to sort all the different choice values
5598 J : Pos := 1;
5599 Low : Node_Id;
5600 High : Node_Id;
5602 begin
5603 Assoc := First (Component_Associations (Sub_Aggr));
5604 while Present (Assoc) loop
5605 Choice := First (Choice_List (Assoc));
5606 while Present (Choice) loop
5607 if Nkind (Choice) = N_Others_Choice then
5608 exit;
5609 end if;
5611 Get_Index_Bounds (Choice, Low, High);
5612 Table (J).Choice_Lo := Low;
5613 Table (J).Choice_Hi := High;
5615 J := J + 1;
5616 Next (Choice);
5617 end loop;
5619 Next (Assoc);
5620 end loop;
5622 -- Sort the discrete choices
5624 Sort_Case_Table (Table);
5626 Choices_Lo := Table (1).Choice_Lo;
5627 Choices_Hi := Table (Nb_Choices).Choice_Hi;
5628 end Compute_Choices_Lo_And_Choices_Hi;
5629 end if;
5631 -- If no others choice in this subaggregate, or the aggregate
5632 -- comprises only an others choice, nothing to do.
5634 if not Need_To_Check then
5635 Cond := Empty;
5637 -- If we are dealing with an aggregate containing an others choice
5638 -- and positional components, we generate the following test:
5640 -- if Ind_Typ'Pos (Aggr_Lo) + (Nb_Elements - 1) >
5641 -- Ind_Typ'Pos (Aggr_Hi)
5642 -- then
5643 -- raise Constraint_Error;
5644 -- end if;
5646 elsif Nb_Elements > Uint_0 then
5647 Cond :=
5648 Make_Op_Gt (Loc,
5649 Left_Opnd =>
5650 Make_Op_Add (Loc,
5651 Left_Opnd =>
5652 Make_Attribute_Reference (Loc,
5653 Prefix => New_Occurrence_Of (Ind_Typ, Loc),
5654 Attribute_Name => Name_Pos,
5655 Expressions =>
5656 New_List
5657 (Duplicate_Subexpr_Move_Checks (Aggr_Lo))),
5658 Right_Opnd => Make_Integer_Literal (Loc, Nb_Elements - 1)),
5660 Right_Opnd =>
5661 Make_Attribute_Reference (Loc,
5662 Prefix => New_Occurrence_Of (Ind_Typ, Loc),
5663 Attribute_Name => Name_Pos,
5664 Expressions => New_List (
5665 Duplicate_Subexpr_Move_Checks (Aggr_Hi))));
5667 -- If we are dealing with an aggregate containing an others choice
5668 -- and discrete choices we generate the following test:
5670 -- [constraint_error when
5671 -- Choices_Lo < Aggr_Lo or else Choices_Hi > Aggr_Hi];
5673 else
5674 Cond :=
5675 Make_Or_Else (Loc,
5676 Left_Opnd =>
5677 Make_Op_Lt (Loc,
5678 Left_Opnd => Duplicate_Subexpr_Move_Checks (Choices_Lo),
5679 Right_Opnd => Duplicate_Subexpr_Move_Checks (Aggr_Lo)),
5681 Right_Opnd =>
5682 Make_Op_Gt (Loc,
5683 Left_Opnd => Duplicate_Subexpr (Choices_Hi),
5684 Right_Opnd => Duplicate_Subexpr (Aggr_Hi)));
5685 end if;
5687 if Present (Cond) then
5688 Insert_Action (N,
5689 Make_Raise_Constraint_Error (Loc,
5690 Condition => Cond,
5691 Reason => CE_Length_Check_Failed));
5692 -- Questionable reason code, shouldn't that be a
5693 -- CE_Range_Check_Failed ???
5694 end if;
5696 -- Now look inside the subaggregate to see if there is more work
5698 if Dim < Aggr_Dimension then
5700 -- Process positional components
5702 if Present (Expressions (Sub_Aggr)) then
5703 Expr := First (Expressions (Sub_Aggr));
5704 while Present (Expr) loop
5705 Others_Check (Expr, Dim + 1);
5706 Next (Expr);
5707 end loop;
5708 end if;
5710 -- Process component associations
5712 if Present (Component_Associations (Sub_Aggr)) then
5713 Assoc := First (Component_Associations (Sub_Aggr));
5714 while Present (Assoc) loop
5715 Expr := Expression (Assoc);
5716 Others_Check (Expr, Dim + 1);
5717 Next (Assoc);
5718 end loop;
5719 end if;
5720 end if;
5721 end Others_Check;
5723 -------------------------
5724 -- Safe_Left_Hand_Side --
5725 -------------------------
5727 function Safe_Left_Hand_Side (N : Node_Id) return Boolean is
5728 function Is_Safe_Index (Indx : Node_Id) return Boolean;
5729 -- If the left-hand side includes an indexed component, check that
5730 -- the indexes are free of side effects.
5732 -------------------
5733 -- Is_Safe_Index --
5734 -------------------
5736 function Is_Safe_Index (Indx : Node_Id) return Boolean is
5737 begin
5738 if Is_Entity_Name (Indx) then
5739 return True;
5741 elsif Nkind (Indx) = N_Integer_Literal then
5742 return True;
5744 elsif Nkind (Indx) = N_Function_Call
5745 and then Is_Entity_Name (Name (Indx))
5746 and then Has_Pragma_Pure_Function (Entity (Name (Indx)))
5747 then
5748 return True;
5750 elsif Nkind (Indx) = N_Type_Conversion
5751 and then Is_Safe_Index (Expression (Indx))
5752 then
5753 return True;
5755 else
5756 return False;
5757 end if;
5758 end Is_Safe_Index;
5760 -- Start of processing for Safe_Left_Hand_Side
5762 begin
5763 if Is_Entity_Name (N) then
5764 return True;
5766 elsif Nkind_In (N, N_Explicit_Dereference, N_Selected_Component)
5767 and then Safe_Left_Hand_Side (Prefix (N))
5768 then
5769 return True;
5771 elsif Nkind (N) = N_Indexed_Component
5772 and then Safe_Left_Hand_Side (Prefix (N))
5773 and then Is_Safe_Index (First (Expressions (N)))
5774 then
5775 return True;
5777 elsif Nkind (N) = N_Unchecked_Type_Conversion then
5778 return Safe_Left_Hand_Side (Expression (N));
5780 else
5781 return False;
5782 end if;
5783 end Safe_Left_Hand_Side;
5785 -- Local variables
5787 Tmp : Entity_Id;
5788 -- Holds the temporary aggregate value
5790 Tmp_Decl : Node_Id;
5791 -- Holds the declaration of Tmp
5793 Aggr_Code : List_Id;
5794 Parent_Node : Node_Id;
5795 Parent_Kind : Node_Kind;
5797 -- Start of processing for Expand_Array_Aggregate
5799 begin
5800 -- Do not touch the special aggregates of attributes used for Asm calls
5802 if Is_RTE (Ctyp, RE_Asm_Input_Operand)
5803 or else Is_RTE (Ctyp, RE_Asm_Output_Operand)
5804 then
5805 return;
5807 -- Do not expand an aggregate for an array type which contains tasks if
5808 -- the aggregate is associated with an unexpanded return statement of a
5809 -- build-in-place function. The aggregate is expanded when the related
5810 -- return statement (rewritten into an extended return) is processed.
5811 -- This delay ensures that any temporaries and initialization code
5812 -- generated for the aggregate appear in the proper return block and
5813 -- use the correct _chain and _master.
5815 elsif Has_Task (Base_Type (Etype (N)))
5816 and then Nkind (Parent (N)) = N_Simple_Return_Statement
5817 and then Is_Build_In_Place_Function
5818 (Return_Applies_To (Return_Statement_Entity (Parent (N))))
5819 then
5820 return;
5822 -- Do not attempt expansion if error already detected. We may reach this
5823 -- point in spite of previous errors when compiling with -gnatq, to
5824 -- force all possible errors (this is the usual ACATS mode).
5826 elsif Error_Posted (N) then
5827 return;
5828 end if;
5830 -- If the semantic analyzer has determined that aggregate N will raise
5831 -- Constraint_Error at run time, then the aggregate node has been
5832 -- replaced with an N_Raise_Constraint_Error node and we should
5833 -- never get here.
5835 pragma Assert (not Raises_Constraint_Error (N));
5837 -- STEP 1a
5839 -- Check that the index range defined by aggregate bounds is
5840 -- compatible with corresponding index subtype.
5842 Index_Compatibility_Check : declare
5843 Aggr_Index_Range : Node_Id := First_Index (Typ);
5844 -- The current aggregate index range
5846 Index_Constraint : Node_Id := First_Index (Etype (Typ));
5847 -- The corresponding index constraint against which we have to
5848 -- check the above aggregate index range.
5850 begin
5851 Compute_Others_Present (N, 1);
5853 for J in 1 .. Aggr_Dimension loop
5854 -- There is no need to emit a check if an others choice is present
5855 -- for this array aggregate dimension since in this case one of
5856 -- N's subaggregates has taken its bounds from the context and
5857 -- these bounds must have been checked already. In addition all
5858 -- subaggregates corresponding to the same dimension must all have
5859 -- the same bounds (checked in (c) below).
5861 if not Range_Checks_Suppressed (Etype (Index_Constraint))
5862 and then not Others_Present (J)
5863 then
5864 -- We don't use Checks.Apply_Range_Check here because it emits
5865 -- a spurious check. Namely it checks that the range defined by
5866 -- the aggregate bounds is nonempty. But we know this already
5867 -- if we get here.
5869 Check_Bounds (Aggr_Index_Range, Index_Constraint);
5870 end if;
5872 -- Save the low and high bounds of the aggregate index as well as
5873 -- the index type for later use in checks (b) and (c) below.
5875 Aggr_Low (J) := Low_Bound (Aggr_Index_Range);
5876 Aggr_High (J) := High_Bound (Aggr_Index_Range);
5878 Aggr_Index_Typ (J) := Etype (Index_Constraint);
5880 Next_Index (Aggr_Index_Range);
5881 Next_Index (Index_Constraint);
5882 end loop;
5883 end Index_Compatibility_Check;
5885 -- STEP 1b
5887 -- If an others choice is present check that no aggregate index is
5888 -- outside the bounds of the index constraint.
5890 Others_Check (N, 1);
5892 -- STEP 1c
5894 -- For multidimensional arrays make sure that all subaggregates
5895 -- corresponding to the same dimension have the same bounds.
5897 if Aggr_Dimension > 1 then
5898 Check_Same_Aggr_Bounds (N, 1);
5899 end if;
5901 -- STEP 1d
5903 -- If we have a default component value, or simple initialization is
5904 -- required for the component type, then we replace <> in component
5905 -- associations by the required default value.
5907 declare
5908 Default_Val : Node_Id;
5909 Assoc : Node_Id;
5911 begin
5912 if (Present (Default_Aspect_Component_Value (Typ))
5913 or else Needs_Simple_Initialization (Ctyp))
5914 and then Present (Component_Associations (N))
5915 then
5916 Assoc := First (Component_Associations (N));
5917 while Present (Assoc) loop
5918 if Nkind (Assoc) = N_Component_Association
5919 and then Box_Present (Assoc)
5920 then
5921 Set_Box_Present (Assoc, False);
5923 if Present (Default_Aspect_Component_Value (Typ)) then
5924 Default_Val := Default_Aspect_Component_Value (Typ);
5925 else
5926 Default_Val := Get_Simple_Init_Val (Ctyp, N);
5927 end if;
5929 Set_Expression (Assoc, New_Copy_Tree (Default_Val));
5930 Analyze_And_Resolve (Expression (Assoc), Ctyp);
5931 end if;
5933 Next (Assoc);
5934 end loop;
5935 end if;
5936 end;
5938 -- STEP 2
5940 -- Here we test for is packed array aggregate that we can handle at
5941 -- compile time. If so, return with transformation done. Note that we do
5942 -- this even if the aggregate is nested, because once we have done this
5943 -- processing, there is no more nested aggregate.
5945 if Packed_Array_Aggregate_Handled (N) then
5946 return;
5947 end if;
5949 -- At this point we try to convert to positional form
5951 if Ekind (Current_Scope) = E_Package
5952 and then Static_Elaboration_Desired (Current_Scope)
5953 then
5954 Convert_To_Positional (N, Max_Others_Replicate => 100);
5955 else
5956 Convert_To_Positional (N);
5957 end if;
5959 -- if the result is no longer an aggregate (e.g. it may be a string
5960 -- literal, or a temporary which has the needed value), then we are
5961 -- done, since there is no longer a nested aggregate.
5963 if Nkind (N) /= N_Aggregate then
5964 return;
5966 -- We are also done if the result is an analyzed aggregate, indicating
5967 -- that Convert_To_Positional succeeded and reanalyzed the rewritten
5968 -- aggregate.
5970 elsif Analyzed (N) and then N /= Original_Node (N) then
5971 return;
5972 end if;
5974 -- If all aggregate components are compile-time known and the aggregate
5975 -- has been flattened, nothing left to do. The same occurs if the
5976 -- aggregate is used to initialize the components of a statically
5977 -- allocated dispatch table.
5979 if Compile_Time_Known_Aggregate (N)
5980 or else Is_Static_Dispatch_Table_Aggregate (N)
5981 then
5982 Set_Expansion_Delayed (N, False);
5983 return;
5984 end if;
5986 -- Now see if back end processing is possible
5988 if Backend_Processing_Possible (N) then
5990 -- If the aggregate is static but the constraints are not, build
5991 -- a static subtype for the aggregate, so that Gigi can place it
5992 -- in static memory. Perform an unchecked_conversion to the non-
5993 -- static type imposed by the context.
5995 declare
5996 Itype : constant Entity_Id := Etype (N);
5997 Index : Node_Id;
5998 Needs_Type : Boolean := False;
6000 begin
6001 Index := First_Index (Itype);
6002 while Present (Index) loop
6003 if not Is_OK_Static_Subtype (Etype (Index)) then
6004 Needs_Type := True;
6005 exit;
6006 else
6007 Next_Index (Index);
6008 end if;
6009 end loop;
6011 if Needs_Type then
6012 Build_Constrained_Type (Positional => True);
6013 Rewrite (N, Unchecked_Convert_To (Itype, N));
6014 Analyze (N);
6015 end if;
6016 end;
6018 return;
6019 end if;
6021 -- STEP 3
6023 -- Delay expansion for nested aggregates: it will be taken care of when
6024 -- the parent aggregate is expanded.
6026 Parent_Node := Parent (N);
6027 Parent_Kind := Nkind (Parent_Node);
6029 if Parent_Kind = N_Qualified_Expression then
6030 Parent_Node := Parent (Parent_Node);
6031 Parent_Kind := Nkind (Parent_Node);
6032 end if;
6034 if Parent_Kind = N_Aggregate
6035 or else Parent_Kind = N_Extension_Aggregate
6036 or else Parent_Kind = N_Component_Association
6037 or else (Parent_Kind = N_Object_Declaration
6038 and then Needs_Finalization (Typ))
6039 or else (Parent_Kind = N_Assignment_Statement
6040 and then Inside_Init_Proc)
6041 then
6042 if Static_Array_Aggregate (N)
6043 or else Compile_Time_Known_Aggregate (N)
6044 then
6045 Set_Expansion_Delayed (N, False);
6046 return;
6047 else
6048 Set_Expansion_Delayed (N);
6049 return;
6050 end if;
6051 end if;
6053 -- STEP 4
6055 -- Look if in place aggregate expansion is possible
6057 -- For object declarations we build the aggregate in place, unless
6058 -- the array is bit-packed or the component is controlled.
6060 -- For assignments we do the assignment in place if all the component
6061 -- associations have compile-time known values. For other cases we
6062 -- create a temporary. The analysis for safety of on-line assignment
6063 -- is delicate, i.e. we don't know how to do it fully yet ???
6065 -- For allocators we assign to the designated object in place if the
6066 -- aggregate meets the same conditions as other in-place assignments.
6067 -- In this case the aggregate may not come from source but was created
6068 -- for default initialization, e.g. with Initialize_Scalars.
6070 if Requires_Transient_Scope (Typ) then
6071 Establish_Transient_Scope
6072 (N, Sec_Stack => Has_Controlled_Component (Typ));
6073 end if;
6075 if Has_Default_Init_Comps (N) then
6076 Maybe_In_Place_OK := False;
6078 elsif Is_Bit_Packed_Array (Typ)
6079 or else Has_Controlled_Component (Typ)
6080 then
6081 Maybe_In_Place_OK := False;
6083 else
6084 Maybe_In_Place_OK :=
6085 (Nkind (Parent (N)) = N_Assignment_Statement
6086 and then In_Place_Assign_OK)
6088 or else
6089 (Nkind (Parent (Parent (N))) = N_Allocator
6090 and then In_Place_Assign_OK);
6091 end if;
6093 -- If this is an array of tasks, it will be expanded into build-in-place
6094 -- assignments. Build an activation chain for the tasks now.
6096 if Has_Task (Etype (N)) then
6097 Build_Activation_Chain_Entity (N);
6098 end if;
6100 -- Perform in-place expansion of aggregate in an object declaration.
6101 -- Note: actions generated for the aggregate will be captured in an
6102 -- expression-with-actions statement so that they can be transferred
6103 -- to freeze actions later if there is an address clause for the
6104 -- object. (Note: we don't use a block statement because this would
6105 -- cause generated freeze nodes to be elaborated in the wrong scope).
6107 -- Do not perform in-place expansion for SPARK 05 because aggregates are
6108 -- expected to appear in qualified form. In-place expansion eliminates
6109 -- the qualification and eventually violates this SPARK 05 restiction.
6111 -- Should document the rest of the guards ???
6113 if not Has_Default_Init_Comps (N)
6114 and then Comes_From_Source (Parent_Node)
6115 and then Parent_Kind = N_Object_Declaration
6116 and then Present (Expression (Parent_Node))
6117 and then not
6118 Must_Slide (Etype (Defining_Identifier (Parent_Node)), Typ)
6119 and then not Has_Controlled_Component (Typ)
6120 and then not Is_Bit_Packed_Array (Typ)
6121 and then not Restriction_Check_Required (SPARK_05)
6122 then
6123 In_Place_Assign_OK_For_Declaration := True;
6124 Tmp := Defining_Identifier (Parent_Node);
6125 Set_No_Initialization (Parent_Node);
6126 Set_Expression (Parent_Node, Empty);
6128 -- Set kind and type of the entity, for use in the analysis
6129 -- of the subsequent assignments. If the nominal type is not
6130 -- constrained, build a subtype from the known bounds of the
6131 -- aggregate. If the declaration has a subtype mark, use it,
6132 -- otherwise use the itype of the aggregate.
6134 Set_Ekind (Tmp, E_Variable);
6136 if not Is_Constrained (Typ) then
6137 Build_Constrained_Type (Positional => False);
6139 elsif Is_Entity_Name (Object_Definition (Parent_Node))
6140 and then Is_Constrained (Entity (Object_Definition (Parent_Node)))
6141 then
6142 Set_Etype (Tmp, Entity (Object_Definition (Parent_Node)));
6144 else
6145 Set_Size_Known_At_Compile_Time (Typ, False);
6146 Set_Etype (Tmp, Typ);
6147 end if;
6149 elsif Maybe_In_Place_OK
6150 and then Nkind (Parent (N)) = N_Qualified_Expression
6151 and then Nkind (Parent (Parent (N))) = N_Allocator
6152 then
6153 Set_Expansion_Delayed (N);
6154 return;
6156 -- In the remaining cases the aggregate is the RHS of an assignment
6158 elsif Maybe_In_Place_OK
6159 and then Safe_Left_Hand_Side (Name (Parent (N)))
6160 then
6161 Tmp := Name (Parent (N));
6163 if Etype (Tmp) /= Etype (N) then
6164 Apply_Length_Check (N, Etype (Tmp));
6166 if Nkind (N) = N_Raise_Constraint_Error then
6168 -- Static error, nothing further to expand
6170 return;
6171 end if;
6172 end if;
6174 -- If a slice assignment has an aggregate with a single others_choice,
6175 -- the assignment can be done in place even if bounds are not static,
6176 -- by converting it into a loop over the discrete range of the slice.
6178 elsif Maybe_In_Place_OK
6179 and then Nkind (Name (Parent (N))) = N_Slice
6180 and then Is_Others_Aggregate (N)
6181 then
6182 Tmp := Name (Parent (N));
6184 -- Set type of aggregate to be type of lhs in assignment, in order
6185 -- to suppress redundant length checks.
6187 Set_Etype (N, Etype (Tmp));
6189 -- Step 5
6191 -- In place aggregate expansion is not possible
6193 else
6194 Maybe_In_Place_OK := False;
6195 Tmp := Make_Temporary (Loc, 'A', N);
6196 Tmp_Decl :=
6197 Make_Object_Declaration (Loc,
6198 Defining_Identifier => Tmp,
6199 Object_Definition => New_Occurrence_Of (Typ, Loc));
6200 Set_No_Initialization (Tmp_Decl, True);
6202 -- If we are within a loop, the temporary will be pushed on the
6203 -- stack at each iteration. If the aggregate is the expression for an
6204 -- allocator, it will be immediately copied to the heap and can
6205 -- be reclaimed at once. We create a transient scope around the
6206 -- aggregate for this purpose.
6208 if Ekind (Current_Scope) = E_Loop
6209 and then Nkind (Parent (Parent (N))) = N_Allocator
6210 then
6211 Establish_Transient_Scope (N, False);
6212 end if;
6214 Insert_Action (N, Tmp_Decl);
6215 end if;
6217 -- Construct and insert the aggregate code. We can safely suppress index
6218 -- checks because this code is guaranteed not to raise CE on index
6219 -- checks. However we should *not* suppress all checks.
6221 declare
6222 Target : Node_Id;
6224 begin
6225 if Nkind (Tmp) = N_Defining_Identifier then
6226 Target := New_Occurrence_Of (Tmp, Loc);
6228 else
6229 if Has_Default_Init_Comps (N) then
6231 -- Ada 2005 (AI-287): This case has not been analyzed???
6233 raise Program_Error;
6234 end if;
6236 -- Name in assignment is explicit dereference
6238 Target := New_Copy (Tmp);
6239 end if;
6241 -- If we are to generate an in place assignment for a declaration or
6242 -- an assignment statement, and the assignment can be done directly
6243 -- by the back end, then do not expand further.
6245 -- ??? We can also do that if in place expansion is not possible but
6246 -- then we could go into an infinite recursion.
6248 if (In_Place_Assign_OK_For_Declaration or else Maybe_In_Place_OK)
6249 and then not AAMP_On_Target
6250 and then not CodePeer_Mode
6251 and then not Modify_Tree_For_C
6252 and then not Possible_Bit_Aligned_Component (Target)
6253 and then not Is_Possibly_Unaligned_Slice (Target)
6254 and then Aggr_Assignment_OK_For_Backend (N)
6255 then
6256 if Maybe_In_Place_OK then
6257 return;
6258 end if;
6260 Aggr_Code :=
6261 New_List (
6262 Make_Assignment_Statement (Loc,
6263 Name => Target,
6264 Expression => New_Copy (N)));
6266 else
6267 Aggr_Code :=
6268 Build_Array_Aggr_Code (N,
6269 Ctype => Ctyp,
6270 Index => First_Index (Typ),
6271 Into => Target,
6272 Scalar_Comp => Is_Scalar_Type (Ctyp));
6273 end if;
6275 -- Save the last assignment statement associated with the aggregate
6276 -- when building a controlled object. This reference is utilized by
6277 -- the finalization machinery when marking an object as successfully
6278 -- initialized.
6280 if Needs_Finalization (Typ)
6281 and then Is_Entity_Name (Target)
6282 and then Present (Entity (Target))
6283 and then Ekind_In (Entity (Target), E_Constant, E_Variable)
6284 then
6285 Set_Last_Aggregate_Assignment (Entity (Target), Last (Aggr_Code));
6286 end if;
6287 end;
6289 -- If the aggregate is the expression in a declaration, the expanded
6290 -- code must be inserted after it. The defining entity might not come
6291 -- from source if this is part of an inlined body, but the declaration
6292 -- itself will.
6294 if Comes_From_Source (Tmp)
6295 or else
6296 (Nkind (Parent (N)) = N_Object_Declaration
6297 and then Comes_From_Source (Parent (N))
6298 and then Tmp = Defining_Entity (Parent (N)))
6299 then
6300 declare
6301 Node_After : constant Node_Id := Next (Parent_Node);
6303 begin
6304 Insert_Actions_After (Parent_Node, Aggr_Code);
6306 if Parent_Kind = N_Object_Declaration then
6307 Collect_Initialization_Statements
6308 (Obj => Tmp, N => Parent_Node, Node_After => Node_After);
6309 end if;
6310 end;
6312 else
6313 Insert_Actions (N, Aggr_Code);
6314 end if;
6316 -- If the aggregate has been assigned in place, remove the original
6317 -- assignment.
6319 if Nkind (Parent (N)) = N_Assignment_Statement
6320 and then Maybe_In_Place_OK
6321 then
6322 Rewrite (Parent (N), Make_Null_Statement (Loc));
6324 elsif Nkind (Parent (N)) /= N_Object_Declaration
6325 or else Tmp /= Defining_Identifier (Parent (N))
6326 then
6327 Rewrite (N, New_Occurrence_Of (Tmp, Loc));
6328 Analyze_And_Resolve (N, Typ);
6329 end if;
6330 end Expand_Array_Aggregate;
6332 ------------------------
6333 -- Expand_N_Aggregate --
6334 ------------------------
6336 procedure Expand_N_Aggregate (N : Node_Id) is
6337 begin
6338 -- Record aggregate case
6340 if Is_Record_Type (Etype (N)) then
6341 Expand_Record_Aggregate (N);
6343 -- Array aggregate case
6345 else
6346 -- A special case, if we have a string subtype with bounds 1 .. N,
6347 -- where N is known at compile time, and the aggregate is of the
6348 -- form (others => 'x'), with a single choice and no expressions,
6349 -- and N is less than 80 (an arbitrary limit for now), then replace
6350 -- the aggregate by the equivalent string literal (but do not mark
6351 -- it as static since it is not).
6353 -- Note: this entire circuit is redundant with respect to code in
6354 -- Expand_Array_Aggregate that collapses others choices to positional
6355 -- form, but there are two problems with that circuit:
6357 -- a) It is limited to very small cases due to ill-understood
6358 -- interactions with bootstrapping. That limit is removed by
6359 -- use of the No_Implicit_Loops restriction.
6361 -- b) It incorrectly ends up with the resulting expressions being
6362 -- considered static when they are not. For example, the
6363 -- following test should fail:
6365 -- pragma Restrictions (No_Implicit_Loops);
6366 -- package NonSOthers4 is
6367 -- B : constant String (1 .. 6) := (others => 'A');
6368 -- DH : constant String (1 .. 8) := B & "BB";
6369 -- X : Integer;
6370 -- pragma Export (C, X, Link_Name => DH);
6371 -- end;
6373 -- But it succeeds (DH looks static to pragma Export)
6375 -- To be sorted out ???
6377 if Present (Component_Associations (N)) then
6378 declare
6379 CA : constant Node_Id := First (Component_Associations (N));
6380 MX : constant := 80;
6382 begin
6383 if Nkind (First (Choice_List (CA))) = N_Others_Choice
6384 and then Nkind (Expression (CA)) = N_Character_Literal
6385 and then No (Expressions (N))
6386 then
6387 declare
6388 T : constant Entity_Id := Etype (N);
6389 X : constant Node_Id := First_Index (T);
6390 EC : constant Node_Id := Expression (CA);
6391 CV : constant Uint := Char_Literal_Value (EC);
6392 CC : constant Int := UI_To_Int (CV);
6394 begin
6395 if Nkind (X) = N_Range
6396 and then Compile_Time_Known_Value (Low_Bound (X))
6397 and then Expr_Value (Low_Bound (X)) = 1
6398 and then Compile_Time_Known_Value (High_Bound (X))
6399 then
6400 declare
6401 Hi : constant Uint := Expr_Value (High_Bound (X));
6403 begin
6404 if Hi <= MX then
6405 Start_String;
6407 for J in 1 .. UI_To_Int (Hi) loop
6408 Store_String_Char (Char_Code (CC));
6409 end loop;
6411 Rewrite (N,
6412 Make_String_Literal (Sloc (N),
6413 Strval => End_String));
6415 if CC >= Int (2 ** 16) then
6416 Set_Has_Wide_Wide_Character (N);
6417 elsif CC >= Int (2 ** 8) then
6418 Set_Has_Wide_Character (N);
6419 end if;
6421 Analyze_And_Resolve (N, T);
6422 Set_Is_Static_Expression (N, False);
6423 return;
6424 end if;
6425 end;
6426 end if;
6427 end;
6428 end if;
6429 end;
6430 end if;
6432 -- Not that special case, so normal expansion of array aggregate
6434 Expand_Array_Aggregate (N);
6435 end if;
6437 exception
6438 when RE_Not_Available =>
6439 return;
6440 end Expand_N_Aggregate;
6442 ------------------------------
6443 -- Expand_N_Delta_Aggregate --
6444 ------------------------------
6446 procedure Expand_N_Delta_Aggregate (N : Node_Id) is
6447 Loc : constant Source_Ptr := Sloc (N);
6448 Typ : constant Entity_Id := Etype (N);
6449 Decl : Node_Id;
6451 begin
6452 Decl :=
6453 Make_Object_Declaration (Loc,
6454 Defining_Identifier => Make_Temporary (Loc, 'T'),
6455 Object_Definition => New_Occurrence_Of (Typ, Loc),
6456 Expression => New_Copy_Tree (Expression (N)));
6458 if Is_Array_Type (Etype (N)) then
6459 Expand_Delta_Array_Aggregate (N, New_List (Decl));
6460 else
6461 Expand_Delta_Record_Aggregate (N, New_List (Decl));
6462 end if;
6463 end Expand_N_Delta_Aggregate;
6465 ----------------------------------
6466 -- Expand_Delta_Array_Aggregate --
6467 ----------------------------------
6469 procedure Expand_Delta_Array_Aggregate (N : Node_Id; Deltas : List_Id) is
6470 Loc : constant Source_Ptr := Sloc (N);
6471 Temp : constant Entity_Id := Defining_Identifier (First (Deltas));
6472 Assoc : Node_Id;
6474 function Generate_Loop (C : Node_Id) return Node_Id;
6475 -- Generate a loop containing individual component assignments for
6476 -- choices that are ranges, subtype indications, subtype names, and
6477 -- iterated component associations.
6479 -------------------
6480 -- Generate_Loop --
6481 -------------------
6483 function Generate_Loop (C : Node_Id) return Node_Id is
6484 Sl : constant Source_Ptr := Sloc (C);
6485 Ix : Entity_Id;
6487 begin
6488 if Nkind (Parent (C)) = N_Iterated_Component_Association then
6489 Ix :=
6490 Make_Defining_Identifier (Loc,
6491 Chars => (Chars (Defining_Identifier (Parent (C)))));
6492 else
6493 Ix := Make_Temporary (Sl, 'I');
6494 end if;
6496 return
6497 Make_Loop_Statement (Loc,
6498 Iteration_Scheme =>
6499 Make_Iteration_Scheme (Sl,
6500 Loop_Parameter_Specification =>
6501 Make_Loop_Parameter_Specification (Sl,
6502 Defining_Identifier => Ix,
6503 Discrete_Subtype_Definition => New_Copy_Tree (C))),
6505 Statements => New_List (
6506 Make_Assignment_Statement (Sl,
6507 Name =>
6508 Make_Indexed_Component (Sl,
6509 Prefix => New_Occurrence_Of (Temp, Sl),
6510 Expressions => New_List (New_Occurrence_Of (Ix, Sl))),
6511 Expression => New_Copy_Tree (Expression (Assoc)))),
6512 End_Label => Empty);
6513 end Generate_Loop;
6515 -- Local variables
6517 Choice : Node_Id;
6519 -- Start of processing for Expand_Delta_Array_Aggregate
6521 begin
6522 Assoc := First (Component_Associations (N));
6523 while Present (Assoc) loop
6524 Choice := First (Choice_List (Assoc));
6525 if Nkind (Assoc) = N_Iterated_Component_Association then
6526 while Present (Choice) loop
6527 Append_To (Deltas, Generate_Loop (Choice));
6528 Next (Choice);
6529 end loop;
6531 else
6532 while Present (Choice) loop
6534 -- Choice can be given by a range, a subtype indication, a
6535 -- subtype name, a scalar value, or an entity.
6537 if Nkind (Choice) = N_Range
6538 or else (Is_Entity_Name (Choice)
6539 and then Is_Type (Entity (Choice)))
6540 then
6541 Append_To (Deltas, Generate_Loop (Choice));
6543 elsif Nkind (Choice) = N_Subtype_Indication then
6544 Append_To (Deltas,
6545 Generate_Loop (Range_Expression (Constraint (Choice))));
6547 else
6548 Append_To (Deltas,
6549 Make_Assignment_Statement (Sloc (Choice),
6550 Name =>
6551 Make_Indexed_Component (Sloc (Choice),
6552 Prefix => New_Occurrence_Of (Temp, Loc),
6553 Expressions => New_List (New_Copy_Tree (Choice))),
6554 Expression => New_Copy_Tree (Expression (Assoc))));
6555 end if;
6557 Next (Choice);
6558 end loop;
6559 end if;
6561 Next (Assoc);
6562 end loop;
6564 Insert_Actions (N, Deltas);
6565 Rewrite (N, New_Occurrence_Of (Temp, Loc));
6566 end Expand_Delta_Array_Aggregate;
6568 -----------------------------------
6569 -- Expand_Delta_Record_Aggregate --
6570 -----------------------------------
6572 procedure Expand_Delta_Record_Aggregate (N : Node_Id; Deltas : List_Id) is
6573 Loc : constant Source_Ptr := Sloc (N);
6574 Temp : constant Entity_Id := Defining_Identifier (First (Deltas));
6575 Assoc : Node_Id;
6576 Choice : Node_Id;
6578 begin
6579 Assoc := First (Component_Associations (N));
6581 while Present (Assoc) loop
6582 Choice := First (Choice_List (Assoc));
6583 while Present (Choice) loop
6584 Append_To (Deltas,
6585 Make_Assignment_Statement (Sloc (Choice),
6586 Name =>
6587 Make_Selected_Component (Sloc (Choice),
6588 Prefix => New_Occurrence_Of (Temp, Loc),
6589 Selector_Name => Make_Identifier (Loc, Chars (Choice))),
6590 Expression => New_Copy_Tree (Expression (Assoc))));
6591 Next (Choice);
6592 end loop;
6594 Next (Assoc);
6595 end loop;
6597 Insert_Actions (N, Deltas);
6598 Rewrite (N, New_Occurrence_Of (Temp, Loc));
6599 end Expand_Delta_Record_Aggregate;
6601 ----------------------------------
6602 -- Expand_N_Extension_Aggregate --
6603 ----------------------------------
6605 -- If the ancestor part is an expression, add a component association for
6606 -- the parent field. If the type of the ancestor part is not the direct
6607 -- parent of the expected type, build recursively the needed ancestors.
6608 -- If the ancestor part is a subtype_mark, replace aggregate with a decla-
6609 -- ration for a temporary of the expected type, followed by individual
6610 -- assignments to the given components.
6612 procedure Expand_N_Extension_Aggregate (N : Node_Id) is
6613 Loc : constant Source_Ptr := Sloc (N);
6614 A : constant Node_Id := Ancestor_Part (N);
6615 Typ : constant Entity_Id := Etype (N);
6617 begin
6618 -- If the ancestor is a subtype mark, an init proc must be called
6619 -- on the resulting object which thus has to be materialized in
6620 -- the front-end
6622 if Is_Entity_Name (A) and then Is_Type (Entity (A)) then
6623 Convert_To_Assignments (N, Typ);
6625 -- The extension aggregate is transformed into a record aggregate
6626 -- of the following form (c1 and c2 are inherited components)
6628 -- (Exp with c3 => a, c4 => b)
6629 -- ==> (c1 => Exp.c1, c2 => Exp.c2, c3 => a, c4 => b)
6631 else
6632 Set_Etype (N, Typ);
6634 if Tagged_Type_Expansion then
6635 Expand_Record_Aggregate (N,
6636 Orig_Tag =>
6637 New_Occurrence_Of
6638 (Node (First_Elmt (Access_Disp_Table (Typ))), Loc),
6639 Parent_Expr => A);
6641 -- No tag is needed in the case of a VM
6643 else
6644 Expand_Record_Aggregate (N, Parent_Expr => A);
6645 end if;
6646 end if;
6648 exception
6649 when RE_Not_Available =>
6650 return;
6651 end Expand_N_Extension_Aggregate;
6653 -----------------------------
6654 -- Expand_Record_Aggregate --
6655 -----------------------------
6657 procedure Expand_Record_Aggregate
6658 (N : Node_Id;
6659 Orig_Tag : Node_Id := Empty;
6660 Parent_Expr : Node_Id := Empty)
6662 Loc : constant Source_Ptr := Sloc (N);
6663 Comps : constant List_Id := Component_Associations (N);
6664 Typ : constant Entity_Id := Etype (N);
6665 Base_Typ : constant Entity_Id := Base_Type (Typ);
6667 Static_Components : Boolean := True;
6668 -- Flag to indicate whether all components are compile-time known,
6669 -- and the aggregate can be constructed statically and handled by
6670 -- the back-end.
6672 procedure Build_Back_End_Aggregate;
6673 -- Build a proper aggregate to be handled by the back-end
6675 function Compile_Time_Known_Composite_Value (N : Node_Id) return Boolean;
6676 -- Returns true if N is an expression of composite type which can be
6677 -- fully evaluated at compile time without raising constraint error.
6678 -- Such expressions can be passed as is to Gigi without any expansion.
6680 -- This returns true for N_Aggregate with Compile_Time_Known_Aggregate
6681 -- set and constants whose expression is such an aggregate, recursively.
6683 function Component_Not_OK_For_Backend return Boolean;
6684 -- Check for presence of a component which makes it impossible for the
6685 -- backend to process the aggregate, thus requiring the use of a series
6686 -- of assignment statements. Cases checked for are a nested aggregate
6687 -- needing Late_Expansion, the presence of a tagged component which may
6688 -- need tag adjustment, and a bit unaligned component reference.
6690 -- We also force expansion into assignments if a component is of a
6691 -- mutable type (including a private type with discriminants) because
6692 -- in that case the size of the component to be copied may be smaller
6693 -- than the side of the target, and there is no simple way for gigi
6694 -- to compute the size of the object to be copied.
6696 -- NOTE: This is part of the ongoing work to define precisely the
6697 -- interface between front-end and back-end handling of aggregates.
6698 -- In general it is desirable to pass aggregates as they are to gigi,
6699 -- in order to minimize elaboration code. This is one case where the
6700 -- semantics of Ada complicate the analysis and lead to anomalies in
6701 -- the gcc back-end if the aggregate is not expanded into assignments.
6703 function Has_Per_Object_Constraint (L : List_Id) return Boolean;
6704 -- Return True if any element of L has Has_Per_Object_Constraint set.
6705 -- L should be the Choices component of an N_Component_Association.
6707 function Has_Visible_Private_Ancestor (Id : E) return Boolean;
6708 -- If any ancestor of the current type is private, the aggregate
6709 -- cannot be built in place. We cannot rely on Has_Private_Ancestor,
6710 -- because it will not be set when type and its parent are in the
6711 -- same scope, and the parent component needs expansion.
6713 function Top_Level_Aggregate (N : Node_Id) return Node_Id;
6714 -- For nested aggregates return the ultimate enclosing aggregate; for
6715 -- non-nested aggregates return N.
6717 ------------------------------
6718 -- Build_Back_End_Aggregate --
6719 ------------------------------
6721 procedure Build_Back_End_Aggregate is
6722 Comp : Entity_Id;
6723 New_Comp : Node_Id;
6724 Tag_Value : Node_Id;
6726 begin
6727 if Nkind (N) = N_Aggregate then
6729 -- If the aggregate is static and can be handled by the back-end,
6730 -- nothing left to do.
6732 if Static_Components then
6733 Set_Compile_Time_Known_Aggregate (N);
6734 Set_Expansion_Delayed (N, False);
6735 end if;
6736 end if;
6738 -- If no discriminants, nothing special to do
6740 if not Has_Discriminants (Typ) then
6741 null;
6743 -- Case of discriminants present
6745 elsif Is_Derived_Type (Typ) then
6747 -- For untagged types, non-stored discriminants are replaced with
6748 -- stored discriminants, which are the ones that gigi uses to
6749 -- describe the type and its components.
6751 Generate_Aggregate_For_Derived_Type : declare
6752 procedure Prepend_Stored_Values (T : Entity_Id);
6753 -- Scan the list of stored discriminants of the type, and add
6754 -- their values to the aggregate being built.
6756 ---------------------------
6757 -- Prepend_Stored_Values --
6758 ---------------------------
6760 procedure Prepend_Stored_Values (T : Entity_Id) is
6761 Discr : Entity_Id;
6762 First_Comp : Node_Id := Empty;
6764 begin
6765 Discr := First_Stored_Discriminant (T);
6766 while Present (Discr) loop
6767 New_Comp :=
6768 Make_Component_Association (Loc,
6769 Choices => New_List (
6770 New_Occurrence_Of (Discr, Loc)),
6771 Expression =>
6772 New_Copy_Tree
6773 (Get_Discriminant_Value
6774 (Discr,
6775 Typ,
6776 Discriminant_Constraint (Typ))));
6778 if No (First_Comp) then
6779 Prepend_To (Component_Associations (N), New_Comp);
6780 else
6781 Insert_After (First_Comp, New_Comp);
6782 end if;
6784 First_Comp := New_Comp;
6785 Next_Stored_Discriminant (Discr);
6786 end loop;
6787 end Prepend_Stored_Values;
6789 -- Local variables
6791 Constraints : constant List_Id := New_List;
6793 Discr : Entity_Id;
6794 Decl : Node_Id;
6795 Num_Disc : Nat := 0;
6796 Num_Gird : Nat := 0;
6798 -- Start of processing for Generate_Aggregate_For_Derived_Type
6800 begin
6801 -- Remove the associations for the discriminant of derived type
6803 declare
6804 First_Comp : Node_Id;
6806 begin
6807 First_Comp := First (Component_Associations (N));
6808 while Present (First_Comp) loop
6809 Comp := First_Comp;
6810 Next (First_Comp);
6812 if Ekind (Entity (First (Choices (Comp)))) =
6813 E_Discriminant
6814 then
6815 Remove (Comp);
6816 Num_Disc := Num_Disc + 1;
6817 end if;
6818 end loop;
6819 end;
6821 -- Insert stored discriminant associations in the correct
6822 -- order. If there are more stored discriminants than new
6823 -- discriminants, there is at least one new discriminant that
6824 -- constrains more than one of the stored discriminants. In
6825 -- this case we need to construct a proper subtype of the
6826 -- parent type, in order to supply values to all the
6827 -- components. Otherwise there is one-one correspondence
6828 -- between the constraints and the stored discriminants.
6830 Discr := First_Stored_Discriminant (Base_Type (Typ));
6831 while Present (Discr) loop
6832 Num_Gird := Num_Gird + 1;
6833 Next_Stored_Discriminant (Discr);
6834 end loop;
6836 -- Case of more stored discriminants than new discriminants
6838 if Num_Gird > Num_Disc then
6840 -- Create a proper subtype of the parent type, which is the
6841 -- proper implementation type for the aggregate, and convert
6842 -- it to the intended target type.
6844 Discr := First_Stored_Discriminant (Base_Type (Typ));
6845 while Present (Discr) loop
6846 New_Comp :=
6847 New_Copy_Tree
6848 (Get_Discriminant_Value
6849 (Discr,
6850 Typ,
6851 Discriminant_Constraint (Typ)));
6853 Append (New_Comp, Constraints);
6854 Next_Stored_Discriminant (Discr);
6855 end loop;
6857 Decl :=
6858 Make_Subtype_Declaration (Loc,
6859 Defining_Identifier => Make_Temporary (Loc, 'T'),
6860 Subtype_Indication =>
6861 Make_Subtype_Indication (Loc,
6862 Subtype_Mark =>
6863 New_Occurrence_Of (Etype (Base_Type (Typ)), Loc),
6864 Constraint =>
6865 Make_Index_Or_Discriminant_Constraint
6866 (Loc, Constraints)));
6868 Insert_Action (N, Decl);
6869 Prepend_Stored_Values (Base_Type (Typ));
6871 Set_Etype (N, Defining_Identifier (Decl));
6872 Set_Analyzed (N);
6874 Rewrite (N, Unchecked_Convert_To (Typ, N));
6875 Analyze (N);
6877 -- Case where we do not have fewer new discriminants than
6878 -- stored discriminants, so in this case we can simply use the
6879 -- stored discriminants of the subtype.
6881 else
6882 Prepend_Stored_Values (Typ);
6883 end if;
6884 end Generate_Aggregate_For_Derived_Type;
6885 end if;
6887 if Is_Tagged_Type (Typ) then
6889 -- In the tagged case, _parent and _tag component must be created
6891 -- Reset Null_Present unconditionally. Tagged records always have
6892 -- at least one field (the tag or the parent).
6894 Set_Null_Record_Present (N, False);
6896 -- When the current aggregate comes from the expansion of an
6897 -- extension aggregate, the parent expr is replaced by an
6898 -- aggregate formed by selected components of this expr.
6900 if Present (Parent_Expr) and then Is_Empty_List (Comps) then
6901 Comp := First_Component_Or_Discriminant (Typ);
6902 while Present (Comp) loop
6904 -- Skip all expander-generated components
6906 if not Comes_From_Source (Original_Record_Component (Comp))
6907 then
6908 null;
6910 else
6911 New_Comp :=
6912 Make_Selected_Component (Loc,
6913 Prefix =>
6914 Unchecked_Convert_To (Typ,
6915 Duplicate_Subexpr (Parent_Expr, True)),
6916 Selector_Name => New_Occurrence_Of (Comp, Loc));
6918 Append_To (Comps,
6919 Make_Component_Association (Loc,
6920 Choices => New_List (
6921 New_Occurrence_Of (Comp, Loc)),
6922 Expression => New_Comp));
6924 Analyze_And_Resolve (New_Comp, Etype (Comp));
6925 end if;
6927 Next_Component_Or_Discriminant (Comp);
6928 end loop;
6929 end if;
6931 -- Compute the value for the Tag now, if the type is a root it
6932 -- will be included in the aggregate right away, otherwise it will
6933 -- be propagated to the parent aggregate.
6935 if Present (Orig_Tag) then
6936 Tag_Value := Orig_Tag;
6938 elsif not Tagged_Type_Expansion then
6939 Tag_Value := Empty;
6941 else
6942 Tag_Value :=
6943 New_Occurrence_Of
6944 (Node (First_Elmt (Access_Disp_Table (Typ))), Loc);
6945 end if;
6947 -- For a derived type, an aggregate for the parent is formed with
6948 -- all the inherited components.
6950 if Is_Derived_Type (Typ) then
6951 declare
6952 First_Comp : Node_Id;
6953 Parent_Comps : List_Id;
6954 Parent_Aggr : Node_Id;
6955 Parent_Name : Node_Id;
6957 begin
6958 -- Remove the inherited component association from the
6959 -- aggregate and store them in the parent aggregate
6961 First_Comp := First (Component_Associations (N));
6962 Parent_Comps := New_List;
6963 while Present (First_Comp)
6964 and then
6965 Scope (Original_Record_Component
6966 (Entity (First (Choices (First_Comp))))) /=
6967 Base_Typ
6968 loop
6969 Comp := First_Comp;
6970 Next (First_Comp);
6971 Remove (Comp);
6972 Append (Comp, Parent_Comps);
6973 end loop;
6975 Parent_Aggr :=
6976 Make_Aggregate (Loc,
6977 Component_Associations => Parent_Comps);
6978 Set_Etype (Parent_Aggr, Etype (Base_Type (Typ)));
6980 -- Find the _parent component
6982 Comp := First_Component (Typ);
6983 while Chars (Comp) /= Name_uParent loop
6984 Comp := Next_Component (Comp);
6985 end loop;
6987 Parent_Name := New_Occurrence_Of (Comp, Loc);
6989 -- Insert the parent aggregate
6991 Prepend_To (Component_Associations (N),
6992 Make_Component_Association (Loc,
6993 Choices => New_List (Parent_Name),
6994 Expression => Parent_Aggr));
6996 -- Expand recursively the parent propagating the right Tag
6998 Expand_Record_Aggregate
6999 (Parent_Aggr, Tag_Value, Parent_Expr);
7001 -- The ancestor part may be a nested aggregate that has
7002 -- delayed expansion: recheck now.
7004 if Component_Not_OK_For_Backend then
7005 Convert_To_Assignments (N, Typ);
7006 end if;
7007 end;
7009 -- For a root type, the tag component is added (unless compiling
7010 -- for the VMs, where tags are implicit).
7012 elsif Tagged_Type_Expansion then
7013 declare
7014 Tag_Name : constant Node_Id :=
7015 New_Occurrence_Of
7016 (First_Tag_Component (Typ), Loc);
7017 Typ_Tag : constant Entity_Id := RTE (RE_Tag);
7018 Conv_Node : constant Node_Id :=
7019 Unchecked_Convert_To (Typ_Tag, Tag_Value);
7021 begin
7022 Set_Etype (Conv_Node, Typ_Tag);
7023 Prepend_To (Component_Associations (N),
7024 Make_Component_Association (Loc,
7025 Choices => New_List (Tag_Name),
7026 Expression => Conv_Node));
7027 end;
7028 end if;
7029 end if;
7030 end Build_Back_End_Aggregate;
7032 ----------------------------------------
7033 -- Compile_Time_Known_Composite_Value --
7034 ----------------------------------------
7036 function Compile_Time_Known_Composite_Value
7037 (N : Node_Id) return Boolean
7039 begin
7040 -- If we have an entity name, then see if it is the name of a
7041 -- constant and if so, test the corresponding constant value.
7043 if Is_Entity_Name (N) then
7044 declare
7045 E : constant Entity_Id := Entity (N);
7046 V : Node_Id;
7047 begin
7048 if Ekind (E) /= E_Constant then
7049 return False;
7050 else
7051 V := Constant_Value (E);
7052 return Present (V)
7053 and then Compile_Time_Known_Composite_Value (V);
7054 end if;
7055 end;
7057 -- We have a value, see if it is compile time known
7059 else
7060 if Nkind (N) = N_Aggregate then
7061 return Compile_Time_Known_Aggregate (N);
7062 end if;
7064 -- All other types of values are not known at compile time
7066 return False;
7067 end if;
7069 end Compile_Time_Known_Composite_Value;
7071 ----------------------------------
7072 -- Component_Not_OK_For_Backend --
7073 ----------------------------------
7075 function Component_Not_OK_For_Backend return Boolean is
7076 C : Node_Id;
7077 Expr_Q : Node_Id;
7079 begin
7080 if No (Comps) then
7081 return False;
7082 end if;
7084 C := First (Comps);
7085 while Present (C) loop
7087 -- If the component has box initialization, expansion is needed
7088 -- and component is not ready for backend.
7090 if Box_Present (C) then
7091 return True;
7092 end if;
7094 if Nkind (Expression (C)) = N_Qualified_Expression then
7095 Expr_Q := Expression (Expression (C));
7096 else
7097 Expr_Q := Expression (C);
7098 end if;
7100 -- Return true if the aggregate has any associations for tagged
7101 -- components that may require tag adjustment.
7103 -- These are cases where the source expression may have a tag that
7104 -- could differ from the component tag (e.g., can occur for type
7105 -- conversions and formal parameters). (Tag adjustment not needed
7106 -- if Tagged_Type_Expansion because object tags are implicit in
7107 -- the machine.)
7109 if Is_Tagged_Type (Etype (Expr_Q))
7110 and then (Nkind (Expr_Q) = N_Type_Conversion
7111 or else (Is_Entity_Name (Expr_Q)
7112 and then
7113 Ekind (Entity (Expr_Q)) in Formal_Kind))
7114 and then Tagged_Type_Expansion
7115 then
7116 Static_Components := False;
7117 return True;
7119 elsif Is_Delayed_Aggregate (Expr_Q) then
7120 Static_Components := False;
7121 return True;
7123 elsif Possible_Bit_Aligned_Component (Expr_Q) then
7124 Static_Components := False;
7125 return True;
7127 elsif Modify_Tree_For_C
7128 and then Nkind (C) = N_Component_Association
7129 and then Has_Per_Object_Constraint (Choices (C))
7130 then
7131 Static_Components := False;
7132 return True;
7134 elsif Modify_Tree_For_C
7135 and then Nkind (Expr_Q) = N_Identifier
7136 and then Is_Array_Type (Etype (Expr_Q))
7137 then
7138 Static_Components := False;
7139 return True;
7140 end if;
7142 if Is_Elementary_Type (Etype (Expr_Q)) then
7143 if not Compile_Time_Known_Value (Expr_Q) then
7144 Static_Components := False;
7145 end if;
7147 elsif not Compile_Time_Known_Composite_Value (Expr_Q) then
7148 Static_Components := False;
7150 if Is_Private_Type (Etype (Expr_Q))
7151 and then Has_Discriminants (Etype (Expr_Q))
7152 then
7153 return True;
7154 end if;
7155 end if;
7157 Next (C);
7158 end loop;
7160 return False;
7161 end Component_Not_OK_For_Backend;
7163 -------------------------------
7164 -- Has_Per_Object_Constraint --
7165 -------------------------------
7167 function Has_Per_Object_Constraint (L : List_Id) return Boolean is
7168 N : Node_Id := First (L);
7169 begin
7170 while Present (N) loop
7171 if Is_Entity_Name (N)
7172 and then Present (Entity (N))
7173 and then Has_Per_Object_Constraint (Entity (N))
7174 then
7175 return True;
7176 end if;
7178 Next (N);
7179 end loop;
7181 return False;
7182 end Has_Per_Object_Constraint;
7184 -----------------------------------
7185 -- Has_Visible_Private_Ancestor --
7186 -----------------------------------
7188 function Has_Visible_Private_Ancestor (Id : E) return Boolean is
7189 R : constant Entity_Id := Root_Type (Id);
7190 T1 : Entity_Id := Id;
7192 begin
7193 loop
7194 if Is_Private_Type (T1) then
7195 return True;
7197 elsif T1 = R then
7198 return False;
7200 else
7201 T1 := Etype (T1);
7202 end if;
7203 end loop;
7204 end Has_Visible_Private_Ancestor;
7206 -------------------------
7207 -- Top_Level_Aggregate --
7208 -------------------------
7210 function Top_Level_Aggregate (N : Node_Id) return Node_Id is
7211 Aggr : Node_Id;
7213 begin
7214 Aggr := N;
7215 while Present (Parent (Aggr))
7216 and then Nkind_In (Parent (Aggr), N_Aggregate,
7217 N_Component_Association)
7218 loop
7219 Aggr := Parent (Aggr);
7220 end loop;
7222 return Aggr;
7223 end Top_Level_Aggregate;
7225 -- Local variables
7227 Top_Level_Aggr : constant Node_Id := Top_Level_Aggregate (N);
7229 -- Start of processing for Expand_Record_Aggregate
7231 begin
7232 -- If the aggregate is to be assigned to an atomic/VFA variable, we have
7233 -- to prevent a piecemeal assignment even if the aggregate is to be
7234 -- expanded. We create a temporary for the aggregate, and assign the
7235 -- temporary instead, so that the back end can generate an atomic move
7236 -- for it.
7238 if Is_Atomic_VFA_Aggregate (N) then
7239 return;
7241 -- No special management required for aggregates used to initialize
7242 -- statically allocated dispatch tables
7244 elsif Is_Static_Dispatch_Table_Aggregate (N) then
7245 return;
7246 end if;
7248 -- Ada 2005 (AI-318-2): We need to convert to assignments if components
7249 -- are build-in-place function calls. The assignments will each turn
7250 -- into a build-in-place function call. If components are all static,
7251 -- we can pass the aggregate to the backend regardless of limitedness.
7253 -- Extension aggregates, aggregates in extended return statements, and
7254 -- aggregates for C++ imported types must be expanded.
7256 if Ada_Version >= Ada_2005 and then Is_Limited_View (Typ) then
7257 if not Nkind_In (Parent (N), N_Component_Association,
7258 N_Object_Declaration)
7259 then
7260 Convert_To_Assignments (N, Typ);
7262 elsif Nkind (N) = N_Extension_Aggregate
7263 or else Convention (Typ) = Convention_CPP
7264 then
7265 Convert_To_Assignments (N, Typ);
7267 elsif not Size_Known_At_Compile_Time (Typ)
7268 or else Component_Not_OK_For_Backend
7269 or else not Static_Components
7270 then
7271 Convert_To_Assignments (N, Typ);
7273 -- In all other cases, build a proper aggregate to be handled by
7274 -- the back-end
7276 else
7277 Build_Back_End_Aggregate;
7278 end if;
7280 -- Gigi doesn't properly handle temporaries of variable size so we
7281 -- generate it in the front-end
7283 elsif not Size_Known_At_Compile_Time (Typ)
7284 and then Tagged_Type_Expansion
7285 then
7286 Convert_To_Assignments (N, Typ);
7288 -- An aggregate used to initialize a controlled object must be turned
7289 -- into component assignments as the components themselves may require
7290 -- finalization actions such as adjustment.
7292 elsif Needs_Finalization (Typ) then
7293 Convert_To_Assignments (N, Typ);
7295 -- Ada 2005 (AI-287): In case of default initialized components we
7296 -- convert the aggregate into assignments.
7298 elsif Has_Default_Init_Comps (N) then
7299 Convert_To_Assignments (N, Typ);
7301 -- Check components
7303 elsif Component_Not_OK_For_Backend then
7304 Convert_To_Assignments (N, Typ);
7306 -- If an ancestor is private, some components are not inherited and we
7307 -- cannot expand into a record aggregate.
7309 elsif Has_Visible_Private_Ancestor (Typ) then
7310 Convert_To_Assignments (N, Typ);
7312 -- ??? The following was done to compile fxacc00.ads in the ACVCs. Gigi
7313 -- is not able to handle the aggregate for Late_Request.
7315 elsif Is_Tagged_Type (Typ) and then Has_Discriminants (Typ) then
7316 Convert_To_Assignments (N, Typ);
7318 -- If the tagged types covers interface types we need to initialize all
7319 -- hidden components containing pointers to secondary dispatch tables.
7321 elsif Is_Tagged_Type (Typ) and then Has_Interfaces (Typ) then
7322 Convert_To_Assignments (N, Typ);
7324 -- If some components are mutable, the size of the aggregate component
7325 -- may be distinct from the default size of the type component, so
7326 -- we need to expand to insure that the back-end copies the proper
7327 -- size of the data. However, if the aggregate is the initial value of
7328 -- a constant, the target is immutable and might be built statically
7329 -- if components are appropriate.
7331 elsif Has_Mutable_Components (Typ)
7332 and then
7333 (Nkind (Parent (Top_Level_Aggr)) /= N_Object_Declaration
7334 or else not Constant_Present (Parent (Top_Level_Aggr))
7335 or else not Static_Components)
7336 then
7337 Convert_To_Assignments (N, Typ);
7339 -- If the type involved has bit aligned components, then we are not sure
7340 -- that the back end can handle this case correctly.
7342 elsif Type_May_Have_Bit_Aligned_Components (Typ) then
7343 Convert_To_Assignments (N, Typ);
7345 -- When generating C, only generate an aggregate when declaring objects
7346 -- since C does not support aggregates in e.g. assignment statements.
7348 elsif Modify_Tree_For_C and then not In_Object_Declaration (N) then
7349 Convert_To_Assignments (N, Typ);
7351 -- In all other cases, build a proper aggregate to be handled by gigi
7353 else
7354 Build_Back_End_Aggregate;
7355 end if;
7356 end Expand_Record_Aggregate;
7358 ----------------------------
7359 -- Has_Default_Init_Comps --
7360 ----------------------------
7362 function Has_Default_Init_Comps (N : Node_Id) return Boolean is
7363 Comps : constant List_Id := Component_Associations (N);
7364 C : Node_Id;
7365 Expr : Node_Id;
7367 begin
7368 pragma Assert (Nkind_In (N, N_Aggregate, N_Extension_Aggregate));
7370 if No (Comps) then
7371 return False;
7372 end if;
7374 if Has_Self_Reference (N) then
7375 return True;
7376 end if;
7378 -- Check if any direct component has default initialized components
7380 C := First (Comps);
7381 while Present (C) loop
7382 if Box_Present (C) then
7383 return True;
7384 end if;
7386 Next (C);
7387 end loop;
7389 -- Recursive call in case of aggregate expression
7391 C := First (Comps);
7392 while Present (C) loop
7393 Expr := Expression (C);
7395 if Present (Expr)
7396 and then Nkind_In (Expr, N_Aggregate, N_Extension_Aggregate)
7397 and then Has_Default_Init_Comps (Expr)
7398 then
7399 return True;
7400 end if;
7402 Next (C);
7403 end loop;
7405 return False;
7406 end Has_Default_Init_Comps;
7408 --------------------------
7409 -- Is_Delayed_Aggregate --
7410 --------------------------
7412 function Is_Delayed_Aggregate (N : Node_Id) return Boolean is
7413 Node : Node_Id := N;
7414 Kind : Node_Kind := Nkind (Node);
7416 begin
7417 if Kind = N_Qualified_Expression then
7418 Node := Expression (Node);
7419 Kind := Nkind (Node);
7420 end if;
7422 if not Nkind_In (Kind, N_Aggregate, N_Extension_Aggregate) then
7423 return False;
7424 else
7425 return Expansion_Delayed (Node);
7426 end if;
7427 end Is_Delayed_Aggregate;
7429 ---------------------------
7430 -- In_Object_Declaration --
7431 ---------------------------
7433 function In_Object_Declaration (N : Node_Id) return Boolean is
7434 P : Node_Id := Parent (N);
7435 begin
7436 while Present (P) loop
7437 if Nkind (P) = N_Object_Declaration then
7438 return True;
7439 end if;
7441 P := Parent (P);
7442 end loop;
7444 return False;
7445 end In_Object_Declaration;
7447 ----------------------------------------
7448 -- Is_Static_Dispatch_Table_Aggregate --
7449 ----------------------------------------
7451 function Is_Static_Dispatch_Table_Aggregate (N : Node_Id) return Boolean is
7452 Typ : constant Entity_Id := Base_Type (Etype (N));
7454 begin
7455 return Static_Dispatch_Tables
7456 and then Tagged_Type_Expansion
7457 and then RTU_Loaded (Ada_Tags)
7459 -- Avoid circularity when rebuilding the compiler
7461 and then Cunit_Entity (Get_Source_Unit (N)) /= RTU_Entity (Ada_Tags)
7462 and then (Typ = RTE (RE_Dispatch_Table_Wrapper)
7463 or else
7464 Typ = RTE (RE_Address_Array)
7465 or else
7466 Typ = RTE (RE_Type_Specific_Data)
7467 or else
7468 Typ = RTE (RE_Tag_Table)
7469 or else
7470 (RTE_Available (RE_Interface_Data)
7471 and then Typ = RTE (RE_Interface_Data))
7472 or else
7473 (RTE_Available (RE_Interfaces_Array)
7474 and then Typ = RTE (RE_Interfaces_Array))
7475 or else
7476 (RTE_Available (RE_Interface_Data_Element)
7477 and then Typ = RTE (RE_Interface_Data_Element)));
7478 end Is_Static_Dispatch_Table_Aggregate;
7480 -----------------------------
7481 -- Is_Two_Dim_Packed_Array --
7482 -----------------------------
7484 function Is_Two_Dim_Packed_Array (Typ : Entity_Id) return Boolean is
7485 C : constant Int := UI_To_Int (Component_Size (Typ));
7486 begin
7487 return Number_Dimensions (Typ) = 2
7488 and then Is_Bit_Packed_Array (Typ)
7489 and then (C = 1 or else C = 2 or else C = 4);
7490 end Is_Two_Dim_Packed_Array;
7492 --------------------
7493 -- Late_Expansion --
7494 --------------------
7496 function Late_Expansion
7497 (N : Node_Id;
7498 Typ : Entity_Id;
7499 Target : Node_Id) return List_Id
7501 Aggr_Code : List_Id;
7503 begin
7504 if Is_Array_Type (Etype (N)) then
7505 Aggr_Code :=
7506 Build_Array_Aggr_Code
7507 (N => N,
7508 Ctype => Component_Type (Etype (N)),
7509 Index => First_Index (Typ),
7510 Into => Target,
7511 Scalar_Comp => Is_Scalar_Type (Component_Type (Typ)),
7512 Indexes => No_List);
7514 -- Directly or indirectly (e.g. access protected procedure) a record
7516 else
7517 Aggr_Code := Build_Record_Aggr_Code (N, Typ, Target);
7518 end if;
7520 -- Save the last assignment statement associated with the aggregate
7521 -- when building a controlled object. This reference is utilized by
7522 -- the finalization machinery when marking an object as successfully
7523 -- initialized.
7525 if Needs_Finalization (Typ)
7526 and then Is_Entity_Name (Target)
7527 and then Present (Entity (Target))
7528 and then Ekind_In (Entity (Target), E_Constant, E_Variable)
7529 then
7530 Set_Last_Aggregate_Assignment (Entity (Target), Last (Aggr_Code));
7531 end if;
7533 return Aggr_Code;
7534 end Late_Expansion;
7536 ----------------------------------
7537 -- Make_OK_Assignment_Statement --
7538 ----------------------------------
7540 function Make_OK_Assignment_Statement
7541 (Sloc : Source_Ptr;
7542 Name : Node_Id;
7543 Expression : Node_Id) return Node_Id
7545 begin
7546 Set_Assignment_OK (Name);
7547 return Make_Assignment_Statement (Sloc, Name, Expression);
7548 end Make_OK_Assignment_Statement;
7550 -----------------------
7551 -- Number_Of_Choices --
7552 -----------------------
7554 function Number_Of_Choices (N : Node_Id) return Nat is
7555 Assoc : Node_Id;
7556 Choice : Node_Id;
7558 Nb_Choices : Nat := 0;
7560 begin
7561 if Present (Expressions (N)) then
7562 return 0;
7563 end if;
7565 Assoc := First (Component_Associations (N));
7566 while Present (Assoc) loop
7567 Choice := First (Choice_List (Assoc));
7568 while Present (Choice) loop
7569 if Nkind (Choice) /= N_Others_Choice then
7570 Nb_Choices := Nb_Choices + 1;
7571 end if;
7573 Next (Choice);
7574 end loop;
7576 Next (Assoc);
7577 end loop;
7579 return Nb_Choices;
7580 end Number_Of_Choices;
7582 ------------------------------------
7583 -- Packed_Array_Aggregate_Handled --
7584 ------------------------------------
7586 -- The current version of this procedure will handle at compile time
7587 -- any array aggregate that meets these conditions:
7589 -- One and two dimensional, bit packed
7590 -- Underlying packed type is modular type
7591 -- Bounds are within 32-bit Int range
7592 -- All bounds and values are static
7594 -- Note: for now, in the 2-D case, we only handle component sizes of
7595 -- 1, 2, 4 (cases where an integral number of elements occupies a byte).
7597 function Packed_Array_Aggregate_Handled (N : Node_Id) return Boolean is
7598 Loc : constant Source_Ptr := Sloc (N);
7599 Typ : constant Entity_Id := Etype (N);
7600 Ctyp : constant Entity_Id := Component_Type (Typ);
7602 Not_Handled : exception;
7603 -- Exception raised if this aggregate cannot be handled
7605 begin
7606 -- Handle one- or two dimensional bit packed array
7608 if not Is_Bit_Packed_Array (Typ)
7609 or else Number_Dimensions (Typ) > 2
7610 then
7611 return False;
7612 end if;
7614 -- If two-dimensional, check whether it can be folded, and transformed
7615 -- into a one-dimensional aggregate for the Packed_Array_Impl_Type of
7616 -- the original type.
7618 if Number_Dimensions (Typ) = 2 then
7619 return Two_Dim_Packed_Array_Handled (N);
7620 end if;
7622 if not Is_Modular_Integer_Type (Packed_Array_Impl_Type (Typ)) then
7623 return False;
7624 end if;
7626 if not Is_Scalar_Type (Component_Type (Typ))
7627 and then Has_Non_Standard_Rep (Component_Type (Typ))
7628 then
7629 return False;
7630 end if;
7632 declare
7633 Csiz : constant Nat := UI_To_Int (Component_Size (Typ));
7635 Lo : Node_Id;
7636 Hi : Node_Id;
7637 -- Bounds of index type
7639 Lob : Uint;
7640 Hib : Uint;
7641 -- Values of bounds if compile time known
7643 function Get_Component_Val (N : Node_Id) return Uint;
7644 -- Given a expression value N of the component type Ctyp, returns a
7645 -- value of Csiz (component size) bits representing this value. If
7646 -- the value is non-static or any other reason exists why the value
7647 -- cannot be returned, then Not_Handled is raised.
7649 -----------------------
7650 -- Get_Component_Val --
7651 -----------------------
7653 function Get_Component_Val (N : Node_Id) return Uint is
7654 Val : Uint;
7656 begin
7657 -- We have to analyze the expression here before doing any further
7658 -- processing here. The analysis of such expressions is deferred
7659 -- till expansion to prevent some problems of premature analysis.
7661 Analyze_And_Resolve (N, Ctyp);
7663 -- Must have a compile time value. String literals have to be
7664 -- converted into temporaries as well, because they cannot easily
7665 -- be converted into their bit representation.
7667 if not Compile_Time_Known_Value (N)
7668 or else Nkind (N) = N_String_Literal
7669 then
7670 raise Not_Handled;
7671 end if;
7673 Val := Expr_Rep_Value (N);
7675 -- Adjust for bias, and strip proper number of bits
7677 if Has_Biased_Representation (Ctyp) then
7678 Val := Val - Expr_Value (Type_Low_Bound (Ctyp));
7679 end if;
7681 return Val mod Uint_2 ** Csiz;
7682 end Get_Component_Val;
7684 -- Here we know we have a one dimensional bit packed array
7686 begin
7687 Get_Index_Bounds (First_Index (Typ), Lo, Hi);
7689 -- Cannot do anything if bounds are dynamic
7691 if not Compile_Time_Known_Value (Lo)
7692 or else
7693 not Compile_Time_Known_Value (Hi)
7694 then
7695 return False;
7696 end if;
7698 -- Or are silly out of range of int bounds
7700 Lob := Expr_Value (Lo);
7701 Hib := Expr_Value (Hi);
7703 if not UI_Is_In_Int_Range (Lob)
7704 or else
7705 not UI_Is_In_Int_Range (Hib)
7706 then
7707 return False;
7708 end if;
7710 -- At this stage we have a suitable aggregate for handling at compile
7711 -- time. The only remaining checks are that the values of expressions
7712 -- in the aggregate are compile-time known (checks are performed by
7713 -- Get_Component_Val), and that any subtypes or ranges are statically
7714 -- known.
7716 -- If the aggregate is not fully positional at this stage, then
7717 -- convert it to positional form. Either this will fail, in which
7718 -- case we can do nothing, or it will succeed, in which case we have
7719 -- succeeded in handling the aggregate and transforming it into a
7720 -- modular value, or it will stay an aggregate, in which case we
7721 -- have failed to create a packed value for it.
7723 if Present (Component_Associations (N)) then
7724 Convert_To_Positional
7725 (N, Max_Others_Replicate => 64, Handle_Bit_Packed => True);
7726 return Nkind (N) /= N_Aggregate;
7727 end if;
7729 -- Otherwise we are all positional, so convert to proper value
7731 declare
7732 Lov : constant Int := UI_To_Int (Lob);
7733 Hiv : constant Int := UI_To_Int (Hib);
7735 Len : constant Nat := Int'Max (0, Hiv - Lov + 1);
7736 -- The length of the array (number of elements)
7738 Aggregate_Val : Uint;
7739 -- Value of aggregate. The value is set in the low order bits of
7740 -- this value. For the little-endian case, the values are stored
7741 -- from low-order to high-order and for the big-endian case the
7742 -- values are stored from high-order to low-order. Note that gigi
7743 -- will take care of the conversions to left justify the value in
7744 -- the big endian case (because of left justified modular type
7745 -- processing), so we do not have to worry about that here.
7747 Lit : Node_Id;
7748 -- Integer literal for resulting constructed value
7750 Shift : Nat;
7751 -- Shift count from low order for next value
7753 Incr : Int;
7754 -- Shift increment for loop
7756 Expr : Node_Id;
7757 -- Next expression from positional parameters of aggregate
7759 Left_Justified : Boolean;
7760 -- Set True if we are filling the high order bits of the target
7761 -- value (i.e. the value is left justified).
7763 begin
7764 -- For little endian, we fill up the low order bits of the target
7765 -- value. For big endian we fill up the high order bits of the
7766 -- target value (which is a left justified modular value).
7768 Left_Justified := Bytes_Big_Endian;
7770 -- Switch justification if using -gnatd8
7772 if Debug_Flag_8 then
7773 Left_Justified := not Left_Justified;
7774 end if;
7776 -- Switch justfification if reverse storage order
7778 if Reverse_Storage_Order (Base_Type (Typ)) then
7779 Left_Justified := not Left_Justified;
7780 end if;
7782 if Left_Justified then
7783 Shift := Csiz * (Len - 1);
7784 Incr := -Csiz;
7785 else
7786 Shift := 0;
7787 Incr := +Csiz;
7788 end if;
7790 -- Loop to set the values
7792 if Len = 0 then
7793 Aggregate_Val := Uint_0;
7794 else
7795 Expr := First (Expressions (N));
7796 Aggregate_Val := Get_Component_Val (Expr) * Uint_2 ** Shift;
7798 for J in 2 .. Len loop
7799 Shift := Shift + Incr;
7800 Next (Expr);
7801 Aggregate_Val :=
7802 Aggregate_Val + Get_Component_Val (Expr) * Uint_2 ** Shift;
7803 end loop;
7804 end if;
7806 -- Now we can rewrite with the proper value
7808 Lit := Make_Integer_Literal (Loc, Intval => Aggregate_Val);
7809 Set_Print_In_Hex (Lit);
7811 -- Construct the expression using this literal. Note that it is
7812 -- important to qualify the literal with its proper modular type
7813 -- since universal integer does not have the required range and
7814 -- also this is a left justified modular type, which is important
7815 -- in the big-endian case.
7817 Rewrite (N,
7818 Unchecked_Convert_To (Typ,
7819 Make_Qualified_Expression (Loc,
7820 Subtype_Mark =>
7821 New_Occurrence_Of (Packed_Array_Impl_Type (Typ), Loc),
7822 Expression => Lit)));
7824 Analyze_And_Resolve (N, Typ);
7825 return True;
7826 end;
7827 end;
7829 exception
7830 when Not_Handled =>
7831 return False;
7832 end Packed_Array_Aggregate_Handled;
7834 ----------------------------
7835 -- Has_Mutable_Components --
7836 ----------------------------
7838 function Has_Mutable_Components (Typ : Entity_Id) return Boolean is
7839 Comp : Entity_Id;
7841 begin
7842 Comp := First_Component (Typ);
7843 while Present (Comp) loop
7844 if Is_Record_Type (Etype (Comp))
7845 and then Has_Discriminants (Etype (Comp))
7846 and then not Is_Constrained (Etype (Comp))
7847 then
7848 return True;
7849 end if;
7851 Next_Component (Comp);
7852 end loop;
7854 return False;
7855 end Has_Mutable_Components;
7857 ------------------------------
7858 -- Initialize_Discriminants --
7859 ------------------------------
7861 procedure Initialize_Discriminants (N : Node_Id; Typ : Entity_Id) is
7862 Loc : constant Source_Ptr := Sloc (N);
7863 Bas : constant Entity_Id := Base_Type (Typ);
7864 Par : constant Entity_Id := Etype (Bas);
7865 Decl : constant Node_Id := Parent (Par);
7866 Ref : Node_Id;
7868 begin
7869 if Is_Tagged_Type (Bas)
7870 and then Is_Derived_Type (Bas)
7871 and then Has_Discriminants (Par)
7872 and then Has_Discriminants (Bas)
7873 and then Number_Discriminants (Bas) /= Number_Discriminants (Par)
7874 and then Nkind (Decl) = N_Full_Type_Declaration
7875 and then Nkind (Type_Definition (Decl)) = N_Record_Definition
7876 and then
7877 Present (Variant_Part (Component_List (Type_Definition (Decl))))
7878 and then Nkind (N) /= N_Extension_Aggregate
7879 then
7881 -- Call init proc to set discriminants.
7882 -- There should eventually be a special procedure for this ???
7884 Ref := New_Occurrence_Of (Defining_Identifier (N), Loc);
7885 Insert_Actions_After (N,
7886 Build_Initialization_Call (Sloc (N), Ref, Typ));
7887 end if;
7888 end Initialize_Discriminants;
7890 ----------------
7891 -- Must_Slide --
7892 ----------------
7894 function Must_Slide
7895 (Obj_Type : Entity_Id;
7896 Typ : Entity_Id) return Boolean
7898 L1, L2, H1, H2 : Node_Id;
7900 begin
7901 -- No sliding if the type of the object is not established yet, if it is
7902 -- an unconstrained type whose actual subtype comes from the aggregate,
7903 -- or if the two types are identical.
7905 if not Is_Array_Type (Obj_Type) then
7906 return False;
7908 elsif not Is_Constrained (Obj_Type) then
7909 return False;
7911 elsif Typ = Obj_Type then
7912 return False;
7914 else
7915 -- Sliding can only occur along the first dimension
7917 Get_Index_Bounds (First_Index (Typ), L1, H1);
7918 Get_Index_Bounds (First_Index (Obj_Type), L2, H2);
7920 if not Is_OK_Static_Expression (L1) or else
7921 not Is_OK_Static_Expression (L2) or else
7922 not Is_OK_Static_Expression (H1) or else
7923 not Is_OK_Static_Expression (H2)
7924 then
7925 return False;
7926 else
7927 return Expr_Value (L1) /= Expr_Value (L2)
7928 or else
7929 Expr_Value (H1) /= Expr_Value (H2);
7930 end if;
7931 end if;
7932 end Must_Slide;
7934 ---------------------------------
7935 -- Process_Transient_Component --
7936 ---------------------------------
7938 procedure Process_Transient_Component
7939 (Loc : Source_Ptr;
7940 Comp_Typ : Entity_Id;
7941 Init_Expr : Node_Id;
7942 Fin_Call : out Node_Id;
7943 Hook_Clear : out Node_Id;
7944 Aggr : Node_Id := Empty;
7945 Stmts : List_Id := No_List)
7947 procedure Add_Item (Item : Node_Id);
7948 -- Insert arbitrary node Item into the tree depending on the values of
7949 -- Aggr and Stmts.
7951 --------------
7952 -- Add_Item --
7953 --------------
7955 procedure Add_Item (Item : Node_Id) is
7956 begin
7957 if Present (Aggr) then
7958 Insert_Action (Aggr, Item);
7959 else
7960 pragma Assert (Present (Stmts));
7961 Append_To (Stmts, Item);
7962 end if;
7963 end Add_Item;
7965 -- Local variables
7967 Hook_Assign : Node_Id;
7968 Hook_Decl : Node_Id;
7969 Ptr_Decl : Node_Id;
7970 Res_Decl : Node_Id;
7971 Res_Id : Entity_Id;
7972 Res_Typ : Entity_Id;
7974 -- Start of processing for Process_Transient_Component
7976 begin
7977 -- Add the access type, which provides a reference to the function
7978 -- result. Generate:
7980 -- type Res_Typ is access all Comp_Typ;
7982 Res_Typ := Make_Temporary (Loc, 'A');
7983 Set_Ekind (Res_Typ, E_General_Access_Type);
7984 Set_Directly_Designated_Type (Res_Typ, Comp_Typ);
7986 Add_Item
7987 (Make_Full_Type_Declaration (Loc,
7988 Defining_Identifier => Res_Typ,
7989 Type_Definition =>
7990 Make_Access_To_Object_Definition (Loc,
7991 All_Present => True,
7992 Subtype_Indication => New_Occurrence_Of (Comp_Typ, Loc))));
7994 -- Add the temporary which captures the result of the function call.
7995 -- Generate:
7997 -- Res : constant Res_Typ := Init_Expr'Reference;
7999 -- Note that this temporary is effectively a transient object because
8000 -- its lifetime is bounded by the current array or record component.
8002 Res_Id := Make_Temporary (Loc, 'R');
8003 Set_Ekind (Res_Id, E_Constant);
8004 Set_Etype (Res_Id, Res_Typ);
8006 -- Mark the transient object as successfully processed to avoid double
8007 -- finalization.
8009 Set_Is_Finalized_Transient (Res_Id);
8011 -- Signal the general finalization machinery that this transient object
8012 -- should not be considered for finalization actions because its cleanup
8013 -- will be performed by Process_Transient_Component_Completion.
8015 Set_Is_Ignored_Transient (Res_Id);
8017 Res_Decl :=
8018 Make_Object_Declaration (Loc,
8019 Defining_Identifier => Res_Id,
8020 Constant_Present => True,
8021 Object_Definition => New_Occurrence_Of (Res_Typ, Loc),
8022 Expression =>
8023 Make_Reference (Loc, New_Copy_Tree (Init_Expr)));
8025 Add_Item (Res_Decl);
8027 -- Construct all pieces necessary to hook and finalize the transient
8028 -- result.
8030 Build_Transient_Object_Statements
8031 (Obj_Decl => Res_Decl,
8032 Fin_Call => Fin_Call,
8033 Hook_Assign => Hook_Assign,
8034 Hook_Clear => Hook_Clear,
8035 Hook_Decl => Hook_Decl,
8036 Ptr_Decl => Ptr_Decl);
8038 -- Add the access type which provides a reference to the transient
8039 -- result. Generate:
8041 -- type Ptr_Typ is access all Comp_Typ;
8043 Add_Item (Ptr_Decl);
8045 -- Add the temporary which acts as a hook to the transient result.
8046 -- Generate:
8048 -- Hook : Ptr_Typ := null;
8050 Add_Item (Hook_Decl);
8052 -- Attach the transient result to the hook. Generate:
8054 -- Hook := Ptr_Typ (Res);
8056 Add_Item (Hook_Assign);
8058 -- The original initialization expression now references the value of
8059 -- the temporary function result. Generate:
8061 -- Res.all
8063 Rewrite (Init_Expr,
8064 Make_Explicit_Dereference (Loc,
8065 Prefix => New_Occurrence_Of (Res_Id, Loc)));
8066 end Process_Transient_Component;
8068 --------------------------------------------
8069 -- Process_Transient_Component_Completion --
8070 --------------------------------------------
8072 procedure Process_Transient_Component_Completion
8073 (Loc : Source_Ptr;
8074 Aggr : Node_Id;
8075 Fin_Call : Node_Id;
8076 Hook_Clear : Node_Id;
8077 Stmts : List_Id)
8079 Exceptions_OK : constant Boolean :=
8080 not Restriction_Active (No_Exception_Propagation);
8082 begin
8083 pragma Assert (Present (Hook_Clear));
8085 -- Generate the following code if exception propagation is allowed:
8087 -- declare
8088 -- Abort : constant Boolean := Triggered_By_Abort;
8089 -- <or>
8090 -- Abort : constant Boolean := False; -- no abort
8092 -- E : Exception_Occurrence;
8093 -- Raised : Boolean := False;
8095 -- begin
8096 -- [Abort_Defer;]
8098 -- begin
8099 -- Hook := null;
8100 -- [Deep_]Finalize (Res.all);
8102 -- exception
8103 -- when others =>
8104 -- if not Raised then
8105 -- Raised := True;
8106 -- Save_Occurrence (E,
8107 -- Get_Curent_Excep.all.all);
8108 -- end if;
8109 -- end;
8111 -- [Abort_Undefer;]
8113 -- if Raised and then not Abort then
8114 -- Raise_From_Controlled_Operation (E);
8115 -- end if;
8116 -- end;
8118 if Exceptions_OK then
8119 Abort_And_Exception : declare
8120 Blk_Decls : constant List_Id := New_List;
8121 Blk_Stmts : constant List_Id := New_List;
8122 Fin_Stmts : constant List_Id := New_List;
8124 Fin_Data : Finalization_Exception_Data;
8126 begin
8127 -- Create the declarations of the two flags and the exception
8128 -- occurrence.
8130 Build_Object_Declarations (Fin_Data, Blk_Decls, Loc);
8132 -- Generate:
8133 -- Abort_Defer;
8135 if Abort_Allowed then
8136 Append_To (Blk_Stmts,
8137 Build_Runtime_Call (Loc, RE_Abort_Defer));
8138 end if;
8140 -- Wrap the hook clear and the finalization call in order to trap
8141 -- a potential exception.
8143 Append_To (Fin_Stmts, Hook_Clear);
8145 if Present (Fin_Call) then
8146 Append_To (Fin_Stmts, Fin_Call);
8147 end if;
8149 Append_To (Blk_Stmts,
8150 Make_Block_Statement (Loc,
8151 Handled_Statement_Sequence =>
8152 Make_Handled_Sequence_Of_Statements (Loc,
8153 Statements => Fin_Stmts,
8154 Exception_Handlers => New_List (
8155 Build_Exception_Handler (Fin_Data)))));
8157 -- Generate:
8158 -- Abort_Undefer;
8160 if Abort_Allowed then
8161 Append_To (Blk_Stmts,
8162 Build_Runtime_Call (Loc, RE_Abort_Undefer));
8163 end if;
8165 -- Reraise the potential exception with a proper "upgrade" to
8166 -- Program_Error if needed.
8168 Append_To (Blk_Stmts, Build_Raise_Statement (Fin_Data));
8170 -- Wrap everything in a block
8172 Append_To (Stmts,
8173 Make_Block_Statement (Loc,
8174 Declarations => Blk_Decls,
8175 Handled_Statement_Sequence =>
8176 Make_Handled_Sequence_Of_Statements (Loc,
8177 Statements => Blk_Stmts)));
8178 end Abort_And_Exception;
8180 -- Generate the following code if exception propagation is not allowed
8181 -- and aborts are allowed:
8183 -- begin
8184 -- Abort_Defer;
8185 -- Hook := null;
8186 -- [Deep_]Finalize (Res.all);
8187 -- at end
8188 -- Abort_Undefer_Direct;
8189 -- end;
8191 elsif Abort_Allowed then
8192 Abort_Only : declare
8193 Blk_Stmts : constant List_Id := New_List;
8195 begin
8196 Append_To (Blk_Stmts, Build_Runtime_Call (Loc, RE_Abort_Defer));
8197 Append_To (Blk_Stmts, Hook_Clear);
8199 if Present (Fin_Call) then
8200 Append_To (Blk_Stmts, Fin_Call);
8201 end if;
8203 Append_To (Stmts,
8204 Build_Abort_Undefer_Block (Loc,
8205 Stmts => Blk_Stmts,
8206 Context => Aggr));
8207 end Abort_Only;
8209 -- Otherwise generate:
8211 -- Hook := null;
8212 -- [Deep_]Finalize (Res.all);
8214 else
8215 Append_To (Stmts, Hook_Clear);
8217 if Present (Fin_Call) then
8218 Append_To (Stmts, Fin_Call);
8219 end if;
8220 end if;
8221 end Process_Transient_Component_Completion;
8223 ---------------------
8224 -- Sort_Case_Table --
8225 ---------------------
8227 procedure Sort_Case_Table (Case_Table : in out Case_Table_Type) is
8228 L : constant Int := Case_Table'First;
8229 U : constant Int := Case_Table'Last;
8230 K : Int;
8231 J : Int;
8232 T : Case_Bounds;
8234 begin
8235 K := L;
8236 while K /= U loop
8237 T := Case_Table (K + 1);
8239 J := K + 1;
8240 while J /= L
8241 and then Expr_Value (Case_Table (J - 1).Choice_Lo) >
8242 Expr_Value (T.Choice_Lo)
8243 loop
8244 Case_Table (J) := Case_Table (J - 1);
8245 J := J - 1;
8246 end loop;
8248 Case_Table (J) := T;
8249 K := K + 1;
8250 end loop;
8251 end Sort_Case_Table;
8253 ----------------------------
8254 -- Static_Array_Aggregate --
8255 ----------------------------
8257 function Static_Array_Aggregate (N : Node_Id) return Boolean is
8258 Bounds : constant Node_Id := Aggregate_Bounds (N);
8260 Typ : constant Entity_Id := Etype (N);
8261 Comp_Type : constant Entity_Id := Component_Type (Typ);
8262 Agg : Node_Id;
8263 Expr : Node_Id;
8264 Lo : Node_Id;
8265 Hi : Node_Id;
8267 begin
8268 if Is_Tagged_Type (Typ)
8269 or else Is_Controlled (Typ)
8270 or else Is_Packed (Typ)
8271 then
8272 return False;
8273 end if;
8275 if Present (Bounds)
8276 and then Nkind (Bounds) = N_Range
8277 and then Nkind (Low_Bound (Bounds)) = N_Integer_Literal
8278 and then Nkind (High_Bound (Bounds)) = N_Integer_Literal
8279 then
8280 Lo := Low_Bound (Bounds);
8281 Hi := High_Bound (Bounds);
8283 if No (Component_Associations (N)) then
8285 -- Verify that all components are static integers
8287 Expr := First (Expressions (N));
8288 while Present (Expr) loop
8289 if Nkind (Expr) /= N_Integer_Literal then
8290 return False;
8291 end if;
8293 Next (Expr);
8294 end loop;
8296 return True;
8298 else
8299 -- We allow only a single named association, either a static
8300 -- range or an others_clause, with a static expression.
8302 Expr := First (Component_Associations (N));
8304 if Present (Expressions (N)) then
8305 return False;
8307 elsif Present (Next (Expr)) then
8308 return False;
8310 elsif Present (Next (First (Choice_List (Expr)))) then
8311 return False;
8313 else
8314 -- The aggregate is static if all components are literals,
8315 -- or else all its components are static aggregates for the
8316 -- component type. We also limit the size of a static aggregate
8317 -- to prevent runaway static expressions.
8319 if Is_Array_Type (Comp_Type)
8320 or else Is_Record_Type (Comp_Type)
8321 then
8322 if Nkind (Expression (Expr)) /= N_Aggregate
8323 or else
8324 not Compile_Time_Known_Aggregate (Expression (Expr))
8325 then
8326 return False;
8327 end if;
8329 elsif Nkind (Expression (Expr)) /= N_Integer_Literal then
8330 return False;
8331 end if;
8333 if not Aggr_Size_OK (N, Typ) then
8334 return False;
8335 end if;
8337 -- Create a positional aggregate with the right number of
8338 -- copies of the expression.
8340 Agg := Make_Aggregate (Sloc (N), New_List, No_List);
8342 for I in UI_To_Int (Intval (Lo)) .. UI_To_Int (Intval (Hi))
8343 loop
8344 Append_To (Expressions (Agg), New_Copy (Expression (Expr)));
8346 -- The copied expression must be analyzed and resolved.
8347 -- Besides setting the type, this ensures that static
8348 -- expressions are appropriately marked as such.
8350 Analyze_And_Resolve
8351 (Last (Expressions (Agg)), Component_Type (Typ));
8352 end loop;
8354 Set_Aggregate_Bounds (Agg, Bounds);
8355 Set_Etype (Agg, Typ);
8356 Set_Analyzed (Agg);
8357 Rewrite (N, Agg);
8358 Set_Compile_Time_Known_Aggregate (N);
8360 return True;
8361 end if;
8362 end if;
8364 else
8365 return False;
8366 end if;
8367 end Static_Array_Aggregate;
8369 ----------------------------------
8370 -- Two_Dim_Packed_Array_Handled --
8371 ----------------------------------
8373 function Two_Dim_Packed_Array_Handled (N : Node_Id) return Boolean is
8374 Loc : constant Source_Ptr := Sloc (N);
8375 Typ : constant Entity_Id := Etype (N);
8376 Ctyp : constant Entity_Id := Component_Type (Typ);
8377 Comp_Size : constant Int := UI_To_Int (Component_Size (Typ));
8378 Packed_Array : constant Entity_Id :=
8379 Packed_Array_Impl_Type (Base_Type (Typ));
8381 One_Comp : Node_Id;
8382 -- Expression in original aggregate
8384 One_Dim : Node_Id;
8385 -- One-dimensional subaggregate
8387 begin
8389 -- For now, only deal with cases where an integral number of elements
8390 -- fit in a single byte. This includes the most common boolean case.
8392 if not (Comp_Size = 1 or else
8393 Comp_Size = 2 or else
8394 Comp_Size = 4)
8395 then
8396 return False;
8397 end if;
8399 Convert_To_Positional
8400 (N, Max_Others_Replicate => 64, Handle_Bit_Packed => True);
8402 -- Verify that all components are static
8404 if Nkind (N) = N_Aggregate
8405 and then Compile_Time_Known_Aggregate (N)
8406 then
8407 null;
8409 -- The aggregate may have been reanalyzed and converted already
8411 elsif Nkind (N) /= N_Aggregate then
8412 return True;
8414 -- If component associations remain, the aggregate is not static
8416 elsif Present (Component_Associations (N)) then
8417 return False;
8419 else
8420 One_Dim := First (Expressions (N));
8421 while Present (One_Dim) loop
8422 if Present (Component_Associations (One_Dim)) then
8423 return False;
8424 end if;
8426 One_Comp := First (Expressions (One_Dim));
8427 while Present (One_Comp) loop
8428 if not Is_OK_Static_Expression (One_Comp) then
8429 return False;
8430 end if;
8432 Next (One_Comp);
8433 end loop;
8435 Next (One_Dim);
8436 end loop;
8437 end if;
8439 -- Two-dimensional aggregate is now fully positional so pack one
8440 -- dimension to create a static one-dimensional array, and rewrite
8441 -- as an unchecked conversion to the original type.
8443 declare
8444 Byte_Size : constant Int := UI_To_Int (Component_Size (Packed_Array));
8445 -- The packed array type is a byte array
8447 Packed_Num : Nat;
8448 -- Number of components accumulated in current byte
8450 Comps : List_Id;
8451 -- Assembled list of packed values for equivalent aggregate
8453 Comp_Val : Uint;
8454 -- Integer value of component
8456 Incr : Int;
8457 -- Step size for packing
8459 Init_Shift : Int;
8460 -- Endian-dependent start position for packing
8462 Shift : Int;
8463 -- Current insertion position
8465 Val : Int;
8466 -- Component of packed array being assembled
8468 begin
8469 Comps := New_List;
8470 Val := 0;
8471 Packed_Num := 0;
8473 -- Account for endianness. See corresponding comment in
8474 -- Packed_Array_Aggregate_Handled concerning the following.
8476 if Bytes_Big_Endian
8477 xor Debug_Flag_8
8478 xor Reverse_Storage_Order (Base_Type (Typ))
8479 then
8480 Init_Shift := Byte_Size - Comp_Size;
8481 Incr := -Comp_Size;
8482 else
8483 Init_Shift := 0;
8484 Incr := +Comp_Size;
8485 end if;
8487 -- Iterate over each subaggregate
8489 Shift := Init_Shift;
8490 One_Dim := First (Expressions (N));
8491 while Present (One_Dim) loop
8492 One_Comp := First (Expressions (One_Dim));
8493 while Present (One_Comp) loop
8494 if Packed_Num = Byte_Size / Comp_Size then
8496 -- Byte is complete, add to list of expressions
8498 Append (Make_Integer_Literal (Sloc (One_Dim), Val), Comps);
8499 Val := 0;
8500 Shift := Init_Shift;
8501 Packed_Num := 0;
8503 else
8504 Comp_Val := Expr_Rep_Value (One_Comp);
8506 -- Adjust for bias, and strip proper number of bits
8508 if Has_Biased_Representation (Ctyp) then
8509 Comp_Val := Comp_Val - Expr_Value (Type_Low_Bound (Ctyp));
8510 end if;
8512 Comp_Val := Comp_Val mod Uint_2 ** Comp_Size;
8513 Val := UI_To_Int (Val + Comp_Val * Uint_2 ** Shift);
8514 Shift := Shift + Incr;
8515 One_Comp := Next (One_Comp);
8516 Packed_Num := Packed_Num + 1;
8517 end if;
8518 end loop;
8520 One_Dim := Next (One_Dim);
8521 end loop;
8523 if Packed_Num > 0 then
8525 -- Add final incomplete byte if present
8527 Append (Make_Integer_Literal (Sloc (One_Dim), Val), Comps);
8528 end if;
8530 Rewrite (N,
8531 Unchecked_Convert_To (Typ,
8532 Make_Qualified_Expression (Loc,
8533 Subtype_Mark => New_Occurrence_Of (Packed_Array, Loc),
8534 Expression => Make_Aggregate (Loc, Expressions => Comps))));
8535 Analyze_And_Resolve (N);
8536 return True;
8537 end;
8538 end Two_Dim_Packed_Array_Handled;
8540 end Exp_Aggr;